Release 960728

Sun Jul 28 17:57:19 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [loader/task.c] [include/task.h]
	Implemented SwitchStackTo()/SwitchStackBack().

	* [include/wintypes.h] [loader/main.c]
	Added __winelib variable to distinguish between emulator and
 	library at run-time. Later on, this should avoid some
 	recompilations when building Winelib.

	* [windows/property.c]
	Implemented Win32 functions for window properties.

Fri Jul 26 18:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [controls/listbox.c]
	Implemented LBS_SORT style, WM_COMPAREITEM, and WM_DELETEITEM
	messages.

	* [controls/menu.c]
	Call TranslateMessage() to enable shortcuts (on WM_CHAR).

	* [include/cursoricon.h]
	Moved #pragma pack(1) back to where it belongs.

	* [objects/palette.c]
	RealizeDefaultPalette() maps to system colors only.
	Do not broadcast palette notifications when in TrueColor.

	* [objects/color.c] [include/palette.h]
	Miscellaneous optimizations. Had to fix several
	"improvements" made to my patch for previous release.

	* [objects/dib.c]
	Reverse dib bits order for 24-bit SetDIBits().

	* [objects/dc.c]
	GetDeviceCaps() does not return RC_PALETTE when in TrueColor.

	* [windows/scroll.c]
	Scroll update region too.

	* [windows/message.c]
	Include QS_MOUSE into the event mask for nonclient mouse
	message filter. Fixes problems with Word 6 freezing when
	mouse hits nonclient area.

	* [windows/win.c] 
	Allow top-level windows to be linked as HWND_TOP in CreateWindow().

	* [windows/winpos.c] [windows/mdi.c]
	Attempt to fix control menu duplication.

Fri Jul 26 09:49:35 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/drive.c]
	GetDriveType32A(): return value for CDROM fixed.

	* [files/file.c]
	SearchPath* added.

	* [if1632/gdi32.spec] [objects/brush.c]
	SetBrushOrgEx() added.

	* [loader/pe_resource.c]
	If even loading the default entry fails, we just use the first
	entry from the resource directory.

	[loader/task.c]
	SetSigHandler() stub added, Paradox 4.5 now starts up.

	* [misc/comm.c] [include/windows.h] [if1632/kernel32.spec]
	COMM functions updated to win32, not complete.

	* [misc/lstr.c]
	FormatMessageA partially implemented.

	* [include/miscemu.h] [memory/selector.c]
	  [memory/global.c] [miscemu/dosmem.c]
	DOS memory handling changed: 1MB preallocated block, real-mode
	segment handling possible, SetSelectorBase into lower physical 1MB
	possible.

	* [miscemu/dpmi.c]
	Real-mode segments changed, real-mode int 21,ax=6506 added.
	AX=0x0303 added.

	* [multimedia/time.c]
	Fixed bug in killTimer.

	* [objects/bitmap.c]
	LoadImageA partially implemented.

Wed Jul 24 18:20:24 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [include/dde_mem.h][include/dde_proc.h]
	  [ipc/dde_atom.c][ipc/dde_proc.c][windows/message.c]
	  [ipc/generic_hash.h][library/miscstubs.c]
	Changes for error free compilation using "--with-ipc":
	replaced some names with *16-equivalent (e.g. MSG to MSG16),
	modified prototype of function DDE_GlobalFree() .

	* [objects/palette.c]
	Added check for metafile-DC in GDISelectPalette(),
	GDIRealizePalette(),RealizeDefaultPalette() and
	IsDCCurrentPalette().

Tue Jul 23 22:46:53 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>

	* [controls/edit.c]
	EDIT_WM_Create: Don't EDIT_EM_ReplaceSel if created with lParam = "",
	fixes Winhelp.

	* [windows/dialog.c]
	DIALOG_CreateIndirect: Initialise dlgProc before creating children.
diff --git a/ANNOUNCE b/ANNOUNCE
index 2c43984..cf7b48e 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,13 +1,13 @@
-This is release 960717 of Wine, the MS Windows emulator.  This is still a
+This is release 960728 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-960717: (see ChangeLog for details)
-	- New palette management.
-	- Changes to the configuration process.
+WHAT'S NEW with Wine-960728: (see ChangeLog for details)
+	- Many fixed to the palette management.
+	- DOS real-mode memory emulation.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -16,10 +16,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960717.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960717.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960717.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960717.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960728.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960728.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960728.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960728.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 09c335f..43a3c8f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,121 @@
 ----------------------------------------------------------------------
+Sun Jul 28 17:57:19 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [loader/task.c] [include/task.h]
+	Implemented SwitchStackTo()/SwitchStackBack().
+
+	* [include/wintypes.h] [loader/main.c]
+	Added __winelib variable to distinguish between emulator and
+ 	library at run-time. Later on, this should avoid some
+ 	recompilations when building Winelib.
+
+	* [windows/property.c]
+	Implemented Win32 functions for window properties.
+
+Fri Jul 26 18:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>
+
+	* [controls/listbox.c]
+	Implemented LBS_SORT style, WM_COMPAREITEM, and WM_DELETEITEM
+	messages.
+
+	* [controls/menu.c]
+	Call TranslateMessage() to enable shortcuts (on WM_CHAR).
+
+	* [include/cursoricon.h]
+	Moved #pragma pack(1) back to where it belongs.
+
+	* [objects/palette.c]
+	RealizeDefaultPalette() maps to system colors only.
+	Do not broadcast palette notifications when in TrueColor.
+
+	* [objects/color.c] [include/palette.h]
+	Miscellaneous optimizations. Had to fix several
+	"improvements" made to my patch for previous release.
+
+	* [objects/dib.c]
+	Reverse dib bits order for 24-bit SetDIBits().
+
+	* [objects/dc.c]
+	GetDeviceCaps() does not return RC_PALETTE when in TrueColor.
+
+	* [windows/scroll.c]
+	Scroll update region too.
+
+	* [windows/message.c]
+	Include QS_MOUSE into the event mask for nonclient mouse
+	message filter. Fixes problems with Word 6 freezing when
+	mouse hits nonclient area.
+
+	* [windows/win.c] 
+	Allow top-level windows to be linked as HWND_TOP in CreateWindow().
+
+	* [windows/winpos.c] [windows/mdi.c]
+	Attempt to fix control menu duplication.
+
+Fri Jul 26 09:49:35 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [files/drive.c]
+	GetDriveType32A(): return value for CDROM fixed.
+
+	* [files/file.c]
+	SearchPath* added.
+
+	* [if1632/gdi32.spec] [objects/brush.c]
+	SetBrushOrgEx() added.
+
+	* [loader/pe_resource.c]
+	If even loading the default entry fails, we just use the first
+	entry from the resource directory.
+
+	[loader/task.c]
+	SetSigHandler() stub added, Paradox 4.5 now starts up.
+
+	* [misc/comm.c] [include/windows.h] [if1632/kernel32.spec]
+	COMM functions updated to win32, not complete.
+
+	* [misc/lstr.c]
+	FormatMessageA partially implemented.
+
+	* [include/miscemu.h] [memory/selector.c]
+	  [memory/global.c] [miscemu/dosmem.c]
+	DOS memory handling changed: 1MB preallocated block, real-mode
+	segment handling possible, SetSelectorBase into lower physical 1MB
+	possible.
+
+	* [miscemu/dpmi.c]
+	Real-mode segments changed, real-mode int 21,ax=6506 added.
+	AX=0x0303 added.
+
+	* [multimedia/time.c]
+	Fixed bug in killTimer.
+
+	* [objects/bitmap.c]
+	LoadImageA partially implemented.
+
+Wed Jul 24 18:20:24 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [include/dde_mem.h][include/dde_proc.h]
+	  [ipc/dde_atom.c][ipc/dde_proc.c][windows/message.c]
+	  [ipc/generic_hash.h][library/miscstubs.c]
+	Changes for error free compilation using "--with-ipc":
+	replaced some names with *16-equivalent (e.g. MSG to MSG16),
+	modified prototype of function DDE_GlobalFree() .
+
+	* [objects/palette.c]
+	Added check for metafile-DC in GDISelectPalette(),
+	GDIRealizePalette(),RealizeDefaultPalette() and
+	IsDCCurrentPalette().
+
+Tue Jul 23 22:46:53 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>
+
+	* [controls/edit.c]
+	EDIT_WM_Create: Don't EDIT_EM_ReplaceSel if created with lParam = "",
+	fixes Winhelp.
+
+	* [windows/dialog.c]
+	DIALOG_CreateIndirect: Initialise dlgProc before creating children.
+
+----------------------------------------------------------------------
 Wed Jul 17 16:10:16 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [configure.in]
@@ -270,7 +387,7 @@
 	* [windows/winproc.c]
 	Allows creating dialog windows with NULL as dialog function.
 
-Wed Jul  3 09:26:41 1996  Peter Lewycky <plewycky@oise.utoronto.ca>
+Wed Jul  3 09:26:41 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>
 
 	* [windows/event.c]
 	EVENT_key: Fixes to VK_ code generation for space bar and
diff --git a/controls/combo.c b/controls/combo.c
index 989c0b2..4990654 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -425,10 +425,7 @@
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
 
-  if (lphl->HasStrings)
-    wRet = ListBoxAddString(lphl, (LPSTR)PTR_SEG_TO_LIN(lParam));
-  else
-    wRet = ListBoxAddString(lphl, (LPSTR)lParam);
+  wRet = ListBoxAddString(lphl, (SEGPTR)lParam);
 
   ComboUpdateWindow(hwnd, lphl, lphc, TRUE);
   return wRet;
diff --git a/controls/edit.c b/controls/edit.c
index 5dae7f9..c646fb6 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -2253,7 +2253,7 @@
 	*text = '\0';
 	EDIT_BuildLineDefs(wndPtr);
 	EDIT_WM_SetFont(wndPtr, 0, 0L);
-	if (cs->lpszName)
+	if (cs->lpszName && *(char *)PTR_SEG_TO_LIN(cs->lpszName) != '\0')
 		EDIT_EM_ReplaceSel(wndPtr, FALSE, (LPARAM)cs->lpszName);
 	EDIT_WM_SetRedraw(wndPtr, TRUE, 0L);
 	return 0L;
diff --git a/controls/listbox.c b/controls/listbox.c
index b3a5b8d..1cbb28c 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -3,15 +3,17 @@
  * 
  * Copyright  Martin Ayotte, 1993
  *            Constantine Sapuntzakis, 1995
- * 	      Alex Korobka, 1995 
+ * 	      Alex Korobka, 1995, 1996 
  * 
  */
 
  /*
   * FIXME: 
-  * - check if multi-column listboxes work
-  * - implement more messages and styles 
-  * - implement caret for LBS_EXTENDEDSEL
+  * - proper scrolling for multicolumn style
+  * - anchor and caret for LBS_EXTENDEDSEL
+  * - proper selection with keyboard
+  * - how to handle (LBS_EXTENDEDSEL | LBS_MULTIPLESEL) style
+  * - support for LBS_NOINTEGRALHEIGHT and LBS_OWNERDRAWVARIABLE styles
   */
 
 #include <stdio.h>
@@ -27,6 +29,7 @@
 #include "drive.h"
 #include "file.h"
 #include "heap.h"
+#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
@@ -43,6 +46,10 @@
 #define LBMM_EDGE   4    /* distance inside box which is same as moving mouse
 			    outside box, to trigger scrolling of LB */
 
+#define MATCH_SUBSTR            2
+#define MATCH_EXACT             1
+#define MATCH_NEAREST           0
+
 static void ListBoxInitialize(LPHEADLIST lphl)
 {
   lphl->lpFirst        = NULL;
@@ -267,6 +274,21 @@
   return LB_ERR;
 }
 
+BOOL lbDeleteItemNotify(LPHEADLIST lphl, LPLISTSTRUCT lpls)
+{
+  /* called only for owner drawn listboxes */
+
+  DELETEITEMSTRUCT16   delItem;
+
+  delItem.CtlType = lphl->DrawCtlType;
+  delItem.CtlID   = lphl->CtlID;
+  delItem.itemID  = lpls->mis.itemID;
+  delItem.hwndItem= lphl->hSelf;
+  delItem.itemData= lpls->mis.itemData;
+
+  return (BOOL) SendMessage16(lphl->hParent, WM_DELETEITEM, (WPARAM)lphl->CtlID,
+                                          (LPARAM)MAKE_SEGPTR(&delItem));
+}
 
 void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls)  
 {
@@ -306,7 +328,97 @@
   return lplsnew;
 }
 
+int ListBoxAskCompare(LPHEADLIST lphl, int startItem, SEGPTR matchData, BOOL exactMatch )
+{
+ /*  Do binary search for sorted listboxes. Linked list item storage sort of 
+  *  defeats the purpose ( forces to traverse item list all the time ) but M$ does it this way...
+  *
+  *  MATCH_NEAREST (0) - return position for insertion - for all styles
+  *  MATCH_EXACT   (1) - search for an item, return index or LB_ERR 
+  *  MATCH_SUBSTR  (2) - same as exact match but with strncmp for string comparision
+  */
 
+ COMPAREITEMSTRUCT16    itemCmp;
+ LPLISTSTRUCT		currentItem = NULL;
+ LPCSTR			matchStr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(matchData):NULL;
+ int                    head, pos = -1, tail, loop = 1;
+ short                  b = 0, s_length = 0;
+
+ /* check if empty */
+
+ if( !lphl->ItemsCount )
+    return (exactMatch)? LB_ERR: 0;
+
+ /* set up variables */
+
+ if( exactMatch == MATCH_NEAREST )
+     startItem = 0;
+ else if( ++startItem ) 
+   {
+     loop = 2;
+     if( startItem >= lphl->ItemsCount ) startItem = lphl->ItemsCount - 1;
+   }
+
+ if( exactMatch == MATCH_SUBSTR && lphl->HasStrings )
+   {
+     s_length = strlen( matchStr );
+     if( !s_length ) return 0; 		        /* head of the list - empty string */
+   }
+
+ head = startItem; tail = lphl->ItemsCount - 1;
+
+ dprintf_listbox(stddeb,"AskCompare: head = %i, tail = %i, data = %08x\n", head, tail, (unsigned)matchData );
+
+ itemCmp.CtlType        = lphl->DrawCtlType;
+ itemCmp.CtlID          = lphl->CtlID;
+ itemCmp.hwndItem       = lphl->hSelf;
+
+ /* search from startItem */
+
+ while ( loop-- )
+  {
+    while( head <= tail )
+     {
+       pos = (tail + head)/2;
+       currentItem = ListBoxGetItem( lphl, pos );
+
+       if( lphl->HasStrings )
+	 {
+           b = ( s_length )? strncasecmp( currentItem->itemText, matchStr, s_length)
+                           : strcasecmp( currentItem->itemText, matchStr);
+	 }
+       else
+         {
+           itemCmp.itemID1      = pos;
+           itemCmp.itemData1    = currentItem->mis.itemData;
+           itemCmp.itemID2      = -1;
+           itemCmp.itemData2    = matchData;
+
+           b = SendMessage16( lphl->hParent, WM_COMPAREITEM, (WPARAM)lphl->CtlID, 
+                                                             (LPARAM)MAKE_SEGPTR(&itemCmp) );
+         }
+
+       if( b == 0 ) 
+           return pos;  /* found exact match */
+       else
+         if( b < 0 ) head = ++pos;
+         else
+           if( b > 0 ) tail = pos - 1;
+     }
+
+    /* reset to search from the first item */
+    head = 0; tail = startItem - 1;
+  }
+
+ dprintf_listbox(stddeb,"\t-> pos = %i\n", pos );
+
+ /* if we got here match is not exact */
+
+ if( pos < 0 ) pos = 0;
+ else if( pos > lphl->ItemsCount ) pos = lphl->ItemsCount;
+
+ return (exactMatch)? LB_ERR: pos;
+}
 
 int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr)
 {
@@ -371,16 +483,14 @@
 }
 
 
-int ListBoxAddString(LPHEADLIST lphl, LPCSTR newstr)
+int ListBoxAddString(LPHEADLIST lphl, SEGPTR itemData)
 {
-    UINT pos = (UINT) -1;
-    
-    if (lphl->HasStrings && (lphl->dwStyle & LBS_SORT)) {
-	LPLISTSTRUCT lpls = lphl->lpFirst;
-	for (pos = 0; lpls != NULL; lpls = lpls->lpNext, pos++)
-	    if (strcmp(lpls->itemText, newstr) >= 0)
-		break;
-    }
+    UINT 	pos = (UINT) -1;
+    LPCSTR	newstr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(itemData):(LPCSTR)itemData;
+
+    if ( lphl->dwStyle & LBS_SORT ) 
+	 pos = ListBoxAskCompare( lphl, -1, itemData, MATCH_NEAREST );
+
     return ListBoxInsertString(lphl, pos, newstr);
 }
 
@@ -438,8 +548,13 @@
   if (lpls == NULL) return LB_ERR;
 
   if (uIndex == 0)
+  {
+    if( lphl->OwnerDrawn )
+        lbDeleteItemNotify( lphl, lpls);
     lphl->lpFirst = lpls->lpNext;
-  else {
+  }
+  else 
+  {
     LPLISTSTRUCT lpls2 = NULL;
     for(Count = 0; Count < uIndex; Count++) {
       if (lpls->lpNext == NULL) return LB_ERR;
@@ -447,6 +562,8 @@
       lpls2 = lpls;
       lpls = (LPLISTSTRUCT)lpls->lpNext;
     }
+    if( lphl->OwnerDrawn )
+	lbDeleteItemNotify( lphl, lpls);
     lpls2->lpNext = lpls->lpNext;
   }
 
@@ -463,28 +580,43 @@
   return lphl->ItemsCount;
 }
 
-
-int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
+int lbFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr, BOOL match)
 {
+  /*  match is either MATCH_SUBSTR or MATCH_EXACT */
+
   LPLISTSTRUCT lpls;
   UINT	       Count;
-  UINT         First = nFirst + 1;
+  UINT         First      = nFirst + 1;
+  int	       s_length   = 0;
   LPSTR        lpMatchStr = (LPSTR)MatchStr;
 
   if (First > lphl->ItemsCount) return LB_ERR;
 
-  if (lphl->HasStrings) lpMatchStr = PTR_SEG_TO_LIN(MatchStr);
-  
+  if (lphl->dwStyle & LBS_SORT )
+      return ListBoxAskCompare( lphl, nFirst, MatchStr, match );
+
+  if (lphl->HasStrings ) 
+  {
+    lpMatchStr = PTR_SEG_TO_LIN(MatchStr);
+
+    if( match == MATCH_SUBSTR )
+    {
+      s_length = strlen(lpMatchStr);
+      if( !s_length ) return (lphl->ItemsCount)?0:LB_ERR;
+    }
+  }
+
   lpls = ListBoxGetItem(lphl, First);
   Count = 0;
-  while(lpls != NULL) {
-    if (lphl->HasStrings) {
-      if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
-    } else if (lphl->dwStyle & LBS_SORT) {
-      /* XXX Do a compare item */
+  while(lpls != NULL) 
+  {
+    if (lphl->HasStrings) 
+    {
+      if ( ( s_length )? !strncasecmp(lpls->itemText, lpMatchStr, s_length)
+                       : !strcasecmp(lpls->itemText, lpMatchStr)  ) return Count;
     }
     else
-      if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count;
+      if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
 
     lpls = lpls->lpNext;
     Count++;
@@ -494,14 +626,16 @@
   Count = 0;
   lpls = lphl->lpFirst;
 
-  while (Count < First) {
-    if (lphl->HasStrings) {
-      if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
-    } else if (lphl->dwStyle & LBS_SORT) {
-      /* XXX Do a compare item */
-    } else {
-      if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count;
+  while (Count < First) 
+  {
+    if (lphl->HasStrings) 
+    {
+      if ( ( s_length )? !strncasecmp(lpls->itemText, lpMatchStr, s_length)
+                       : !strcasecmp(lpls->itemText, lpMatchStr)  ) return Count;
     }
+    else
+      if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
+    
     lpls = lpls->lpNext;
     Count++;
   }
@@ -509,6 +643,15 @@
   return LB_ERR;
 }
 
+int ListBoxFindString(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
+{
+  return lbFindString(lphl, nFirst, MatchStr, MATCH_SUBSTR );
+}
+
+int ListBoxFindStringExact(LPHEADLIST lphl, UINT nFirst, SEGPTR MatchStr)
+{
+  return lbFindString(lphl, nFirst, MatchStr, MATCH_EXACT );
+}
 
 int ListBoxResetContent(LPHEADLIST lphl)
 {
@@ -523,7 +666,9 @@
     for(i = 0; i < lphl->ItemsCount; i++) {
       lpls = lphl->lpFirst;
       if (lpls == NULL) return LB_ERR;
-      
+
+      if (lphl->OwnerDrawn) lbDeleteItemNotify(lphl, lpls);
+
       lphl->lpFirst = lpls->lpNext;
       if (lpls->hData != 0) LIST_HEAP_FREE(lphl, lpls->hData);
       free(lpls);
@@ -603,12 +748,13 @@
 
 LONG ListBoxDirectory(LPHEADLIST lphl, UINT attrib, LPCSTR filespec)
 {
-    char temp[16], mask[13];
+    char 	mask[13];
+    char*	temp = NULL;
+    const char*	ptr;
+    int 	skip, count;
+    LONG 	ret;
+    DOS_DIRENT 	entry;
     char *path, *p;
-    const char *ptr;
-    int skip, count;
-    LONG ret;
-    DOS_DIRENT entry;
 
     dprintf_listbox(stddeb, "ListBoxDirectory: '%s' %04x\n", filespec, attrib);
     if (!filespec) return LB_ERR;
@@ -616,11 +762,13 @@
     path = xstrdup(ptr);
     p = strrchr( path, '/' );
     *p++ = '\0';
-    if (!(ptr = DOSFS_ToDosFCBFormat( p )))
+    if (!(ptr = DOSFS_ToDosFCBFormat( p )) || 
+        !(temp = SEGPTR_ALLOC( sizeof(char) * 16 )) )
     {
         free( path );
         return LB_ERR;
     }
+
     strcpy( mask, ptr );
 
     dprintf_listbox(stddeb, "ListBoxDirectory: path=%s mask=%s\n", path, mask);
@@ -636,7 +784,7 @@
             {
                 sprintf(temp, "[%s]", DOSFS_ToDosDTAFormat( entry.name ) );
                 AnsiLower( temp );
-                if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break;
+                if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
             }
         }
         else  /* not a directory */
@@ -647,9 +795,11 @@
             {
                 strcpy( temp, DOSFS_ToDosDTAFormat( entry.name ) );
                 AnsiLower( temp );
-                if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break;
+                if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
             }
         }
+
+        dprintf_listbox(stddeb,"\tn - %i, file '%s'\n", count, temp); 
     }
     if (attrib & DDL_DRIVES)
     {
@@ -658,10 +808,13 @@
         for (x = 0; x < MAX_DOS_DRIVES; x++, temp[2]++)
         {
             if (DRIVE_IsValid(x))
-                if ((ret = ListBoxAddString(lphl, temp)) == LB_ERR) break;
+                if ((ret = ListBoxAddString(lphl, SEGPTR_GET(temp))) == LB_ERR) break;
         }
     }
+
     free( path );
+    SEGPTR_FREE( temp );
+
     return ret;
 }
 
@@ -1432,10 +1585,7 @@
   WORD  wRet;
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-  if (lphl->HasStrings)
-    wRet = ListBoxAddString(lphl, (LPCSTR)PTR_SEG_TO_LIN(lParam));
-  else
-    wRet = ListBoxAddString(lphl, (LPCSTR)lParam);
+  wRet = ListBoxAddString(lphl, (SEGPTR)lParam);
 
   ListBoxUpdateWindow(hwnd,lphl,TRUE);
   return wRet;
@@ -1490,7 +1640,16 @@
 static LONG LBFindString(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  return ListBoxFindString(lphl, wParam, (SEGPTR)lParam);
+  return lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_SUBSTR);
+}
+
+/***********************************************************************
+ *           LBFindStringExact
+ */
+static LONG LBFindStringExact(HWND hwnd, WORD wParam, LONG lParam)
+{
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  return lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_EXACT);
 }
 
 /***********************************************************************
@@ -1661,7 +1820,7 @@
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   INT  iRet;
 
-  iRet = ListBoxFindString(lphl, wParam, (SEGPTR)lParam);
+  iRet = lbFindString(lphl, wParam, (SEGPTR)lParam, MATCH_SUBSTR);
 
   if( iRet != LB_ERR)
     {
@@ -1920,6 +2079,7 @@
      case LB_INSERTSTRING: return LBInsertString(hwnd, wParam, lParam);
      case LB_DELETESTRING: return LBDeleteString(hwnd, wParam, lParam);
      case LB_FINDSTRING: return LBFindString(hwnd, wParam, lParam);
+     case LB_FINDSTRINGEXACT: return LBFindStringExact(hwnd, wParam, lParam);
      case LB_GETCARETINDEX: return LBGetCaretIndex(hwnd, wParam, lParam);
      case LB_GETCOUNT: return LBGetCount(hwnd, wParam, lParam);
      case LB_GETCURSEL: return LBGetCurSel(hwnd, wParam, lParam);
diff --git a/controls/menu.c b/controls/menu.c
index c880829..e38a4cd 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -1533,6 +1533,8 @@
                                      hwnd, MSGF_MENU, 0, TRUE ))
 	    break;
 
+        TranslateMessage( msg );
+
         fRemove = FALSE;
 	if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
 	{
diff --git a/documentation/debugging b/documentation/debugging
new file mode 100644
index 0000000..1cee434
--- /dev/null
+++ b/documentation/debugging
@@ -0,0 +1,206 @@
+This file describes where to start debugging Wine and how to write
+useful bug reports.
+
+Crashes
+=======
+
+  These usually show up like this:
+
+|Unexpected Windows program segfault - opcode = 8b
+|Segmentation fault in Windows program 1b7:c41.
+|Reading symbols from file /root/wine/wine.sym
+|In 16 bit mode.
+|Register dump:
+| CS:01b7 SS:016f DS:0287 ES:0000
+| IP:0c41 SP:878a BP:8796 FLAGS:0246
+| AX:811e BX:0000 CX:0000 DX:0000 SI:0001 DI:ffff
+|Stack dump:
+|0x016f:0x878a:  0001 016f ffed 0000 0000 0287 890b 1e5b
+|0x016f:0x879a:  01b7 0001 000d 1050 08b7 016f 0001 000d
+|0x016f:0x87aa:  000a 0003 0004 0000 0007 0007 0190 0000
+|0x016f:0x87ba:
+|
+|0050: sel=0287 base=40211d30 limit=0b93f (bytes) 16-bit rw-
+|Backtrace:
+|0 0x01b7:0x0c41 (PXSRV.FONGETFACENAME+0x7c)
+|1 0x01b7:0x1e5b (PXSRV.FONPUTCATFONT+0x2cd)
+|2 0x01a7:0x05aa
+|3 0x01b7:0x0768 (PXSRV.FONINITFONTS+0x81)
+|4 0x014f:0x03ed (PDOXWIN.@SQLCURCB$Q6CBTYPEULN8CBSCTYPE+0x1b1)
+|5 0x013f:0x00ac
+|
+|0x01b7:0x0c41 (PXSRV.FONGETFACENAME+0x7c):  movw        %es:0x38(%bx),%dx
+
+Steps to debug a crash. You may stop at any step, but please report the bug
+and provide as much of the information gathered to the newsgroup or the
+relevant developer as feasonable.
+  
+ 1. Get the reason for the crash. This is usually an access to an invalid
+    selector, an access to an out of range address in a valid selector,
+    popping a segmentregister from the stack or the like. When reporting a
+    crash, report this WHOLE crashdump even if it doesn't make sense to you.
+
+    (In this case it is access to an invalid selector, for %es is 0000, as
+    seen in the register dump).
+    
+ 2. Determine where the reason came from.
+    Since this is usually a primary/secondary reaction to a failed or
+    misbehaving Wine function, rerun Wine with "-debugmsg +relay" (without ")
+    added to the commandline. This will get rather much output, but usually
+    the reason is located in the last call(s).  Those lines usually look like
+    this:
+
+|Call KERNEL.90: LSTRLEN(0227:0692) ret=01e7:2ce7 ds=0227
+      ^^^^^^^^^  ^       ^^^^^^^^^      ^^^^^^^^^    ^^^^
+      |          |       |              |            |Datasegment on entry
+      |          |       |              |Return address.
+      |          |       |
+      |          |       |Argument(s). This one is a win16 segmented pointer.
+      |          |Function called.
+      |The module, the function is called in. In this case it is KERNEL.
+		        
+|Ret  KERNEL.90: LSTRLEN() retval=0x0007 ret=01e7:2ce7 ds=0227
+                                  ^^^^^^
+				  |Returnvalue is 16 bit and has the value 7.
+
+ 3. If you have found a misbehaving function, try to find out why it
+    misbehaves. Find the function in the source code. Try to make sense of
+    the arguments passed. Usually there is a
+    "dprintf_xyz(stddeb,"Fnction(...)"...);" at the beginning of the
+    function. Rerun wine with "-debugmsg +xyz,+relay" added to the
+    commandline.
+
+
+ 4. If those information isn't clear enough or if you want to know more about
+    what's happening in the function itself, try running wine with "-debugmsg
+    +all", which dumps ALL included debug information in wine.
+
+ 5. If that isn't enough add more debug output for yourself into the
+    functions you find relevant.
+  
+ 6. You can also set a breakpoint for that function. Start wine with the
+    "-debug" option added to the commandline. After loading the executable
+    wine will enter the internal debugger. Use "break KERNEL.LSTRLEN"
+    (replace by function you want to debug, CASE IS RELEVANT.) to set a
+    breakpoint.  Then use "continue" to start normal program-execution. Wine
+    will stop if it reaches the breakpoint. If the program isn't yet at the
+    crashing call of that function, use "continue" again until you are about
+    to enter that function. You may now proceed with single-stepping the
+    function until you reach the point of crash. Use the other debugger
+    commands to print registers and the like.
+
+
+Program hangs, nothing happens
+==============================
+
+  Switch to UNIX shell, get the process-ID using "ps -a|grep wine", and do a
+  "kill -HUP <pid>" (without " and <>). Wine will then enter its internal
+  debugger and you can procede as explained above.
+
+Program reports an error with a Messagebox
+==========================================
+
+  Sometimes programs are reporting failure using a more or less nondescript
+  messageboxes. We can debug this using the same method as Crashes, but there
+  is one problem... For setting up a message box the program also calls Wine
+  producing huge chunks of debug code.
+
+  Since the failure happens usually directly before setting up the Messagebox
+  you can start wine with "-debug" added to the commandline, set a breakpoint
+  at "USER.MESSAGEBOX" (win16 programs) "USER32.MessageBox" (win32 Programs)
+  and proceed with "continue". With "-debugmsg +all" Wine will now stop
+  directly directly before setting up the Messagebox.  Proceed as explained
+  above.
+
+
+Sample debugging session:
+=========================
+
+  Let's debug the infamous Word SHARE.EXE messagebox: 
+
+|marcus@jet $ wine winword.exe
+|            +---------------------------------------------+
+|            | !  You must leave Windows and load SHARE.EXE|
+|            |    before starting Word.                    |
+|            +---------------------------------------------+
+
+
+|marcus@jet $ wine winword.exe -debugmsg +relay -debug
+|CallTo32(func=08007e00,000001c4,00000081,00000000,00000000)
+|CallTo32(func=08007e00,000001c4,00000014,000006d0,00000000)
+|Win16 task 'winword': Breakpoint 1 at 0x0157:0x001a
+|CallTo16(func=0097:0130,ds=0000)
+|Call WPROCS.24: TASK_RESCHEDULE() ret=003f:0759 ds=0000
+|Ret  WPROCS.24: TASK_RESCHEDULE() retval=0x0000 ret=003f:0759 ds=08a7
+|CallTo16(func=0157:001a,ds=08a7,0x11d7,0x0000,0x0000,0x3cb4,0x1f40,0x0000,0x0000,0x08a7)
+|Reading symbols from file /root/wine/wine.sym
+|Stopped on breakpoint 1 at 0x0157:0x001a
+|In 16 bit mode.
+|0x0157:0x001a:  xorw	%bp,%bp
+|Wine-dbg> break USER.MESSAGEBOX                       <---- Set Breakpoint
+|Breakpoint 2 at 0x0067:0x00000000 (USER.MESSAGEBOX)
+|Wine-dbg>c                                            <---- Continue
+|Call KERNEL.91: INITTASK() ret=0157:0022 ds=08a7
+|     AX=0000 BX=3cb4 CX=1f40 DX=0000 SI=0000 DI=08a7 ES=11d7 EFL=00000286
+|CallTo16(func=090f:085c,ds=0dcf,0x0000,0x0000,0x0000,0x0000,0x0800,0x0000,0x0000,0x0dcf)
+|...                                                   <----- Much debugoutput
+|Call KERNEL.97: GETTEMPFILENAME(0x00c3,08a7:8350,0x0000,08a7:8234) ret=058f:09b1 ds=08a7
+                                 ^      ^         ^      ^
+				 |      |         |      |LPSTR buffer
+				 |      |         |UINT16 unique
+				 |      |LPCSTR prefix
+				 |BYTE drive
+
+|Ret  KERNEL.97: GETTEMPFILENAME() retval=0xce3f ret=058f:09b1 ds=08a7
+                                          ^
+                                          |new unique number
+
+|Call KERNEL.74: OPENFILE(08a7:8234,08a7:82c6,0x1012) ret=058f:09d8 ds=08a7
+                          ^         ^         ^
+                          |         |         |UINT32 mode
+                          |         |OFSTRUCT *ofs
+                          |LPCSTR name
+
+|Ret  KERNEL.74: OPENFILE() retval=0xffff ret=058f:09d8 ds=08a7
+                                   ^
+				   | -1 aka. HFILE_ERROR
+
+|Stopped on breakpoint 2 at 0x0067:0x00000000 (USER.MESSAGEBOX)
+|In 32 bit mode.
+|0x0067:0x00000000 (USER.MESSAGEBOX):  pushw	%bp
+
+    Now, we see that OPENFILE seem to have returned 0xFFFF (or -1). Checking
+    the implementation of OpenFile in files/file.c, this signals an error.
+    The mode flags (OF_READWRITE|OF_SHARE_EXCLUSIVE|OF_CREATE) seems to
+    indicate, that WinWord wants to open the file for writing, so we check
+    the filename. Since we don't see the filename in this debugoutput, we use
+    the dprintf_file() in OpenFile to print out more information by adding
+    "-debugmsg +relay" to the commandline.
+
+    (In fact, we see that the filename has been returned by the GetTempFileName
+     function above, but we check it anyway.)
+
+|marcus@jet $ wine winword.exe -debugmsg +relay,+file -debug
+|.....much more debugoutput .....
+|
+|Call KERNEL.97: GETTEMPFILENAME(0x00c3,08a7:8350,0x0000,08a7:8234) ret=058f:09b1 ds=08a7
+|FILE_Create: 'C:~docd03d.tmp' 01b6 1
+|FILE_SetDosError: errno = 13
+|GetTempFileName: returning C:\~DOCD03D.TMP
+|Ret  KERNEL.97: GETTEMPFILENAME() retval=0xd03d ret=058f:09b1 ds=08a7
+|Call KERNEL.74: OPENFILE(08a7:8234,08a7:82c6,0x1012) ret=058f:09d8 ds=08a7
+|OpenFile: C:\~DOCD03D.TMP 1012
+|FILE_AllocTaskHandle: returning task handle 1, dos_file 0, file 1 of 254
+|FILE_Create: 'C:\~DOCD03D.TMP' 01b6 0
+|FILE_SetDosError: errno = 13
+|OpenFile(C:\~DOCD03D.TMP): return = HFILE_ERROR
+|FILE_FreeTaskHandle: dos=1 file=0
+|Ret  KERNEL.74: OPENFILE() retval=0xffff ret=058f:09d8 ds=08a7
+
+    The filename is "C:\~DOCD03D.TMP". Of course, C:\ is writeable for the
+    superuser only, so the open fails for a normal user and OpenFile returns
+    -1, which in turn generates this messagebox.
+
+
+Written by Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>,
+additions welcome.
diff --git a/files/drive.c b/files/drive.c
index fb15297..f85c149 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -557,7 +557,7 @@
     {
     case TYPE_FLOPPY:  return DRIVE_REMOVABLE;
     case TYPE_HD:      return DRIVE_FIXED;
-    case TYPE_CDROM:   return DRIVE_REMOVABLE;
+    case TYPE_CDROM:   return DRIVE_CDROM;
     case TYPE_NETWORK: return DRIVE_REMOTE;
     case TYPE_INVALID:
     default:           return DRIVE_CANNOTDETERMINE;
diff --git a/files/file.c b/files/file.c
index 7d30397..2ea02e3 100644
--- a/files/file.c
+++ b/files/file.c
@@ -802,6 +802,121 @@
     return HFILE_ERROR;
 }
 
+/***********************************************************************
+ *           SearchPath32A   (KERNEL32.447)
+ * Code borrowed from OpenFile above.
+ */
+DWORD SearchPath32A(
+	LPCSTR path,LPCSTR fn,LPCSTR ext,DWORD buflen,LPSTR buf,LPSTR *lastpart
+) {
+    LPCSTR	unixName;
+    INT32	len;
+    char	testpath[1000]; /* should be enough for now */
+    char	*name,*p;
+    int		i;
+
+    if (ext==NULL)
+    	ext = "";
+    name=(char*)xmalloc(strlen(fn)+strlen(ext)+1);
+    strcpy(name,fn);
+    strcat(name,ext);
+
+    dprintf_file(stddeb,"SearchPath32A(%s,%s,%s,%ld,%p,%p)\n",
+    	path,fn,ext,buflen,buf,lastpart
+    );
+    if (path) {
+	strcpy(testpath,path);
+	strcat(testpath,"\\");
+	strcat(testpath,name);
+	if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL) {
+	    goto found;
+	} else
+	    return 0;
+    }
+    if ((len=sizeof(testpath)-strlen(name)-1)<0)
+    	return 0;
+
+    /* Try the path of the current executable */
+    if (GetCurrentTask()) {
+	GetModuleFileName(GetCurrentTask(),testpath,len);
+	if ((p=strrchr(testpath,'\\'))) {
+            strcpy(p+1,name);
+            if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE)))
+                goto found;
+        }
+    }
+
+    /* Try the current directory */
+    lstrcpyn32A(testpath,name,sizeof(testpath) );
+    if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+        goto found;
+
+    /* Try the Windows directory */
+    GetWindowsDirectory(testpath,len);
+    strcat(testpath,"\\");
+    strcat(testpath,name);
+    if ((unixName = DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+        goto found;
+
+    /* Try the Windows system directory */
+    GetSystemDirectory32A(testpath,len);
+    strcat(testpath,"\\");
+    strcat(testpath,name);
+    if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+        goto found;
+
+    /* Try all directories in path */
+
+    for (i=0;;i++)
+    {
+        if (!DIR_GetDosPath(i,testpath,len)) 
+		return 0;
+        strcat(testpath,"\\");
+        strcat(testpath,name);
+        if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+            break;
+    }
+
+found:
+    strncpy(buf,testpath,buflen);
+    if (NULL!=(p=strrchr(testpath,'\\')))
+    	p=p+1;
+    else
+        p=testpath;
+    if (p-testpath<buflen)
+	*lastpart=(p-testpath)+buf;
+    else
+    	*lastpart=NULL;
+    dprintf_file(stddeb,"	-> found %s,last part is %s\n",testpath,p);
+    return strlen(testpath);
+}
+
+/***********************************************************************
+ *           SearchPath32W   (KERNEL32.448)
+ */
+DWORD SearchPath32W(
+	LPCWSTR path,LPCWSTR fn,LPCWSTR ext,DWORD buflen,LPWSTR buf,
+	LPWSTR *lastpart
+) {
+	LPSTR	pathA = path?STRING32_DupUniToAnsi(path):NULL;
+	LPSTR	fnA = STRING32_DupUniToAnsi(fn);
+	LPSTR	extA = ext?STRING32_DupUniToAnsi(fn):NULL;
+	LPSTR	lastpartA;
+	LPSTR	bufA = (char*)xmalloc(buflen+1);
+	DWORD	ret;
+
+	ret=SearchPath32A(pathA,fnA,extA,buflen,bufA,&lastpartA);
+	lstrcpynAtoW(buf,bufA,buflen);
+	if (lastpartA)
+		*lastpart = buf+(lastpartA-bufA);
+	else
+		*lastpart = NULL;
+	free(bufA);
+	free(fnA);
+	if (pathA) free(pathA);
+	if (extA) free(extA);
+	return ret;
+}
 
 /***********************************************************************
  *           _lclose   (KERNEL.81) (KERNEL32.592)
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index f145907..dca8d1b 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -312,7 +312,7 @@
 0305 stdcall SetBkColor(long long) SetBkColor
 0306 stdcall SetBkMode(long long) SetBkMode
 0307 stub SetBoundsRect
-0308 stub SetBrushOrgEx
+0308 stdcall SetBrushOrgEx(long long long ptr) SetBrushOrgEx
 0309 stub SetColorAdjustment
 0310 stub SetColorSpace
 0311 stub SetDIBColorTable
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index a607a33..ece39884 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -104,8 +104,8 @@
 105 stub GetExeVersion
 106 pascal SetSwapAreaSize(word) SetSwapAreaSize
 107 pascal16 SetErrorMode(word) SetErrorMode
-108 stub SwitchStackTo
-109 stub SwitchStackBack
+108 pascal16 SwitchStackTo(word word word) SwitchStackTo
+109 register SwitchStackBack() SwitchStackBack
 110 pascal16 PatchCodeHandle(word) PatchCodeHandle
 111 pascal GlobalWire(word) GlobalWire
 112 pascal16 GlobalUnWire(word) GlobalUnWire
@@ -138,7 +138,7 @@
 137 pascal FatalAppExit(word ptr) FatalAppExit
 138 pascal GetHeapSpaces(word) GetHeapSpaces
 139 stub DoSignal
-140 stub SetSigHandler
+140 pascal16 SetSigHandler(segptr ptr ptr word word) SetSigHandler
 141 stub InitTask1
 142 stub GetProfileSectionNames
 143 stub GetPrivateProfileSectionNames
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 7378cce..71833e4 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -16,14 +16,14 @@
 0011 stdcall Beep(long long) Beep
 0012 stub BeginUpdateResourceA
 0013 stub BeginUpdateResourceW
-0014 stub BuildCommDCBA
-0015 stub BuildCommDCBAndTimeoutsA
-0016 stub BuildCommDCBAndTimeoutsW
-0017 stub BuildCommDCBW
+0014 stdcall BuildCommDCBA(ptr ptr) BuildCommDCB32A
+0015 stdcall BuildCommDCBAndTimeoutsA(ptr ptr ptr) BuildCommDCBAndTimeouts32A
+0016 stdcall BuildCommDCBAndTimeoutsW(ptr ptr ptr) BuildCommDCBAndTimeouts32W
+0017 stdcall BuildCommDCBW(ptr ptr) BuildCommDCB32W
 0018 stub CallNamedPipeA
 0019 stub CallNamedPipeW
-0020 stub ClearCommBreak
-0021 stub ClearCommError
+0020 stdcall ClearCommBreak(long) ClearCommBreak32
+0021 stdcall ClearCommError(long ptr ptr) ClearCommError
 0022 stub CloseConsoleHandle
 0023    stdcall CloseHandle(long) CloseHandle
 0024 stub CloseProfileUserMapping
@@ -101,8 +101,8 @@
 0096 stub EnumTimeFormatsA
 0097 stub EnumTimeFormatsW
 0098 stub EraseTape
-0099 stub EscapeCommFunction
-0100   stdcall ExitProcess(long) ExitProcess
+0099 stdcall EscapeCommFunction(long long) EscapeCommFunction32
+0100 stdcall ExitProcess(long) ExitProcess
 0101 stub ExitThread
 0102 stub ExitVDM
 0103 stub ExpandEnvironmentStringsA
@@ -140,7 +140,7 @@
 0135 stub FlushViewOfFile
 0136 stub FoldStringA
 0137 stub FoldStringW
-0138 stub FormatMessageA
+0138 stdcall FormatMessageA(long ptr long long ptr long ptr) FormatMessage32A
 0139 stub FormatMessageW
 0140 stub FreeConsole
 0141 stdcall FreeEnvironmentStringsA(ptr)	FreeEnvironmentStringsA
@@ -156,14 +156,14 @@
 0151 stub GetBinaryType
 0152 stub GetBinaryTypeA
 0153 stub GetBinaryTypeW
-0154    stdcall GetCPInfo(long ptr) GetCPInfo
+0154 stdcall GetCPInfo(long ptr) GetCPInfo
 0155 stub GetCommConfig
-0156 stub GetCommMask
+0156 stdcall GetCommMask(long ptr) GetCommMask
 0157 stub GetCommModemStatus
 0158 stub GetCommProperties
-0159 stub GetCommState
-0160 stub GetCommTimeouts
-0161	stdcall GetCommandLineA()	GetCommandLineA
+0159 stdcall GetCommState(long ptr) GetCommState32
+0160 stdcall GetCommTimeouts(long ptr) GetCommTimeouts
+0161 stdcall GetCommandLineA()	GetCommandLineA
 0162 stub GetCommandLineW
 0163 stub GetCompressedFileSizeA
 0164 stub GetCompressedFileSizeW
@@ -449,13 +449,13 @@
 0444 stdcall RtlZeroMemory(ptr long) RtlZeroMemory
 0445 stub ScrollConsoleScreenBufferA
 0446 stub ScrollConsoleScreenBufferW
-0447 stub SearchPathA
-0448 stub SearchPathW
-0449 stub SetCommBreak
+0447 stdcall SearchPathA(ptr ptr ptr long ptr ptr) SearchPath32A
+0448 stdcall SearchPathW(ptr ptr ptr long ptr ptr) SearchPath32W
+0449 stdcall SetCommBreak(long) SetCommBreak32
 0450 stub SetCommConfig
-0451 stub SetCommMask
-0452 stub SetCommState
-0453 stub SetCommTimeouts
+0451 stdcall SetCommMask(long ptr) SetCommMask
+0452 stdcall SetCommState(long ptr) SetCommState32
+0453 stdcall SetCommTimeouts(long ptr) SetCommTimeouts
 0454 stub SetComputerNameA
 0455 stub SetComputerNameW
 0456 stub SetConsoleActiveScreenBuffer
@@ -537,7 +537,7 @@
 0532 stdcall TlsGetValue(long)	TlsGetValue
 0533 stdcall TlsSetValue(long ptr)	TlsSetValue
 0534 stub TransactNamedPipe
-0535 stub TransmitCommChar
+0535 stdcall TransmitCommChar(long long) TransmitCommChar32
 0536 stub TrimVirtualBuffer
 0537    stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
 0538 stub UnlockFile
diff --git a/if1632/relay.c b/if1632/relay.c
index 8401948..614c419 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -4,7 +4,7 @@
  */
 
 #include <stdio.h>
-
+#include "windows.h"
 #include "global.h"
 #include "module.h"
 #include "registers.h"
@@ -268,6 +268,19 @@
     /* only 9 words long. Hopefully no one will have the silly    */
     /* idea to change the current stack before calling Throw()... */
 
+    /* Windows uses:
+     * lpbuf[0] = ip
+     * lpbuf[1] = cs
+     * lpbuf[2] = sp
+     * lpbuf[3] = bp
+     * lpbuf[4] = si
+     * lpbuf[5] = di
+     * lpbuf[6] = ds
+     * lpbuf[7] = unused
+     * lpbuf[8] = ss
+     */
+    /* FIXME: we need to save %si and %di */
+
     lpbuf[0] = IF1632_Saved16_sp;
     lpbuf[1] = LOWORD(IF1632_Saved32_esp);
     lpbuf[2] = HIWORD(IF1632_Saved32_esp);
@@ -287,6 +300,7 @@
 INT16 Throw( LPCATCHBUF lpbuf, INT16 retval )
 {
     STACK16FRAME *pFrame;
+    WORD es = CURRENT_STACK16->es;
 
     IF1632_Saved16_sp  = lpbuf[0] - sizeof(WORD);
     IF1632_Saved32_esp = MAKELONG( lpbuf[1], lpbuf[2] );
@@ -297,6 +311,15 @@
     pFrame->bp         = lpbuf[6];
     pFrame->ip         = lpbuf[7];
     pFrame->cs         = lpbuf[8];
-    pFrame->es         = 0;
+    pFrame->es         = es;
+    if (debugging_relay)  /* Make sure we have a valid entry point address */
+    {
+        static FARPROC16 entryPoint = NULL;
+
+        if (!entryPoint)  /* Get entry point for Throw() */
+            entryPoint = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"), 56 );
+        pFrame->entry_cs = SELECTOROF(entryPoint);
+        pFrame->entry_ip = OFFSETOF(entryPoint);
+    }
     return retval;
 }
diff --git a/if1632/user.spec b/if1632/user.spec
index 52ff7e7..5e10675 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -23,10 +23,10 @@
 21  pascal16 GetDoubleClickTime() GetDoubleClickTime
 22  pascal16 SetFocus(word) SetFocus
 23  pascal16 GetFocus() GetFocus
-24  pascal16 RemoveProp(word segptr) RemoveProp
-25  pascal16 GetProp(word segptr) GetProp
-26  pascal16 SetProp(word segptr word) SetProp
-27  pascal16 EnumProps(word segptr) EnumProps
+24  pascal16 RemoveProp(word ptr) RemoveProp16
+25  pascal16 GetProp(word ptr) GetProp16
+26  pascal16 SetProp(word ptr word) SetProp16
+27  pascal16 EnumProps(word segptr) EnumProps16
 28  pascal16 ClientToScreen(word ptr) ClientToScreen16
 29  pascal16 ScreenToClient(word ptr) ScreenToClient16
 30  pascal16 WindowFromPoint(long) WindowFromPoint16
@@ -201,20 +201,20 @@
 198 pascal16 CascadeChildWindows(word word) CascadeChildWindows
 199 pascal16 TileChildWindows(word word) TileChildWindows
 200 pascal16 OpenComm(ptr word word) OpenComm
-201 pascal16 SetCommState(ptr) SetCommState
-202 pascal16 GetCommState(word ptr) GetCommState
+201 pascal16 SetCommState(ptr) SetCommState16
+202 pascal16 GetCommState(word ptr) GetCommState16
 203 pascal16 GetCommError(word ptr) GetCommError
 204 pascal16 ReadComm(word ptr word) ReadComm
 205 pascal16 WriteComm(word ptr word) WriteComm
-206 pascal16 TransmitCommChar(word byte) TransmitCommChar 
+206 pascal16 TransmitCommChar(word byte) TransmitCommChar16
 207 pascal16 CloseComm(word) CloseComm
 208 pascal   SetCommEventMask(word word) SetCommEventMask
 209 pascal16 GetCommEventMask(word word) GetCommEventMask
-210 pascal16 SetCommBreak(word) SetCommBreak
-211 pascal16 ClearCommBreak(word) ClearCommBreak
+210 pascal16 SetCommBreak(word) SetCommBreak16
+211 pascal16 ClearCommBreak(word) ClearCommBreak16
 212 pascal16 UngetCommChar(word byte) UngetCommChar
-213 pascal16 BuildCommDCB(ptr ptr) BuildCommDCB
-214 pascal   EscapeCommFunction(word word) EscapeCommFunction
+213 pascal16 BuildCommDCB(ptr ptr) BuildCommDCB16
+214 pascal   EscapeCommFunction(word word) EscapeCommFunction16
 215 pascal16 FlushComm(word word) FlushComm
 #216 USERSEEUSERDO
 217 pascal16 LookupMenuHandle(word s_word) LookupMenuHandle
diff --git a/if1632/user32.spec b/if1632/user32.spec
index ef4b733..d6da555 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -55,7 +55,7 @@
 0050 stub ClientThreadConnect
 0051 stdcall ClientToScreen(long ptr) ClientToScreen32
 0052 stdcall ClipCursor(ptr) ClipCursor32
-0053 stub CloseClipboard
+0053 stdcall CloseClipboard() CloseClipboard
 0054 stub CloseDesktop
 0055 stub CloseWindow
 0056 stub CloseWindowStation
@@ -189,10 +189,10 @@
 0182 stub EnumDisplayDeviceModesW
 0183 stub EnumDisplayDevicesA
 0184 stub EnumDisplayDevicesW
-0185 stub EnumPropsA
-0186 stub EnumPropsExA
-0187 stub EnumPropsExW
-0188 stub EnumPropsW
+0185 stdcall EnumPropsA(long ptr) EnumProps32A
+0186 stdcall EnumPropsExA(long ptr long) EnumPropsEx32A
+0187 stdcall EnumPropsExW(long ptr long) EnumPropsEx32W
+0188 stdcall EnumPropsW(long ptr) EnumProps32W
 0189 stdcall EnumThreadWindows(long ptr long) EnumThreadWindows
 0190 stub EnumWindowStationsA
 0191 stub EnumWindowStationsW
@@ -243,7 +243,7 @@
 0236 stdcall GetDlgItemTextA(long long ptr long) GetDlgItemText32A
 0237 stdcall GetDlgItemTextW(long long ptr long) GetDlgItemText32W
 0238 stub GetDoubleClickTime
-0239 stub GetFocus
+0239 stdcall GetFocus() GetFocus
 0240 stub GetForegroundWindow
 0241 stub GetIconInfo
 0242 stub GetInputDesktop
@@ -265,7 +265,7 @@
 0258 stub GetMenuContextHelpId
 0259 stub GetMenuDefaultItem
 0260 stub GetMenuIndex
-0261 stub GetMenuItemCount
+0261 stdcall GetMenuItemCount(long) GetMenuItemCount
 0262 stub GetMenuItemID
 0263 stub GetMenuItemInfoA
 0264 stub GetMenuItemInfoW
@@ -284,8 +284,8 @@
 0277 stub GetParent
 0278 stub GetPriorityClipboardFormat
 0279 stub GetProcessWindowStation
-0280 stub GetPropA
-0281 stub GetPropW
+0280 stdcall GetPropA(long ptr) GetProp32A
+0281 stdcall GetPropW(long ptr) GetProp32W
 0282 stub GetQueueStatus
 0283 stub GetScrollInfo
 0284 stub GetScrollPos
@@ -343,7 +343,7 @@
 0336 stdcall IsCharUpperA(long) IsCharUpper32A
 0337 stdcall IsCharUpperW(long) IsCharUpper32W
 0338 stub IsChild
-0339 stub IsClipboardFormatAvailable
+0339 stdcall IsClipboardFormatAvailable(long) IsClipboardFormatAvailable
 0340 stub IsDialogMessage
 0341 stub IsDialogMessageA
 0342 stub IsDialogMessageW
@@ -368,7 +368,7 @@
 0361 stdcall LoadCursorW(long ptr) LoadCursor32W
 0362 stdcall LoadIconA(long ptr) LoadIcon32A
 0363 stdcall LoadIconW(long ptr) LoadIcon32W
-0364 stub LoadImageA
+0364 stdcall LoadImageA(long ptr long long long long) LoadImage32A
 0365 stub LoadImageW
 0366 stub LoadKeyboardLayoutA
 0367 stub LoadKeyboardLayoutW
@@ -410,7 +410,7 @@
 0403 stdcall OemToCharBuffW(ptr ptr long) OemToCharBuff32W
 0404 stdcall OemToCharW(ptr ptr) OemToChar32W
 0405 stdcall OffsetRect(ptr long long) OffsetRect32
-0406 stub OpenClipboard
+0406 stdcall OpenClipboard(long) OpenClipboard
 0407 stub OpenDesktopA
 0408 stub OpenDesktopW
 0409 stub OpenIcon
@@ -445,8 +445,8 @@
 0438 stdcall ReleaseCapture() ReleaseCapture
 0439 stdcall ReleaseDC(long long) ReleaseDC
 0440 stub RemoveMenu
-0441 stub RemovePropA
-0442 stub RemovePropW
+0441 stdcall RemovePropA(long ptr) RemoveProp32A
+0442 stdcall RemovePropW(long ptr) RemoveProp32W
 0443 stub ReplyMessage
 0444 stub ResetDisplay
 0445 stub ReuseDDElParam
@@ -490,7 +490,7 @@
 0483 stub SetKeyboardState
 0484 stub SetLastErrorEx
 0485 stub SetLogonNotifyWindow
-0486 stub SetMenu
+0486 stdcall SetMenu(long long) SetMenu
 0487 stub SetMenuContextHelpId
 0488 stub SetMenuDefaultItem
 0489 stub SetMenuItemBitmaps
@@ -500,8 +500,8 @@
 0493 stdcall  SetMessageQueue(long) SetMessageQueue
 0494 stub SetParent
 0495 stub SetProcessWindowStation
-0496 stub SetPropA
-0497 stub SetPropW
+0496 stdcall SetPropA(long ptr long) SetProp32A
+0497 stdcall SetPropW(long ptr long) SetProp32W
 0498 stdcall SetRect(ptr long long long long) SetRect32
 0499 stdcall SetRectEmpty(ptr) SetRectEmpty32
 0500 stub SetScrollInfo
@@ -535,7 +535,7 @@
 0528 stdcall ShowCaret(long) ShowCaret
 0529 stdcall ShowCursor(long) ShowCursor
 0530 stub ShowOwnedPopups
-0531 stub ShowScrollBar
+0531 stdcall ShowScrollBar(long long long) ShowScrollBar
 0532 stub ShowStartGlass
 0533 stdcall ShowWindow(long long) ShowWindow
 0534 stub ShowWindowAsync
diff --git a/include/callback.h b/include/callback.h
index 6d2d7aa..d420f76 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -60,8 +60,8 @@
     CallTo16_word_wllwl(func, CURRENT_DS, hdc, lptable, lprecord, objs, lParam)
 #define CallEnumObjectsProc( func, lpobj, lParam ) \
     CallTo16_word_ll( func, CURRENT_DS, lpobj, lParam )
-#define CallEnumPropProc( func, hwnd, lpstr, data ) \
-    CallTo16_word_wlw( func, CURRENT_DS, hwnd, lpstr, data )
+#define CallEnumPropProc16( func, hwnd, lpstr, handle ) \
+    CallTo16_word_wlw( (FARPROC16)(func), CURRENT_DS, hwnd, lpstr, handle )
 #define CallEnumTaskWndProc( func, hwnd, lParam ) \
     CallTo16_word_wl( func, CURRENT_DS, hwnd, lParam )
 #define CallEnumWindowsProc16( func, hwnd, lParam ) \
@@ -100,6 +100,10 @@
     CallTo32_0( func )
 #define CallDLLEntryProc32( func, hmodule, a, b ) \
     CallTo32_3( func, hmodule, a, b )
+#define CallEnumPropProc32( func, hwnd, lpstr, handle ) \
+    CallTo32_3( (FARPROC32)(func), hwnd, (DWORD)(lpstr), handle )
+#define CallEnumPropProcEx32( func, hwnd, lpstr, handle, data ) \
+    CallTo32_4( (FARPROC32)(func), hwnd, (DWORD)(lpstr), handle, data )
 #define CallEnumWindowsProc32( func, hwnd, lParam ) \
     CallTo32_2( func, hwnd, lParam )
 #define CallWndProc32( func, hwnd, msg, wParam, lParam ) \
@@ -122,8 +126,12 @@
     (*func)( hdc, lptable, lprecord, objs, lParam)
 #define CallEnumObjectsProc( func, lpobj, lParam ) \
     (*func)( lpobj, lParam )
-#define CallEnumPropProc( func, hwnd, lpstr, data ) \
-    (*func)( hwnd, lpstr, data )
+#define CallEnumPropProc16( func, hwnd, lpstr, handle ) \
+    (*func)( hwnd, lpstr, handle )
+#define CallEnumPropProc32( func, hwnd, lpstr, handle ) \
+    (*func)( hwnd, lpstr, handle )
+#define CallEnumPropProcEx32( func, hwnd, lpstr, handle, data ) \
+    (*func)( hwnd, lpstr, handle, data )
 #define CallEnumTaskWndProc( func, hwnd, lParam ) \
     (*func)( hwnd, lParam )
 #define CallEnumWindowsProc16( func, hwnd, lParam ) \
diff --git a/include/class.h b/include/class.h
index dda909c..418f723 100644
--- a/include/class.h
+++ b/include/class.h
@@ -37,6 +37,5 @@
 extern void CLASS_WalkClasses(void);
 extern void CLASS_FreeModuleClasses( HMODULE16 hModule );
 extern CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE16 hinstance );
-extern CLASS * CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance );
 
 #endif  /* CLASS_H */
diff --git a/include/color.h b/include/color.h
index 03a658b..7cc07e9 100644
--- a/include/color.h
+++ b/include/color.h
@@ -9,8 +9,9 @@
 
 #define COLOR_PRIVATE   0x1000          /* private colormap, identity mapping */
 
-#define PC_SYS_USED     0x80		/* system peFlags */
-#define PC_SYS_RESERVED 0x40
+#define PC_SYS_USED     0x80		/* palentry is used (both system and logical) */
+#define PC_SYS_RESERVED 0x40		/* system palentry is not to be mapped to */
+#define PC_SYS_MAPPED   0x10		/* logical palentry is a direct alias for system palentry */
 
 extern HPALETTE16 	COLOR_Init(void);
 extern COLORREF		COLOR_ToLogical(int pixel);
@@ -21,6 +22,9 @@
 extern UINT16		COLOR_GetSystemPaletteSize();
 extern UINT16		COLOR_GetSystemPaletteFlags();
 
+extern COLORREF		COLOR_LookupNearestColor( PALETTEENTRY*, int, COLORREF );
+extern int		COLOR_PaletteLookupPixel( PALETTEENTRY*, int, int* , COLORREF, BOOL );
+
 extern int 	COLOR_mapEGAPixel[16];
 extern int* 	COLOR_PaletteToPixel;
 extern int* 	COLOR_PixelToPalette;
diff --git a/include/cursoricon.h b/include/cursoricon.h
index 1555b18..14c34b8 100644
--- a/include/cursoricon.h
+++ b/include/cursoricon.h
@@ -10,6 +10,8 @@
 #include <X11/Xlib.h>
 #include "windows.h"
 
+#pragma pack(1)
+
 typedef struct
 {
     BYTE   bWidth;
@@ -38,8 +40,6 @@
     CURSORDIRENTRY  cursor;
 } CURSORICONDIRENTRY;
 
-#pragma pack(1)
-
 typedef struct
 {
     WORD                idReserved;
diff --git a/include/dde_mem.h b/include/dde_mem.h
index 3bc8dfa..b2c3079 100644
--- a/include/dde_mem.h
+++ b/include/dde_mem.h
@@ -26,7 +26,7 @@
 WORD DDE_SyncHandle(HGLOBAL handle, WORD sel);
 void *DDE_malloc(unsigned int flags,unsigned long size, SHMDATA *shmdata);
 HANDLE DDE_GlobalReAlloc(WORD,long,WORD);
-HANDLE DDE_GlobalFree(WORD block);
+HGLOBAL DDE_GlobalFree(HGLOBAL block);
 void *DDE_AttachHandle(HGLOBAL handle, SEGPTR *segptr);
 WORD DDE_GlobalHandleToSel( HGLOBAL handle );
 int DDE_GlobalUnlock(int);
diff --git a/include/dde_proc.h b/include/dde_proc.h
index 011d389..29397d7 100644
--- a/include/dde_proc.h
+++ b/include/dde_proc.h
@@ -52,8 +52,8 @@
 
 /* Send ack. to hnd indicating that posted/sent msg. got to destination*/
 void dde_proc_send_ack(HWND wnd, BOOL val);
-BOOL DDE_PostMessage( MSG *msg);
-BOOL DDE_SendMessage( MSG *msg);
+BOOL DDE_PostMessage( MSG16 *msg);
+BOOL DDE_SendMessage( MSG16 *msg);
 int DDE_GetRemoteMessage();
 void DDE_DestroyWindow(HWND hwnd); /* delete DDE info regarding hwnd */
 void DDE_TestDDE(HWND hwnd);	   /* do we have dde handling in the window ?*/
diff --git a/include/heap.h b/include/heap.h
index ee55f9b..e262c09 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -16,6 +16,7 @@
 extern int HEAP_IsInsideHeap( HANDLE32 heap, DWORD flags, LPCVOID ptr );
 extern SEGPTR HEAP_GetSegptr( HANDLE32 heap, DWORD flags, LPCVOID ptr );
 extern LPSTR HEAP_strdupA( HANDLE32 heap, DWORD flags, LPCSTR str );
+extern LPWSTR HEAP_strdupW( HANDLE32 heap, DWORD flags, LPCWSTR str );
 
 /* SEGPTR helper macros */
 
diff --git a/include/ldt.h b/include/ldt.h
index 78ab156..f77592a 100644
--- a/include/ldt.h
+++ b/include/ldt.h
@@ -4,8 +4,10 @@
  * Copyright 1995 Alexandre Julliard
  */
 
-#ifndef _WINE_LDT_H
-#define _WINE_LDT_H
+#ifndef __WINE_LDT_H
+#define __WINE_LDT_H
+
+#include "wintypes.h"
 
 enum seg_type
 {
@@ -54,17 +56,14 @@
 #define GET_SEL_BASE(sel)       (ldt_copy[SELECTOR_TO_ENTRY(sel)].base)
 #define GET_SEL_LIMIT(sel)      (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit)
 
-#define PTR_SEG_OFF_TO_LIN(seg,off) \
-           ((void*)(GET_SEL_BASE(seg) + (unsigned int)(off)))
+/* Convert a segmented ptr (16:16) to a linear (32) pointer */
 
-#ifndef WINELIB
-  /* Convert a segmented ptr (16:16) to a linear (32) pointer */
-#define PTR_SEG_TO_LIN(ptr) PTR_SEG_OFF_TO_LIN(SELECTOROF(ptr),OFFSETOF(ptr))
-#define PTR_SEG_OFF_TO_SEGPTR(seg,off) ((SEGPTR)MAKELONG(off,seg))
-#else
-#define PTR_SEG_TO_LIN(ptr)	((void*)(ptr))
-#define PTR_SEG_OFF_TO_SEGPTR(seg,off) ((SEGPTR)PTR_SEG_OFF_TO_LIN(seg,off))
-#endif
+#define PTR_SEG_OFF_TO_LIN(seg,off) \
+ ((void*)(GET_SEL_BASE(seg) + (unsigned int)(off)))
+#define PTR_SEG_TO_LIN(ptr) \
+ (__winelib ? (void*)(ptr) : PTR_SEG_OFF_TO_LIN(SELECTOROF(ptr),OFFSETOF(ptr)))
+#define PTR_SEG_OFF_TO_SEGPTR(seg,off) \
+ (__winelib ? (SEGPTR)PTR_SEG_OFF_TO_LIN(seg,off) : (SEGPTR)MAKELONG(off,seg))
 
 extern unsigned char ldt_flags_copy[LDT_SIZE];
 
@@ -77,4 +76,4 @@
 
 #define GET_SEL_FLAGS(sel)   (ldt_flags_copy[SELECTOR_TO_ENTRY(sel)])
 
-#endif  /* _WINE_LDT_H */
+#endif  /* __WINE_LDT_H */
diff --git a/include/listbox.h b/include/listbox.h
index cdd82cb..8b9130f 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -47,7 +47,7 @@
 extern LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex);
 extern int ListMaxFirstVisible(LPHEADLIST lphl);
 extern int ListBoxScrollToFocus(LPHEADLIST lphl);
-extern int ListBoxAddString(LPHEADLIST lphl, LPCSTR newstr);
+extern int ListBoxAddString(LPHEADLIST lphl, SEGPTR itemData);
 extern int ListBoxInsertString(LPHEADLIST lphl, UINT uIndex, LPCSTR newstr);
 extern int ListBoxGetText(LPHEADLIST lphl, UINT uIndex, LPSTR OutStr);
 extern DWORD ListBoxGetItemData(LPHEADLIST lphl, UINT uIndex);
diff --git a/include/miscemu.h b/include/miscemu.h
index 90b9184..c876e60 100644
--- a/include/miscemu.h
+++ b/include/miscemu.h
@@ -16,6 +16,11 @@
 extern void DOSMEM_Tick(void);
 extern void DOSMEM_FillBiosSegment(void);
 extern HANDLE16 DOSMEM_BiosSeg;
+extern void DOSMEM_InitMemoryHandling();
+extern LPVOID DOSMEM_RealMode2Linear(DWORD);
+extern WORD DOSMEM_AllocSelector(WORD);
+extern DWORD DOSMEM_CollateTable;
+extern void DOSMEM_InitCollateTable();
 
   /* miscemu/instr.c */
 extern BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context );
diff --git a/include/palette.h b/include/palette.h
index ce4519b..1bdef2f 100644
--- a/include/palette.h
+++ b/include/palette.h
@@ -15,8 +15,8 @@
 typedef struct
 {
     GDIOBJHDR   header;
-    LOGPALETTE  logpalette WINE_PACKED;
-    int        *mapping;
+    int        *mapping    WINE_PACKED; 
+    LOGPALETTE  logpalette WINE_PACKED; /* _MUST_ be the last field */
 } PALETTEOBJ;
 
 #pragma pack(4)
diff --git a/include/task.h b/include/task.h
index 2881c70..f7c92a5 100644
--- a/include/task.h
+++ b/include/task.h
@@ -81,7 +81,9 @@
     DWORD     int3e WINE_PACKED;          /* 46 int 3e (80x87 emu) handler */
     DWORD     int75 WINE_PACKED;          /* 4a int 75 (80x87 error) handler */
     DWORD     compat_flags WINE_PACKED;   /* 4e Compatibility flags */
-    BYTE      unused4[14];                /* 52 */
+    BYTE      unused4[10];                /* 52 */
+    WORD      switchStackSS;              /* 5c Saved %ss for SwitchStackTo */
+    WORD      switchStackSP;              /* 5e Saved %sp for SwitchStackTo */
     HANDLE16  hPDB;                       /* 60 Selector of PDB (i.e. PSP) */
     SEGPTR    dta WINE_PACKED;            /* 62 Current DTA */
     BYTE      curdrive;                   /* 66 Current drive */
diff --git a/include/win.h b/include/win.h
index 37938c1..3c95981 100644
--- a/include/win.h
+++ b/include/win.h
@@ -47,17 +47,17 @@
     LPSTR          text;          /* Window text */
     void          *pVScroll;      /* Vertical scroll-bar info */
     void          *pHScroll;      /* Horizontal scroll-bar info */
-    HGLOBAL        hmemTaskQ;     /* Task queue global memory handle */
-    HRGN           hrgnUpdate;    /* Update region */
-    HWND           hwndLastActive;/* Last active popup hwnd */
+    void          *pProp;         /* Pointer to properties list */
+    HGLOBAL16      hmemTaskQ;     /* Task queue global memory handle */
+    HRGN16         hrgnUpdate;    /* Update region */
+    HWND16         hwndLastActive;/* Last active popup hwnd */
     DWORD          dwStyle;       /* Window style (from CreateWindow) */
     DWORD          dwExStyle;     /* Extended style (from CreateWindowEx) */
-    HANDLE         hdce;          /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
-    UINT           wIDmenu;       /* ID or hmenu (from CreateWindow) */
+    HANDLE16       hdce;          /* Window DCE (if CS_OWNDC or CS_CLASSDC) */
+    UINT16         wIDmenu;       /* ID or hmenu (from CreateWindow) */
     WORD           flags;         /* Misc. flags (see below) */
     Window         window;        /* X window (only for top-level windows) */
-    HMENU          hSysMenu;      /* window's copy of System Menu */
-    HANDLE         hProp;         /* Handle of Properties List */
+    HMENU16        hSysMenu;      /* window's copy of System Menu */
     DWORD          userdata;      /* User private data */
     DWORD          wExtra[1];     /* Window extra bytes */
 } WND;
@@ -75,23 +75,25 @@
 #define WIN_ISDIALOG           0x0200 /* Window is a dialog */
 
   /* Window functions */
-extern WND *WIN_FindWndPtr( HWND hwnd );
+extern WND *WIN_FindWndPtr( HWND32 hwnd );
 extern WND *WIN_GetDesktop(void);
-extern void WIN_DumpWindow( HWND hwnd );
-extern void WIN_WalkWindows( HWND hwnd, int indent );
-extern Window WIN_GetXWindow( HWND hwnd );
-extern BOOL WIN_UnlinkWindow( HWND hwnd );
-extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter );
-extern HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue );
-extern void WIN_SendParentNotify( HWND hwnd, WORD event,
+extern void WIN_DumpWindow( HWND32 hwnd );
+extern void WIN_WalkWindows( HWND32 hwnd, int indent );
+extern Window WIN_GetXWindow( HWND32 hwnd );
+extern BOOL32 WIN_UnlinkWindow( HWND32 hwnd );
+extern BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter );
+extern HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue );
+extern void WIN_SendParentNotify( HWND32 hwnd, WORD event,
                                   WORD idChild, LONG lValue );
-extern BOOL WIN_CreateDesktopWindow(void);
-extern HWND WIN_GetTopParent( HWND hwnd );
-extern HINSTANCE WIN_GetWindowInstance( HWND hwnd );
+extern BOOL32 WIN_CreateDesktopWindow(void);
+extern HWND32 WIN_GetTopParent( HWND32 hwnd );
+extern HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd );
 extern WND **WIN_BuildWinArray( WND *wndPtr );
 
 extern void DEFWND_SetText( WND *wndPtr, LPCSTR text );  /* windows/defwnd.c */
 
+extern void PROPERTY_RemoveWindowProps( WND *pWnd );   /* windows/property.c */
+
 extern Display * display;
 extern Screen * screen;
 extern Window rootWindow;
diff --git a/include/windows.h b/include/windows.h
index 396942a..767363a 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1486,6 +1486,9 @@
 #define DRIVE_REMOVABLE            2
 #define DRIVE_FIXED                3
 #define DRIVE_REMOTE               4
+/* Win32 additions */
+#define DRIVE_CDROM                5
+#define DRIVE_RAMDISK              6
 
 #define HFILE_ERROR	-1
 
@@ -1592,15 +1595,20 @@
 #define SETDTR		5
 #define CLRDTR		6
 #define RESETDEV	7
+/* win16 only */
 #define GETMAXLPT	8
 #define GETMAXCOM	9
+/* win32 only */
+#define SETBREAK	8
+#define CLRBREAK	9
+
 #define GETBASEIRQ	10
 
 #define CN_RECEIVE	0x0001
 #define CN_TRANSMIT	0x0002
 #define CN_EVENT	0x0004
 
-typedef struct tagDCB
+typedef struct tagDCB16
 {
     BYTE   Id;
     UINT16 BaudRate WINE_PACKED;
@@ -1636,14 +1644,65 @@
     CHAR   EofChar;
     CHAR   EvtChar;
     UINT16 TxDelay WINE_PACKED;
-} DCB, *LPDCB;
+} DCB16, *LPDCB16;
+
+typedef struct tagDCB32
+{
+    DWORD DCBlength;
+    DWORD BaudRate;
+    DWORD fBinary		:1;
+    DWORD fParity		:1;
+    DWORD fOutxCtsFlow		:1;
+    DWORD fOutxDsrFlow		:1;
+    DWORD fDtrControl		:2;
+    DWORD fDsrSensitivity	:1;
+    DWORD fTXContinueOnXoff	:1;
+    DWORD fOutX			:1;
+    DWORD fInX			:1;
+    DWORD fErrorChar		:1;
+    DWORD fNull			:1;
+    DWORD fRtsControl		:2;
+    DWORD fAbortOnError		:1;
+    DWORD fDummy2		:17;
+    WORD wReserved;
+    WORD XonLim;
+    WORD XoffLim;
+    BYTE ByteSize;
+    BYTE Parity;
+    BYTE StopBits;
+    char XonChar;
+    char XoffChar;
+    char ErrorChar;
+    char EofChar;
+    char EvtChar;
+} DCB32, *LPDCB32;
+
+DECL_WINELIB_TYPE(DCB);
+DECL_WINELIB_TYPE(LPDCB);
+
+#define	RTS_CONTROL_DISABLE	0
+#define	RTS_CONTROL_ENABLE	1
+#define	RTS_CONTROL_HANDSHAKE	2
+#define	RTS_CONTROL_TOGGLE	3
+
+#define	DTR_CONTROL_DISABLE	0
+#define	DTR_CONTROL_ENABLE	1
+#define	DTR_CONTROL_HANDSHAKE	2
+
+typedef struct tagCOMMTIMEOUTS {
+	DWORD	ReadIntervalTimeout;
+	DWORD	ReadTotalTimeoutMultiplier;
+	DWORD	ReadTotalTimeoutConstant;
+	DWORD	WriteTotalTimeoutMultiplier;
+	DWORD	WriteTotalTimeoutConstant;
+} COMMTIMEOUTS,*LPCOMMTIMEOUTS;
 
 typedef struct tagCOMSTAT
 {
     BYTE   status;
     UINT16 cbInQue WINE_PACKED;
     UINT16 cbOutQue WINE_PACKED;
-} COMSTAT;
+} COMSTAT,*LPCOMSTAT;
 
 #define CSTF_CTSHOLD	0x01
 #define CSTF_DSRHOLD	0x02
@@ -3179,6 +3238,31 @@
   DWORD   BatteryFullLifeTime;
 } SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS;
 
+/* flags to FormatMessage */
+#define	FORMAT_MESSAGE_ALLOCATE_BUFFER	0x00000100
+#define	FORMAT_MESSAGE_IGNORE_INSERTS	0x00000200
+#define	FORMAT_MESSAGE_FROM_STRING	0x00000400
+#define	FORMAT_MESSAGE_FROM_HMODULE	0x00000800
+#define	FORMAT_MESSAGE_FROM_SYSTEM	0x00001000
+#define	FORMAT_MESSAGE_ARGUMENT_ARRAY	0x00002000
+#define	FORMAT_MESSAGE_MAX_WIDTH_MASK	0x000000FF
+
+/* types of LoadImage */
+#define IMAGE_BITMAP	0
+#define IMAGE_ICON	1
+#define IMAGE_CURSOR	2
+#define IMAGE_ENHMETA	3
+
+/* loadflags to LoadImage */
+#define LR_DEFAULTCOLOR		0x0000
+#define LR_MONOCHROME		0x0001
+#define LR_COPYRETURNONORG	0x0002
+#define LR_COPYDELETEORC	0x0004
+#define LR_COPYFROMRESOURCE	0x0008
+#define LR_LOADFROMFILE		0x0010
+#define LR_LOADREALSIZE		0x0020
+#define LR_LOADMAP3DCOLORS	0x1000
+
 #pragma pack(4)
 
 /* Declarations for functions that exist only in Win16 */
@@ -3186,11 +3270,15 @@
 WORD       AllocSelector(WORD);
 WORD       AllocSelectorArray(WORD);
 INT16      Catch(LPCATCHBUF);
+INT16      CloseComm(INT16);
 HANDLE16   FarGetOwner(HGLOBAL16);
 VOID       FarSetOwner(HGLOBAL16,HANDLE16);
 VOID       FillWindow(HWND16,HWND16,HDC16,HBRUSH16);
+INT16      FlushComm(INT16,INT16);
 WORD       FreeSelector(WORD);
 DWORD      GetBitmapDimension(HBITMAP16);
+INT16      GetCommError(INT16,LPCOMSTAT);
+UINT16     GetCommEventMask(INT16,UINT16);
 HTASK16    GetCurrentTask(void);
 HMODULE16  GetExePtr(HANDLE16);
 HINSTANCE16 GetTaskDS(void);
@@ -3198,22 +3286,33 @@
 BOOL16     LocalInit(HANDLE16,WORD,WORD);
 DWORD      OffsetViewportOrg(HDC16,INT16,INT16);
 DWORD      OffsetWindowOrg(HDC16,INT16,INT16);
+INT16      OpenComm(LPCSTR,UINT16,UINT16);
 VOID       PaintRect(HWND16,HWND16,HDC16,HBRUSH16,const RECT16*);
+INT16      ReadComm(INT16,LPSTR,INT16);
 DWORD      ScaleViewportExt(HDC16,INT16,INT16,INT16,INT16);
 DWORD      ScaleWindowExt(HDC16,INT16,INT16,INT16,INT16);
 DWORD      SetBitmapDimension(HBITMAP16,INT16,INT16);
+DWORD      SetBrushOrg(HDC16,INT16,INT16);
+UINT16*    SetCommEventMask(INT16,UINT16);
 DWORD      SetViewportExt(HDC16,INT16,INT16);
 DWORD      SetViewportOrg(HDC16,INT16,INT16);
 DWORD      SetWindowExt(HDC16,INT16,INT16);
 DWORD      SetWindowOrg(HDC16,INT16,INT16);
 INT16      Throw(LPCATCHBUF,INT16);
+INT16      UngetCommChar(INT16,CHAR);
+INT16      WriteComm(INT16,LPSTR,INT16);
 VOID       hmemcpy(LPVOID,LPCVOID,LONG);
 
 /* Declarations for functions that exist only in Win32 */
 
 BOOL32     Beep(DWORD,DWORD);
+BOOL32     ClearCommError(HANDLE32,LPDWORD,LPCOMSTAT);
+INT32      EnumPropsEx32A(HWND32,PROPENUMPROCEX32A,LPARAM);
+INT32      EnumPropsEx32W(HWND32,PROPENUMPROCEX32W,LPARAM);
+#define    EnumPropsEx WINELIB_NAME_AW(EnumPropsEx)
 BOOL32     EnumThreadWindows(DWORD,WNDENUMPROC32,LPARAM);
 BOOL32     FlushFileBuffers(HFILE);
+BOOL32     GetCommTimeouts(HANDLE32,LPCOMMTIMEOUTS);
 DWORD      GetLogicalDrives(void);
 HANDLE32   GetProcessHeap(void);
 LPVOID     HeapAlloc(HANDLE32,DWORD,DWORD);
@@ -3227,9 +3326,31 @@
 BOOL32     HeapUnlock(HANDLE32);
 BOOL32     HeapValidate(HANDLE32,DWORD,LPVOID);
 BOOL32     IsWindowUnicode(HWND32);
+DWORD      RegCreateKeyEx32A(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM,
+                             LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
+DWORD      RegCreateKeyEx32W(HKEY,LPCWSTR,DWORD,LPWSTR,DWORD,REGSAM,
+                             LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
+#define    RegCreateKeyEx WINELIB_NAME_AW(RegCreateKeyEx)
+DWORD      RegEnumKeyEx32A(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPSTR,LPDWORD,FILETIME*);
+DWORD      RegEnumKeyEx32W(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPWSTR,LPDWORD,FILETIME*);
+#define    RegEnumKeyEx WINELIB_NAME_AW(RegEnumKeyEx)
+DWORD      RegOpenKeyEx32W(HKEY,LPCWSTR,DWORD,REGSAM,LPHKEY);
+DWORD      RegOpenKeyEx32A(HKEY,LPCSTR,DWORD,REGSAM,LPHKEY);
+#define    RegOpenKeyEx WINELIB_NAME_AW(RegOpenKeyEx)
+DWORD      RegQueryInfoKey32W(HKEY,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD,
+                            LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*);
+DWORD      RegQueryInfoKey32A(HKEY,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD,
+                            LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*);
+#define    RegQueryInfoKey WINELIB_NAME_AW(RegQueryInfoKey)
 VOID       RtlFillMemory(LPVOID,UINT32,UINT32);
 VOID       RtlMoveMemory(LPVOID,LPCVOID,UINT32);
 VOID       RtlZeroMemory(LPVOID,UINT32);
+DWORD      SearchPath32A(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*);
+DWORD      SearchPath32W(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*);
+#define    SearchPath WINELIB_NAME(SearchPath)
+BOOL32     SetCommMask(HANDLE32,DWORD);
+BOOL32     SetCommTimeouts(HANDLE32,LPCOMMTIMEOUTS);
+BOOL32     SetBrushOrgEx(HDC32,INT32,INT32,LPPOINT32);
 LPVOID     VirtualAlloc(LPVOID,DWORD,DWORD,DWORD);
 BOOL32     VirtualFree(LPVOID,DWORD,DWORD);
 
@@ -3307,6 +3428,13 @@
 HDC16      BeginPaint16(HWND16,LPPAINTSTRUCT16);
 HDC32      BeginPaint32(HWND32,LPPAINTSTRUCT32);
 #define    BeginPaint WINELIB_NAME(BeginPaint)
+BOOL16     BuildCommDCB16(LPCSTR,LPDCB16);
+BOOL32     BuildCommDCB32A(LPCSTR,LPDCB32);
+BOOL32     BuildCommDCB32W(LPCWSTR,LPDCB32);
+#define    BuildCommDCB WINELIB_NAME_AW(BuildCommDCB)
+BOOL32     BuildCommDCBAndTimeouts32A(LPCSTR,LPDCB32,LPCOMMTIMEOUTS);
+BOOL32     BuildCommDCBAndTimeouts32W(LPCWSTR,LPDCB32,LPCOMMTIMEOUTS);
+#define    BuildCommDCBAndTimeouts WINELIB_NAME_AW(BuildCommDCBAndTimeouts)
 LRESULT    CallWindowProc16(WNDPROC16,HWND16,UINT16,WPARAM16,LPARAM);
 LRESULT    CallWindowProc32A(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
 LRESULT    CallWindowProc32W(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
@@ -3348,6 +3476,9 @@
 HWND16     ChildWindowFromPoint16(HWND16,POINT16);
 HWND32     ChildWindowFromPoint32(HWND32,POINT32);
 #define    ChildWindowFromPoint WINELIB_NAME(ChildWindowFromPoint)
+INT16      ClearCommBreak16(INT16);
+BOOL32     ClearCommBreak32(HANDLE32);
+#define    ClearCommBreak WINELIB_NAME(ClearCommBreak)
 BOOL16     ClientToScreen16(HWND16,LPPOINT16);
 BOOL32     ClientToScreen32(HWND32,LPPOINT32);
 #define    ClientToScreen WINELIB_NAME(ClientToScreen)
@@ -3494,6 +3625,10 @@
 BOOL16     EnumChildWindows16(HWND16,WNDENUMPROC16,LPARAM);
 BOOL32     EnumChildWindows32(HWND32,WNDENUMPROC32,LPARAM);
 #define    EnumChildWindows WINELIB_NAME(EnumChildWindows)
+INT16      EnumProps16(HWND16,PROPENUMPROC16);
+INT32      EnumProps32A(HWND32,PROPENUMPROC32A);
+INT32      EnumProps32W(HWND32,PROPENUMPROC32W);
+#define    EnumProps WINELIB_NAME_AW(EnumProps)
 BOOL16     EnumTaskWindows16(HTASK16,WNDENUMPROC16,LPARAM);
 #define    EnumTaskWindows32(handle,proc,lparam) \
            EnumThreadWindows(handle,proc,lparam)
@@ -3504,6 +3639,9 @@
 BOOL16     EqualRect16(const RECT16*,const RECT16*);
 BOOL32     EqualRect32(const RECT32*,const RECT32*);
 #define    EqualRect WINELIB_NAME(EqualRect)
+LONG       EscapeCommFunction16(UINT16,UINT16);
+BOOL32     EscapeCommFunction32(HANDLE32,UINT32);
+#define    EscapeCommFunction WINELIB_NAME(EscapeCommFunction)
 BOOL16     ExtTextOut16(HDC16,INT16,INT16,UINT16,const RECT16*,LPCSTR,UINT16,const INT16*);
 BOOL32     ExtTextOut32A(HDC32,INT32,INT32,UINT32,const RECT32*,LPCSTR,UINT32,const INT32*);
 BOOL32     ExtTextOut32W(HDC32,INT32,INT32,UINT32,const RECT32*,LPCWSTR,UINT32,const INT32*);
@@ -3572,6 +3710,9 @@
 void       GetClipCursor16(LPRECT16);
 void       GetClipCursor32(LPRECT32);
 #define    GetClipCursor WINELIB_NAME(GetClipCursor)
+INT16      GetCommState16(INT16,LPDCB16);
+BOOL32     GetCommState32(HANDLE32,LPDCB32);
+#define    GetCommState WINELIB_NAME(GetCommState)
 UINT16     GetCurrentDirectory16(UINT16,LPSTR);
 UINT32     GetCurrentDirectory32A(UINT32,LPSTR);
 UINT32     GetCurrentDirectory32W(UINT32,LPWSTR);
@@ -3619,6 +3760,10 @@
 FARPROC16  GetProcAddress16(HMODULE16,SEGPTR);
 FARPROC32  GetProcAddress32(HMODULE32,LPCSTR);
 #define    GetProcAddress WINELIB_NAME(GetProcAddress)
+HANDLE16   GetProp16(HWND16,LPCSTR);
+HANDLE32   GetProp32A(HWND32,LPCSTR);
+HANDLE32   GetProp32W(HWND32,LPCWSTR);
+#define    GetProp WINELIB_NAME_AW(GetProp)
 INT16      GetRgnBox16(HRGN16,LPRECT16);
 INT32      GetRgnBox32(HRGN32,LPRECT32);
 #define    GetRgnBox WINELIB_NAME(GetRgnBox)
@@ -3902,12 +4047,6 @@
 DWORD      RegCreateKey32A(HKEY,LPCSTR,LPHKEY);
 DWORD      RegCreateKey32W(HKEY,LPCWSTR,LPHKEY);
 #define    RegCreateKey WINELIB_NAME_AW(RegCreateKey)
-DWORD      RegCreateKeyEx32A(HKEY,LPCSTR,DWORD,LPSTR,DWORD,REGSAM,
-                             LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
-DWORD      RegCreateKeyEx32W(HKEY,LPCWSTR,DWORD,LPWSTR,DWORD,REGSAM,
-                             LPSECURITY_ATTRIBUTES,LPHKEY,LPDWORD);
-/* there is no RegCreateKeyEx16 */
-#define    RegCreateKeyEx WINELIB_NAME_AW(RegCreateKeyEx)
 DWORD      RegDeleteKey16(HKEY,LPCSTR);
 DWORD      RegDeleteKey32A(HKEY,LPCSTR);
 DWORD      RegDeleteKey32W(HKEY,LPWSTR);
@@ -3920,10 +4059,6 @@
 DWORD      RegEnumKey32A(HKEY,DWORD,LPSTR,DWORD);
 DWORD      RegEnumKey32W(HKEY,DWORD,LPWSTR,DWORD);
 #define    RegEnumKey WINELIB_NAME_AW(RegEnumKey)
-DWORD      RegEnumKeyEx32A(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPSTR,LPDWORD,FILETIME*);
-DWORD      RegEnumKeyEx32W(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPWSTR,LPDWORD,FILETIME*);
-/* there is no RegEnumKeyEx16 */
-#define    RegEnumKeyEx WINELIB_NAME_AW(RegEnumKeyEx)
 DWORD      RegEnumValue16(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
 DWORD      RegEnumValue32A(HKEY,DWORD,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
 DWORD      RegEnumValue32W(HKEY,DWORD,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPBYTE,LPDWORD);
@@ -3944,16 +4079,6 @@
 DWORD      RegOpenKey32A(HKEY,LPCSTR,LPHKEY);
 DWORD      RegOpenKey32W(HKEY,LPCWSTR,LPHKEY);
 #define    RegOpenKey WINELIB_NAME_AW(RegOpenKey)
-DWORD      RegOpenKeyEx32W(HKEY,LPCWSTR,DWORD,REGSAM,LPHKEY);
-DWORD      RegOpenKeyEx32A(HKEY,LPCSTR,DWORD,REGSAM,LPHKEY);
-/* there is no RegOpenKeyEx16 */
-#define    RegOpenKeyEx WINELIB_NAME_AW(RegOpenKeyEx)
-DWORD      RegQueryInfoKey32W(HKEY,LPWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD,
-                            LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*);
-DWORD      RegQueryInfoKey32A(HKEY,LPSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD,
-                            LPDWORD,LPDWORD,LPDWORD,LPDWORD,LPDWORD,FILETIME*);
-/* there is no RegQueryInfoKey16 */
-#define    RegQueryInfoKey WINELIB_NAME_AW(RegQueryInfoKey)
 DWORD      RegQueryValue16(HKEY,LPSTR,LPSTR,LPDWORD);
 DWORD      RegQueryValue32A(HKEY,LPSTR,LPSTR,LPDWORD);
 DWORD      RegQueryValue32W(HKEY,LPWSTR,LPWSTR,LPDWORD);
@@ -3970,6 +4095,10 @@
 DWORD      RegSetValueEx32A(HKEY,LPSTR,DWORD,DWORD,LPBYTE,DWORD);
 DWORD      RegSetValueEx32W(HKEY,LPWSTR,DWORD,DWORD,LPBYTE,DWORD);
 #define    RegSetValueEx WINELIB_NAME_AW(RegSetValueEx)
+HANDLE16   RemoveProp16(HWND16,LPCSTR);
+HANDLE32   RemoveProp32A(HWND32,LPCSTR);
+HANDLE32   RemoveProp32W(HWND32,LPCWSTR);
+#define    RemoveProp WINELIB_NAME_AW(RemoveProp)
 BOOL16     RemoveDirectory16(LPCSTR);
 BOOL32     RemoveDirectory32A(LPCSTR);
 BOOL32     RemoveDirectory32W(LPCWSTR);
@@ -3998,6 +4127,12 @@
 LONG       SetClassLong32A(HWND32,INT32,LONG);
 LONG       SetClassLong32W(HWND32,INT32,LONG);
 #define    SetClassLong WINELIB_NAME_AW(SetClassLong)
+INT16      SetCommBreak16(INT16);
+BOOL32     SetCommBreak32(HANDLE32);
+#define    SetCommBreak WINELIB_NAME(SetCommBreak)
+INT16      SetCommState16(LPDCB16);
+BOOL32     SetCommState32(HANDLE32,LPDCB32);
+#define    SetCommState WINELIB_NAME(SetCommState)
 void       SetDlgItemInt16(HWND16,INT16,UINT16,BOOL16);
 void       SetDlgItemInt32(HWND32,INT32,UINT32,BOOL32);
 #define    SetDlgItemInt WINELIB_NAME(SetDlgItemInt)
@@ -4011,6 +4146,10 @@
 void       SetInternalWindowPos16(HWND16,UINT16,LPRECT16,LPPOINT16);
 void       SetInternalWindowPos32(HWND32,UINT32,LPRECT32,LPPOINT32);
 #define    SetInternalWindowPos WINELIB_NAME(SetInternalWindowPos)
+BOOL16     SetProp16(HWND16,LPCSTR,HANDLE16);
+BOOL32     SetProp32A(HWND32,LPCSTR,HANDLE32);
+BOOL32     SetProp32W(HWND32,LPCWSTR,HANDLE32);
+#define    SetProp WINELIB_NAME_AW(SetProp)
 void       SetRect16(LPRECT16,INT16,INT16,INT16,INT16);
 void       SetRect32(LPRECT32,INT32,INT32,INT32,INT32);
 #define    SetRect WINELIB_NAME(SetRect)
@@ -4059,6 +4198,9 @@
 BOOL16     TrackPopupMenu16(HMENU16,UINT16,INT16,INT16,INT16,HWND16,const RECT16*);
 BOOL32     TrackPopupMenu32(HMENU32,UINT32,INT32,INT32,INT32,HWND32,const RECT32*);
 #define    TrackPopupMenu WINELIB_NAME(TrackPopupMenu)
+INT16      TransmitCommChar16(INT16,CHAR);
+BOOL32     TransmitCommChar32(HANDLE32,CHAR);
+#define    TransmitCommChar WINELIB_NAME(TransmitCommChar)
 BOOL16     UnionRect16(LPRECT16,const RECT16*,const RECT16*);
 BOOL32     UnionRect32(LPRECT32,const RECT32*,const RECT32*);
 #define    UnionRect WINELIB_NAME(UnionRect)
@@ -4222,14 +4364,12 @@
 typedef int (*GOBJENUMPROC)(LPVOID,LPARAM);
 /*typedef int (*MFENUMPROC)(HDC,HANDLETABLE*,METARECORD*,int,LPARAM);*/
 typedef int (*MFENUMPROC)(HDC,void*,void*,int,LPARAM);
-typedef BOOL (*PROPENUMPROC)(HWND,LPCSTR,HANDLE);
 #else
 typedef SEGPTR DRIVERPROC;
 typedef SEGPTR EDITWORDBREAKPROC;
 typedef SEGPTR FONTENUMPROC;
 typedef SEGPTR GOBJENUMPROC;
 typedef SEGPTR MFENUMPROC;
-typedef SEGPTR PROPENUMPROC;
 #endif
 
 ATOM       AddAtom(SEGPTR);
@@ -4251,7 +4391,6 @@
 HDWP16     BeginDeferWindowPos(INT);
 BOOL       BitBlt(HDC,INT,INT,INT,INT,HDC,INT,INT,DWORD);
 BOOL       BringWindowToTop(HWND);
-BOOL       BuildCommDCB(LPCSTR,DCB*);
 void       CalcChildScroll(HWND,WORD);
 BOOL       CallMsgFilter(SEGPTR,INT);
 LRESULT    CallNextHookEx(HHOOK,INT,WPARAM,LPARAM);
@@ -4259,9 +4398,7 @@
 WORD       ChangeSelector(WORD,WORD);
 INT        CheckMenuItem(HMENU,UINT,UINT);
 BOOL       Chord(HDC,INT,INT,INT,INT,INT,INT,INT,INT);
-int        ClearCommBreak(int);
 BOOL       CloseClipboard(void);
-int        CloseComm(int);
 HMETAFILE  CloseMetaFile(HDC);
 void       CloseSound(void);
 BOOL       CloseWindow(HWND);
@@ -4322,9 +4459,7 @@
 INT        EnumFonts(HDC,LPCSTR,FONTENUMPROC,LPARAM);
 BOOL       EnumMetaFile(HDC,HMETAFILE,MFENUMPROC,LPARAM);
 INT        EnumObjects(HDC,INT,GOBJENUMPROC,LPARAM);
-INT        EnumProps(HWND,PROPENUMPROC);
 INT        Escape(HDC,INT,INT,LPCSTR,LPVOID);
-LONG       EscapeCommFunction(int,int);
 int        ExcludeClipRect(HDC,short,short,short,short);
 int        ExcludeVisRect(HDC,short,short,short,short);
 BOOL       ExitWindows(DWORD,WORD);
@@ -4335,7 +4470,6 @@
 ATOM       FindAtom(SEGPTR);
 HINSTANCE  FindExecutable(LPCSTR,LPCSTR,LPSTR);
 BOOL       FlashWindow(HWND,BOOL);
-int        FlushComm(int,int);
 BOOL       FrameRgn(HDC,HRGN,HBRUSH,int,int);
 void       FreeLibrary(HANDLE);
 UINT       GDIRealizePalette(HDC);
@@ -4358,9 +4492,6 @@
 HWND       GetClipboardViewer(void);
 HANDLE     GetCodeHandle(FARPROC16);
 void       GetCodeInfo(FARPROC16,LPVOID);
-int        GetCommError(int,COMSTAT*);
-UINT       GetCommEventMask(int,int);
-int        GetCommState(int,DCB*);
 HBRUSH     GetControlBrush(HWND,HDC,WORD);
 HANDLE     GetCurrentPDB(void);
 DWORD      GetCurrentPosition(HDC);
@@ -4427,7 +4558,6 @@
 INT        GetPrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,INT,LPCSTR);
 UINT       GetProfileInt(LPCSTR,LPCSTR,INT);
 INT        GetProfileString(LPCSTR,LPCSTR,LPCSTR,LPSTR,INT);
-HANDLE     GetProp(HWND,SEGPTR);
 DWORD      GetQueueStatus(UINT);
 BOOL       GetRasterizerCaps(LPRASTERIZER_STATUS,UINT);
 WORD       GetROP2(HDC);
@@ -4524,7 +4654,6 @@
 void       OemToAnsiBuff(LPCSTR,LPSTR,INT);
 int        OffsetClipRgn(HDC,short,short);
 BOOL       OpenClipboard(HWND);
-int        OpenComm(LPCSTR,UINT,UINT);
 BOOL       OpenIcon(HWND);
 int        OpenSound(void);
 void       OutputDebugString(LPCSTR);
@@ -4547,7 +4676,6 @@
 void       ProfStart(void);
 void       ProfStop(void);
 BOOL       PtVisible(HDC,short,short);
-int        ReadComm(int,LPSTR,int);
 WORD       RealizeDefaultPalette(HDC);
 BOOL       Rectangle(HDC,INT,INT,INT,INT);
 WORD       RegisterClipboardFormat(LPCSTR);
@@ -4555,7 +4683,6 @@
 int        ReleaseDC(HWND,HDC);
 BOOL       RemoveFontResource(LPSTR);
 BOOL       RemoveMenu(HMENU,UINT,UINT);
-HANDLE     RemoveProp(HWND,SEGPTR);
 void       ReplyMessage(LRESULT);
 HDC        ResetDC(HDC,LPVOID);
 BOOL       ResizePalette(HPALETTE16,UINT);
@@ -4576,13 +4703,9 @@
 HWND       SetActiveWindow(HWND);
 DWORD      SetBkColor(HDC,COLORREF);
 WORD       SetBkMode(HDC,WORD);
-DWORD      SetBrushOrg(HDC,short,short);
 HWND       SetCapture(HWND);
 HANDLE     SetClipboardData(WORD,HANDLE);
 HWND       SetClipboardViewer(HWND);
-int        SetCommBreak(int);
-UINT*      SetCommEventMask(int,UINT);
-int        SetCommState(DCB*);
 void       SetConvertHook(BOOL);
 BOOL       SetConvertParams(int,int);
 BOOL32     SetCurrentDirectory(LPCSTR);
@@ -4609,7 +4732,6 @@
 HWND       SetParent(HWND,HWND);
 COLORREF   SetPixel(HDC,short,short,COLORREF);
 WORD       SetPolyFillMode(HDC,WORD);
-BOOL       SetProp(HWND,SEGPTR,HANDLE);
 WORD       SetROP2(HDC,WORD);
 WORD       SetRelAbs(HDC,WORD);
 FARPROC16  SetResourceHandler(HANDLE,LPSTR,FARPROC16);
@@ -4661,8 +4783,6 @@
 int        TranslateAccelerator(HWND,HANDLE,LPMSG16);
 BOOL       TranslateMDISysAccel(HWND,LPMSG16);
 BOOL       TranslateMessage(LPMSG16);
-int        TransmitCommChar(int,char);
-int        UngetCommChar(int,char);
 BOOL       UnhookWindowsHook(short,HOOKPROC16);
 BOOL       UnhookWindowsHookEx(HHOOK);
 BOOL       UnrealizeObject(HBRUSH);
@@ -4680,7 +4800,6 @@
 int        WaitSoundState(int);
 HANDLE     WinExec(LPSTR,WORD);
 BOOL       WinHelp(HWND,LPSTR,WORD,DWORD);
-int        WriteComm(int,LPSTR,int);
 void       WriteOutProfiles(void);
 BOOL       WritePrivateProfileString(LPCSTR,LPCSTR,LPCSTR,LPCSTR);
 BOOL       WriteProfileString(LPCSTR,LPCSTR,LPCSTR);
diff --git a/include/wintypes.h b/include/wintypes.h
index 5a61ec9..389a9fe 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -160,23 +160,33 @@
 DECLARE_HANDLE(HWND);
 #undef DECLARE_HANDLE
 
-/* Callback function pointers types for Win16. */
+/* Callback function pointers types */
 
 typedef LRESULT (*DLGPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
-typedef LRESULT (*FARPROC16)();
-typedef LRESULT (*HOOKPROC16)(INT16,WPARAM16,LPARAM);
-typedef VOID (*TIMERPROC16)(HWND16,UINT16,UINT16,DWORD);
-typedef LRESULT (*WNDENUMPROC16)(HWND16,LPARAM);
-typedef LRESULT (*WNDPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
-
-/* Callback function pointers types for Win32. */
-
 typedef LRESULT (*DLGPROC32)(HWND32,UINT32,WPARAM32,LPARAM);
+DECL_WINELIB_TYPE(DLGPROC);
+typedef LRESULT (*FARPROC16)();
 typedef LRESULT (*FARPROC32)();
+DECL_WINELIB_TYPE(FARPROC);
+typedef LRESULT (*HOOKPROC16)(INT16,WPARAM16,LPARAM);
 typedef LRESULT (*HOOKPROC32)(INT32,WPARAM32,LPARAM);
-typedef VOID (*TIMERPROC32)(HWND32,UINT32,UINT32,DWORD);
+DECL_WINELIB_TYPE(HOOKPROC);
+typedef BOOL16  (*PROPENUMPROC16)(HWND16,SEGPTR,HANDLE16);
+typedef BOOL32  (*PROPENUMPROC32A)(HWND32,LPCSTR,HANDLE32);
+typedef BOOL32  (*PROPENUMPROC32W)(HWND32,LPCWSTR,HANDLE32);
+DECL_WINELIB_TYPE_AW(PROPENUMPROC);
+typedef BOOL32  (*PROPENUMPROCEX32A)(HWND32,LPCSTR,HANDLE32,LPARAM);
+typedef BOOL32  (*PROPENUMPROCEX32W)(HWND32,LPCWSTR,HANDLE32,LPARAM);
+DECL_WINELIB_TYPE_AW(PROPENUMPROCEX);
+typedef VOID    (*TIMERPROC16)(HWND16,UINT16,UINT16,DWORD);
+typedef VOID    (*TIMERPROC32)(HWND32,UINT32,UINT32,DWORD);
+DECL_WINELIB_TYPE(TIMERPROC);
+typedef LRESULT (*WNDENUMPROC16)(HWND16,LPARAM);
 typedef LRESULT (*WNDENUMPROC32)(HWND32,LPARAM);
+DECL_WINELIB_TYPE(WNDENUMPROC);
+typedef LRESULT (*WNDPROC16)(HWND16,UINT16,WPARAM16,LPARAM);
 typedef LRESULT (*WNDPROC32)(HWND32,UINT32,WPARAM32,LPARAM);
+DECL_WINELIB_TYPE(WNDPROC);
 
 /* TCHAR data types definitions for Winelib. */
 /* These types are _not_ defined for the emulator, because they */
@@ -236,11 +246,6 @@
 DECL_WINELIB_TYPE(HWAVEOUT);
 DECL_WINELIB_TYPE(HWND);
 
-DECL_WINELIB_TYPE(DLGPROC);
-DECL_WINELIB_TYPE(FARPROC);
-DECL_WINELIB_TYPE(WNDENUMPROC);
-DECL_WINELIB_TYPE(WNDPROC);
-
 /* Misc. constants. */
 
 #ifdef FALSE
@@ -330,4 +335,10 @@
 #endif
 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
 
+/* Winelib run-time flag */
+
+#ifdef __WINE__
+extern int __winelib;
+#endif  /* __WINE__ */
+
 #endif /* __WINE_WINTYPES_H */
diff --git a/ipc/dde_atom.c b/ipc/dde_atom.c
index 6d24908..1aef654 100644
--- a/ipc/dde_atom.c
+++ b/ipc/dde_atom.c
@@ -66,7 +66,7 @@
       deleted=hash1;
       break;
     default :			   /* non empty atom entry */
-      if (lstrcmpi( OFS2AtomStr(atom_ofs) , str) == 0)
+      if (lstrcmpi16( OFS2AtomStr(atom_ofs) , str) == 0)
 	 return hash1;		   /* found string in atom table */
   }
   hash2%= DDE_ATOMS-1 ;		   /* hash2=0..(DDE_ATOMS-2) */
@@ -92,7 +92,7 @@
 	    deleted= i;
 	 break;
        default :		   /* nonempty atom entry */
-	 if (lstrcmpi( OFS2AtomStr(atom_ofs) , str) == 0)
+	 if (lstrcmpi16( OFS2AtomStr(atom_ofs) , str) == 0)
 	    return i;	   /* found string in atom table */
      }
   }
diff --git a/ipc/dde_proc.c b/ipc/dde_proc.c
index b65b5fa..36ca350 100644
--- a/ipc/dde_proc.c
+++ b/ipc/dde_proc.c
@@ -45,7 +45,7 @@
 #define DDE_SEND 1
 #define DDE_POST 2
 #define DDE_ACK	 3
-#define DDE_MSG_SIZE   sizeof(MSG)
+#define DDE_MSG_SIZE   sizeof(MSG16)
 #define FREE_WND (WORD)(-2)
 #define DELETED_WND (WORD)(-3)
 #if defined(DEBUG_MSG) || defined(DEBUG_RUNTIME)
@@ -106,7 +106,7 @@
   return val;
 }
 
-static void print_dde_message(char *desc, MSG *msg);
+static void print_dde_message(char *desc, MSG16 *msg);
 
 /* This should be run only when main_block is first allocated.	*/
 void dde_proc_init(dde_proc proc)
@@ -201,7 +201,7 @@
   }
 
   if (debugging_dde) {
-     MSG *msg=(MSG*) &msgbuf->mtext;
+     MSG16 *msg=(MSG16*) &msgbuf->mtext;
      char *title;
      if (msgbuf->mtype==DDE_SEND)
 	title="sending dde:";
@@ -290,11 +290,11 @@
   return 0;			
 }
 
-static BOOL DDE_DoMessage( MSG *msg, int type )
+static BOOL DDE_DoMessage( MSG16 *msg, int type )
 {
   int proc_idx;
 
-  MSG *remote_message;
+  MSG16 *remote_message;
   struct msg_dat msg_dat;
   BOOL success;
   
@@ -346,12 +346,12 @@
   }
 }
 
-BOOL DDE_SendMessage( MSG *msg)
+BOOL DDE_SendMessage( MSG16 *msg)
 {
   return DDE_DoMessage(msg, DDE_SEND);
 }
 
-BOOL DDE_PostMessage( MSG *msg)
+BOOL DDE_PostMessage( MSG16 *msg)
 {
   return DDE_DoMessage(msg, DDE_POST);
 }
@@ -381,7 +381,7 @@
 {
   static int nesting=0;		   /* to avoid infinite recursion */
 
-  MSG *remote_message;
+  MSG16 *remote_message;
   int size;
   struct msg_dat msg_dat;
   BOOL was_sent;		   /* sent/received */
@@ -551,7 +551,7 @@
   }
 }
 
-static void print_dde_message(char *desc, MSG *msg)
+static void print_dde_message(char *desc, MSG16 *msg)
 {
 /*    extern const char *MessageTypeNames[];*/
     extern int debug_last_handle_size;
diff --git a/ipc/generic_hash.h b/ipc/generic_hash.h
index 5def7e6..6bd296f 100644
--- a/ipc/generic_hash.h
+++ b/ipc/generic_hash.h
@@ -10,6 +10,7 @@
 
 #include "wintypes.h"
 #include "shm_block.h"
+#include "win.h"
 /* default hash values */
 #define HASH_LOAD           70
 #define HASH_MEM_ALLOC      (HASH_PTR (*)(int size)) malloc
diff --git a/library/miscstubs.c b/library/miscstubs.c
index 0f3d9a0..071b69e 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -7,8 +7,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include "dde_mem.h"
 #include "windows.h"
+#include "dde_mem.h"
 #include "global.h"
 #include "debug.h"
 #include "xmalloc.h"
diff --git a/loader/main.c b/loader/main.c
index 01b6511..235faea 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -41,6 +41,13 @@
 #include "debug.h"
 
 
+/* Winelib run-time flag */
+#ifdef WINELIB
+int __winelib = 1;
+#else
+int __winelib = 0;
+#endif
+
 HANDLE32 SystemHeap = 0;
 HANDLE32 SegptrHeap = 0;
 
diff --git a/loader/module.c b/loader/module.c
index 31a998b..bf4fd5e 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -273,13 +273,8 @@
 DWORD MODULE_AllocateSegment(WORD wFlags, WORD wSize, WORD wElem)
 {
     WORD size = wSize << wElem;
-    HANDLE hMem = GlobalAlloc16( MODULE_Ne2MemFlags(wFlags), size);
-#ifdef WINELIB
-    return (DWORD)GlobalLock16(hMem);
-#else
-    WORD selector = HIWORD(WIN16_GlobalLock16(hMem));
-    return MAKELONG(hMem, selector);
-#endif
+    HANDLE16 hMem = GlobalAlloc16( MODULE_Ne2MemFlags(wFlags), size);
+    return MAKELONG( hMem, GlobalHandleToSel(hMem) );
 }
 
 /***********************************************************************
@@ -318,7 +313,6 @@
 /***********************************************************************
  *           MODULE_GetInstance
  */
-#ifndef WINELIB32
 HINSTANCE16 MODULE_GetInstance( HMODULE16 hModule )
 {
     SEGTABLEENTRY *pSegment;
@@ -331,7 +325,6 @@
     
     return pSegment->selector;
 }
-#endif
 
 
 /***********************************************************************
@@ -1299,13 +1292,13 @@
  */
 HANDLE LoadLibrary( LPCSTR libname )
 {
-#ifdef WINELIB
-    dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
-    WINELIB_UNIMP("LoadLibrary()");
-    return (HANDLE)0;
-#else
     HANDLE handle;
 
+    if (__winelib)
+    {
+        fprintf( stderr, "LoadLibrary not supported in Winelib\n" );
+        return (HANDLE)0;
+    }
     dprintf_module( stddeb, "LoadLibrary: (%08x) %s\n", (int)libname, libname);
 
     /* This does not increment the module reference count, and will
@@ -1320,9 +1313,10 @@
         strcat( buffer, ".dll" );
         handle = LoadModule( buffer, (LPVOID)-1 );
     }
+#ifndef WINELIB
     if (handle >= (HANDLE)32) NE_InitializeDLLs( GetExePtr(handle) );
-    return handle;
 #endif
+    return handle;
 }
 
 
@@ -1440,20 +1434,22 @@
             }
 
 	    /* Failed ! */
-#ifdef WINELIB
-	    /* build argv */
-	    argptr = argv;
-	    *argptr++ = "wine";
-	    if (iconic) *argptr++ = "-iconic";
-	    *argptr++ = lpCmdLine;
-	    *argptr++ = 0;
 
-	    /* Execute */
-	    execvp(argv[0] , (char**)argv);
+            if (__winelib)
+            {
+                /* build argv */
+                argptr = argv;
+                *argptr++ = "wine";
+                if (iconic) *argptr++ = "-iconic";
+                *argptr++ = lpCmdLine;
+                *argptr++ = 0;
 
-	    /* Failed ! */
-	    fprintf(stderr, "WinExec: can't exec 'wine %s'\n", lpCmdLine);
-#endif
+                /* Execute */
+                execvp(argv[0] , (char**)argv);
+
+                /* Failed ! */
+                fprintf(stderr, "WinExec: can't exec 'wine %s'\n", lpCmdLine);
+            }
 	    exit(1);
 	}
     }
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 9178772..fd3a302 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -82,6 +82,11 @@
 		return (PIMAGE_RESOURCE_DIRECTORY) (
 			root +
 			(entryTable[entrynum].OffsetToData & 0x7fffffff));
+	/* just use first entry if no default can be found */
+	if (!name && resdirptr->NumberOfIdEntries)
+		return (PIMAGE_RESOURCE_DIRECTORY) (
+			root +
+			(entryTable[0].OffsetToData & 0x7fffffff));
 	return NULL;
     }
 }
diff --git a/loader/task.c b/loader/task.c
index ef862d2..bf32790 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -1060,6 +1060,68 @@
 
 
 /***********************************************************************
+ *           SwitchStackTo   (KERNEL.108)
+ */
+void SwitchStackTo( WORD seg, WORD ptr, WORD top )
+{
+    TDB *pTask;
+    STACK16FRAME *oldFrame, *newFrame;
+
+    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+    dprintf_task( stddeb, "SwitchStackTo: old=%04x:%04x new=%04x:%04x\n",
+                  IF1632_Saved16_ss, IF1632_Saved16_sp, seg, ptr );
+    /* Save the old stack */
+    oldFrame = CURRENT_STACK16;
+    pTask->switchStackSS = IF1632_Saved16_ss;
+    pTask->switchStackSP = IF1632_Saved16_sp;
+    /* Switch to the new stack */
+    IF1632_Saved16_ss = seg;
+    IF1632_Saved16_sp = ptr - sizeof(STACK16FRAME);
+    newFrame = CURRENT_STACK16;
+    /* Build the stack frame on the new stack */
+    *newFrame = *oldFrame;
+}
+
+
+/***********************************************************************
+ *           SwitchStackBack   (KERNEL.109)
+ *
+ * Note: the function is declared as 'register' in the spec file in order
+ * to make sure all registers are preserved, but we don't use them in any
+ * way, so we don't need a SIGCONTEXT* argument.
+ */
+void SwitchStackBack(void)
+{
+    TDB *pTask;
+    STACK16FRAME *oldFrame, *newFrame;
+
+    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+    if (!pTask->switchStackSS)
+    {
+        fprintf( stderr, "SwitchStackBack: no previous SwitchStackTo\n" );
+        return;
+    }
+    dprintf_task( stddeb, "SwitchStackBack: restoring stack %04x:%04x\n",
+                  pTask->switchStackSS, pTask->switchStackSP );
+
+    oldFrame = CURRENT_STACK16;
+    /* Switch back to the old stack */
+    IF1632_Saved16_ss = pTask->switchStackSS;
+    IF1632_Saved16_sp = pTask->switchStackSP;
+    pTask->switchStackSS = 0;
+    /* Build a stack frame for the return */
+    newFrame = CURRENT_STACK16;
+    newFrame->saved_ss = oldFrame->saved_ss;
+    newFrame->saved_sp = oldFrame->saved_sp;
+    newFrame->entry_ip = oldFrame->entry_ip;
+    newFrame->entry_cs = oldFrame->entry_cs;
+    newFrame->bp       = oldFrame->bp;
+    newFrame->ip       = oldFrame->ip;
+    newFrame->cs       = oldFrame->cs;
+}
+
+
+/***********************************************************************
  *           GetTaskQueueDS  (KERNEL.118)
  */
 #ifndef WINELIB
@@ -1287,3 +1349,15 @@
     if (GlobalSize16(hTask) < sizeof(TDB)) return 0;
     return pTask->compat_flags;
 }
+
+
+/***********************************************************************
+ *           SetSigHandler   (KERNEL.140)
+ */
+WORD SetSigHandler( SEGPTR newhandler,SEGPTR* oldhandler,
+                    LPUINT16 *oldmode,UINT16 newmode,UINT16 flag )
+{
+    fprintf(stdnimp,"SetSigHandler(%lx,%p,%p,%d,%d), unimplemented.\n",
+            newhandler,oldhandler,oldmode,newmode,flag );
+    return 0;
+}
diff --git a/memory/global.c b/memory/global.c
index c3d66a7..f88d129 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -46,8 +46,6 @@
 static GLOBALARENA *pGlobalArena = NULL;
 static int globalArenaSize = 0;
 
-static DWORD globalDOSfree = 655350;
-
 #define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000  /* Largest allocation is 16M - 64K */
 
 #define GET_ARENA_PTR(handle)  (pGlobalArena + ((handle) >> __AHSHIFT))
@@ -551,41 +549,6 @@
 
 
 /***********************************************************************
- *           GlobalDOSAlloc   (KERNEL.184)
- *
- * Some programs rely on failure to allocate > 640K total with this function
- */
-DWORD GlobalDOSAlloc( DWORD size )
-{
-    WORD sel;
-
-    if (size > globalDOSfree) return 0;
-    sel = GlobalAlloc16( GMEM_FIXED, size );
-
-    dprintf_global( stddeb, "GlobalDOSAlloc: %08lx -> returning %04x\n",
-                    size, sel );
-    if (!sel) return 0;
-
-    globalDOSfree -= size;
-    return MAKELONG( sel, sel /* this one ought to be a real-mode segment */ );
-}
-
-
-/***********************************************************************
- *           GlobalDOSFree   (KERNEL.185)
- */
-WORD GlobalDOSFree( WORD sel )
-{
-    GLOBALARENA *pArena = GET_ARENA_PTR(sel);
-
-    if (!pArena) return sel;
-    globalDOSfree += pArena->size;
-    GlobalFree16( pArena->handle );
-    return 0;
-}
-
-
-/***********************************************************************
  *           SetSwapAreaSize   (KERNEL.106)
  */
 LONG SetSwapAreaSize( WORD size )
diff --git a/memory/heap.c b/memory/heap.c
index acdd8df..5c3573c 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -1212,6 +1212,18 @@
 {
     INT32 len = lstrlen32A(str) + 1;
     LPSTR p = HeapAlloc( heap, flags, len );
-    if (p) strcpy( p, str );
+    lstrcpy32A( p, str );
+    return p;
+}
+
+
+/***********************************************************************
+ *           HEAP_strdupW
+ */
+LPWSTR HEAP_strdupW( HANDLE32 heap, DWORD flags, LPCWSTR str )
+{
+    INT32 len = lstrlen32W(str) + 1;
+    LPWSTR p = HeapAlloc( heap, flags, len * sizeof(WCHAR) );
+    lstrcpy32W( p, str );
     return p;
 }
diff --git a/memory/ldt.c b/memory/ldt.c
index 3511637..9b1ef9e 100644
--- a/memory/ldt.c
+++ b/memory/ldt.c
@@ -13,8 +13,6 @@
 #include "stddebug.h"
 #include "debug.h"
 
-#ifndef WINELIB
-
 #ifdef linux
 #include <linux/unistd.h>
 #include <linux/head.h>
@@ -22,6 +20,7 @@
 
 _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
 #endif  /* linux */
+
 #if defined(__svr4__) || defined(_SCO_DS)
 #include <sys/sysi86.h>
 #include <sys/seg.h>
@@ -34,8 +33,6 @@
 extern int i386_set_ldt(int, union descriptor *, int);
 #endif  /* __NetBSD__ || __FreeBSD__ */
 
-#endif  /* ifndef WINELIB */
-
 
 ldt_copy_entry ldt_copy[LDT_SIZE];
 unsigned char ldt_flags_copy[LDT_SIZE];
@@ -121,8 +118,8 @@
     /* Entry 0 must not be modified; its base and limit are always 0 */
     if (!entry) return 0;
 
-#ifndef WINELIB
 #ifdef linux
+    if (!__winelib)
     {
         struct modify_ldt_ldt_s ldt_info;
 
@@ -167,6 +164,7 @@
 #endif  /* linux */
 
 #if defined(__NetBSD__) || defined(__FreeBSD__)
+    if (!__winelib)
     {
         long d[2];
 
@@ -182,35 +180,32 @@
     }
 #endif  /* __NetBSD__ || __FreeBSD__ */
 #if defined(__svr4__) || defined(_SCO_DS)
-{
-    struct ssd ldt_mod;
-    int i;
-    ldt_mod.sel = ENTRY_TO_SELECTOR(entry) | 4;
-    ldt_mod.bo = content->base;
-    ldt_mod.ls = content->limit;
-    i =   (content->limit & 0xf0000) |
-        (content->type << 10) |
-            (((content->read_only != 0) ^ 1) << 9) |
-                ((content->seg_32bit != 0) << 22) |
-                    ((content->limit_in_pages != 0)<< 23) |
-                        (1<<15) |
-                            0x7000;
-
-    ldt_mod.acc1 = (i & 0xff00) >> 8;
-    ldt_mod.acc2 = (i & 0xf00000) >> 20;
-    
-    
-    if (content->base == 0)
+    if (!__winelib)
     {
-        ldt_mod.acc1 =  0;
-        ldt_mod.acc2 = 0;
+        struct ssd ldt_mod;
+        int i;
+        ldt_mod.sel = ENTRY_TO_SELECTOR(entry) | 4;
+        ldt_mod.bo = content->base;
+        ldt_mod.ls = content->limit;
+        i = ((content->limit & 0xf0000) |
+             (content->type << 10) |
+             (((content->read_only != 0) ^ 1) << 9) |
+             ((content->seg_32bit != 0) << 22) |
+             ((content->limit_in_pages != 0)<< 23) |
+             (1<<15) |
+             0x7000);
+
+        ldt_mod.acc1 = (i & 0xff00) >> 8;
+        ldt_mod.acc2 = (i & 0xf00000) >> 20;
+
+        if (content->base == 0)
+        {
+            ldt_mod.acc1 =  0;
+            ldt_mod.acc2 = 0;
+        }
+        if ((ret = sysi86(SI86DSCR, &ldt_mod)) == -1) perror("sysi86");
     }    
-    if ((i = sysi86(SI86DSCR, &ldt_mod)) == -1)
-        perror("sysi86");
-    
-}    
 #endif
-#endif  /* ifndef WINELIB */
 
     if (ret < 0) return ret;
     ldt_copy[entry].base = content->base;
diff --git a/memory/selector.c b/memory/selector.c
index a38a0d1..ecf7df4 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -262,7 +262,20 @@
  */
 DWORD GetSelectorBase( WORD sel )
 {
-    return GET_SEL_BASE(sel);
+    extern char* DOSMEM_dosmem;
+    DWORD base;
+
+    base = GET_SEL_BASE(sel);
+
+#ifndef WINELIB
+    /* if base points into DOSMEM, assume we have to
+     * return pointer into physical lower 1MB
+     */
+    if ((base >=  (DWORD)DOSMEM_dosmem)  &&
+        (base <  ((DWORD)DOSMEM_dosmem+0x100000))) 
+    	base = base - (DWORD)DOSMEM_dosmem;
+#endif
+    return base;
 }
 
 
@@ -271,9 +284,23 @@
  */
 WORD SetSelectorBase( WORD sel, DWORD base )
 {
+    extern char* DOSMEM_dosmem;
     ldt_entry entry;
+
     LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
-    entry.base = base;
+#ifndef WINELIB
+    if (base < 0x100000)
+    {
+    	/* Assume pointers in the lower 1MB range are
+	 * in fact physical addresses into DOS memory.
+	 * Translate the base to our internal representation
+	 *
+	 * (NETAPI.DLL of Win95 does use SetSelectorBase this way)
+	 */
+	entry.base = (DWORD)(DOSMEM_dosmem+base);
+    }
+    else entry.base = base;
+#endif
     LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );
     return sel;
 }
diff --git a/misc/comm.c b/misc/comm.c
index a68542a..b628a2b 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -1,5 +1,7 @@
 /*
  * DEC 93 Erik Bos <erik@xs4all.nl>
+ *
+ * Copyright 1996 Marcus Meissner
  */
 
 #include <stdio.h>
@@ -11,7 +13,6 @@
 #include <ctype.h>
 #include <sys/stat.h>
 #if defined(__NetBSD__) || defined(__FreeBSD__)
-#include <errno.h>
 #include <sys/ioctl.h>
 #endif
 #include <unistd.h>
@@ -20,9 +21,9 @@
 #include "comm.h"
 #include "options.h"
 #include "stddebug.h"
-/* #define DEBUG_COMM */
-/* #undef  DEBUG_COMM */
 #include "debug.h"
+#include "handle32.h"
+#include "string32.h"
 
 int commerror = 0, eventmask = 0;
 
@@ -126,11 +127,13 @@
 		}
 }
 
-BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb)
+/**************************************************************************
+ *         BuildCommDCB		(USER.213)
+ */
+BOOL16 BuildCommDCB16(LPCSTR device, LPDCB16 lpdcb)
 {
 	/* "COM1:9600,n,8,1"	*/
 	/*  012345		*/
-
 	int port;
 	char *ptr, temp[256];
 
@@ -177,14 +180,12 @@
 			*ptr = toupper(*ptr);
 
         	dprintf_comm(stddeb,"BuildCommDCB: parity (%c)\n", *ptr);
+		lpdcb->fParity = 1;
 		switch (*ptr) {
 			case 'N':
 				lpdcb->Parity = NOPARITY;
 				lpdcb->fParity = 0;
 				break;			
-			
-			lpdcb->fParity = 1;
-			
 			case 'E':
 				lpdcb->Parity = EVENPARITY;
 				break;			
@@ -221,7 +222,162 @@
 	return 0;
 }
 
-int OpenComm(LPCSTR device, UINT cbInQueue, UINT cbOutQueue)
+/**************************************************************************
+ *         BuildCommDCBA		(KERNEL32.14)
+ */
+BOOL32 BuildCommDCB32A(LPCSTR device,LPDCB32 lpdcb) {
+	return BuildCommDCBAndTimeouts32A(device,lpdcb,NULL);
+}
+
+/**************************************************************************
+ *         BuildCommDCBAndTimeoutsA	(KERNEL32.15)
+ */
+BOOL32 BuildCommDCBAndTimeouts32A(LPCSTR device, LPDCB32 lpdcb,LPCOMMTIMEOUTS lptimeouts) {
+	int	port;
+	char	*ptr,*temp;
+
+	dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device,lpdcb,lptimeouts);
+	commerror = 0;
+
+	if (!lstrncmpi32A(device,"COM",3)) {
+		port=device[3]-'0';
+		if (port--==0) {
+			fprintf(stderr,"comm:BUG! COM0 can't exists!.\n");
+			return FALSE;
+		}
+		if (!ValidCOMPort(port))
+			return FALSE;
+		if (*(device+4)!=':')
+			return FALSE;
+		temp=(LPSTR)(device+5);
+	} else
+		temp=(LPSTR)device;
+	lpdcb->DCBlength	= sizeof(DCB32);
+	if (strchr(temp,',')) {	/* old style */
+		DCB16	dcb16;
+		BOOL16	ret;
+		char	last=temp[strlen(temp)-1];
+
+		ret=BuildCommDCB16(device,&dcb16);
+		if (!ret)
+			return FALSE;
+		lpdcb->BaudRate		= dcb16.BaudRate;
+		lpdcb->ByteSize		= dcb16.ByteSize;
+		lpdcb->fBinary		= dcb16.fBinary;
+		lpdcb->Parity		= dcb16.Parity;
+		lpdcb->fParity		= dcb16.fParity;
+		lpdcb->fNull		= dcb16.fNull;
+		lpdcb->StopBits		= dcb16.StopBits;
+		if (last == 'x') {
+			lpdcb->fInX		= TRUE;
+			lpdcb->fOutX		= TRUE;
+			lpdcb->fOutxCtsFlow	= FALSE;
+			lpdcb->fOutxDsrFlow	= FALSE;
+			lpdcb->fDtrControl	= DTR_CONTROL_ENABLE;
+			lpdcb->fRtsControl	= RTS_CONTROL_ENABLE;
+		} else if (last=='p') {
+			lpdcb->fInX		= FALSE;
+			lpdcb->fOutX		= FALSE;
+			lpdcb->fOutxCtsFlow	= TRUE;
+			lpdcb->fOutxDsrFlow	= TRUE;
+			lpdcb->fDtrControl	= DTR_CONTROL_HANDSHAKE;
+			lpdcb->fRtsControl	= RTS_CONTROL_HANDSHAKE;
+		} else {
+			lpdcb->fInX		= FALSE;
+			lpdcb->fOutX		= FALSE;
+			lpdcb->fOutxCtsFlow	= FALSE;
+			lpdcb->fOutxDsrFlow	= FALSE;
+			lpdcb->fDtrControl	= DTR_CONTROL_ENABLE;
+			lpdcb->fRtsControl	= RTS_CONTROL_ENABLE;
+		}
+		lpdcb->XonChar	= dcb16.XonChar;
+		lpdcb->XoffChar	= dcb16.XoffChar;
+		lpdcb->ErrorChar= dcb16.PeChar;
+		lpdcb->fErrorChar= dcb16.fPeChar;
+		lpdcb->EofChar	= dcb16.EofChar;
+		lpdcb->EvtChar	= dcb16.EvtChar;
+		lpdcb->XonLim	= dcb16.XonLim;
+		lpdcb->XoffLim	= dcb16.XoffLim;
+		return TRUE;
+	}
+	ptr=strtok(temp," "); 
+	while (ptr) {
+		DWORD	flag,x;
+
+		flag=0;
+		if (!strncmp("baud=",ptr,5)) {
+			if (!sscanf(ptr+5,"%ld",&x))
+				fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+			lpdcb->BaudRate = x;
+			flag=1;
+		}
+		if (!strncmp("stop=",ptr,5)) {
+			if (!sscanf(ptr+5,"%ld",&x))
+				fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+			lpdcb->StopBits = x;
+			flag=1;
+		}
+		if (!strncmp("data=",ptr,5)) {
+			if (!sscanf(ptr+5,"%ld",&x))
+				fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+			lpdcb->ByteSize = x;
+			flag=1;
+		}
+		if (!strncmp("parity=",ptr,7)) {
+			lpdcb->fParity	= TRUE;
+			switch (ptr[8]) {
+			case 'N':case 'n':
+				lpdcb->fParity	= FALSE;
+				lpdcb->Parity	= NOPARITY;
+				break;
+			case 'E':case 'e':
+				lpdcb->Parity	= EVENPARITY;
+				break;
+			case 'O':case 'o':
+				lpdcb->Parity	= ODDPARITY;
+				break;
+			case 'M':case 'm':
+				lpdcb->Parity	= MARKPARITY;
+				break;
+			}
+			flag=1;
+		}
+		if (!flag)
+			fprintf(stderr,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr);
+		ptr=strtok(NULL," ");
+	}
+	if (lpdcb->BaudRate==110)
+		lpdcb->StopBits = 2;
+	return TRUE;
+}
+
+/**************************************************************************
+ *         BuildCommDCBAndTimeoutsW		(KERNEL32.16)
+ */
+BOOL32 BuildCommDCBAndTimeouts32W(
+	LPCWSTR devid,LPDCB32 lpdcb,LPCOMMTIMEOUTS lptimeouts
+) {
+	LPSTR	devidA;
+	BOOL32	ret;
+
+	dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
+	devidA = STRING32_DupUniToAnsi(devid);
+	ret=BuildCommDCBAndTimeouts32A(devidA,lpdcb,lptimeouts);
+	free(devidA);
+	return ret;
+}
+
+/**************************************************************************
+ *         BuildCommDCBW		(KERNEL32.17)
+ */
+BOOL32 BuildCommDCB32W(LPCWSTR devid,LPDCB32 lpdcb) {
+	return BuildCommDCBAndTimeouts32W(devid,lpdcb,NULL);
+}
+
+/*****************************************************************************
+ *	OpenComm		(USER.200)
+ */
+INT16 OpenComm(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue)
 {
 	int port, fd;
 
@@ -282,7 +438,10 @@
 	return 0;
 }
 
-int CloseComm(int fd)
+/*****************************************************************************
+ *	CloseComm		(USER.207)
+ */
+INT16 CloseComm(INT16 fd)
 {
     	dprintf_comm(stddeb,"CloseComm: fd %d\n", fd);
 	if (close(fd) == -1) {
@@ -294,7 +453,10 @@
 	}
 }
 
-int SetCommBreak(int fd)
+/*****************************************************************************
+ *	SetCommBreak		(USER.210)
+ */
+INT16 SetCommBreak16(INT16 fd)
 {
 	struct DosDeviceStruct *ptr;
 
@@ -309,7 +471,31 @@
 	return 0;
 }
 
-int ClearCommBreak(int fd)
+/*****************************************************************************
+ *	SetCommBreak		(KERNEL32.449)
+ */
+BOOL32 SetCommBreak32(HANDLE32 hfile)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+
+	struct DosDeviceStruct *ptr;
+
+	dprintf_comm(stddeb,"SetCommBreak: fd: %d\n", fd);
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+
+	ptr->suspended = 1;
+	commerror = 0;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	ClearCommBreak		(USER.211)
+ */
+INT16 ClearCommBreak16(INT16 fd)
 {
 	struct DosDeviceStruct *ptr;
 
@@ -324,15 +510,37 @@
 	return 0;
 }
 
-LONG EscapeCommFunction(int fd, int nFunction)
+/*****************************************************************************
+ *	ClearCommBreak		(KERNEL32.20)
+ */
+BOOL32 ClearCommBreak32(HANDLE32 hfile)
 {
-	int max;
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct DosDeviceStruct *ptr;
+
+    	dprintf_comm(stddeb,"ClearCommBreak: fd: %d\n", fd);
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+
+	ptr->suspended = 0;
+	commerror = 0;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	EscapeCommFunction	(USER.214)
+ */
+LONG EscapeCommFunction16(UINT16 fd,UINT16 nFunction)
+{
+	int	max;
 	struct termios port;
 
-    	dprintf_comm(stddeb,
-		"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
-	if (tcgetattr(fd, &port) == -1) {
-		commerror = WinError();	
+    	dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
+	if (tcgetattr(fd,&port) == -1) {
+		commerror=WinError();	
 		return -1;
 	}
 
@@ -342,13 +550,13 @@
 
 		case GETMAXCOM:
 			for (max = MAX_PORTS;!COM[max].devicename;max--)
-				;		
+				;
 			return max;
 			break;
 
 		case GETMAXLPT:
 			for (max = MAX_PORTS;!LPT[max].devicename;max--)
-				;		
+				;
 			return 0x80 + max;
 			break;
 
@@ -398,25 +606,99 @@
 	}
 }
 
-int FlushComm(int fd, int fnQueue)
+/*****************************************************************************
+ *	EscapeCommFunction	(KERNEL32.214)
+ */
+BOOL32 EscapeCommFunction32(HANDLE32 hfile,UINT32 nFunction)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct termios	port;
+	struct DosDeviceStruct *ptr;
+
+    	dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
+	if (tcgetattr(fd,&port) == -1) {
+		commerror=WinError();	
+		return FALSE;
+	}
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+
+	switch (nFunction) {
+		case RESETDEV:
+			break;					
+
+#ifdef TIOCM_DTR
+		case CLRDTR:
+			port.c_cflag &= TIOCM_DTR;
+			break;
+#endif
+
+#ifdef TIOCM_RTS
+		case CLRRTS:
+			port.c_cflag &= TIOCM_RTS;
+			break;
+#endif
+	
+#ifdef CRTSCTS
+		case SETDTR:
+			port.c_cflag |= CRTSCTS;
+			break;
+
+		case SETRTS:
+			port.c_cflag |= CRTSCTS;
+			break;
+#endif
+
+		case SETXOFF:
+			port.c_iflag |= IXOFF;
+			break;
+
+		case SETXON:
+			port.c_iflag |= IXON;
+			break;
+		case SETBREAK:
+			ptr->suspended = 1;
+			break;
+		case CLRBREAK:
+			ptr->suspended = 0;
+			break;
+		default:
+			fprintf(stderr,
+			"EscapeCommFunction32 fd: %d, unknown function: %d\n", 
+			fd, nFunction);
+			break;				
+	}
+	
+	if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
+		commerror = WinError();
+		return FALSE;	
+	} else {
+		commerror = 0;
+		return TRUE;
+	}
+}
+
+/*****************************************************************************
+ *	FlushComm	(USER.215)
+ */
+INT16 FlushComm(INT16 fd,INT16 fnQueue)
 {
 	int queue;
 
     	dprintf_comm(stddeb,"FlushComm fd: %d, queue: %d\n", fd, fnQueue);
 	switch (fnQueue) {
-		case 0:
-			queue = TCOFLUSH;
+		case 0:	queue = TCOFLUSH;
 			break;
-		case 1:
-			queue = TCIFLUSH;
+		case 1:	queue = TCIFLUSH;
 			break;
-		default:
-			fprintf(stderr,
+		default:fprintf(stderr,
 				"FlushComm fd: %d, UNKNOWN queue: %d\n", 
 				fd, fnQueue);
 			return -1;
 		}
-	
 	if (tcflush(fd, fnQueue)) {
 		commerror = WinError();
 		return -1;	
@@ -426,7 +708,10 @@
 	}
 }  
 
-int GetCommError(int fd, COMSTAT *lpStat)
+/*****************************************************************************
+ *	GetCommError	(USER.203)
+ */
+INT16 GetCommError(INT16 fd,LPCOMSTAT lpStat)
 {
 	int temperror;
 
@@ -437,15 +722,36 @@
 	return(temperror);
 }
 
-UINT * SetCommEventMask(int fd, UINT fuEvtMask)
+/*****************************************************************************
+ *	ClearCommError	(KERNEL32.21)
+ */
+BOOL32 ClearCommError(HANDLE32 hfile,LPDWORD errors,LPCOMSTAT lpStat)
 {
+	int temperror;
+	FILE_OBJECT	*fob=(FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+
     	dprintf_comm(stddeb,
-		"SetCommEventMask: fd %d, mask %d\n", fd, fuEvtMask);
-	eventmask |= fuEvtMask;
-	return (UINT *)&eventmask;
+		"ClearCommError: fd %d (current error %d)\n", fd, commerror);
+	temperror = commerror;
+	commerror = 0;
+	return TRUE;
 }
 
-UINT GetCommEventMask(int fd, int fnEvtClear)
+/*****************************************************************************
+ *	SetCommEventMask	(USER.208)
+ */
+UINT16	*SetCommEventMask(INT16 fd,UINT16 fuEvtMask)
+{
+    	dprintf_comm(stddeb,"SetCommEventMask:fd %d,mask %d\n",fd,fuEvtMask);
+	eventmask |= fuEvtMask;
+	return (UINT *)&eventmask;	/* FIXME, should be SEGPTR */
+}
+
+/*****************************************************************************
+ *	GetCommEventMask	(USER.209)
+ */
+UINT16 GetCommEventMask(INT16 fd,UINT16 fnEvtClear)
 {
     	dprintf_comm(stddeb,
 		"GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear);
@@ -453,7 +759,38 @@
 	return eventmask;
 }
 
-int SetCommState(DCB *lpdcb)
+/*****************************************************************************
+ *	GetCommMask	(KERNEL32.156)
+ */
+BOOL32 GetCommMask(HANDLE32 hfile,LPDWORD evtmask)
+{
+	FILE_OBJECT	*fob=(FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+
+    	dprintf_comm(stddeb,
+		"GetCommMask: fd %d, mask %p\n", fd, evtmask);
+	*evtmask = eventmask;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	SetCommMask	(KERNEL32.451)
+ */
+BOOL32 SetCommMask(HANDLE32 hfile,DWORD evtmask)
+{
+	FILE_OBJECT	*fob=(FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+
+    	dprintf_comm(stddeb,
+		"SetCommMask: fd %d, mask %lx\n", fd, evtmask);
+	eventmask = evtmask;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	SetCommState16	(USER.201)
+ */
+INT16 SetCommState16(LPDCB16 lpdcb)
 {
 	struct termios port;
 	struct DosDeviceStruct *ptr;
@@ -652,7 +989,216 @@
 	}
 }
 
-int GetCommState(int fd, DCB *lpdcb)
+/*****************************************************************************
+ *	SetCommState32	(KERNEL32.452)
+ */
+BOOL32 SetCommState32(HANDLE32 hfile,LPDCB32 lpdcb)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct termios port;
+	struct DosDeviceStruct *ptr;
+
+    	dprintf_comm(stddeb,"SetCommState: fd %d, ptr %p\n",fd,lpdcb);
+	if (tcgetattr(fd,&port) == -1) {
+		commerror = WinError();	
+		return FALSE;
+	}
+
+	port.c_cc[VMIN] = 0;
+	port.c_cc[VTIME] = 1;
+
+#ifdef IMAXBEL
+	port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
+#else
+	port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
+#endif
+	port.c_iflag |= (IGNBRK);
+
+	port.c_oflag &= ~(OPOST);
+
+	port.c_cflag &= ~(HUPCL);
+	port.c_cflag |= CLOCAL | CREAD;
+
+	port.c_lflag &= ~(ICANON|ECHO|ISIG);
+	port.c_lflag |= NOFLSH;
+
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+	if (ptr->baudrate > 0)
+	  	lpdcb->BaudRate = ptr->baudrate;
+    	dprintf_comm(stddeb,"SetCommState: baudrate %ld\n",lpdcb->BaudRate);
+#ifdef CBAUD
+	port.c_cflag &= ~CBAUD;
+	switch (lpdcb->BaudRate) {
+		case 110:
+		case CBR_110:
+			port.c_cflag |= B110;
+			break;		
+		case 300:
+		case CBR_300:
+			port.c_cflag |= B300;
+			break;		
+		case 600:
+		case CBR_600:
+			port.c_cflag |= B600;
+			break;		
+		case 1200:
+		case CBR_1200:
+			port.c_cflag |= B1200;
+			break;		
+		case 2400:
+		case CBR_2400:
+			port.c_cflag |= B2400;
+			break;		
+		case 4800:
+		case CBR_4800:
+			port.c_cflag |= B4800;
+			break;		
+		case 9600:
+		case CBR_9600:
+			port.c_cflag |= B9600;
+			break;		
+		case 19200:
+		case CBR_19200:
+			port.c_cflag |= B19200;
+			break;		
+		case 38400:
+		case CBR_38400:
+			port.c_cflag |= B38400;
+			break;		
+		default:
+			commerror = IE_BAUDRATE;
+			return FALSE;
+	}
+#else
+        switch (lpdcb->BaudRate) {
+                case 110:
+                case CBR_110:
+                        port.c_ospeed = B110;
+                        break;
+                case 300:
+                case CBR_300:
+                        port.c_ospeed = B300;
+                        break;
+                case 600:
+                case CBR_600:
+                        port.c_ospeed = B600;
+                        break;
+                case 1200:
+                case CBR_1200:
+                        port.c_ospeed = B1200;
+                        break;
+                case 2400:
+                case CBR_2400:
+                        port.c_ospeed = B2400;
+                        break;
+                case 4800:
+                case CBR_4800:
+                        port.c_ospeed = B4800;
+                        break;
+                case 9600:
+                case CBR_9600:
+                        port.c_ospeed = B9600;
+                        break;
+                case 19200:
+                case CBR_19200:
+                        port.c_ospeed = B19200;
+                        break;
+                case 38400:
+                case CBR_38400:
+                        port.c_ospeed = B38400;
+                        break;
+                default:
+                        commerror = IE_BAUDRATE;
+                        return FALSE;
+        }
+        port.c_ispeed = port.c_ospeed;
+#endif
+    	dprintf_comm(stddeb,"SetCommState: bytesize %d\n",lpdcb->ByteSize);
+	port.c_cflag &= ~CSIZE;
+	switch (lpdcb->ByteSize) {
+		case 5:
+			port.c_cflag |= CS5;
+			break;
+		case 6:
+			port.c_cflag |= CS6;
+			break;
+		case 7:
+			port.c_cflag |= CS7;
+			break;
+		case 8:
+			port.c_cflag |= CS8;
+			break;
+		default:
+			commerror = IE_BYTESIZE;
+			return FALSE;
+	}
+
+    	dprintf_comm(stddeb,"SetCommState: parity %d\n",lpdcb->Parity);
+	port.c_cflag &= ~(PARENB | PARODD);
+	if (lpdcb->fParity)
+		switch (lpdcb->Parity) {
+			case NOPARITY:
+				port.c_iflag &= ~INPCK;
+				break;
+			case ODDPARITY:
+				port.c_cflag |= (PARENB | PARODD);
+				port.c_iflag |= INPCK;
+				break;
+			case EVENPARITY:
+				port.c_cflag |= PARENB;
+				port.c_iflag |= INPCK;
+				break;
+			default:
+				commerror = IE_BYTESIZE;
+				return FALSE;
+		}
+	
+
+    	dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
+	switch (lpdcb->StopBits) {
+		case ONESTOPBIT:
+				port.c_cflag &= ~CSTOPB;
+				break;
+		case TWOSTOPBITS:
+				port.c_cflag |= CSTOPB;
+				break;
+		default:
+			commerror = IE_BYTESIZE;
+			return FALSE;
+	}
+#ifdef CRTSCTS
+	if (	lpdcb->fOutxCtsFlow 			||
+		lpdcb->fDtrControl == DTR_CONTROL_ENABLE||
+		lpdcb->fRtsControl == RTS_CONTROL_ENABLE
+	)
+		port.c_cflag |= CRTSCTS;
+	if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE)
+		port.c_cflag &= ~CRTSCTS;
+
+#endif	
+	if (lpdcb->fInX)
+		port.c_iflag |= IXON;
+	if (lpdcb->fOutX)
+		port.c_iflag |= IXOFF;
+
+	if (tcsetattr(fd,TCSADRAIN,&port)==-1) {
+		commerror = WinError();	
+		return FALSE;
+	} else {
+		commerror = 0;
+		return TRUE;
+	}
+}
+
+
+/*****************************************************************************
+ *	GetCommState	(USER.202)
+ */
+INT16 GetCommState16(INT16 fd, LPDCB16 lpdcb)
 {
 	struct termios port;
 
@@ -661,9 +1207,7 @@
 		commerror = WinError();	
 		return -1;
 	}
-
 	lpdcb->Id = fd;
-
 #ifdef CBAUD
         switch (port.c_cflag & CBAUD) {
 #else
@@ -769,7 +1313,127 @@
 	return 0;
 }
 
-int TransmitCommChar(int fd, char chTransmit)
+/*****************************************************************************
+ *	GetCommState	(KERNEL32.159)
+ */
+BOOL32 GetCommState32(HANDLE32 hfile, LPDCB32 lpdcb)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct termios	port;
+
+
+    	dprintf_comm(stddeb,"GetCommState32: fd %d, ptr %p\n", fd, lpdcb);
+	if (tcgetattr(fd, &port) == -1) {
+		commerror = WinError();	
+		return FALSE;
+	}
+#ifdef CBAUD
+        switch (port.c_cflag & CBAUD) {
+#else
+        switch (port.c_ospeed) {
+#endif
+		case B110:
+			lpdcb->BaudRate = 110;
+			break;
+		case B300:
+			lpdcb->BaudRate = 300;
+			break;
+		case B600:
+			lpdcb->BaudRate = 600;
+			break;
+		case B1200:
+			lpdcb->BaudRate = 1200;
+			break;
+		case B2400:
+			lpdcb->BaudRate = 2400;
+			break;
+		case B4800:
+			lpdcb->BaudRate = 4800;
+			break;
+		case B9600:
+			lpdcb->BaudRate = 9600;
+			break;
+		case B19200:
+			lpdcb->BaudRate = 19200;
+			break;
+		case B38400:
+			lpdcb->BaudRate = 38400;
+			break;
+	}
+
+	switch (port.c_cflag & CSIZE) {
+		case CS5:
+			lpdcb->ByteSize = 5;
+			break;
+		case CS6:
+			lpdcb->ByteSize = 6;
+			break;
+		case CS7:
+			lpdcb->ByteSize = 7;
+			break;
+		case CS8:
+			lpdcb->ByteSize = 8;
+			break;
+	}	
+	
+	switch (port.c_cflag & ~(PARENB | PARODD)) {
+		case 0:
+			lpdcb->fParity = NOPARITY;
+			break;
+		case PARENB:
+			lpdcb->fParity = EVENPARITY;
+			break;
+		case (PARENB | PARODD):
+			lpdcb->fParity = ODDPARITY;		
+			break;
+	}
+
+	if (port.c_cflag & CSTOPB)
+		lpdcb->StopBits = TWOSTOPBITS;
+	else
+		lpdcb->StopBits = ONESTOPBIT;
+
+	lpdcb->fNull = 0;
+	lpdcb->fBinary = 1;
+
+#ifdef CRTSCTS
+
+	if (port.c_cflag & CRTSCTS) {
+		lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
+		lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
+		lpdcb->fOutxCtsFlow = 1;
+		lpdcb->fOutxDsrFlow = 1;
+	} else 
+#endif
+	{
+		lpdcb->fDtrControl = DTR_CONTROL_DISABLE;
+		lpdcb->fRtsControl = RTS_CONTROL_DISABLE;
+	}
+	if (port.c_iflag & IXON)
+		lpdcb->fInX = 1;
+	else
+		lpdcb->fInX = 0;
+
+	if (port.c_iflag & IXOFF)
+		lpdcb->fOutX = 1;
+	else
+		lpdcb->fOutX = 0;
+/*
+	lpdcb->XonChar = 
+	lpdcb->XoffChar = 
+ */
+	lpdcb->XonLim = 10;
+	lpdcb->XoffLim = 10;
+
+	commerror = 0;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	TransmitCommChar	(USER.206)
+ */
+INT16 TransmitCommChar16(INT16 fd,CHAR chTransmit)
 {
 	struct DosDeviceStruct *ptr;
 
@@ -794,7 +1458,38 @@
 	}
 }
 
-int UngetCommChar(int fd, char chUnget)
+/*****************************************************************************
+ *	TransmitCommChar	(KERNEL32.535)
+ */
+BOOL32 TransmitCommChar32(HANDLE32 hfile,CHAR chTransmit)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct DosDeviceStruct *ptr;
+
+    	dprintf_comm(stddeb,"TransmitCommChar32(%d,'%c')\n",fd,chTransmit);
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+
+	if (ptr->suspended) {
+		commerror = IE_HARDWARE;
+		return FALSE;
+	}
+	if (write(fd, (void *) &chTransmit, 1) == -1) {
+		commerror = WinError();
+		return FALSE;
+	}  else {
+		commerror = 0;
+		return TRUE;
+	}
+}
+
+/*****************************************************************************
+ *	UngetCommChar	(USER.212)
+ */
+INT16 UngetCommChar(INT16 fd,CHAR chUnget)
 {
 	struct DosDeviceStruct *ptr;
 
@@ -811,12 +1506,14 @@
 
 	ptr->unget = 1;
 	ptr->unget_byte = chUnget;
-	
 	commerror = 0;
 	return 0;
 }
 
-int ReadComm(int fd, LPSTR lpvBuf, int cbRead)
+/*****************************************************************************
+ *	ReadComm	(USER.204)
+ */
+INT16 ReadComm(INT16 fd,LPSTR lpvBuf,INT16 cbRead)
 {
 	int status, length;
 	struct DosDeviceStruct *ptr;
@@ -858,7 +1555,10 @@
 	}
 }
 
-int WriteComm(int fd, LPSTR lpvBuf, int cbWrite)
+/*****************************************************************************
+ *	WriteComm	(USER.205)
+ */
+INT16 WriteComm(INT16 fd, LPSTR lpvBuf, INT16 cbWrite)
 {
 	int x, length;
 	struct DosDeviceStruct *ptr;
@@ -888,3 +1588,24 @@
 		return length;
 	}
 }
+
+
+/*****************************************************************************
+ *	GetCommTimeouts		(KERNEL32.160)
+ */
+BOOL32 GetCommTimeouts(HANDLE32 hfile,LPCOMMTIMEOUTS lptimeouts) {
+	dprintf_comm(stddeb,"GetCommTimeouts(%lx,%p), empty stub.\n",
+		(DWORD)hfile,lptimeouts
+	);
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	SetCommTimeouts		(KERNEL32.453)
+ */
+BOOL32 SetCommTimeouts(HANDLE32 hfile,LPCOMMTIMEOUTS lptimeouts) {
+	dprintf_comm(stddeb,"SetCommTimeouts(%lx,%p), empty stub.\n",
+		(DWORD)hfile,lptimeouts
+	);
+	return TRUE;
+}
diff --git a/misc/commdlg.c b/misc/commdlg.c
index dda9e25..176bb5a 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -416,13 +416,8 @@
   UINT control,notification;
 
   /* Notifications are packaged differently in Win32 */
-#ifdef WINELIB32
-  control = LOWORD(wParam);
-  notification = HIWORD(wParam);
-#else
   control = wParam;
   notification = HIWORD(lParam);
-#endif
     
   lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
   switch (control)
diff --git a/misc/lstr.c b/misc/lstr.c
index 2c811e3..fc0de18 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -631,3 +631,148 @@
     STRING32_AnsiToUni(d,x);
     return TRUE;
 }
+
+/***********************************************************************
+ *           FormatMessageA   (KERNEL32.138)
+ * FIXME: missing wrap, function has no clue about varargs handling
+ */
+DWORD
+FormatMessage32A(
+	DWORD	dwFlags,
+	LPCVOID	lpSource,
+	DWORD	dwMessageId,
+	DWORD	dwLanguageId,
+	LPSTR	lpBuffer,
+	DWORD	nSize,
+	LPDWORD	*Arguments /* va_list *Arguments */
+) {
+	LPSTR	target,t;
+	DWORD	talloced;
+	LPSTR	from,f;
+	DWORD	width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
+
+	fprintf(stddeb,"FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
+		dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,
+		nSize,Arguments
+	);
+	if (width) 
+		fprintf(stdnimp,"	- line wrapping not supported.\n");
+	from = NULL;
+	if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
+		from = (LPSTR)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) {
+		/* gather information from module's message tables ... */
+		fprintf(stdnimp,"	- FORMAT_MESSAGE_FROM_HMODULE not implemented.\n");
+	}
+	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;
+		fprintf(stddeb,"	from is %s\n",from);
+		while (*f) {
+			if (*f=='%') {
+				int	insertnr;
+				char	*fmtstr,*sprintfbuf,*x;
+				DWORD	arg1,arg2,arg3;
+
+				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';
+						break;
+					default:break;
+					}
+					if (f[1]=='!') {
+						f+=2;
+						if (NULL!=(x=strchr(f,'!'))) {
+							*x='\0';
+							fmtstr=strdup(f);
+							f=x+1;
+						}
+					} else {
+						fmtstr=strdup("%s");
+					}
+
+					if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) {
+						DWORD	*args = (DWORD*)Arguments;
+						arg1 = args[insertnr-1];
+						arg2 = args[insertnr+0];
+						arg3 = args[insertnr+1];
+					} else {
+						/* 
+						int	i;
+						va_list	vl;
+
+						vl=va_start(Arguments,7);
+						for (i=insertnr;i--;)
+							va_arg(vl,DWORD);
+						arg1 = va_arg(vl,DWORD);
+						arg2 = va_arg(vl,DWORD);
+						arg3 = va_arg(vl,DWORD);
+						va_end(vl);
+						*/
+						fprintf(stdnimp,"	- varargs not supported yet.\n");
+					}
+
+					if (fmtstr[strlen(fmtstr)]=='s') {
+						sprintfbuf=(char*)xmalloc(strlen((LPSTR)arg1)+1);
+					} else {
+						sprintfbuf=(char*)xmalloc(100);
+					}
+					sprintf(sprintfbuf,fmtstr,arg1,arg2,arg3);
+					x=sprintfbuf;
+					while (*x) {
+						ADD_TO_T(*x++);
+					}
+					free(sprintfbuf);
+					free(fmtstr);
+					break;
+				default:ADD_TO_T(*f++)
+					break;
+
+				}
+			} else {
+				ADD_TO_T(*f++)
+			}
+		}
+		*t='\0';
+	}
+	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);
+		memcpy(*(LPSTR*)lpBuffer,target,talloced);
+	} else
+		strncpy(lpBuffer,target,nSize);
+	free(target);
+	return strlen(lpBuffer);
+}
diff --git a/misc/port.c b/misc/port.c
index 33866f1..3eec824 100644
--- a/misc/port.c
+++ b/misc/port.c
@@ -22,25 +22,26 @@
 #endif /* HAVE_USLEEP */
 
 #ifndef HAVE_MEMMOVE
-void *memmove( void *dst, const void *src, unsigned int len )
+void *memmove( void *dest, const void *src, unsigned int len )
 {
+    register char *dst = dest;
+
     /* Use memcpy if not overlapping */
-    if (((char *)dst + len <= (char *)src) ||
-        ((char *)src + len <= (char *)dst))
+    if ((dst + len <= (char *)src) || ((char *)src + len <= dst))
     {
         memcpy( dst, src, len );
     }
     /* Otherwise do it the hard way (FIXME: could do better than this) */
     else if (dst < src)
     {
-        while (len--) *((char *)dst)++ = *((char *)src)++;
+        while (len--) *dst++ = *((char *)src)++;
     }
     else
     {
-        dst = (char *)dst + len - 1;
+        dst += len - 1;
         src = (char *)src + len - 1;
-        while (len--) *((char *)dst)-- = *((char *)src)--;
+        while (len--) *dst-- = *((char *)src)--;
     }
-    return dst;
+    return dest;
 }
 #endif  /* HAVE_MEMMOVE */
diff --git a/miscemu/dosmem.c b/miscemu/dosmem.c
index 95f1aa0..8b454e7 100644
--- a/miscemu/dosmem.c
+++ b/miscemu/dosmem.c
@@ -2,6 +2,7 @@
  * DOS memory emulation
  *
  * Copyright 1995 Alexandre Julliard
+ * Copyright 1996 Marcus Meissner
  */
 
 #include <signal.h>
@@ -14,6 +15,7 @@
 #include "ldt.h"
 #include "miscemu.h"
 #include "module.h"
+#include "debug.h"
 
 
 HANDLE16 DOSMEM_BiosSeg;  /* BIOS data segment at 0x40:0 */
@@ -76,6 +78,11 @@
 
 
 static BIOSDATA *pBiosData = NULL;
+char	*DOSMEM_dosmem;
+struct dosmem_entry {
+	struct	dosmem_entry	*next;
+	BYTE			isfree;
+};
 
 
 /***********************************************************************
@@ -87,54 +94,82 @@
 BOOL32 DOSMEM_Init(void)
 {
     HMODULE16 hModule = GetModuleHandle( "KERNEL" );
-    char *dosmem;
 
-    /* Allocate 7 64k segments for 0000, A000, B000, C000, D000, E000, F000. */
-
-    dosmem = VirtualAlloc( NULL, 0x70000, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
-    if (!dosmem)
+    /* Allocate 1 MB dosmemory */
+    /* Yes, allocating 1 MB of memory, which is usually not even used, is a 
+     * waste of memory. But I (MM) don't see any easy method to use 
+     * GlobalDOS{Alloc,Free} within an area of memory, with protected mode
+     * selectors pointing into it, and the possibilty, that the userprogram
+     * calls SetSelectorBase(,physical_address_in_DOSMEM); that includes 
+     * dynamical enlarging (reallocing) the dosmem area.
+     * Yes, one could walk the ldt_copy on every realloc() on DOSMEM, but
+     * this feels more like a hack to me than this current implementation is.
+     * If you find another, better, method, just change it. -Marcus Meissner
+     */
+    DOSMEM_dosmem = VirtualAlloc(NULL,0x1000000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
+    if (!DOSMEM_dosmem)
     {
-        fprintf( stderr, "Could not allocate DOS segments\n" );
+        fprintf( stderr, "Could not allocate DOS memory.\n" );
         return FALSE;
     }
 
     MODULE_SetEntryPoint( hModule, 183,  /* KERNEL.183: __0000H */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
-    DOSMEM_BiosSeg = GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x400, 0x100,
+    DOSMEM_BiosSeg = GLOBAL_CreateBlock(GMEM_FIXED,DOSMEM_dosmem+0x400,0x100,
                                          hModule, FALSE, FALSE, FALSE, NULL );
 
     MODULE_SetEntryPoint( hModule, 193,  /* KERNEL.193: __0040H */
                           DOSMEM_BiosSeg );
     MODULE_SetEntryPoint( hModule, 174,  /* KERNEL.174: __A000H */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x10000,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xA0000,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
     MODULE_SetEntryPoint( hModule, 181,  /* KERNEL.181: __B000H */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x20000,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xB0000,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
     MODULE_SetEntryPoint( hModule, 182,  /* KERNEL.182: __B800H */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x28000,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xB8000,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
     MODULE_SetEntryPoint( hModule, 195,  /* KERNEL.195: __C000H */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x30000,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xC0000,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
     MODULE_SetEntryPoint( hModule, 179,  /* KERNEL.179: __D000H */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x40000,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xD0000,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
     MODULE_SetEntryPoint( hModule, 190,  /* KERNEL.190: __E000H */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x50000,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xE0000,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
     MODULE_SetEntryPoint( hModule, 173,  /* KERNEL.173: __ROMBIOS */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xF0000,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
     MODULE_SetEntryPoint( hModule, 194,  /* KERNEL.194: __F000H */
-                          GLOBAL_CreateBlock( GMEM_FIXED, dosmem + 0x60000,
+                          GLOBAL_CreateBlock( GMEM_FIXED, DOSMEM_dosmem+0xF0000,
                                 0x10000, hModule, FALSE, FALSE, FALSE, NULL ));
     DOSMEM_FillBiosSegment();
 
+    DOSMEM_InitMemoryHandling();
+    DOSMEM_InitCollateTable();
+
     return TRUE;
 }
 
+/***********************************************************************
+ *           DOSMEM_InitMemoryHandling
+ *
+ * Initialises the DOS Memory structures.
+ */
+void
+DOSMEM_InitMemoryHandling()
+{
+    struct	dosmem_entry	*dm;
+
+    dm = (struct dosmem_entry*)(DOSMEM_dosmem+0x10000);
+    dm->isfree	=  1;
+    dm->next	=  (struct dosmem_entry*)(DOSMEM_dosmem+0x9FFF0);
+    dm		=  dm->next;
+    dm->isfree	= 0;
+    dm->next	= NULL;
+}
 
 /***********************************************************************
  *           DOSMEM_Tick
@@ -180,3 +215,146 @@
     pBiosData->KbdBufferEnd         = 0x3e;
 }
 
+/***********************************************************************
+ *           DOSMEM_InitCollateTable
+ *
+ * Initialises the collate table (character sorting, language dependend)
+ */
+DWORD DOSMEM_CollateTable;
+
+void
+DOSMEM_InitCollateTable()
+{
+	DWORD		x;
+	unsigned char	*tbl;
+	int		i;
+
+	x=GlobalDOSAlloc(258);
+	DOSMEM_CollateTable=MAKELONG(0,(x>>16));
+	tbl=DOSMEM_RealMode2Linear(DOSMEM_CollateTable);
+	*(WORD*)tbl	= 0x100;
+	tbl+=2;
+	for (i=0;i<0x100;i++)
+		*tbl++=i;
+}
+
+/***********************************************************************
+ *           GlobalDOSAlloc	(KERNEL.184)
+ *
+ * Allocates a piece of DOS Memory, in the first 1 MB physical memory.
+ * 
+ * operates on the preallocated DOSMEM_dosmem (1MB). The useable area
+ * starts at 1000:0000 and ends at 9FFF:FFEF
+ * Memory allocation strategy is First Fit. (FIXME: Yes,I know that First Fit
+ * is a rather bad strategy. But since those functions are rather seldom
+ * called, it's easyness fits the purpose well.)
+ * 
+ */
+
+DWORD GlobalDOSAlloc(DWORD size)
+{
+	struct	dosmem_entry	*dm,*ndm;
+	DWORD	start,blocksize;
+	WORD	sel;
+	HMODULE16 hModule=GetModuleHandle("KERNEL");
+
+
+	start	= 0;
+	dm	= (struct dosmem_entry*)(DOSMEM_dosmem+0x10000);
+	size	= (size+0xf)&~0xf;
+	while (dm && dm->next) {
+		blocksize = ((char*)dm->next-(char*)dm)-16;
+		if ((dm->isfree) && (blocksize>=size)) {
+			dm->isfree = 0;
+			start = ((((char*)dm)-DOSMEM_dosmem)+0x10)& ~0xf;
+			if ((blocksize-size) >= 0x20) {
+				/* if enough memory is left for a new block
+				 * split this area into two blocks
+				 */
+				ndm=(struct dosmem_entry*)((char*)dm+0x10+size);
+				ndm->isfree	= 1;
+				ndm->next	= dm->next;
+				dm->next	= ndm;
+			}
+			break;
+		}
+		dm=dm->next;
+	}
+	if (!start)
+		return 0;
+	sel=GLOBAL_CreateBlock(
+		GMEM_FIXED,DOSMEM_dosmem+start,size,
+		hModule,FALSE,FALSE,FALSE,NULL
+	);
+	return MAKELONG(sel,start>>4);
+}
+
+/***********************************************************************
+ *           GlobalDOSFree	(KERNEL.185)
+ *
+ * Frees allocated dosmemory and corresponding selector.
+ */
+
+WORD
+GlobalDOSFree(WORD sel)
+{
+	DWORD	base;
+	struct	dosmem_entry	*dm;
+
+	base = GetSelectorBase(sel);
+	/* base has already been conversed to a physical address */
+	if (base>=0x100000)
+		return sel;
+	dm	= (struct dosmem_entry*)(DOSMEM_dosmem+base-0x10);
+	if (dm->isfree) {
+		fprintf(stderr,"Freeing already freed DOSMEM.\n");
+		return 0;
+	}
+	dm->isfree = 1;
+
+	/* collapse adjunct free blocks into one */
+	dm = (struct dosmem_entry*)(DOSMEM_dosmem+0x10000);
+	while (dm && dm->next) {
+		if (dm->isfree && dm->next->isfree)
+			dm->next = dm->next->next;
+		dm = dm->next;
+	}
+	GLOBAL_FreeBlock(sel);
+	return 0;
+}
+
+/***********************************************************************
+ *           DOSMEM_RealMode2Linear
+ *
+ * Converts a realmode segment:offset address into a linear pointer
+ */
+LPVOID DOSMEM_RealMode2Linear(DWORD x)
+{
+	LPVOID	lin;
+
+	lin=DOSMEM_dosmem+(x&0xffff)+(((x&0xffff0000)>>16)*16);
+	dprintf_selector(stddeb,"DOSMEM_RealMode2Linear(0x%08lx) returns 0x%p.\n",
+		x,lin
+	);
+	return lin;
+}
+
+/***********************************************************************
+ *           DOSMEM_RealMode2Linear
+ *
+ * Allocates a protected mode selector for a realmode segment.
+ */
+WORD DOSMEM_AllocSelector(WORD realsel)
+{
+	HMODULE16 hModule=GetModuleHandle("KERNEL");
+	WORD	sel;
+
+	sel=GLOBAL_CreateBlock(
+		GMEM_FIXED,DOSMEM_dosmem+realsel*16,0x10000,
+		hModule,FALSE,FALSE,FALSE,NULL
+	);
+	dprintf_selector(stddeb,"DOSMEM_AllocSelector(0x%04x) returns 0x%04x.\n",
+		realsel,sel
+	);
+	return sel;
+}
diff --git a/miscemu/dpmi.c b/miscemu/dpmi.c
index 738c413..2e41f4b 100644
--- a/miscemu/dpmi.c
+++ b/miscemu/dpmi.c
@@ -98,10 +98,7 @@
             case 0xe000: entryPoint = 190; break;  /* __E000H */
             case 0xf000: entryPoint = 194; break;  /* __F000H */
             default:
-                fprintf( stderr, "DPMI: real-mode seg to descriptor %04x not possible\n",
-                         BX_reg(context) );
-                AX_reg(context) = 0x8011;
-                SET_CFLAG(context);
+	    	AX_reg(context) = DOSMEM_AllocSelector(BX_reg(context));
                 break;
             }
             if (entryPoint) 
@@ -215,6 +212,35 @@
                 do_mscdex( context );
 		break;
             }
+	    /* NETAPI.DLL of Win95 does AX=6506 to fetch a realmode ptr
+	     * to the COLLATE table.
+	     */
+	    if (BL_reg(context) == 0x21) {
+	    	switch ((p->eax & 0xFF00)>>8) {
+		case 0x65:
+		    switch (p->eax & 0xFF) {
+		    case 06:{/* get collate table */
+		    	extern  DWORD	DOSMEM_CollateTable;
+		        char	*table;
+		        /* ES:DI is a REALMODE pointer to 5 byte dosmem 
+			 * we fill that with 0x6, realmode pointer to collateTB
+			 */
+			table = DOSMEM_RealMode2Linear(MAKELONG(p->edi,p->es));
+			*(BYTE*)table		= 0x06;
+			*(DWORD*)(table+1)	= DOSMEM_CollateTable;
+
+			CX_reg(context)		= 258;/*FIXME: size of table?*/
+			break;
+		    }
+		    default:
+            		SET_CFLAG(context);
+		    }
+		default:
+            	    SET_CFLAG(context);
+		    break;
+		}
+		break;
+	    }
             SET_CFLAG(context);
         }
         break;
@@ -243,6 +269,18 @@
         }
         break;
 
+    case 0x0303:  /* Allocate Real Mode Callback Address */
+        {
+            REALMODECALL *p = (REALMODECALL *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
+            fprintf(stdnimp,
+                    "AllocRMCB: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n"
+                    "           ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x\n",
+                    p->eax, p->ebx, p->ecx, p->edx,
+                    p->esi, p->edi, p->es, p->ds, p->cs, p->ip );
+            SET_CFLAG(context);
+        }
+        break;
+
     case 0x0400:  /* Get DPMI version */
         AX_reg(context) = 0x005a;  /* DPMI version 0.90 */
         BX_reg(context) = 0x0005;  /* Flags: 32-bit, virtual memory */
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 79176dc..7594219 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -1308,6 +1308,9 @@
         case 0x0d:
             ioctlGenericBlkDevReq(context);
             break;
+	case 0x0e: /* get logical drive mapping */
+	    AL_reg(context) = 0; /* drive has no mapping */
+	    break;
 
         case 0x0F:   /* Set logical drive mapping */
             /* FIXME: Not implemented at the moment, always returns error
diff --git a/multimedia/time.c b/multimedia/time.c
index cd2d86b..b525372 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -174,6 +174,8 @@
 	    if (lpTimer->Next != NULL)
 		lpTimer->Next->Prev = lpTimer->Prev;
 	    free(lpTimer);
+	    if (lpTimer==lpTimerList)
+	    	lpTimerList=NULL;
 	    return TRUE;
 	}
 	lpTimer = lpTimer->Next;
diff --git a/objects/bitblt.c b/objects/bitblt.c
index 4eba5db..1cb29bb 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -891,7 +891,8 @@
     short width  = visRectDst->right - visRectDst->left;
     short height = visRectDst->bottom - visRectDst->top;
 
-    if (!COLOR_PixelToPalette || (dc->w.bitsPerPixel == 1))
+    if (!COLOR_PixelToPalette || (dc->w.bitsPerPixel == 1) ||
+	(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
     {
         XCopyArea( display, dc->u.x.drawable, pixmap, gc,
                    visRectDst->left, visRectDst->top, width, height, 0, 0 );
@@ -922,7 +923,10 @@
     short width  = visRectDst->right - visRectDst->left;
     short height = visRectDst->bottom - visRectDst->top;
 
-    if (!COLOR_PaletteToPixel)
+    /* !COLOR_PaletteToPixel is _NOT_ enough */
+
+    if (!COLOR_PaletteToPixel || (dc->w.bitsPerPixel == 1) || 
+        (COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
     {
         XCopyArea( display, pixmap, dc->u.x.drawable, gc, 0, 0,
                    width, height, visRectDst->left, visRectDst->top );
@@ -1111,6 +1115,20 @@
             !Options.perfectGraphics)
         {
             XSetFunction( display, dcDst->u.x.gc, GXinvert );
+
+            if( COLOR_GetSystemPaletteFlags() & (COLOR_PRIVATE | COLOR_VIRTUAL) )
+                XSetFunction( display, dcDst->u.x.gc, GXinvert);
+            else
+            {
+                /* Xor is much better when we do not have full colormap.   */
+                /* Using white^black ensures that we invert at least black */
+                /* and white. */
+                Pixel xor_pix = (WhitePixelOfScreen(screen) ^
+                                 BlackPixelOfScreen(screen));
+                XSetFunction( display, dcDst->u.x.gc, GXxor );
+                XSetForeground( display, dcDst->u.x.gc, xor_pix);
+                XSetFillStyle( display, dcDst->u.x.gc, FillSolid ); 
+            }
             XFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
                             visRectDst.left, visRectDst.top, width, height ); 
             return TRUE;
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 5680581..f609f25 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -227,6 +227,35 @@
     return height * bmp->bitmap.bmWidthBytes;
 }
 
+/**********************************************************************
+ *	    LoadImageA    (USER32.364)
+ * FIXME: implementation still lacks nearly all features, see LR_*
+ * defines in windows.h
+ */
+
+HANDLE32 LoadImage32A(
+	HINSTANCE32 hinst,LPCSTR name,UINT32 type,INT32 desiredx,
+	INT32 desiredy,UINT32 loadflags
+) {
+	if (HIWORD(name)) {
+		dprintf_resource(stddeb,"LoadImage32A(0x%04x,%s,%d,%d,%d,0x%08x)\n",
+			hinst,name,type,desiredx,desiredy,loadflags
+		);
+	} else {
+		dprintf_resource(stddeb,"LoadImage32A(0x%04x,%p,%d,%d,%d,0x%08x)\n",
+			hinst,name,type,desiredx,desiredy,loadflags
+		);
+	}
+	switch (type) {
+	case IMAGE_BITMAP:
+		return LoadBitmap32A(hinst,name);
+	case IMAGE_ICON:
+		return LoadIcon32A(hinst,name);
+	case IMAGE_CURSOR:
+		return LoadCursor32A(hinst,name);
+	}
+	return 0;
+}
 
 /**********************************************************************
  *	    LoadBitmap16    (USER.175)
diff --git a/objects/brush.c b/objects/brush.c
index 6331df0..00553ab 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -236,7 +236,7 @@
 /***********************************************************************
  *           SetBrushOrg    (GDI.148)
  */
-DWORD SetBrushOrg( HDC hdc, short x, short y )
+DWORD SetBrushOrg( HDC16 hdc, INT16 x, INT16 y )
 {
     DWORD retval;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
@@ -247,14 +247,36 @@
     return retval;
 }
 
+
+/***********************************************************************
+ *           SetBrushOrgEx    (GDI32.308)
+ */
+BOOL32 SetBrushOrgEx( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 oldorg )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+
+    if (!dc) return FALSE;
+    if (oldorg)
+    {
+        oldorg->x = dc->w.brushOrgX;
+        oldorg->y = dc->w.brushOrgY;
+    }
+    dc->w.brushOrgX = x;
+    dc->w.brushOrgY = y;
+    return TRUE;
+}
+
+
 /***********************************************************************
  *           GetSysColorBrush    (USER.281)
  */
 HBRUSH GetSysColorBrush(WORD x)
 {
-	return GetStockObject(GRAY_BRUSH);
+    fprintf( stderr, "Unimplemented stub: GetSysColorBrush(%d)\n", x );
+    return GetStockObject(LTGRAY_BRUSH);
 }
 
+
 /***********************************************************************
  *           BRUSH_DeleteObject
  */
diff --git a/objects/color.c b/objects/color.c
index e92adea..b7c45a2 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -62,7 +62,8 @@
  * currently inactive window it changes only DC palette mappings.
  */
 
-#define NB_RESERVED_COLORS  20 /* number of fixed colors in system palette */
+#define NB_RESERVED_COLORS  		20 /* number of fixed colors in system palette */
+#define NB_COLORCUBE_START_INDEX	63
 
 Visual* 		visual = NULL;
 
@@ -71,7 +72,8 @@
 static int COLOR_gapEnd = -1;
 
   /* First free dynamic color cell, 0 = full palette, -1 = fixed palette */
-static int COLOR_firstFree = 0; 
+static int            COLOR_firstFree = 0; 
+static unsigned char  COLOR_freeList[256];
 
   /* Maps entry in the system palette to X pixel value */
 int* COLOR_PaletteToPixel = NULL;
@@ -134,21 +136,97 @@
     return cSpace.flags;
 }
 
-void COLOR_FormatSystemPalette(void)
+COLORREF COLOR_GetSystemPaletteEntry(BYTE i)
 {
-    int i, j = COLOR_firstFree = NB_RESERVED_COLORS/2;
-
-    COLOR_sysPal[j].peFlags = 0;
-    for( i = NB_RESERVED_COLORS/2 + 1 ; i < 256 - NB_RESERVED_COLORS/2 ; i++ )
-        if( i < COLOR_gapStart || i > COLOR_gapEnd )
-        {
-            COLOR_sysPal[i].peFlags = 0;       /* unused tag */
-            COLOR_sysPal[j].peRed = i;         /* next */
-            j = i;
-        }
-    COLOR_sysPal[j].peRed = 0;		 /* terminal */
+ return *(COLORREF*)(COLOR_sysPal + i) & 0x00ffffff;
 }
 
+void COLOR_FormatSystemPalette(void)
+{
+ /* Build free list so we'd have an easy way to find
+  * out if there are any available colorcells. 
+  */
+
+  int i, j = COLOR_firstFree = NB_RESERVED_COLORS/2;
+
+  COLOR_sysPal[j].peFlags = 0;
+  for( i = NB_RESERVED_COLORS/2 + 1 ; i < 256 - NB_RESERVED_COLORS/2 ; i++ )
+    if( i < COLOR_gapStart || i > COLOR_gapEnd )
+      {
+	COLOR_sysPal[i].peFlags = 0;  /* unused tag */
+	COLOR_freeList[j] = i;	  /* next */
+        j = i;
+      }
+  COLOR_freeList[j] = 0;
+}
+
+void COLOR_FillDefaultColors(void)
+{
+ /* initialize unused entries to what Windows uses as a color 
+  * cube - based on Greg Kreider's code. 
+  */
+
+  int i = 0, idx = 0;
+  int red, no_r, inc_r;
+  int green, no_g, inc_g; 
+  int blue, no_b, inc_b;
+
+  while (i*i*i < (cSpace.size - NB_RESERVED_COLORS)) i++;
+  no_r = no_g = no_b = --i;
+  if ((no_r * (no_g+1) * no_b) < (cSpace.size - NB_RESERVED_COLORS)) no_g++;
+  if ((no_r * no_g * (no_b+1)) < (cSpace.size - NB_RESERVED_COLORS)) no_b++;
+  inc_r = (255 - NB_COLORCUBE_START_INDEX)/no_r;
+  inc_g = (255 - NB_COLORCUBE_START_INDEX)/no_g;
+  inc_b = (255 - NB_COLORCUBE_START_INDEX)/no_b;
+
+  idx = COLOR_firstFree;
+
+  for (blue = NB_COLORCUBE_START_INDEX; blue < 256 && idx; blue += inc_b )
+    for (green = NB_COLORCUBE_START_INDEX; green < 256 && idx; green += inc_g )
+      for (red = NB_COLORCUBE_START_INDEX; red < 256 && idx; red += inc_r )
+      {
+	 /* weird but true */
+
+	 if( red == NB_COLORCUBE_START_INDEX && green == red && blue == green ) continue;
+
+         COLOR_sysPal[idx].peRed = red;
+         COLOR_sysPal[idx].peGreen = green;
+         COLOR_sysPal[idx].peBlue = blue;
+         
+	 /* set X color */
+
+	 if( cSpace.flags & COLOR_VIRTUAL )
+	 {
+            if (COLOR_Redmax != 255) no_r = (red * COLOR_Redmax) / 255;
+            if (COLOR_Greenmax != 255) no_g = (green * COLOR_Greenmax) / 255;
+            if (COLOR_Bluemax != 255) no_b = (blue * COLOR_Bluemax) / 255;
+
+            COLOR_PaletteToPixel[idx] = (no_r << COLOR_Redshift) | (no_g << COLOR_Greenshift) | (no_b << COLOR_Blueshift);
+	 }
+	 else if( !(cSpace.flags & COLOR_FIXED) )
+	 {
+	   XColor color = { color.pixel = (COLOR_PaletteToPixel)? COLOR_PaletteToPixel[idx] : idx ,
+	                    COLOR_sysPal[idx].peRed << 8,
+			    COLOR_sysPal[idx].peGreen << 8,
+			    COLOR_sysPal[idx].peGreen << 8,
+			    (DoRed | DoGreen | DoBlue) };
+	   XStoreColor(display, cSpace.colorMap, &color);
+	 }
+
+	 idx = COLOR_freeList[idx];
+      }
+
+  /* fill the rest with gray for now - only needed for
+   * sparse palette (in seamless mode)
+   */
+
+  for ( i = COLOR_gapStart; i <= COLOR_gapEnd; i++ )
+  {
+     *(COLORREF*)(COLOR_sysPal + i) = 0x00c0c0c0;
+      if( COLOR_PaletteToPixel )
+	  COLOR_PaletteToPixel[i] = COLOR_PaletteToPixel[7];
+  }
+}
 
 /***********************************************************************
  *           COLOR_BuildPrivateMap/COLOR_BuildSharedMap
@@ -310,6 +388,7 @@
            * color translations but we have to allocate full palette 
 	   * to maintain compatibility
 	   */
+	  cs->size = 256;
 	  dprintf_palette(stddeb,"\tvirtual colorspace - screendepth %i\n", screenDepth);
 	}
    else cs->size = NB_RESERVED_COLORS;	/* system palette only - however we can alloc a bunch
@@ -338,40 +417,47 @@
    /* Setup system palette entry <-> pixel mappings and fill in 20 fixed entries */
 
    if( screenDepth <= 8 )
-   {
+     {
        COLOR_PixelToPalette = (int*)xmalloc(sizeof(int)*256);
-       COLOR_PaletteToPixel = (int*)xmalloc(sizeof(int)*256);
+       memset( COLOR_PixelToPalette, 0, 256*sizeof(int) );
+     }
 
-       for( i = j = 0; i < 256; i++ )
-       {
-           if( i >= COLOR_gapStart && i <= COLOR_gapEnd ) 
-           {
-               COLOR_PaletteToPixel[i] = 0;
-               COLOR_sysPal[i].peFlags = 0;	/* mark as unused */
-               continue;
-           }
+   /* for hicolor visuals PaletteToPixel mapping is used to skip
+    * RGB->pixel calculation in COLOR_ToPhysical(). 
+    */
 
-           if( i < NB_RESERVED_COLORS/2 )
-           {
-               COLOR_PaletteToPixel[i] = sysPixel[i];
-               COLOR_sysPal[i] = __sysPalTemplate[i];
-           }
-           else if( i >= 256 - NB_RESERVED_COLORS/2 )
-           {
-               COLOR_PaletteToPixel[i] = sysPixel[(i + NB_RESERVED_COLORS) - 256]; 
-               COLOR_sysPal[i] = __sysPalTemplate[(i + NB_RESERVED_COLORS) - 256];
-           }
-           else if( pixDynMapping )
-               COLOR_PaletteToPixel[i] = pixDynMapping[j++];
+   COLOR_PaletteToPixel = (int*)xmalloc(sizeof(int)*256);
+
+   for( i = j = 0; i < 256; i++ )
+   {
+      if( i >= COLOR_gapStart && i <= COLOR_gapEnd ) 
+      {
+         COLOR_PaletteToPixel[i] = 0;
+         COLOR_sysPal[i].peFlags = 0;	/* mark as unused */
+         continue;
+      }
+
+      if( i < NB_RESERVED_COLORS/2 )
+      {
+        COLOR_PaletteToPixel[i] = sysPixel[i];
+        COLOR_sysPal[i] = __sysPalTemplate[i];
+      }
+      else if( i >= 256 - NB_RESERVED_COLORS/2 )
+      {
+        COLOR_PaletteToPixel[i] = sysPixel[(i + NB_RESERVED_COLORS) - 256]; 
+        COLOR_sysPal[i] = __sysPalTemplate[(i + NB_RESERVED_COLORS) - 256];
+      }
+      else if( pixDynMapping )
+             COLOR_PaletteToPixel[i] = pixDynMapping[j++];
            else
-               COLOR_PaletteToPixel[i] = i;
+             COLOR_PaletteToPixel[i] = i;
 
-           dprintf_palette(stddeb,"\tindex %i -> pixel %i\n", i, COLOR_PaletteToPixel[i]);
+      dprintf_palette(stddeb,"\tindex %i -> pixel %i\n", i, COLOR_PaletteToPixel[i]);
 
-           memset( COLOR_PixelToPalette, 0, 256*sizeof(int) );
-           COLOR_PixelToPalette[COLOR_PaletteToPixel[i]] = i;
-       }
+      if( COLOR_PixelToPalette )
+        COLOR_PixelToPalette[COLOR_PaletteToPixel[i]] = i;
    }
+
    if( pixDynMapping ) free(pixDynMapping);
    return TRUE;
 }
@@ -387,6 +473,9 @@
     int 		i;
     HPALETTE16 		hpalette;
     LOGPALETTE * 	palPtr;
+    PALETTEOBJ*         palObj;
+
+    memset(COLOR_freeList, 0, 256*sizeof(unsigned char));
 
     /* calculate max palette size */
 
@@ -397,11 +486,13 @@
     else
 	COLOR_BuildSharedMap( &cSpace );
 
-    /* Build free list ( use peRed as "next" ) */
+    /* Build free list */
 
     if( COLOR_firstFree != -1 )
 	COLOR_FormatSystemPalette();
 
+    COLOR_FillDefaultColors();
+
     /* create default palette (20 system colors) */
 
     palPtr = xmalloc( sizeof(LOGPALETTE) + (NB_RESERVED_COLORS-1)*sizeof(PALETTEENTRY) );
@@ -417,6 +508,11 @@
         palPtr->palPalEntry[i].peFlags = 0;  
     }
     hpalette = CreatePalette( palPtr );
+
+    palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
+
+    palObj->mapping = xmalloc( sizeof(int) * 20 );
+
     free( palPtr );
     return hpalette;
 }
@@ -534,8 +630,7 @@
 
 
 /***********************************************************************
- *	     COLOR_PaletteLookup
- *
+ *	     COLOR_PaletteLookupPixel
  */
 int COLOR_PaletteLookupPixel( PALETTEENTRY* palPalEntry, int size,
                               int* mapping, COLORREF col, BOOL skipReserved )
@@ -543,7 +638,7 @@
     int i, best = 0, diff = 0x7fffffff;
     int r,g,b;
 
-    for( i = 0; i < size; i++ )
+    for( i = 0; i < size && diff ; i++ )
     {
         if( !(palPalEntry[i].peFlags & PC_SYS_USED) ||
             (skipReserved && palPalEntry[i].peFlags  & PC_SYS_RESERVED) )
@@ -560,10 +655,33 @@
     return (mapping) ? mapping[best] : best;
 }
 
+/***********************************************************************
+ *           COLOR_LookupSystemPixel
+ */
+int COLOR_LookupSystemPixel(COLORREF col)
+{
+ int            i, best = 0, diff = 0x7fffffff;
+ int            size = COLOR_GetSystemPaletteSize();
+ int            r,g,b;
+
+ for( i = 0; i < size && diff ; i++ )
+    {
+      if( i == NB_RESERVED_COLORS/2 ) i = size - NB_RESERVED_COLORS/2;
+
+      r = COLOR_sysPal[i].peRed - GetRValue(col);
+      g = COLOR_sysPal[i].peGreen - GetGValue(col);
+      b = COLOR_sysPal[i].peBlue - GetBValue(col);
+
+      r = r*r + g*g + b*b;
+
+      if( r < diff ) { best = i; diff = r; }
+    }
+ 
+ return (COLOR_PaletteToPixel)? COLOR_PaletteToPixel[best] : best;
+}
 
 /***********************************************************************
  *	     COLOR_PaletteLookupExactIndex
- *
  */
 int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
                                    COLORREF col )
@@ -581,6 +699,32 @@
     return -1;
 }
 
+/***********************************************************************
+ *           COLOR_LookupNearestColor
+ */
+COLORREF COLOR_LookupNearestColor( PALETTEENTRY* palPalEntry, int size, COLORREF color )
+{
+  unsigned char		spec_type = color >> 24;
+  int			i;
+
+  /* we need logical palette for PALETTERGB and PALETTEINDEX colorrefs */
+
+  if( spec_type == 2 ) /* PALETTERGB */
+    color = *(COLORREF*)
+	     (palPalEntry + COLOR_PaletteLookupPixel(palPalEntry,size,NULL,color,FALSE));
+
+  else if( spec_type == 1 ) /* PALETTEINDEX */
+    if( (i = color & 0x0000ffff) >= size ) 
+      {
+	fprintf(stderr, "\tRGB(%lx) : idx %d is out of bounds, assuming NULL\n", color, i);
+	color = *(COLORREF*)palPalEntry;
+      }
+    else color = *(COLORREF*)(palPalEntry + i);
+
+  color &= 0x00ffffff;
+  return (0x00ffffff & *(COLORREF*)
+         (COLOR_sysPal + COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, color, FALSE)));
+}
 
 /***********************************************************************
  *           COLOR_ToLogical
@@ -590,13 +734,29 @@
 COLORREF COLOR_ToLogical(int pixel)
 {
     XColor color;
-  
-    if (screenDepth > 8) return pixel;
-    if ((screenDepth <= 8) && (pixel < 256) && !(cSpace.flags & COLOR_VIRTUAL))
-        return  ( *(COLORREF*)(COLOR_sysPal + ((COLOR_PixelToPalette)?COLOR_PixelToPalette[pixel]:pixel)) ) & 0x00ffffff;
 
-    color.pixel = pixel;
-    XQueryColor(display, cSpace.colorMap, &color);
+    /* truecolor visual */
+
+    if (screenDepth >= 24) return pixel;
+
+    /* check for hicolor visuals first */
+
+    if ( cSpace.flags & COLOR_FIXED && !COLOR_Graymax )
+       {
+         color.red = pixel >> COLOR_Redshift;
+         color.green = pixel >> COLOR_Greenshift;
+         color.blue = pixel >> COLOR_Blueshift;
+       }
+    else if ((screenDepth <= 8) && (pixel < 256) && 
+	    !(cSpace.flags & (COLOR_VIRTUAL | COLOR_FIXED)) )
+        return  ( *(COLORREF*)(COLOR_sysPal + 
+		  ((COLOR_PixelToPalette)?COLOR_PixelToPalette[pixel]:pixel)) ) & 0x00ffffff;
+    else
+       {
+         color.pixel = pixel;
+         XQueryColor(display, cSpace.colorMap, &color);
+         return RGB(color.red >> 8, color.green >> 8, color.blue >> 8);
+       }
 
     return RGB((color.red * 255)/COLOR_Redmax,
                (color.green * 255)/COLOR_Greenmax,
@@ -650,38 +810,37 @@
 
 	switch(spec_type)
         {
-	  default: 
-          case 0: /* RGB */
-
-            red = GetRValue(color);
-            green = GetGValue(color);
-            blue = GetBValue(color);
-            break;
-
           case 2: /* PALETTERGB - not sure if we really need to search palette */
 	
 	    idx = COLOR_PaletteLookupPixel( palPtr->logpalette.palPalEntry,
 					    palPtr->logpalette.palNumEntries,
 					    NULL, color, FALSE);
+
+            if( palPtr->mapping ) return palPtr->mapping[idx];
+
+	    color = *(COLORREF*)(palPtr->logpalette.palPalEntry + idx);
+	    break;
+
           case 1: /* PALETTEINDEX */
 
-            idx = ((spec_type == 1)?color:idx) & 0xffff;
-
-            if (idx >= palPtr->logpalette.palNumEntries)
+            if ( (idx = color & 0xffff) >= palPtr->logpalette.palNumEntries)
             {
                 fprintf(stderr, "\tRGB(%lx) : idx %d is out of bounds, assuming black\n", color, idx);
-                /* out of bounds */
-                red = green = blue = 0;
+                return 0;
             }
-            else if( palPtr->mapping ) return palPtr->mapping[idx];
-	    else
-            {
-                red = palPtr->logpalette.palPalEntry[idx].peRed;
-                green = palPtr->logpalette.palPalEntry[idx].peGreen;
-                blue = palPtr->logpalette.palPalEntry[idx].peBlue;
-            }
+
+            if( palPtr->mapping ) return palPtr->mapping[idx];
+
+	    color = *(COLORREF*)(palPtr->logpalette.palPalEntry + idx);
+
+	    /* fall through and out */
+
+	  case 0: /* RGB */
+	  default:
 	}
 
+        red = GetRValue(color); green = GetGValue(color); blue = GetBValue(color);
+
 	if (COLOR_Graymax)
         {
 	    /* grayscale only; return scaled value */
@@ -740,7 +899,6 @@
     return index;
 }
 
-
 /***********************************************************************
  *           COLOR_SetMapping
  *
@@ -754,11 +912,10 @@
     int  prevMapping = (palPtr->mapping) ? 1 : 0;
     int  iRemapped = 0;
 
-    /* free dynamic colors in system palette - 
-     * certain optimization is to free them only when they are needed */
+    /* reset dynamic system palette entries */
 
     if( !mapOnly && COLOR_firstFree != -1)
-        COLOR_FormatSystemPalette();
+         COLOR_FormatSystemPalette();
 
     /* initialize palette mapping table */
  
@@ -783,6 +940,7 @@
 
 	case PC_RESERVED:   /* forbid future mappings to this entry */
             flag |= PC_SYS_RESERVED;
+
             /* fall through */
 	default:	    /* try to collapse identical colors */
             index = COLOR_PaletteLookupExactIndex(COLOR_sysPal, 256,  
@@ -791,26 +949,32 @@
 	case PC_NOCOLLAPSE: 
             if( index < 0 )
             {
-                if( COLOR_firstFree > 0 && !(cSpace.flags & COLOR_FIXED) && !mapOnly )
+                if( COLOR_firstFree > 0 && !(cSpace.flags & COLOR_FIXED) )
                 {
                     XColor color;
                     index = COLOR_firstFree;  /* ought to be available */
-                    COLOR_firstFree = COLOR_sysPal[index].peRed;
+                    COLOR_firstFree = COLOR_freeList[index];
+
                     color.pixel = (COLOR_PaletteToPixel) ? COLOR_PaletteToPixel[index] : index;
-                    color.red = palPtr->logpalette.palPalEntry[i].peRed * 65535 / 255;
-                    color.green = palPtr->logpalette.palPalEntry[i].peGreen * 65535 / 255;
-                    color.blue = palPtr->logpalette.palPalEntry[i].peBlue * 65535 / 255;
+                    color.red = palPtr->logpalette.palPalEntry[i].peRed << 8;
+                    color.green = palPtr->logpalette.palPalEntry[i].peGreen << 8;
+                    color.blue = palPtr->logpalette.palPalEntry[i].peBlue << 8;
                     color.flags = DoRed | DoGreen | DoBlue;
                     XStoreColor(display, cSpace.colorMap, &color);
+
                     COLOR_sysPal[index] = palPtr->logpalette.palPalEntry[i];
                     COLOR_sysPal[index].peFlags = flag;
                     if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
+
+		    COLOR_freeList[index] = 0;
+		    palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED | PC_SYS_MAPPED;
                     break;
                 }
                 else if ( cSpace.flags & COLOR_VIRTUAL ) 
                 {
                     index = COLOR_ToPhysical( NULL, 0x00ffffff &
                              *(COLORREF*)(palPtr->logpalette.palPalEntry + i));
+		    palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED;
                     break;     
                 }
 
@@ -819,6 +983,7 @@
                 index = COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, 
                        *(COLORREF*)(palPtr->logpalette.palPalEntry + i), TRUE);
             }
+	    palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED;
 
             if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
             break;
@@ -827,9 +992,9 @@
         if( !prevMapping || palPtr->mapping[i] != index ) iRemapped++;
         palPtr->mapping[i] = index;
 
-        /* dprintf_palette(stddeb,"\tentry %i (%lx) -> pixel %i\n", i, 
+        dprintf_palette(stddeb,"\tentry %i (%lx) -> pixel %i\n", i, 
 				*(COLORREF*)(palPtr->logpalette.palPalEntry + i), index);
-	*/
+	
     }
     return iRemapped;
 }
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index c750d61..5a35ff8 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -35,6 +35,7 @@
 #include "xmalloc.h"
 #include "task.h"
 
+extern UINT16 COLOR_GetSystemPaletteSize();
 
 Cursor CURSORICON_XCursor = None;  /* Current X cursor */
 static HCURSOR hActiveCursor = 0;  /* Active cursor */
@@ -491,7 +492,7 @@
 
     return CURSORICON_Load( hInstance, name,
                             SYSMETRICS_CXICON, SYSMETRICS_CYICON,
-                            MIN( 16, 1 << screenDepth ), FALSE );
+                            MIN( 16, COLOR_GetSystemPaletteSize() ), FALSE );
 }
 
 
@@ -935,7 +936,8 @@
  */
 WORD GetIconID( HANDLE hResource, DWORD resType )
 {
-    CURSORICONDIR *lpDir = LockResource16(hResource);
+    CURSORICONDIR *lpDir = (CURSORICONDIR *)GlobalLock16(hResource);
+/* LockResource16(hResource); */
 
     if (!lpDir || lpDir->idReserved ||
         ((lpDir->idType != 1) && (lpDir->idType != 2)))
@@ -957,9 +959,9 @@
         }
     case 3:  /* icon */
         {
-            ICONDIRENTRY *entry = CURSORICON_FindBestIcon( lpDir,
-                                          SYSMETRICS_CXICON, SYSMETRICS_CYICON,
-                                          MIN( 16, 1 << screenDepth ) );
+            ICONDIRENTRY * entry =  CURSORICON_FindBestIcon( lpDir,
+                                    SYSMETRICS_CXICON, SYSMETRICS_CYICON,
+                                    MIN( 16, COLOR_GetSystemPaletteSize() ) );
             return entry ? entry->wResId : 0;
         }
     }
diff --git a/objects/dc.c b/objects/dc.c
index 5e3eff9..58529ac 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -112,7 +112,7 @@
     caps->numPens       = 16;    /* 16 solid pens */
     caps->numMarkers    = 0;
     caps->numFonts      = 0;
-    caps->numColors     = 1 << caps->bitsPixel;
+    caps->numColors     = 100;
     caps->pdeviceSize   = 0;
     caps->curveCaps     = CC_CIRCLES | CC_PIE | CC_CHORD | CC_ELLIPSES |
 	                  CC_WIDE | CC_STYLED | CC_WIDESTYLED | 
@@ -126,14 +126,20 @@
 	                  TC_IA_ABLE | TC_UA_ABLE | TC_SO_ABLE | TC_RA_ABLE;
     caps->clipCaps      = CP_REGION;
     caps->rasterCaps    = RC_BITBLT | RC_BANDING | RC_SCALING | RC_BITMAP64 |
-	                  RC_DI_BITMAP | RC_PALETTE | RC_DIBTODEV | RC_BIGFONT|
-			  RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS;
+                          RC_DI_BITMAP | RC_DIBTODEV | RC_BIGFONT|
+                          RC_STRETCHBLT | RC_STRETCHDIB | RC_DEVBITS;
+
+    if( !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
+        caps->rasterCaps |= RC_PALETTE;
+
     caps->aspectX       = 36;  /* ?? */
     caps->aspectY       = 36;  /* ?? */
     caps->aspectXY      = 51;
     caps->logPixelsX    = (int)(caps->horzRes * 25.4 / caps->horzSize);
     caps->logPixelsY    = (int)(caps->vertRes * 25.4 / caps->vertSize);
-    caps->sizePalette   = DefaultVisual(display,DefaultScreen(display))->map_entries;
+    caps->sizePalette   = (caps->rasterCaps & RC_PALETTE)
+                          ? DefaultVisual(display,DefaultScreen(display))->map_entries
+                          : 0;
     caps->numReserved   = 0;
     caps->colorRes      = 0;
 }
diff --git a/objects/dib.c b/objects/dib.c
index 8190af4..ef9f072 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -542,13 +542,14 @@
     WORD x;
     BYTE pad = (4 - ((width*3) & 3)) & 3;
 
+    /* "bits" order is reversed for some reason */
+
     while (lines--)
     {
 	for (x = 0; x < width; x++, bits += 3)
-	{
-	    XPutPixel( bmpImage, x, lines,
-		       COLOR_ToPhysical( dc, RGB(bits[0],bits[1],bits[2]) ));
-	}
+	    XPutPixel( bmpImage, x, lines, 
+		       COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])) );
+
 	bits += pad;
     }
 }
diff --git a/objects/palette.c b/objects/palette.c
index c287be8..854322a 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -17,6 +17,9 @@
 
 extern HWND 		DCE_hDC2hWnd( HDC );			/* get associated window by 
 								 * walking DCE list */
+extern int              COLOR_LookupSystemPixel(COLORREF);      /* lookup pixel among static entries 
+                                                                 * of the system palette */
+extern COLORREF		COLOR_GetSystemPaletteEntry(BYTE);
 
 static WORD SystemPaletteUse = SYSPAL_STATIC;	/* currently not considered */
 
@@ -25,56 +28,6 @@
 
 
 /***********************************************************************
- *           PALETTE_GetNearestIndexAndColor
- */
-static WORD PALETTE_GetNearestIndexAndColor( HPALETTE16 hpalette,
-                                             COLORREF *color)
-{
-    int i, minDist, dist;
-    WORD index = 0;
-    BYTE r, g, b;
-    PALETTEENTRY * entry;
-    PALETTEOBJ * palPtr;
-    
-    palPtr = (PALETTEOBJ *) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
-    if (!palPtr) return 0;
-
-    if ( hpalette == STOCK_DEFAULT_PALETTE )
-    {
-	if ((*color & 0xffffff) == 0) return 0;  /* Entry 0 is black */
-	if ((*color & 0xffffff) == 0xffffff)     /* Max entry is white */
-	    return palPtr->logpalette.palNumEntries - 1;
-    }
-
-    r = GetRValue(*color);
-    g = GetGValue(*color);
-    b = GetBValue(*color);
-
-    entry = palPtr->logpalette.palPalEntry;
-    for (i = 0, minDist = 0xffffff; minDist !=0 &&
-         i < palPtr->logpalette.palNumEntries ; i++)
-    {
-	if (entry->peFlags != 0xff)
-	{
-	    dist = (r - entry->peRed) * (r - entry->peRed) +
-		   (g - entry->peGreen) * (g - entry->peGreen) +
-		   (b - entry->peBlue) * (b - entry->peBlue);	
-	    if (dist < minDist)
-	    {
-		minDist = dist;
-		index = i;
-	    }
-	}
-	entry++;
-    }
-
-    entry = &palPtr->logpalette.palPalEntry[index];
-    *color = RGB( entry->peRed, entry->peGreen, entry->peBlue );
-    return index;
-}
-
-
-/***********************************************************************
  *           PALETTE_ValidateFlags
  */
 void PALETTE_ValidateFlags(PALETTEENTRY* lpPalE, int size)
@@ -158,6 +111,9 @@
 	    count * sizeof(PALETTEENTRY) );
     PALETTE_ValidateFlags(palPtr->logpalette.palPalEntry, 
 			  palPtr->logpalette.palNumEntries);
+    free(palPtr->mapping);
+    palPtr->mapping = NULL;
+
     return count;
 }
 
@@ -213,7 +169,8 @@
 {
     WORD i;
     DC *dc;
-    XColor color;
+
+    dprintf_palette(stddeb,"GetSystemPaletteEntries: hdc = %04x, cound = %i", hdc, count );
 
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
     if (start >= dc->w.devCaps->sizePalette) return 0;
@@ -221,14 +178,10 @@
 	count = dc->w.devCaps->sizePalette - start;
     for (i = 0; i < count; i++)
     {
-	color.pixel = (COLOR_PaletteToPixel)
-		      ? COLOR_PaletteToPixel[start + i]
-		      : start + i;
-	XQueryColor( display, COLOR_GetColormap(), &color );
-	entries[i].peRed   = color.red >> 8;
-	entries[i].peGreen = color.green >> 8;
-	entries[i].peBlue  = color.blue >> 8;
-	entries[i].peFlags = 0;	
+	*(COLORREF*)(entries + i) = COLOR_GetSystemPaletteEntry((BYTE)(start + i));
+
+        dprintf_palette(stddeb,"\tidx(%02x) -> RGB(%08lx)\n", (unsigned char)(start + i), 
+							    *(COLORREF*)(entries + i) );
     }
     return count;
 }
@@ -239,7 +192,14 @@
  */
 WORD GetNearestPaletteIndex( HPALETTE16 hpalette, COLORREF color )
 {
-    WORD index = PALETTE_GetNearestIndexAndColor( hpalette, &color );
+    PALETTEOBJ*	palObj = (PALETTEOBJ*) GDI_GetObjPtr( hpalette, PALETTE_MAGIC );
+    WORD	index  = 0;
+
+    if( palObj )
+        index = COLOR_PaletteLookupPixel( palObj->logpalette.palPalEntry, 
+				          palObj->logpalette.palNumEntries, NULL,
+					  color, FALSE );
+
     dprintf_palette(stddeb,"GetNearestPaletteIndex(%04x,%06lx): returning %d\n", 
                     hpalette, color, index );
     return index;
@@ -251,11 +211,20 @@
  */
 COLORREF GetNearestColor( HDC hdc, COLORREF color )
 {
-    COLORREF nearest = color;
-    DC *dc;
+    COLORREF 	 nearest = 0xFADECAFE;
+    DC 		*dc;
+    PALETTEOBJ  *palObj;
 
-    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
-    PALETTE_GetNearestIndexAndColor( dc->w.hPalette, &nearest );
+    if ( (dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC )) )
+    {
+      palObj = (PALETTEOBJ*) 
+	        GDI_GetObjPtr( (dc->w.hPalette)? dc->w.hPalette
+				 	       : STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
+
+      nearest = COLOR_LookupNearestColor( palObj->logpalette.palPalEntry,
+					  palObj->logpalette.palNumEntries, color );
+    }
+
     dprintf_palette(stddeb,"GetNearestColor(%06lx): returning %06lx\n", 
                     color, nearest );
     return nearest;
@@ -307,7 +276,13 @@
     DC *dc;
 
     dprintf_palette(stddeb, "GDISelectPalette: %04x %04x\n", hdc, hpal );
-    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
     prev = dc->w.hPalette;
     dc->w.hPalette = hpal;
     if (!wBkg) hPrimaryPalette = hpal; 
@@ -321,14 +296,22 @@
  */
 UINT GDIRealizePalette( HDC hdc )
 {
-    DC*         dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ) ;
     PALETTEOBJ* palPtr;
     int		realized = 0;
+    DC*		dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
 
     dprintf_palette(stddeb, "GDIRealizePalette: %04x...", hdc );
     
     if( dc &&  dc->w.hPalette != hLastRealizedPalette )
     {
+	if( dc->w.hPalette == STOCK_DEFAULT_PALETTE )
+            return RealizeDefaultPalette( hdc );
+
         palPtr = (PALETTEOBJ *) GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC );
         
 	realized = COLOR_SetMapping(palPtr, dc->w.hPalette != hPrimaryPalette 
@@ -347,18 +330,38 @@
  */
 WORD RealizeDefaultPalette( HDC hdc )
 {
-    DC *dc;
+    DC          *dc;
+    PALETTEOBJ*  palPtr;
+    int          i, index, realized = 0;
 
     dprintf_palette(stddeb,"RealizeDefaultPalette: %04x\n", hdc );
 
-    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
+
     if ( dc->w.flags & DC_MEMORY ) return 0;
 
     hPrimaryPalette = STOCK_DEFAULT_PALETTE;
     hLastRealizedPalette = STOCK_DEFAULT_PALETTE;
-    return COLOR_SetMapping( (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC ), TRUE);
-}
 
+    palPtr = (PALETTEOBJ*)GDI_GetObjPtr(STOCK_DEFAULT_PALETTE, PALETTE_MAGIC );
+
+    /* lookup is needed to account for SetSystemPaletteUse() stuff */
+
+    for( i = 0; i < 20; i++ )
+       {
+         index = COLOR_LookupSystemPixel(*(COLORREF*)(palPtr->logpalette.palPalEntry + i));
+
+         /* mapping is allocated in COLOR_InitPalette() */
+
+         if( index != palPtr->mapping[i] ) { palPtr->mapping[i]=index; realized++; }
+       }
+    return realized;
+}
 
 /***********************************************************************
  *           IsDCCurrentPalette   (GDI.412)
@@ -366,7 +369,7 @@
 BOOL IsDCCurrentPalette(HDC hDC)
 {
     DC* dc = (DC *)GDI_GetObjPtr( hDC, DC_MAGIC );
-    return (dc->w.hPalette == hPrimaryPalette);
+    return (dc)?(dc->w.hPalette == hPrimaryPalette):FALSE;
 }
 
 /***********************************************************************
@@ -391,7 +394,7 @@
 	
 	/* set primary palette if it's related to current active */
 
-	if( hWnd && (hActive == hWnd || IsChild(hActive,hWnd)) &&
+	if((!hWnd || (hActive == hWnd || IsChild(hActive,hWnd))) &&
             !bForceBackground )
 	    wBkgPalette = 0;
     }
@@ -408,7 +411,8 @@
 
     /* do not send anything if no colors were changed */
 
-    if( IsDCCurrentPalette( hDC ) && realized )
+    if( IsDCCurrentPalette( hDC ) && realized && 
+        !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
     {
 	/* Send palette change notification */
 
@@ -431,6 +435,8 @@
     /* Docs say that we have to remap current drawable pixel by pixel
      * but it would take forever given the speed of XGet/PutPixel.
      */
-    if (hWnd) InvalidateRect16( hWnd, NULL, FALSE );
+    if (hWnd && !(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) ) 
+	InvalidateRect16( hWnd, NULL, FALSE );
     return 0x666;
 }
+
diff --git a/windows/class.c b/windows/class.c
index 80b6cc9..e956801 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -240,20 +240,6 @@
 
 
 /***********************************************************************
- *           CLASS_FindClassByName
- *
- * Return a pointer to the class.
- */
-CLASS *CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance )
-{
-    ATOM atom;
-
-    if (!(atom = GlobalFindAtom16( name ))) return 0;
-    return CLASS_FindClassByAtom( atom, hinstance );
-}
-
-
-/***********************************************************************
  *           CLASS_RegisterClass
  *
  * The real RegisterClass() functionality.
diff --git a/windows/dialog.c b/windows/dialog.c
index bdd46a3..9faec22 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -577,6 +577,7 @@
       /* Initialise dialog extra data */
 
     dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
+    WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType );
     dlgInfo->hUserFont = hFont;
     dlgInfo->hMenu     = hMenu;
     dlgInfo->xBaseUnit = xUnit;
@@ -595,7 +596,6 @@
 
     /* Send initialisation messages and set focus */
 
-    WINPROC_SetProc( &dlgInfo->dlgProc, dlgProc, procType );
     dlgInfo->hwndFocus = DIALOG_GetFirstTabItem( hwnd );
     if (dlgInfo->hUserFont)
 	SendMessage32A( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
diff --git a/windows/event.c b/windows/event.c
index e6a053b..f00cfe9 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -149,6 +149,9 @@
 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event);
 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event );
 
+/* Usable only with OLVWM - compile option perhaps?
+static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
+*/
 
 /***********************************************************************
  *           EVENT_ProcessEvent
@@ -230,7 +233,10 @@
     case ClientMessage:
 	EVENT_ClientMessage( pWnd, (XClientMessageEvent *) event );
 	break;
-
+/*  case EnterNotify:
+ *       EVENT_EnterNotify( pWnd, (XCrossingEvent *) event );
+ *       break;
+ */
     case NoExpose:
 	break;   
 
@@ -822,6 +828,20 @@
     SendMessage16( pWnd->hwndSelf, WM_SYSCOMMAND, SC_CLOSE, 0 );
 }
 
+/**********************************************************************
+ *           EVENT_EnterNotify
+ *
+ * Install colormap when Wine window is focused in
+ * self-managed mode with private colormap
+ */
+/*
+  void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event )
+  {
+   if( !Options.managed && rootWindow == DefaultRootWindow(display) &&
+     (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) && GetFocus() )
+      XInstallColormap( display, COLOR_GetColormap() );
+  }
+ */ 
 
 /**********************************************************************
  *		SetCapture 	(USER.18)
diff --git a/windows/hook.c b/windows/hook.c
index aa616c5..e9cb158 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -276,11 +276,7 @@
  */
 FARPROC16 SetWindowsHook( INT16 id, HOOKPROC16 proc )
 {
-#ifdef WINELIB
-    HINSTANCE16 hInst = 0;
-#else
-    HINSTANCE16 hInst = FarGetOwner( HIWORD(proc) );
-#endif
+    HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
     /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
     HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
 
diff --git a/windows/mdi.c b/windows/mdi.c
index 5f53691..2ff08e2 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -373,8 +373,14 @@
 	else
 	  {
 	    SetWindowPos( hwnd, 0, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE );
-	    if( wnd->dwStyle & WS_MAXIMIZE )
-	      {
+
+	    /* Set maximized state here in case hwnd didn't receive WM_SIZE
+	     * during CreateWindow - bad!
+	     */
+
+            if( wnd->dwStyle & WS_MAXIMIZE && !ci->hwndChildMaximized )
+              {
+                ci->hwndChildMaximized = wnd->hwndSelf;
                 MDI_AugmentFrameMenu( ci, w->parent, hwnd );
                 MDI_UpdateFrameText( w->parent, ci->self, MDI_REPAINTFRAME, NULL ); 
 	      }
@@ -409,6 +415,10 @@
 
  lpMinMax->ptMaxPosition.x = rect.left;
  lpMinMax->ptMaxPosition.y = rect.top; 
+
+ dprintf_mdi(stddeb,"\tChildMinMaxInfo: max rect (%i,%i - %i, %i)\n", 
+                        rect.left,rect.top,rect.right,rect.bottom);
+
 }
 
 /**********************************************************************
diff --git a/windows/message.c b/windows/message.c
index 62c4c93..ff5e646 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -24,6 +24,9 @@
 /* #define DEBUG_MSG */
 #include "debug.h"
 
+#define WM_NCMOUSEFIRST         WM_NCMOUSEMOVE
+#define WM_NCMOUSELAST          WM_NCMBUTTONDBLCLK
+
 #define HWND_BROADCAST16  ((HWND16)0xffff)
 #define HWND_BROADCAST32  ((HWND32)0xffffffff)
 
@@ -378,11 +381,14 @@
     mask = QS_POSTMESSAGE | QS_SENDMESSAGE;  /* Always selected */
     if (first || last)
     {
-	if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
-	if ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) mask |= QS_MOUSE;
-	if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
-	if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
-	if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
+        /* MSWord gets stuck if we do not check for nonclient mouse messages */
+
+        if ((first <= WM_KEYLAST) && (last >= WM_KEYFIRST)) mask |= QS_KEY;
+        if ( ((first <= WM_MOUSELAST) && (last >= WM_MOUSEFIRST)) ||
+             ((first <= WM_NCMOUSELAST) && (last >= WM_NCMOUSEFIRST)) ) mask |= QS_MOUSE;
+        if ((first <= WM_TIMER) && (last >= WM_TIMER)) mask |= QS_TIMER;
+        if ((first <= WM_SYSTIMER) && (last >= WM_SYSTIMER)) mask |= QS_TIMER;
+        if ((first <= WM_PAINT) && (last >= WM_PAINT)) mask |= QS_PAINT;
     }
     else mask |= QS_MOUSE | QS_KEY | QS_TIMER | QS_PAINT;
 
@@ -642,7 +648,7 @@
     } msgstruct = { lParam, wParam, msg, hwnd };
 
 #ifdef CONFIG_IPC
-    MSG DDE_msg = { hwnd, msg, wParam, lParam };
+    MSG16 DDE_msg = { hwnd, msg, wParam, lParam };
     if (DDE_SendMessage(&DDE_msg)) return TRUE;
 #endif  /* CONFIG_IPC */
 
diff --git a/windows/property.c b/windows/property.c
index dc5303c..e60a61c 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -1,145 +1,367 @@
 /*
  * Window properties
  *
- * Copyright 1995 Alexandre Julliard
+ * Copyright 1995, 1996 Alexandre Julliard
  */
 
+#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include <string.h>
 #include "win.h"
-#include "user.h"
+#include "heap.h"
 #include "callback.h"
+#include "string32.h"
 #include "stddebug.h"
-/* #define DEBUG_PROP */
 #include "debug.h"
 
 
-typedef struct
+typedef struct tagPROPERTY
 {
-    HANDLE next;       /* Next property in window list */
-    ATOM   atom;       /* Atom (or 0 if string) */
-    HANDLE hData;      /* User's data */
-    char   string[1];  /* Property string */
+    struct tagPROPERTY *next;     /* Next property in window list */
+    HANDLE32            handle;   /* User's data */
+    LPSTR               string;   /* Property string (or atom) */
 } PROPERTY;
 
 
 /***********************************************************************
- *           SetProp   (USER.26)
+ *           PROP_FindProp
  */
-BOOL SetProp( HWND hwnd, SEGPTR str, HANDLE hData )
+static PROPERTY *PROP_FindProp( HWND32 hwnd, LPCSTR str )
 {
-    HANDLE hProp;
     PROPERTY *prop;
-    WND *wndPtr;
+    WND *pWnd = WIN_FindWndPtr( hwnd );
 
-    dprintf_prop( stddeb, "SetProp: %04x %08lx %04x\n",
-                  hwnd, (DWORD)str, hData );
-    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
-    hProp = USER_HEAP_ALLOC( sizeof(PROPERTY) + 
-                             (HIWORD(str) ? strlen(PTR_SEG_TO_LIN(str)) : 0 ));
-    if (!hProp) return FALSE;
-    prop = (PROPERTY *) USER_HEAP_LIN_ADDR( hProp );
-    if (HIWORD(str))  /* string */
+    if (!pWnd) return NULL;
+    if (HIWORD(str))
     {
-        prop->atom = 0;
-        strcpy( prop->string, PTR_SEG_TO_LIN(str) );
+        for (prop = pWnd->pProp; prop; prop = prop->next)
+            if (HIWORD(prop->string) && !lstrcmpi32A( prop->string, str ))
+                return prop;
     }
     else  /* atom */
     {
-        prop->atom = LOWORD(str);
-        prop->string[0] = '\0';
+        for (prop = pWnd->pProp; (prop); prop = prop->next)
+            if (!HIWORD(prop->string) && (LOWORD(prop->string) == LOWORD(str)))
+                return prop;
     }
-    prop->hData = hData;
-    prop->next = wndPtr->hProp;
-    wndPtr->hProp = hProp;
+    return NULL;
+}
+
+
+/***********************************************************************
+ *           GetProp16   (USER.25)
+ */
+HANDLE16 GetProp16( HWND16 hwnd, LPCSTR str )
+{
+    return (HANDLE16)GetProp32A( hwnd, str );
+}
+
+
+/***********************************************************************
+ *           GetProp32A   (USER32.280)
+ */
+HANDLE32 GetProp32A( HWND32 hwnd, LPCSTR str )
+{
+    PROPERTY *prop = PROP_FindProp( hwnd, str );
+
+    dprintf_prop( stddeb, "GetProp(%08x,'%s'): returning %08x\n",
+                  hwnd, str, prop ? prop->handle : 0 );
+    return prop ? prop->handle : 0;
+}
+
+
+/***********************************************************************
+ *           GetProp32W   (USER32.281)
+ */
+HANDLE32 GetProp32W( HWND32 hwnd, LPCWSTR str )
+{
+    LPSTR strA;
+    HANDLE32 ret;
+
+    if (!HIWORD(str)) return GetProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str) );
+    strA = STRING32_DupUniToAnsi( str );
+    ret = GetProp32A( hwnd, strA );
+    free( strA );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           SetProp16   (USER.26)
+ */
+BOOL16 SetProp16( HWND16 hwnd, LPCSTR str, HANDLE16 handle )
+{
+    return (BOOL16)SetProp32A( hwnd, str, handle );
+}
+
+
+/***********************************************************************
+ *           SetProp32A   (USER32.496)
+ */
+BOOL32 SetProp32A( HWND32 hwnd, LPCSTR str, HANDLE32 handle )
+{
+    PROPERTY *prop;
+
+    dprintf_prop( stddeb, "SetProp: %04x '%s' %08x\n", hwnd, str, handle );
+    if (!(prop = PROP_FindProp( hwnd, str )))
+    {
+        /* We need to create it */
+        WND *pWnd = WIN_FindWndPtr( hwnd );
+        if (!pWnd) return FALSE;
+        if (!(prop = HeapAlloc( SystemHeap, 0, sizeof(*prop) ))) return FALSE;
+        if (!(prop->string = SEGPTR_STRDUP(str)))
+        {
+            HeapFree( SystemHeap, 0, prop );
+            return FALSE;
+        }
+        prop->next  = pWnd->pProp;
+        pWnd->pProp = prop;
+    }
+    prop->handle = handle;
     return TRUE;
 }
 
 
 /***********************************************************************
- *           GetProp   (USER.25)
+ *           SetProp32W   (USER32.497)
  */
-HANDLE GetProp( HWND hwnd, SEGPTR str )
+BOOL32 SetProp32W( HWND32 hwnd, LPCWSTR str, HANDLE32 handle )
 {
-    HANDLE hProp;
-    WND *wndPtr;
+    BOOL32 ret;
+    LPSTR strA;
 
-    dprintf_prop( stddeb, "GetProp: %04x %08lx\n", hwnd, (DWORD)str );
-    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    hProp = wndPtr->hProp;
-    while (hProp)
-    {
-        PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR(hProp);
-        if (HIWORD(str))
-        {
-            if (!prop->atom && !lstrcmpi32A(prop->string, PTR_SEG_TO_LIN(str)))
-                return prop->hData;
-        }
-        else if (prop->atom && (prop->atom == LOWORD(str))) return prop->hData;
-        hProp = prop->next;
-    }
-    return 0;
+    if (!HIWORD(str))
+        return SetProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str), handle );
+    strA = STRING32_DupUniToAnsi( str );
+    ret = SetProp32A( hwnd, strA, handle );
+    free( strA );
+    return ret;
 }
 
 
 /***********************************************************************
- *           RemoveProp   (USER.24)
+ *           RemoveProp16   (USER.24)
  */
-HANDLE RemoveProp( HWND hwnd, SEGPTR str )
+HANDLE16 RemoveProp16( HWND16 hwnd, LPCSTR str )
 {
-    HANDLE *hProp;
-    WND *wndPtr;
-
-    dprintf_prop( stddeb, "RemoveProp: %04x %08lx\n", hwnd, (DWORD)str );
-    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    hProp = &wndPtr->hProp;
-    while (*hProp)
-    {
-        PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR( *hProp );
-        if ((HIWORD(str) && !prop->atom &&
-             !lstrcmpi32A( prop->string, PTR_SEG_TO_LIN(str))) ||
-            (!HIWORD(str) && prop->atom && (prop->atom == LOWORD(str))))
-        {
-            HANDLE hNext = prop->next;
-            HANDLE hData = prop->hData;
-            USER_HEAP_FREE( *hProp );
-            *hProp = hNext;
-            return hData;
-        }
-        hProp = &prop->next;
-    }
-    return 0;
+    return (HANDLE16)RemoveProp32A( hwnd, str );
 }
 
 
 /***********************************************************************
- *           EnumProps   (USER.27)
+ *           RemoveProp32A   (USER32.441)
  */
-INT EnumProps( HWND hwnd, PROPENUMPROC func )
+HANDLE32 RemoveProp32A( HWND32 hwnd, LPCSTR str )
 {
-    int ret = -1;
-    HANDLE hProp;
-    WND *wndPtr;
+    HANDLE32 handle;
+    PROPERTY **pprop, *prop;
+    WND *pWnd = WIN_FindWndPtr( hwnd );
 
-    dprintf_prop( stddeb, "EnumProps: %04x %08lx\n", hwnd, (LONG)func );
-    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    hProp = wndPtr->hProp;
-    while (hProp)
+    dprintf_prop( stddeb, "RemoveProp: %04x '%s'\n", hwnd, str );
+    if (!pWnd) return NULL;
+    if (HIWORD(str))
     {
-        PROPERTY *prop = (PROPERTY *)USER_HEAP_LIN_ADDR(hProp);
-        
-        dprintf_prop( stddeb, "  Callback: atom=%04x data=%04x str='%s'\n",
-                      prop->atom, prop->hData, prop->string );
+        for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
+            if (HIWORD((*pprop)->string) &&
+                !lstrcmpi32A( (*pprop)->string, str )) break;
+    }
+    else  /* atom */
+    {
+        for (pprop=(PROPERTY**)&pWnd->pProp; (*pprop); pprop = &(*pprop)->next)
+            if (!HIWORD((*pprop)->string) &&
+                (LOWORD((*pprop)->string) == LOWORD(str))) break;
+    }
+    if (!*pprop) return 0;
+    prop   = *pprop;
+    handle = prop->handle;
+    *pprop = prop->next;
+    SEGPTR_FREE(prop->string);
+    HeapFree( SystemHeap, 0, prop );
+    return handle;
+}
 
-          /* Already get the next in case the callback */
-          /* function removes the current property.    */
-        hProp = prop->next;
-        ret = CallEnumPropProc( (FARPROC16)func, hwnd,
-                                prop->atom ? 
-                                  (LONG)MAKELONG( prop->atom, 0 )
-				:
-                                  (LONG)(USER_HEAP_SEG_ADDR(hProp) +
-                                         ((int)prop->string - (int)prop)),
-                                prop->hData );
+
+/***********************************************************************
+ *           RemoveProp32W   (USER32.442)
+ */
+HANDLE32 RemoveProp32W( HWND32 hwnd, LPCWSTR str )
+{
+    LPSTR strA;
+    HANDLE32 ret;
+
+    if (!HIWORD(str))
+        return RemoveProp32A( hwnd, (LPCSTR)(UINT32)LOWORD(str) );
+    strA = STRING32_DupUniToAnsi( str );
+    ret = RemoveProp32A( hwnd, strA );
+    free( strA );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           PROPERTY_RemoveWindowProps
+ *
+ * Remove all properties of a window.
+ */
+void PROPERTY_RemoveWindowProps( WND *pWnd )
+{
+    PROPERTY *prop, *next;
+
+    for (prop = pWnd->pProp; (prop); prop = next)
+    {
+        next = prop->next;
+        SEGPTR_FREE( prop->string );
+        HeapFree( SystemHeap, 0, prop );
+    }
+    pWnd->pProp = NULL;
+}
+
+
+/***********************************************************************
+ *           EnumProps16   (USER.27)
+ */
+INT16 EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
+{
+    PROPERTY *prop, *next;
+    WND *pWnd;
+    INT16 ret = -1;
+
+    dprintf_prop( stddeb, "EnumProps: %04x %08x\n", hwnd, (UINT32)func );
+    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+    for (prop = pWnd->pProp; (prop); prop = next)
+    {
+        /* Already get the next in case the callback */
+        /* function removes the current property.    */
+        next = prop->next;
+
+        dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
+                      prop->handle, prop->string );
+        ret = CallEnumPropProc16( (FARPROC16)func, hwnd,
+                                  SEGPTR_GET(prop->string), prop->handle );
+        if (!ret) break;
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *           EnumProps32A   (USER32.185)
+ */
+INT32 EnumProps32A( HWND32 hwnd, PROPENUMPROC32A func )
+{
+    PROPERTY *prop, *next;
+    WND *pWnd;
+    INT32 ret = -1;
+
+    dprintf_prop( stddeb, "EnumProps32A: %04x %08x\n", hwnd, (UINT32)func );
+    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+    for (prop = pWnd->pProp; (prop); prop = next)
+    {
+        /* Already get the next in case the callback */
+        /* function removes the current property.    */
+        next = prop->next;
+
+        dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
+                      prop->handle, prop->string );
+        ret = CallEnumPropProc32( func, hwnd, prop->string, prop->handle );
+        if (!ret) break;
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *           EnumProps32W   (USER32.188)
+ */
+INT32 EnumProps32W( HWND32 hwnd, PROPENUMPROC32W func )
+{
+    PROPERTY *prop, *next;
+    WND *pWnd;
+    INT32 ret = -1;
+
+    dprintf_prop( stddeb, "EnumProps32W: %04x %08x\n", hwnd, (UINT32)func );
+    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+    for (prop = pWnd->pProp; (prop); prop = next)
+    {
+        /* Already get the next in case the callback */
+        /* function removes the current property.    */
+        next = prop->next;
+
+        dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
+                      prop->handle, prop->string );
+        if (HIWORD(prop->string))
+        {
+            LPWSTR str = STRING32_DupAnsiToUni( prop->string );
+            ret = CallEnumPropProc32( func, hwnd, str, prop->handle );
+            free( str );
+        }
+        else
+            ret = CallEnumPropProc32( func, hwnd,
+                                      (LPCWSTR)(UINT32)LOWORD(prop->string),
+                                      prop->handle );
+        if (!ret) break;
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *           EnumPropsEx32A   (USER32.186)
+ */
+INT32 EnumPropsEx32A( HWND32 hwnd, PROPENUMPROCEX32A func, LPARAM lParam )
+{
+    PROPERTY *prop, *next;
+    WND *pWnd;
+    INT32 ret = -1;
+
+    dprintf_prop( stddeb, "EnumPropsEx32A: %04x %08x %08lx\n",
+                  hwnd, (UINT32)func, lParam );
+    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+    for (prop = pWnd->pProp; (prop); prop = next)
+    {
+        /* Already get the next in case the callback */
+        /* function removes the current property.    */
+        next = prop->next;
+
+        dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
+                      prop->handle, prop->string );
+        ret = CallEnumPropProcEx32( func, hwnd, prop->string,
+                                    prop->handle, lParam );
+        if (!ret) break;
+    }
+    return ret;
+}
+
+
+/***********************************************************************
+ *           EnumPropsEx32W   (USER32.187)
+ */
+INT32 EnumPropsEx32W( HWND32 hwnd, PROPENUMPROCEX32W func, LPARAM lParam )
+{
+    PROPERTY *prop, *next;
+    WND *pWnd;
+    INT32 ret = -1;
+
+    dprintf_prop( stddeb, "EnumPropsEx32W: %04x %08x %08lx\n",
+                  hwnd, (UINT32)func, lParam );
+    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
+    for (prop = pWnd->pProp; (prop); prop = next)
+    {
+        /* Already get the next in case the callback */
+        /* function removes the current property.    */
+        next = prop->next;
+
+        dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
+                      prop->handle, prop->string );
+        if (HIWORD(prop->string))
+        {
+            LPWSTR str = STRING32_DupAnsiToUni( prop->string );
+            ret = CallEnumPropProcEx32( func, hwnd, str, prop->handle, lParam);
+            free( str );
+        }
+        else
+            ret = CallEnumPropProcEx32( func, hwnd,
+                                        (LPCWSTR)(UINT32)LOWORD(prop->string),
+                                        prop->handle, lParam );
         if (!ret) break;
     }
     return ret;
diff --git a/windows/scroll.c b/windows/scroll.c
index d25450d..d00330b 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -33,9 +33,8 @@
  * dcx can have DCX_WINDOW, DCX_CLIPCHILDREN, DCX_CLIPSIBLINGS set
  */
 
-HRGN	SCROLL_TraceChildren( HWND hScroll, short dx, short dy, WORD dcx)
+HRGN	SCROLL_TraceChildren( WND* wndScroll, short dx, short dy, WORD dcx)
 {
- WND	       *wndScroll = WIN_FindWndPtr( hScroll ); 
  HRGN		hRgnWnd;
  HRGN		hUpdateRgn,hCombineRgn;
 
@@ -45,13 +44,13 @@
 	 hRgnWnd   = CreateRectRgnIndirect16(&wndScroll->rectWindow);
  else
 	{
-	 RECT32 rect;
+	 RECT32 rect = { 0, 0, wndScroll->rectClient.right - wndScroll->rectClient.left,
+			       wndScroll->rectClient.bottom - wndScroll->rectClient.top };
 
-	 GetClientRect32(hScroll,&rect);
  	 hRgnWnd   = CreateRectRgnIndirect32(&rect);
 	}
 
- hUpdateRgn  = DCE_GetVisRgn( hScroll, dcx );
+ hUpdateRgn  = DCE_GetVisRgn( wndScroll->hwndSelf, dcx );
  hCombineRgn = CreateRectRgn(0,0,0,0);
 
  if( !hUpdateRgn || !hCombineRgn )
@@ -74,21 +73,21 @@
 /* ----------------------------------------------------------------------
  *	       SCROLL_ScrollChildren
  */
-BOOL	SCROLL_ScrollChildren( HWND hScroll, short dx, short dy)
+BOOL	SCROLL_ScrollChildren( WND* wndScroll, short dx, short dy)
 {
- WND           *wndPtr = WIN_FindWndPtr(hScroll);
+ WND           *wndPtr = NULL;
  HRGN		hUpdateRgn;
  BOOL		b = 0;
 
- if( !wndPtr || ( !dx && !dy )) return 0;
+ if( !wndScroll || ( !dx && !dy )) return 0;
 
- dprintf_scroll(stddeb,"SCROLL_ScrollChildren: hwnd %04x dx=%i dy=%i\n",hScroll,dx,dy);
+ dprintf_scroll(stddeb,"SCROLL_ScrollChildren: hwnd %04x dx=%i dy=%i\n",wndScroll->hwndSelf,dx,dy);
 
  /* get a region in client rect invalidated by siblings and ansectors */
- hUpdateRgn = SCROLL_TraceChildren(hScroll, dx , dy, DCX_CLIPSIBLINGS);
+ hUpdateRgn = SCROLL_TraceChildren(wndScroll, dx , dy, DCX_CLIPSIBLINGS);
 
    /* update children coordinates */
-   for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
+   for (wndPtr = wndScroll->child; wndPtr; wndPtr = wndPtr->next)
    {
 	/* we can check if window intersects with clipRect parameter
 	 * and do not move it if not - just a thought.     - AK
@@ -100,8 +99,8 @@
   } 
 
  /* invalidate uncovered region and paint frames */
- b = RedrawWindow32( hScroll, NULL, hUpdateRgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
-				              RDW_ERASENOW | RDW_ALLCHILDREN ); 
+ b = RedrawWindow32( wndScroll->hwndSelf, NULL, hUpdateRgn, 
+		     RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN ); 
 
  DeleteObject( hUpdateRgn);
  return b;
@@ -114,10 +113,11 @@
  */
 void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT16 rect, LPRECT16 clipRect)
 {
-    HDC  hdc;
-    HRGN hrgnUpdate,hrgnClip;
-    RECT16 rc, cliprc;
-    HWND hCaretWnd = CARET_GetHwnd();
+    HDC  	hdc;
+    HRGN 	hrgnUpdate,hrgnClip;
+    RECT16 	rc, cliprc;
+    HWND 	hCaretWnd = CARET_GetHwnd();
+    WND*	wndScroll = WIN_FindWndPtr( hwnd );
 
     dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, lpRect =%08lx clipRect=%i,%i,%i,%i\n", 
 	    dx, dy, (LONG)rect, (int)((clipRect)?clipRect->left:0),
@@ -158,6 +158,11 @@
     else
 	CopyRect16(&cliprc, clipRect);
 
+    /* move window update region (if any) */
+
+    if( wndScroll->hrgnUpdate > 1 )
+	OffsetRgn( wndScroll->hrgnUpdate, dx, dy );
+
     hrgnUpdate = CreateRectRgn(0, 0, 0, 0);
     ScrollDC(hdc, dx, dy, &rc, &cliprc, hrgnUpdate, NULL);
     ReleaseDC(hwnd, hdc);
@@ -165,13 +170,14 @@
     if( !rect )
       {
          /* FIXME: this doesn't take into account hrgnUpdate */
-         if( !SCROLL_ScrollChildren(hwnd,dx,dy) )
+
+         if( !SCROLL_ScrollChildren( wndScroll, dx,dy) )
 	     InvalidateRgn(hwnd, hrgnUpdate, TRUE);
       }
     else
       {
-        HRGN hrgnInv = SCROLL_TraceChildren(hwnd,dx,dy,DCX_CLIPCHILDREN |
-						       DCX_CLIPSIBLINGS );
+        HRGN hrgnInv = SCROLL_TraceChildren( wndScroll ,dx,dy,DCX_CLIPCHILDREN |
+						              DCX_CLIPSIBLINGS );
         if( hrgnInv )
         {
 	    CombineRgn(hrgnUpdate,hrgnInv,hrgnUpdate,RGN_OR);
diff --git a/windows/win.c b/windows/win.c
index 25ccc7f..29b902f 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -52,11 +52,11 @@
  *
  * Return a pointer to the WND structure corresponding to a HWND.
  */
-WND * WIN_FindWndPtr( HWND hwnd )
+WND * WIN_FindWndPtr( HWND32 hwnd )
 {
     WND * ptr;
     
-    if (!hwnd) return NULL;
+    if (!hwnd || HIWORD(hwnd)) return NULL;
     ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
     if (ptr->dwMagic != WND_MAGIC) return NULL;
     if (ptr->hwndSelf != hwnd)
@@ -74,7 +74,7 @@
  *
  * Dump the content of a window structure to stderr.
  */
-void WIN_DumpWindow( HWND hwnd )
+void WIN_DumpWindow( HWND32 hwnd )
 {
     WND *ptr;
     char className[80];
@@ -95,7 +95,7 @@
              "inst=%04x  taskQ=%04x  updRgn=%04x  active=%04x hdce=%04x  idmenu=%04x\n"
              "style=%08lx  exstyle=%08lx  wndproc=%08x  text='%s'\n"
              "client=%d,%d-%d,%d  window=%d,%d-%d,%d  iconpos=%d,%d  maxpos=%d,%d\n"
-             "sysmenu=%04x  flags=%04x  props=%04x  vscroll=%p  hscroll=%p\n",
+             "sysmenu=%04x  flags=%04x  props=%p  vscroll=%p  hscroll=%p\n",
              ptr->next, ptr->child, ptr->parent, ptr->owner,
              ptr->class, className, ptr->hInstance, ptr->hmemTaskQ,
              ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
@@ -105,7 +105,7 @@
              ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
              ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
              ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
-             ptr->flags, ptr->hProp, ptr->pVScroll, ptr->pHScroll );
+             ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll );
 
     if (ptr->class->cbWndExtra)
     {
@@ -123,7 +123,7 @@
  *
  * Walk the windows tree and print each window on stderr.
  */
-void WIN_WalkWindows( HWND hwnd, int indent )
+void WIN_WalkWindows( HWND32 hwnd, int indent )
 {
     WND *ptr;
     char className[80];
@@ -160,7 +160,7 @@
  *
  * Return the X window associated to a window.
  */
-Window WIN_GetXWindow( HWND hwnd )
+Window WIN_GetXWindow( HWND32 hwnd )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     while (wndPtr && !wndPtr->window) wndPtr = wndPtr->parent;
@@ -173,7 +173,7 @@
  *
  * Remove a window from the siblings linked list.
  */
-BOOL WIN_UnlinkWindow( HWND hwnd )
+BOOL32 WIN_UnlinkWindow( HWND32 hwnd )
 {    
     WND *wndPtr, **ppWnd;
 
@@ -192,7 +192,7 @@
  * The window is inserted after the specified window, which can also
  * be specified as HWND_TOP or HWND_BOTTOM.
  */
-BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter )
+BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter )
 {    
     WND *wndPtr, **ppWnd;
 
@@ -221,7 +221,7 @@
  *
  * Find a window that needs repaint.
  */
-HWND WIN_FindWinToRepaint( HWND hwnd, HQUEUE hQueue )
+HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue )
 {
     HWND hwndRet;
     WND *pWnd = pWndDesktop;
@@ -267,7 +267,7 @@
  * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
  * the window has the WS_EX_NOPARENTNOTIFY style.
  */
-void WIN_SendParentNotify( HWND hwnd, WORD event, WORD idChild, LONG lValue )
+void WIN_SendParentNotify( HWND32 hwnd, WORD event, WORD idChild, LONG lValue )
 {
     LPPOINT16 lppt = (LPPOINT16)&lValue;
     WND     *wndPtr = WIN_FindWndPtr( hwnd );
@@ -320,6 +320,7 @@
     if (!wndPtr) return;
     WIN_UnlinkWindow( hwnd ); /* Remove the window from the linked list */
     TIMER_RemoveWindowTimers( hwnd );
+    PROPERTY_RemoveWindowProps( wndPtr );
     wndPtr->dwMagic = 0;  /* Mark it as invalid */
     wndPtr->hwndSelf = 0;
     if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
@@ -362,7 +363,7 @@
  *
  * Create the desktop window.
  */
-BOOL WIN_CreateDesktopWindow(void)
+BOOL32 WIN_CreateDesktopWindow(void)
 {
     CLASS *class;
     HDC hdc;
@@ -406,11 +407,11 @@
     pWndDesktop->hdce              = 0;
     pWndDesktop->pVScroll          = NULL;
     pWndDesktop->pHScroll          = NULL;
+    pWndDesktop->pProp             = NULL;
     pWndDesktop->wIDmenu           = 0;
     pWndDesktop->flags             = 0;
     pWndDesktop->window            = rootWindow;
     pWndDesktop->hSysMenu          = 0;
-    pWndDesktop->hProp             = 0;
     pWndDesktop->userdata          = 0;
 
     WINPROC_SetProc( &pWndDesktop->winproc, (WNDPROC16)class->winproc, 0 );
@@ -528,8 +529,8 @@
     wndPtr->flags          = 0;
     wndPtr->pVScroll       = NULL;
     wndPtr->pHScroll       = NULL;
+    wndPtr->pProp          = NULL;
     wndPtr->hSysMenu       = MENU_GetDefSysMenu();
-    wndPtr->hProp          = 0;
     wndPtr->userdata       = 0;
 
     if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra);
@@ -556,7 +557,7 @@
 
     /* Insert the window in the linked list */
 
-    WIN_LinkWindow( hwnd, HWND_BOTTOM );
+    WIN_LinkWindow( hwnd, (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP );
 
     /* Send the WM_GETMINMAXINFO message and fix the size if needed */
 
@@ -565,6 +566,8 @@
         NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
         if (maxSize.x < cs->cx) cs->cx = maxSize.x;
         if (maxSize.y < cs->cy) cs->cy = maxSize.y;
+        if (cs->cx < minTrack.x ) cs->cx = minTrack.x;
+        if (cs->cy < minTrack.y ) cs->cy = minTrack.y;
     }
     if (cs->cx <= 0) cs->cx = 1;
     if (cs->cy <= 0) cs->cy = 1;
@@ -711,20 +714,25 @@
 
     if (wndPtr->dwStyle & WS_MINIMIZE)
     {
+	/* MinMaximize(hwnd, SW_SHOWMINNOACTIVE, 1) in "Internals" */
+
         wndPtr->dwStyle &= ~WS_MAXIMIZE;
         WINPOS_FindIconPos( hwnd );
         SetWindowPos( hwnd, 0, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y,
-                      SYSMETRICS_CXICON, SYSMETRICS_CYICON, SWP_FRAMECHANGED |
-                      ((cs->style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0 ));
+                      SYSMETRICS_CXICON, SYSMETRICS_CYICON, 
+                      SWP_FRAMECHANGED | ((GetActiveWindow())? SWP_NOACTIVATE : 0)  );
     }
     else if (wndPtr->dwStyle & WS_MAXIMIZE)
     {
+	/* MinMaximize(hwnd, SW_SHOWMAXIMIZED, 1) */
+
         POINT16 maxSize, maxPos, minTrack, maxTrack;
         NC_GetMinMaxInfo( hwnd, &maxSize, &maxPos, &minTrack, &maxTrack );
         SetWindowPos( hwnd, 0, maxPos.x, maxPos.y, maxSize.x, maxSize.y,
-            SWP_FRAMECHANGED | ((cs->style & WS_VISIBLE) ? SWP_SHOWWINDOW : 0) );
+            ((GetActiveWindow())? SWP_NOACTIVATE : 0) | SWP_FRAMECHANGED );
     }
-    else if (cs->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
+    
+    if (cs->style & WS_VISIBLE) ShowWindow( hwnd, SW_SHOW );
 
     /* Call WH_SHELL hook */
 
@@ -898,8 +906,10 @@
 		      SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
     if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
 	ReleaseCapture();
-   if (!QUEUE_GetDoomedQueue())
-       WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
+    if (!QUEUE_GetDoomedQueue())
+        WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
+
+    CLIPBOARD_DisOwn( hwnd );
 
       /* Recursively destroy owned windows */
 
@@ -915,8 +925,6 @@
         else break;
     }
 
-    CLIPBOARD_DisOwn( hwnd );
-
       /* Send destroy messages and destroy children */
 
     SendMessage16( hwnd, WM_DESTROY, 0, 0 );
@@ -1197,10 +1205,10 @@
 /**********************************************************************
  *	     WIN_GetWindowInstance
  */
-HINSTANCE WIN_GetWindowInstance(HWND hwnd)
+HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd )
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
-    if (!wndPtr) return (HINSTANCE)0;
+    if (!wndPtr) return (HINSTANCE16)0;
     return wndPtr->hInstance;
 }
 
@@ -1477,7 +1485,7 @@
  *
  * Get the top-level parent for a child window.
  */
-HWND WIN_GetTopParent( HWND hwnd )
+HWND32 WIN_GetTopParent( HWND32 hwnd )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     while (wndPtr && (wndPtr->dwStyle & WS_CHILD)) wndPtr = wndPtr->parent;
diff --git a/windows/winpos.c b/windows/winpos.c
index db6e82b..23ab087 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -672,10 +672,21 @@
         if (!IsWindow( hwnd )) return wasVisible;
     }
 
-    /* We can't activate a child window */
-    if (wndPtr->dwStyle & WS_CHILD) swpflags |= SWP_NOACTIVATE | SWP_NOZORDER;
-    SetWindowPos( hwnd, HWND_TOP, x, y, cx, cy, swpflags );
-    if (!IsWindow( hwnd )) return wasVisible;
+    if ((wndPtr->dwStyle & WS_CHILD) &&
+        !IsWindowVisible( wndPtr->parent->hwndSelf ) &&
+        (swpflags & SWP_NOSIZE) && (swpflags & SWP_NOMOVE))
+    {
+        /* Don't call SetWindowPos() on invisible child windows */
+        if (cmd == SW_HIDE) wndPtr->dwStyle &= ~WS_VISIBLE;
+        else wndPtr->dwStyle |= WS_VISIBLE;
+    }
+    else
+    {
+        /* We can't activate a child window */
+        if (wndPtr->dwStyle & WS_CHILD) swpflags |= SWP_NOACTIVATE;
+        SetWindowPos( hwnd, HWND_TOP, x, y, cx, cy, swpflags );
+        if (!IsWindow( hwnd )) return wasVisible;
+    }
 
     if (wndPtr->flags & WIN_NEED_SIZE)
     {