Release 950319

Sun Mar 19 16:30:20 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)

	* [*/*]
	Implemented a new memory mapping scheme. There's no longer a
	one-to-one mapping between 16-bit and 32-bit pointers. Please see
	file DEVELOPERS-HINTS for technical details.

	* [controls/scroll.c]
	Fixed bug when dragging mouse in horizontal scrollbars.

	* [tools/build.c] [if1632/*.spec]
	Removed support for C callback functions and for re-ordering
	of the 32-bit arguments, as these were never used. This should
	allow a more efficient callback scheme to be implemented.

	* [if1632/olecli.spec]
	Reduced the number of entries to make the 16-bit code fit in 64k.
	This limitation will soon be removed.

	* [loader/ldt.c]
	Rewrote LDT manipulation functions and implemented LDT_GetEntry().

	* [memory/global.c]
	Rewrote Global*() routines to use the new selector allocation
	mechanism.

	* [memory/local.c]
	Rewrote local heap handling to use a Windows-compatible layout
	(not really finished yet).
	Implemented TOOLHELP heap-walking routines.

	* [memory/selector.c]
	Implemented LDT manipulation API functions.

Tue Mar 14 19:50:28 EST 1995 William Magro (wmagro@tc.cornell.edu)

	* [windows/defdlg.c]
	Fixed problem where dialogs closed using the System menu 
        ('Close' item or double click on close box) would
	hang Wine.

Sun Mar 12 14:28:13 1995  Michael Patra <micky@marie.physik.TU-Berlin.DE>

	* [controls/listbox.c]
	Removed most of the statements for sending a notification message
	ListBoxDirectory(), DlgDirSelect(), DlgDirList(): Improved the
	code; Borland's standard file open dialog will work now.
	
	* [misc/main.c], [misc/file.c], [miscemu/int21.c]
	Added support for new command line option "-allowreadonly". If set
	an attempt to open a read only file in write mode will be converted 
	to opening it read only (many programs try to open all files in 
	read/write mode even if they only intend to read it - this might 
	cause a few under problems under an unix-like environment where most 
	files are read only for a "normal" user)

	* [loader/selector.c]
	GetMemoryReference(): Added support for __AHIncr and __AHShift

	* [misc/dos_fs.c]
	DOS_SimplifyPath(): This routine simplifies path names ( e.g., it
	will change "/usr///local/bin/../lib//a" to "/usr/local/lib/a" )
	match(): rewritten
	
	* [objects/text.c]
	TEXT_NextLine(): Removed a bug in the handling of LF's

	* [miscemu/int21.c]
	GetFileDateTime(): Fixed. SetFileDateTime() is still broken.

Sat Mar 11 19:46:19 1995  Martin von Loewis  <loewis@informatik.hu-berlin.de>

	* [controls/menu.c]
	ChangeMenu: defaults to MF_INSERT
	InsertMenu: allow insertion even if position is one after last item

	* [if1632/Imakefile] [if1632/compobj.spec] [if1632/relay.c]
	  [if1632/storage.spec] [include/dlls.h]
	Added stubs for STORAGE.DLL and COMPOBJ.DLL

	* [if1632/user.spec] [windows/message.c]
	InSendMessage: new function

	* [include/neexe.h][include/ne_image.c]
	NE_FixupSegment: fixed handling of additive records

	* [loader/selector.c]
	GetEntryDLLName: return NULL instead of pointer to DLL.0 if not found

	* [loader/signal.c]
	win_fault: Enter debugger on SIGFPE, too

Wed Mar  1 21:47:42 1995  Cameron Heide  (heide@ee.ualberta.ca)

        * [miscemu/int*.c]
        Various minor modifications to the clock tick counter,
        FindFirst/FindNext funcs, and DPB handling.
diff --git a/windows/class.c b/windows/class.c
index 7f937bb..fc7a4b5 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -13,6 +13,7 @@
 #include "user.h"
 #include "win.h"
 #include "dce.h"
+#include "toolhelp.h"
 #include "stddebug.h"
 /* #define DEBUG_CLASS */
 #include "debug.h"
@@ -33,37 +34,33 @@
     HCLASS class;
     CLASS * classPtr;
 
+    if (!(atom = GlobalFindAtom( name ))) return 0;
+
       /* First search task-specific classes */
 
-    if ((atom = /*FindAtom*/GlobalFindAtom( name )) != 0)
+    for (class = firstClass; (class); class = classPtr->hNext)
     {
-	for (class = firstClass; (class); class = classPtr->hNext)
-	{
-	    classPtr = (CLASS *) USER_HEAP_ADDR(class);
-	    if (classPtr->wc.style & CS_GLOBALCLASS) continue;
-	    if ((classPtr->atomName == atom) && 
-		(( hinstance==0xffff )|| (hinstance == classPtr->wc.hInstance)))
-	    {
-		if (ptr) *ptr = classPtr;
-		return class;
-	    }
-	}
+        classPtr = (CLASS *) USER_HEAP_LIN_ADDR(class);
+        if (classPtr->wc.style & CS_GLOBALCLASS) continue;
+        if ((classPtr->atomName == atom) && 
+            ((hinstance==0xffff )|| (hinstance == classPtr->wc.hInstance)))
+        {
+            if (ptr) *ptr = classPtr;
+            return class;
+        }
     }
     
       /* Then search global classes */
 
-    if ((atom = GlobalFindAtom( name )) != 0)
+    for (class = firstClass; (class); class = classPtr->hNext)
     {
-	for (class = firstClass; (class); class = classPtr->hNext)
-	{
-	    classPtr = (CLASS *) USER_HEAP_ADDR(class);
-	    if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
-	    if (classPtr->atomName == atom)
-	    {
-		if (ptr) *ptr = classPtr;
-		return class;
-	    }
-	}
+        classPtr = (CLASS *) USER_HEAP_LIN_ADDR(class);
+        if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
+        if (classPtr->atomName == atom)
+        {
+            if (ptr) *ptr = classPtr;
+            return class;
+        }
     }
 
     return 0;
@@ -80,7 +77,7 @@
     CLASS * ptr;
     
     if (!hclass) return NULL;
-    ptr = (CLASS *) USER_HEAP_ADDR( hclass );
+    ptr = (CLASS *) USER_HEAP_LIN_ADDR( hclass );
     if (ptr->wMagic != CLASS_MAGIC) return NULL;
     return ptr;
 }
@@ -94,15 +91,14 @@
     CLASS * newClass, * prevClassPtr;
     HCLASS handle, prevClass;
     int classExtra;
+    char *name = PTR_SEG_TO_LIN( class->lpszClassName );
 
     dprintf_class(stddeb, "RegisterClass: wndproc=%p hinst=%d name='%s' background %x\n", 
-	    class->lpfnWndProc, class->hInstance, class->lpszClassName,
-	    class->hbrBackground );
+	    class->lpfnWndProc, class->hInstance, name, class->hbrBackground );
 
       /* Check if a class with this name already exists */
 
-    prevClass = CLASS_FindClassByName( class->lpszClassName, class->hInstance,
-	&prevClassPtr );
+    prevClass = CLASS_FindClassByName( name, class->hInstance, &prevClassPtr );
     if (prevClass)
     {
 	  /* Class can be created only if it is local and */
@@ -115,9 +111,9 @@
       /* Create class */
 
     classExtra = (class->cbClsExtra < 0) ? 0 : class->cbClsExtra;
-    handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS) + classExtra );
+    handle = USER_HEAP_ALLOC( sizeof(CLASS) + classExtra );
     if (!handle) return 0;
-    newClass = (CLASS *) USER_HEAP_ADDR( handle );
+    newClass = (CLASS *) USER_HEAP_LIN_ADDR( handle );
     newClass->hNext         = firstClass;
     newClass->wMagic        = CLASS_MAGIC;
     newClass->cWindows      = 0;  
@@ -125,9 +121,7 @@
     newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
     newClass->wc.cbClsExtra = classExtra;
 
-    /*if (newClass->wc.style & CS_GLOBALCLASS)*/
-	newClass->atomName = GlobalAddAtom( class->lpszClassName );
-    /*else newClass->atomName = AddAtom( class->lpszClassName );*/
+    newClass->atomName = GlobalAddAtom( name );
     newClass->wc.lpszClassName = NULL; 
 
     if (newClass->wc.style & CS_CLASSDC)
@@ -138,12 +132,12 @@
 
     if ((int)class->lpszMenuName & 0xffff0000)
     {
-	HANDLE hname;
-	hname = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(class->lpszMenuName)+1);
+        char *menuname = PTR_SEG_TO_LIN( class->lpszMenuName );
+	HANDLE hname = USER_HEAP_ALLOC( strlen(menuname)+1 );
 	if (hname)
 	{
-	    newClass->wc.lpszMenuName = (char *)USER_HEAP_ADDR( hname );
-	    strcpy( newClass->wc.lpszMenuName, class->lpszMenuName );
+	    newClass->wc.lpszMenuName = (char *)USER_HEAP_SEG_ADDR( hname );
+	    strcpy( USER_HEAP_LIN_ADDR( hname ), menuname );
 	}
     }
 
@@ -173,7 +167,7 @@
     {
 	for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
 	{
-	    prevClassPtr = (CLASS *) USER_HEAP_ADDR(prevClass);
+	    prevClassPtr = (CLASS *) USER_HEAP_LIN_ADDR(prevClass);
 	    if (prevClassPtr->hNext == class) break;
 	}
 	if (!prevClass)
@@ -264,6 +258,7 @@
     CLASS *classPtr;
 
     /* FIXME: We have the find the correct hInstance */
+    dprintf_class(stddeb,"GetClassName(%x,%p,%d\n)",hwnd,lpClassName,maxCount);
     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
     if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0;
 
@@ -307,3 +302,29 @@
     memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
     return TRUE;
 }
+
+
+/***********************************************************************
+ *           ClassFirst      (TOOLHELP.69)
+ */
+BOOL ClassFirst( CLASSENTRY *pClassEntry )
+{
+    pClassEntry->wNext = firstClass;
+    return ClassNext( pClassEntry );
+}
+
+
+/***********************************************************************
+ *           ClassNext      (TOOLHELP.70)
+ */
+BOOL ClassNext( CLASSENTRY *pClassEntry )
+{
+    CLASS *classPtr = (CLASS *) USER_HEAP_LIN_ADDR( pClassEntry->wNext );
+    if (!classPtr) return FALSE;
+
+    pClassEntry->hInst = classPtr->wc.hInstance;
+    pClassEntry->wNext = classPtr->hNext;
+    GlobalGetAtomName( classPtr->atomName, pClassEntry->szClassName,
+                       sizeof(pClassEntry->szClassName) );
+    return TRUE;
+}
diff --git a/windows/cursor.c b/windows/cursor.c
index 911637e..369506d 100644
--- a/windows/cursor.c
+++ b/windows/cursor.c
@@ -29,7 +29,7 @@
 static HCURSOR hEmptyCursor = 0;
 RECT	ClipCursorRect;
 
-static struct { LPSTR name; HCURSOR cursor; } system_cursor[] =
+static struct { SEGPTR name; HCURSOR cursor; } system_cursor[] =
 {
     { IDC_ARROW, 0 },
     { IDC_IBEAM, 0 },
@@ -50,7 +50,7 @@
 /**********************************************************************
  *			LoadCursor [USER.173]
  */
-HCURSOR LoadCursor(HANDLE instance, LPSTR cursor_name)
+HCURSOR LoadCursor(HANDLE instance, SEGPTR cursor_name)
 {
     XColor	bkcolor;
     XColor	fgcolor;
@@ -62,7 +62,7 @@
     HDC 	hdc;
     int i, j, image_size;
 
-    dprintf_resource(stddeb,"LoadCursor: instance = %04x, name = %p\n",
+    dprintf_resource(stddeb,"LoadCursor: instance = %04x, name = %08lx\n",
 	   instance, cursor_name);
     if (!instance)
     {
@@ -127,7 +127,7 @@
     rsc_mem = RSC_LoadResource(instance, cursor_name, NE_RSCTYPE_GROUP_CURSOR, 
 			       &image_size);
     if (rsc_mem == (HANDLE)NULL) {
-    fprintf(stderr,"LoadCursor / Cursor %p not Found !\n", cursor_name);
+    fprintf(stderr,"LoadCursor / Cursor %08lx not Found !\n", cursor_name);
 	ReleaseDC(GetDesktopWindow(), hdc); 
 	return 0;
 	}
@@ -162,7 +162,7 @@
     	NE_RSCTYPE_CURSOR, &image_size);
     if (rsc_mem == (HANDLE)NULL) {
     	fprintf(stderr,
-		"LoadCursor / Cursor %p Bitmap not Found !\n", cursor_name);
+		"LoadCursor / Cursor %08lx Bitmap not Found !\n", cursor_name);
 	ReleaseDC(GetDesktopWindow(), hdc); 
 	return 0;
 	}
diff --git a/windows/dce.c b/windows/dce.c
index 3148ba2..cbd6cf4 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -30,9 +30,9 @@
 HANDLE DCE_AllocDCE( DCE_TYPE type )
 {
     DCE * dce;
-    HANDLE handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(DCE) );
+    HANDLE handle = USER_HEAP_ALLOC( sizeof(DCE) );
     if (!handle) return 0;
-    dce = (DCE *) USER_HEAP_ADDR( handle );
+    dce = (DCE *) USER_HEAP_LIN_ADDR( handle );
     if (!(dce->hdc = CreateDC( "DISPLAY", NULL, NULL, NULL )))
     {
 	USER_HEAP_FREE( handle );
@@ -57,10 +57,10 @@
     DCE * dce;
     HANDLE *handle = &firstDCE;
 
-    if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return;
+    if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return;
     while (*handle && (*handle != hdce))
     {
-	DCE * prev = (DCE *) USER_HEAP_ADDR( *handle );	
+	DCE * prev = (DCE *) USER_HEAP_LIN_ADDR( *handle );	
 	handle = &prev->hNext;
     }
     if (*handle == hdce) *handle = dce->hNext;
@@ -81,7 +81,7 @@
     for (i = 0; i < NB_DCE; i++)
     {
 	if (!(handle = DCE_AllocDCE( DCE_CACHE_DC ))) return;
-	dce = (DCE *) USER_HEAP_ADDR( handle );	
+	dce = (DCE *) USER_HEAP_LIN_ADDR( handle );	
 	if (!defaultDCstate) defaultDCstate = GetDCState( dce->hdc );
     }
 }
@@ -335,14 +335,14 @@
     {
 	for (hdce = firstDCE; (hdce); hdce = dce->hNext)
 	{
-	    if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
+	    if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return 0;
 	    if ((dce->type == DCE_CACHE_DC) && (!dce->inUse)) break;
 	}
     }
     else hdce = wndPtr->hdce;
 
     if (!hdce) return 0;
-    dce = (DCE *) USER_HEAP_ADDR( hdce );
+    dce = (DCE *) USER_HEAP_LIN_ADDR( hdce );
     dce->hwndCurrent = hwnd;
     dce->inUse       = TRUE;
     hdc = dce->hdc;
@@ -436,7 +436,7 @@
         
     for (hdce = firstDCE; (hdce); hdce = dce->hNext)
     {
-	if (!(dce = (DCE *) USER_HEAP_ADDR( hdce ))) return 0;
+	if (!(dce = (DCE *) USER_HEAP_LIN_ADDR( hdce ))) return 0;
 	if (dce->inUse && (dce->hdc == hdc)) break;
     }
     if (!hdce) return 0;
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 4bd8592..a3fb464 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -211,6 +211,11 @@
             }
             break;
 
+        case WM_CLOSE:
+            EndDialog( hwnd, TRUE );
+            DestroyWindow( hwnd );
+            return 0;
+
 	default:
 	    return DefWindowProc( hwnd, msg, wParam, lParam );
     }
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 37ed5aa..7417429 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -8,7 +8,6 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include "windows.h"
 #include "win.h"
 #include "class.h"
 #include "user.h"
@@ -33,8 +32,8 @@
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
     if (wndPtr->hText) USER_HEAP_FREE( wndPtr->hText );
-    wndPtr->hText = USER_HEAP_ALLOC( LMEM_MOVEABLE, strlen(text) + 1 );
-    textPtr = (LPSTR) USER_HEAP_ADDR( wndPtr->hText );
+    wndPtr->hText = USER_HEAP_ALLOC( strlen(text) + 1 );
+    textPtr = (LPSTR) USER_HEAP_LIN_ADDR( wndPtr->hText );
     strcpy( textPtr, text );
 }
 
@@ -45,11 +44,11 @@
  */
 LONG DefWindowProc( HWND hwnd, WORD msg, WORD wParam, LONG lParam )
 {
-	MEASUREITEMSTRUCT *measure;
-	CLASS * classPtr;
-	LPSTR textPtr;
-	int len;
-	WND * wndPtr = WIN_FindWndPtr( hwnd );
+    MEASUREITEMSTRUCT *measure;
+    CLASS * classPtr;
+    LPSTR textPtr;
+    int len;
+    WND * wndPtr = WIN_FindWndPtr( hwnd );
     
     dprintf_message(stddeb, "DefWindowProc: %d %d %d %08lx\n", 
 		    hwnd, msg, wParam, lParam );
@@ -58,14 +57,16 @@
     {
     case WM_NCCREATE:
 	{
-	    CREATESTRUCT * createStruct = (CREATESTRUCT *)lParam;
+	    CREATESTRUCT *createStruct = (CREATESTRUCT*)PTR_SEG_TO_LIN(lParam);
 	    if (createStruct->lpszName)
-		DEFWND_SetText( hwnd, createStruct->lpszName );
+		DEFWND_SetText( hwnd,
+                               (LPSTR)PTR_SEG_TO_LIN(createStruct->lpszName) );
 	    return 1;
 	}
 
     case WM_NCCALCSIZE:
-	return NC_HandleNCCalcSize( hwnd, (NCCALCSIZE_PARAMS *)lParam );
+	return NC_HandleNCCalcSize( hwnd,
+                                 (NCCALCSIZE_PARAMS *)PTR_SEG_TO_LIN(lParam) );
 
     case WM_PAINTICON: 
     case WM_NCPAINT:
@@ -126,11 +127,11 @@
 	break;
 
     case WM_WINDOWPOSCHANGING:
-	return WINPOS_HandleWindowPosChanging( (WINDOWPOS *)lParam );
+	return WINPOS_HandleWindowPosChanging( (WINDOWPOS *)PTR_SEG_TO_LIN(lParam) );
 
     case WM_WINDOWPOSCHANGED:
 	{
-	    WINDOWPOS * winPos = (WINDOWPOS *)lParam;
+	    WINDOWPOS * winPos = (WINDOWPOS *)PTR_SEG_TO_LIN(lParam);
 	    if (!(winPos->flags & SWP_NOMOVE))
 		SendMessage( hwnd, WM_MOVE, 0,
 		             MAKELONG( wndPtr->rectClient.left,
@@ -187,30 +188,29 @@
 	    {
 		if (wndPtr->hText)
 		{
-		    textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
+		    textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText);
 		    if ((int)wParam > (len = strlen(textPtr)))
 		    {
-			strcpy((char *)lParam, textPtr);
+			strcpy((char *)PTR_SEG_TO_LIN(lParam), textPtr);
 			return (DWORD)len;
 		    }
 		}
-	        lParam = (DWORD)NULL;
 	    }
-	    return (0L);
+	    return 0;
 	}
 
     case WM_GETTEXTLENGTH:
 	{
 	    if (wndPtr->hText)
 	    {
-		textPtr = (LPSTR)USER_HEAP_ADDR(wndPtr->hText);
+		textPtr = (LPSTR)USER_HEAP_LIN_ADDR(wndPtr->hText);
 		return (DWORD)strlen(textPtr);
 	    }
 	    return (0L);
 	}
 
     case WM_SETTEXT:
-	DEFWND_SetText( hwnd, (LPSTR)lParam );
+	DEFWND_SetText( hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam) );
 	NC_HandleNCPaint( hwnd );  /* Repaint caption */
 	return 0;
 
@@ -235,7 +235,7 @@
     case WM_SYSKEYUP:
 		break;    	
     case WM_MEASUREITEM:
-		measure = (MEASUREITEMSTRUCT *)lParam;
+		measure = (MEASUREITEMSTRUCT *)PTR_SEG_TO_LIN(lParam);
 		switch(measure->CtlType) {
 			case ODT_BUTTON:
 				break;
diff --git a/windows/dialog.c b/windows/dialog.c
index ead08ba..479592f 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -12,9 +12,9 @@
 #include "windows.h"
 #include "dialog.h"
 #include "win.h"
+#include "ldt.h"
 #include "user.h"
 #include "message.h"
-#include "heap.h"
 #include "stddebug.h"
 /* #define DEBUG_DIALOG */
 #include "debug.h"
@@ -173,7 +173,7 @@
 /***********************************************************************
  *           CreateDialog   (USER.89)
  */
-HWND CreateDialog( HINSTANCE hInst, LPCSTR dlgTemplate,
+HWND CreateDialog( HINSTANCE hInst, SEGPTR dlgTemplate,
 		   HWND owner, WNDPROC dlgProc )
 {
     return CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, 0 );
@@ -183,14 +183,14 @@
 /***********************************************************************
  *           CreateDialogParam   (USER.241)
  */
-HWND CreateDialogParam( HINSTANCE hInst, LPCSTR dlgTemplate,
+HWND CreateDialogParam( HINSTANCE hInst, SEGPTR dlgTemplate,
 		        HWND owner, WNDPROC dlgProc, LPARAM param )
 {
     HWND hwnd = 0;
     HANDLE hres, hmem;
     LPCSTR data;
 
-    dprintf_dialog(stddeb, "CreateDialogParam: %d,'%p',%d,%p,%ld\n",
+    dprintf_dialog(stddeb, "CreateDialogParam: %d,%08lx,%d,%p,%ld\n",
 	    hInst, dlgTemplate, owner, dlgProc, param );
      
       /* FIXME: MAKEINTRESOURCE should be replaced by RT_DIALOG */
@@ -251,7 +251,13 @@
 						   256*template.menuName[2] ));
 	  break;
       default:
-	  hMenu = LoadMenu( hInst, template.menuName );
+          {
+                /* Need to copy the menu name to a 16-bit area */
+              HANDLE handle = USER_HEAP_ALLOC( strlen(template.menuName)+1 );
+              strcpy( USER_HEAP_LIN_ADDR( handle ), template.menuName );
+              hMenu = LoadMenu( hInst, USER_HEAP_SEG_ADDR( handle ) );
+              USER_HEAP_FREE( handle );
+          }
 	  break;
     }
 
@@ -297,8 +303,7 @@
 			   rect.left + template.header->x * xUnit / 4,
 			   rect.top + template.header->y * yUnit / 8,
 			   rect.right - rect.left, rect.bottom - rect.top,
-			   owner, hMenu, hInst,
-			   NULL );
+			   owner, hMenu, hInst, (SEGPTR)0 );
     if (!hwnd)
     {
 	if (hFont) DeleteObject( hFont );
@@ -339,14 +344,14 @@
 		    fprintf(stderr,"CreateDialogIndirectParam: Insufficient memory to create heap for edit control\n");
 		    continue;
 		}
-		HEAP_LocalInit(dlgInfo->hDialogHeap, GlobalLock(dlgInfo->hDialogHeap), 0x10000);
+		LocalInit(dlgInfo->hDialogHeap, 0, 0xffff);
 	    }
 	    header->style |= WS_CHILD;
 	    hwndCtrl = CreateWindowEx( WS_EX_NOPARENTNOTIFY, 
                            class, text, header->style,
                            header->x * xUnit / 4, header->y * yUnit / 8,
                            header->cx * xUnit / 4, header->cy * yUnit / 8,
-                           hwnd, header->id, dlgInfo->hDialogHeap, NULL );
+                           hwnd, header->id, dlgInfo->hDialogHeap, (SEGPTR)0 );
 	}
 	else
         {
@@ -355,7 +360,7 @@
                                 class, text, header->style,
                                 header->x * xUnit / 4, header->y * yUnit / 8,
                                 header->cx * xUnit / 4, header->cy * yUnit / 8,
-                                hwnd, header->id, hInst, NULL );
+                                hwnd, header->id, hInst, (SEGPTR)0 );
 	}
         /* Make the control last one in Z-order, so that controls remain
            in the order in which they were created */
@@ -412,13 +417,13 @@
       /* Owner must be a top-level window */
     while (owner && GetParent(owner)) owner = GetParent(owner);
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
-    if (!(msgHandle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(MSG)))) return -1;
-    lpmsg = (MSG *) USER_HEAP_ADDR( msgHandle );
+    if (!(msgHandle = USER_HEAP_ALLOC( sizeof(MSG) ))) return -1;
+    lpmsg = (MSG *) USER_HEAP_LIN_ADDR( msgHandle );
     dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
     EnableWindow( owner, FALSE );
     ShowWindow( hwnd, SW_SHOW );
 
-    while (MSG_InternalGetMessage( lpmsg, hwnd, owner,
+    while (MSG_InternalGetMessage( USER_HEAP_SEG_ADDR(msgHandle), hwnd, owner,
                                    MSGF_DIALOGBOX, PM_REMOVE,
                                    !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
     {
@@ -440,7 +445,7 @@
 /***********************************************************************
  *           DialogBox   (USER.87)
  */
-int DialogBox( HINSTANCE hInst, LPCSTR dlgTemplate,
+int DialogBox( HINSTANCE hInst, SEGPTR dlgTemplate,
 	       HWND owner, WNDPROC dlgProc )
 {
     return DialogBoxParam( hInst, dlgTemplate, owner, dlgProc, 0 );
@@ -450,12 +455,12 @@
 /***********************************************************************
  *           DialogBoxParam   (USER.239)
  */
-int DialogBoxParam( HINSTANCE hInst, LPCSTR dlgTemplate,
+int DialogBoxParam( HINSTANCE hInst, SEGPTR dlgTemplate,
 		    HWND owner, WNDPROC dlgProc, LPARAM param )
 {
     HWND hwnd;
     
-    dprintf_dialog(stddeb, "DialogBoxParam: %d,'%p',%d,%p,%ld\n",
+    dprintf_dialog(stddeb, "DialogBoxParam: %d,%08lx,%d,%p,%ld\n",
 	    hInst, dlgTemplate, owner, dlgProc, param );
     hwnd = CreateDialogParam( hInst, dlgTemplate, owner, dlgProc, param );
     if (hwnd) return DIALOG_DoDialogBox( hwnd, owner );
@@ -666,7 +671,7 @@
 /*******************************************************************
  *           SetDlgItemText   (USER.92)
  */
-void SetDlgItemText( HWND hwnd, WORD id, LPSTR lpString )
+void SetDlgItemText( HWND hwnd, WORD id, SEGPTR lpString )
 {
     SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)lpString );
 }
@@ -675,7 +680,7 @@
 /***********************************************************************
  *           GetDlgItemText   (USER.93)
  */
-int GetDlgItemText( HWND hwnd, WORD id, LPSTR str, WORD max )
+int GetDlgItemText( HWND hwnd, WORD id, SEGPTR str, WORD max )
 {
     return (int)SendDlgItemMessage( hwnd, id, WM_GETTEXT, max, (DWORD)str );
 }
@@ -686,12 +691,13 @@
  */
 void SetDlgItemInt( HWND hwnd, WORD id, WORD value, BOOL fSigned )
 {
-    HANDLE hText = USER_HEAP_ALLOC(0, 10 );
-    char * str = (char *) USER_HEAP_ADDR( hText );
+    HANDLE hText = USER_HEAP_ALLOC( 10 );
+    char * str = (char *) USER_HEAP_LIN_ADDR( hText );
 
     if (fSigned) sprintf( str, "%d", value );
     else sprintf( str, "%u", value );
-    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0, (DWORD)str );
+    SendDlgItemMessage( hwnd, id, WM_SETTEXT, 0,
+                        USER_HEAP_SEG_ADDR(hText) );
     USER_HEAP_FREE( hText );
 }
 
@@ -709,10 +715,10 @@
     if (translated) *translated = FALSE;
     if (!(len = SendDlgItemMessage( hwnd, id, WM_GETTEXTLENGTH, 0, 0 )))
 	return 0;
-    if (!(hText = USER_HEAP_ALLOC(0, len+1 )))
-	return 0;
-    str = (char *) USER_HEAP_ADDR( hText );
-    if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, len+1, (DWORD)str ))
+    if (!(hText = USER_HEAP_ALLOC( len+1 ))) return 0;
+    str = (char *) USER_HEAP_LIN_ADDR( hText );
+    if (SendDlgItemMessage( hwnd, id, WM_GETTEXT, len+1,
+                            USER_HEAP_SEG_ADDR(hText) ))
     {
 	char * endptr;
 	result = strtol( str, &endptr, 10 );
diff --git a/windows/event.c b/windows/event.c
index 06b3ded..63bb4e2 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -357,7 +357,8 @@
 	if (count == 1)                /* key has an ASCII representation */
 	{
 	    dprintf_key(stddeb,"WM_CHAR :   wParam=%X\n", (WORD)Str[0] );
-	    PostMessage( GetFocus(), WM_CHAR, (WORD)Str[0], keylp.lp2 );
+	    PostMessage( GetFocus(), WM_CHAR, (WORD)(unsigned char)(Str[0]), 
+			keylp.lp2 );
 	}
     }
     else
diff --git a/windows/graphics.c b/windows/graphics.c
index 8ed3f8c..2531ed3 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -525,7 +525,7 @@
     XDestroyImage( image );
     
     if (screenDepth > 8) return pixel;
-    mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hRevMapping );
+    mapping = (WORD *) GDI_HEAP_LIN_ADDR( dc->u.x.pal.hRevMapping );
     if (mapping) pixel = mapping[pixel];
     GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry );
     return RGB( entry.peRed, entry.peGreen, entry.peBlue );
diff --git a/windows/hook.c b/windows/hook.c
index 0f15595..e91a22b 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -10,6 +10,7 @@
  */
 
 #include "hook.h"
+#include "user.h"
 
 
 HHOOK systemHooks[LAST_HOOK-FIRST_HOOK+1] = { 0, };
@@ -49,7 +50,7 @@
 /***********************************************************************
  *           CallMsgFilter   (USER.123)
  */
-BOOL CallMsgFilter( LPMSG msg, short code )
+BOOL CallMsgFilter( SEGPTR msg, short code )
 {
     if (CALL_SYSTEM_HOOK( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
     else return CALL_TASK_HOOK( WH_MSGFILTER, code, 0, (LPARAM)msg );
@@ -77,16 +78,16 @@
 	prevHook = &SYSTEM_HOOK( id );
     }
     
-    handle = (HANDLE) USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*data) );
+    handle = (HANDLE) USER_HEAP_ALLOC( sizeof(*data) );
     if (!handle) return 0;
-    data   = (HOOKDATA *) USER_HEAP_ADDR( handle );
+    data   = (HOOKDATA *) USER_HEAP_LIN_ADDR( handle );
 
     data->next  = *prevHook;
     data->proc  = proc;
     data->id    = id;
     data->htask = htask;
-    *prevHook   = (HHOOK)data;
-    return (HHOOK)data;
+    *prevHook   = USER_HEAP_SEG_ADDR(handle);
+    return *prevHook;
 }
 
 
@@ -95,7 +96,7 @@
  */
 BOOL UnhookWindowsHookEx( HHOOK hhook )
 {
-    HOOKDATA *data = (HOOKDATA *)hhook;
+    HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
     HHOOK *prevHook;
 
     if (!data) return FALSE;
@@ -114,7 +115,7 @@
  */
 DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam )
 {
-    HOOKDATA *data = (HOOKDATA *)hhook;
+    HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
     if (!data->next) return 0;
     else return INTERNAL_CALL_HOOK( data->next, code, wParam, lParam );
 }
diff --git a/windows/mdi.c b/windows/mdi.c
index f59d501..b03a2e1 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -62,8 +62,9 @@
  *					MDICreateChild
  */
 HWND 
-MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPMDICREATESTRUCT cs)
+MDICreateChild(WND *w, MDICLIENTINFO *ci, HWND parent, LPARAM lParam )
 {
+    MDICREATESTRUCT *cs = (MDICREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
     HWND hwnd;
 
     /*
@@ -71,17 +72,18 @@
      */
     cs->style &= (WS_MINIMIZE | WS_MAXIMIZE | WS_HSCROLL | WS_VSCROLL);
     
-    hwnd = CreateWindowEx(0, cs->szClass, cs->szTitle, 
+    hwnd = CreateWindowEx(0, PTR_SEG_TO_LIN(cs->szClass),
+                          PTR_SEG_TO_LIN(cs->szTitle), 
 			  WS_CHILD | WS_BORDER | WS_CAPTION | WS_CLIPSIBLINGS |
 			  WS_MAXIMIZEBOX | WS_MINIMIZEBOX | WS_SYSMENU |
 			  WS_THICKFRAME | WS_VISIBLE | cs->style,
 			  cs->x, cs->y, cs->cx, cs->cy, parent, (HMENU) 0,
-			  w->hInstance, (LPSTR) cs);
+			  w->hInstance, lParam);
 
     if (hwnd)
     {
-	HANDLE h = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MDICHILDINFO));
-	MDICHILDINFO *child_info = USER_HEAP_ADDR(h);
+	HANDLE h = USER_HEAP_ALLOC( sizeof(MDICHILDINFO) );
+	MDICHILDINFO *child_info = USER_HEAP_LIN_ADDR(h);
 	if (!h)
 	{
 	    DestroyWindow(hwnd);
@@ -577,8 +579,8 @@
 	return MDIChildActivated(w, ci, hwnd);
 
       case WM_CREATE:
-	cs                      = (LPCREATESTRUCT) lParam;
-	ccs                     = (LPCLIENTCREATESTRUCT) cs->lpCreateParams;
+	cs                      = (LPCREATESTRUCT) PTR_SEG_TO_LIN(lParam);
+	ccs                     = (LPCLIENTCREATESTRUCT) PTR_SEG_TO_LIN(cs->lpCreateParams);
 	ci->hWindowMenu         = ccs->hWindowMenu;
 	ci->idFirstChild        = ccs->idFirstChild;
 	ci->infoActiveChildren  = NULL;
@@ -600,7 +602,7 @@
 	return MDICascade(hwnd, ci);
 
       case WM_MDICREATE:
-	return MDICreateChild(w, ci, hwnd, (LPMDICREATESTRUCT) lParam);
+	return MDICreateChild(w, ci, hwnd, lParam );
 
       case WM_MDIDESTROY:
 	return MDIDestroyChild(w, ci, hwnd, wParam, TRUE);
diff --git a/windows/message.c b/windows/message.c
index d77c2b6..cf1d2cd 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -778,29 +778,34 @@
  * 'hwnd' must be the handle of the dialog or menu window.
  * 'code' is the message filter value (MSGF_??? codes).
  */
-BOOL MSG_InternalGetMessage( LPMSG msg, HWND hwnd, HWND hwndOwner, short code,
+BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner, short code,
 			     WORD flags, BOOL sendIdle ) 
 {
     for (;;)
     {
 	if (sendIdle)
 	{
-	    if (!MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, flags, TRUE ))
+	    if (!MSG_PeekMessage( appMsgQueue, (MSG *)PTR_SEG_TO_LIN(msg),
+                                  0, 0, 0, flags, TRUE ))
 	    {
 		  /* No message present -> send ENTERIDLE and wait */
 		SendMessage( hwndOwner, WM_ENTERIDLE, code, (LPARAM)hwnd );
-		MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, flags, FALSE );
+		MSG_PeekMessage( appMsgQueue, (MSG *)PTR_SEG_TO_LIN(msg),
+                                 0, 0, 0, flags, FALSE );
 	    }
 	}
 	else  /* Always wait for a message */
-	    MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, flags, FALSE );
+	    MSG_PeekMessage( appMsgQueue, (MSG *)PTR_SEG_TO_LIN(msg),
+                             0, 0, 0, flags, FALSE );
 
-	if (!CallMsgFilter( msg, code )) return (msg->message != WM_QUIT);
+	if (!CallMsgFilter( msg, code ))
+            return (((MSG *)PTR_SEG_TO_LIN(msg))->message != WM_QUIT);
 
 	  /* Message filtered -> remove it from the queue */
 	  /* if it's still there. */
 	if (!(flags & PM_REMOVE))
-	    MSG_PeekMessage( appMsgQueue, msg, 0, 0, 0, PM_REMOVE, TRUE );
+	    MSG_PeekMessage( appMsgQueue, (MSG *)PTR_SEG_TO_LIN(msg),
+                             0, 0, 0, PM_REMOVE, TRUE );
     }
 }
 
@@ -817,12 +822,13 @@
 /***********************************************************************
  *           GetMessage   (USER.108)
  */
-BOOL GetMessage( LPMSG msg, HWND hwnd, WORD first, WORD last ) 
+BOOL GetMessage( SEGPTR msg, HWND hwnd, WORD first, WORD last ) 
 {
-    MSG_PeekMessage( appMsgQueue, msg, hwnd, first, last, PM_REMOVE, FALSE );
+    MSG_PeekMessage( appMsgQueue, (MSG *)PTR_SEG_TO_LIN(msg),
+                     hwnd, first, last, PM_REMOVE, FALSE );
     CALL_SYSTEM_HOOK( WH_GETMESSAGE, 0, 0, (LPARAM)msg );
     CALL_TASK_HOOK( WH_GETMESSAGE, 0, 0, (LPARAM)msg );
-    return (msg->message != WM_QUIT);
+    return (((MSG *)PTR_SEG_TO_LIN(msg))->message != WM_QUIT);
 }
 
 
@@ -1000,9 +1006,22 @@
 /***********************************************************************
  *           GetTickCount    (USER.13)
  */
-DWORD GetTickCount()
+DWORD GetTickCount(void)
 {
     struct timeval t;
     gettimeofday( &t, NULL );
     return (t.tv_sec * 1000) + (t.tv_usec / 1000);
 }
+
+/***********************************************************************
+ *			InSendMessage	(USER.192
+ *
+ * According to the book, this should return true iff the current message
+ * was send from another application. In that case, the application should
+ * invoke ReplyMessage before calling message relevant API.
+ * Currently, Wine will always return FALSE, as there is no other app.
+ */
+BOOL InSendMessage()
+{
+	return FALSE;
+}
diff --git a/windows/nonclient.c b/windows/nonclient.c
index c12e293..8e43752 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -161,12 +161,13 @@
         MinMax.ptMaxPosition.y = -yinc;
     }
 
-    minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) );
+    minmaxHandle = USER_HEAP_ALLOC( sizeof(MINMAXINFO) );
     if (minmaxHandle)
     {
-	pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle );
+	pMinMax = (MINMAXINFO *) USER_HEAP_LIN_ADDR( minmaxHandle );
 	memcpy( pMinMax, &MinMax, sizeof(MinMax) );	
-	SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax );
+	SendMessage( hwnd, WM_GETMINMAXINFO, 0,
+                     USER_HEAP_SEG_ADDR(minmaxHandle) );
     }
     else pMinMax = &MinMax;
 
@@ -1085,7 +1086,8 @@
  */
 static void NC_TrackScrollBar( HWND hwnd, WORD wParam, POINT pt )
 {
-    MSG msg;
+    MSG *msg;
+    HLOCAL hMsg;
     WORD scrollbar;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
@@ -1100,6 +1102,8 @@
 	scrollbar = SB_VERT;
     }
 
+    hMsg = USER_HEAP_ALLOC( sizeof(MSG) );
+    msg  = (MSG *) USER_HEAP_LIN_ADDR( hMsg );
     pt.x -= wndPtr->rectWindow.left;
     pt.y -= wndPtr->rectWindow.top;
     SetCapture( hwnd );
@@ -1107,20 +1111,20 @@
 
     do
     {
-        GetMessage( &msg, 0, 0, 0 );
-	switch(msg.message)
+        GetMessage( USER_HEAP_SEG_ADDR(hMsg), 0, 0, 0 );
+	switch(msg->message)
 	{
 	case WM_LBUTTONUP:
 	case WM_MOUSEMOVE:
         case WM_SYSTIMER:
-            pt = MAKEPOINT(msg.lParam);
+            pt = MAKEPOINT(msg->lParam);
             pt.x += wndPtr->rectClient.left - wndPtr->rectWindow.left;
             pt.y += wndPtr->rectClient.top - wndPtr->rectWindow.top;
-            SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt );
+            SCROLL_HandleScrollEvent( hwnd, scrollbar, msg->message, pt );
 	    break;
         default:
-            TranslateMessage( &msg );
-            DispatchMessage( &msg );
+            TranslateMessage( msg );
+            DispatchMessage( msg );
             break;
 	}
         if (!IsWindow( hwnd ))
@@ -1128,7 +1132,8 @@
             ReleaseCapture();
             break;
         }
-    } while (msg.message != WM_LBUTTONUP);
+    } while (msg->message != WM_LBUTTONUP);
+    USER_HEAP_FREE( hMsg );
 }
 
 /***********************************************************************
diff --git a/windows/utility.c b/windows/utility.c
index ec69566..3858487 100644
--- a/windows/utility.c
+++ b/windows/utility.c
@@ -13,6 +13,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include "windows.h"
+#include "ldt.h"
 #include "stddebug.h"
 /* #define DEBUG_UTILITY */
 #include "debug.h"
@@ -246,7 +247,7 @@
 				case 's':
 				case 'p':
 				case 'n':	/* A pointer, is a pointer, is a pointer... */
-					*(((char **)rptr)++) = *(((char **)winarg)++);
+					*(((char **)rptr)++) = (char *)PTR_SEG_TO_LIN(*(((char **)winarg)++));
 					break;
 				case 'e':
 				case 'E':
@@ -269,72 +270,88 @@
 #ifndef WINELIB
 INT windows_wsprintf(BYTE *win_stack)
 {
-	LPSTR lpOutput, lpFormat, ptr;
-	BYTE new_stack[1024], *stack_ptr;
+    LPSTR lpOutput, lpFormat, ptr;
+    BYTE new_stack[1024], *stack_ptr;
+    BOOL fLarge;
 
-	lpOutput = (LPSTR) *(DWORD*)win_stack;
-	win_stack += 4;
-	lpFormat = (LPSTR) *(DWORD*)win_stack;
-	win_stack += 4;
+    lpOutput = (LPSTR) PTR_SEG_TO_LIN(*(DWORD*)win_stack);
+    win_stack += sizeof(DWORD);
+    lpFormat = (LPSTR) PTR_SEG_TO_LIN(*(DWORD*)win_stack);
+    win_stack += sizeof(DWORD);
 
-	/* create 32-bit stack for libc's vsprintf() */
+      /* create 32-bit stack for libc's vsprintf() */
 
-	for (ptr = lpFormat, stack_ptr = new_stack; *ptr; ptr++) {
-		if (*ptr != '%' || *++ptr == '%')
-			continue;
+    for (ptr = lpFormat, stack_ptr = new_stack; *ptr; ptr++)
+    {
+        if (*ptr != '%' || *++ptr == '%')
+            continue;
 
-		/* skip width/precision */
-		while (*ptr == '-' || *ptr == '+' || *ptr == '.' ||
-		       *ptr == ' ' || isdigit(*ptr) || *ptr == '#')
-			ptr++;
-			
-		switch (*ptr) {
-			case 's':
-				*(DWORD*)stack_ptr = *(DWORD*)win_stack;
-				stack_ptr += 4;
- 				win_stack += 4;
-				break;
-			case 'l':
-				*(DWORD*)stack_ptr = *(DWORD*)win_stack;
-				stack_ptr += 4;
-				win_stack += 4;
-				ptr++; /* skip next type character */
-				break;
-			case 'c':
+        /* skip width/precision */
+        while (*ptr == '-' || *ptr == '+' || *ptr == '.' ||
+               *ptr == ' ' || isdigit(*ptr) || *ptr == '#')
+            ptr++;
+
+        /* handle modifier */
+        fLarge = ((*ptr == 'l') || (*ptr == 'L'));
+        if (fLarge) ptr++;
+
+        switch (*ptr)
+        {
+        case 's':
+            *(char**)stack_ptr = (char *)PTR_SEG_TO_LIN(*(DWORD*)win_stack);
+            stack_ptr += sizeof(char *);
+            win_stack += sizeof(DWORD);
+            break;
+
+        case 'c':
 	
 /* windows' wsprintf() %c ignores 0's, we replace 0 with SPACE to make sure
    that the remaining part of the string isn't ignored by the winapp */
 				
-				if (*(WORD*)win_stack)
-					*(DWORD*)stack_ptr = *(WORD*)win_stack;
-				else
-					*(DWORD*)stack_ptr = ' ';
-				stack_ptr += 4;
-				win_stack += 2;
-				break;
-			case 'd':
-			case 'i':
-				*(int*)stack_ptr = *(INT*)win_stack;
-				stack_ptr += 4;
-				win_stack += 2;
-				break;
-			case 'u':
-			case 'x':
-			case 'X':
-				*(DWORD*)stack_ptr = *(WORD*)win_stack;
-				stack_ptr += 4;
-				win_stack += 2;
-				break;
-			default:
-				*(DWORD*)stack_ptr = 0;
-				stack_ptr += 4;
-				win_stack += 4;
-				fprintf(stderr, "wsprintf: oops, unknown formattype %c used!\n", *ptr);
-				break;
-		}
-	}
+            if (*(WORD*)win_stack)
+                *(DWORD*)stack_ptr = *(WORD*)win_stack;
+            else
+                *(DWORD*)stack_ptr = ' ';
+            stack_ptr += sizeof(DWORD);
+            win_stack += sizeof(WORD);
+            break;
 
-	return vsprintf(lpOutput, lpFormat, new_stack);
+        case 'd':
+        case 'i':
+            if (!fLarge)
+            {
+                *(int*)stack_ptr = *(INT*)win_stack;
+                stack_ptr += sizeof(int);
+                win_stack += sizeof(INT);
+                break;
+            }
+            /* else fall through */
+        case 'u':
+        case 'x':
+        case 'X':
+            if (fLarge)
+            {
+                *(DWORD*)stack_ptr = *(DWORD*)win_stack;
+                win_stack += sizeof(DWORD);
+            }
+            else
+            {
+                *(DWORD*)stack_ptr = *(WORD*)win_stack;
+                win_stack += sizeof(WORD);
+            }
+            stack_ptr += sizeof(DWORD);
+            break;
+
+        default:
+            *(DWORD*)stack_ptr = 0;
+            stack_ptr += sizeof(DWORD);
+            win_stack += sizeof(WORD);
+            fprintf(stderr, "wsprintf: oops, unknown formattype %c used!\n", *ptr);
+            break;
+        }
+    }
+
+    return vsprintf(lpOutput, lpFormat, new_stack);
 }
 #endif
 
diff --git a/windows/win.c b/windows/win.c
index 3d9e49a..6ed50d8 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -18,6 +18,7 @@
 #include "cursor.h"
 #include "event.h"
 #include "message.h"
+#include "nonclient.h"
 #include "winpos.h"
 #include "color.h"
 #include "stddebug.h"
@@ -39,8 +40,7 @@
     WND * ptr;
     
     if (!hwnd) return NULL;
-    ptr = (WND *) USER_HEAP_ADDR( hwnd );
-    if (IsBadReadPtr(ptr, sizeof *ptr)) return NULL;
+    ptr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
     if (ptr->dwMagic != WND_MAGIC) return NULL;
     return ptr;
 }
@@ -219,10 +219,9 @@
     if (!(hclass = CLASS_FindClassByName( DESKTOP_CLASS_NAME, 0, &classPtr )))
 	return FALSE;
 
-    hwndDesktop = USER_HEAP_ALLOC( GMEM_MOVEABLE,
-				   sizeof(WND)+classPtr->wc.cbWndExtra );
+    hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+classPtr->wc.cbWndExtra );
     if (!hwndDesktop) return FALSE;
-    wndPtr = (WND *) USER_HEAP_ADDR( hwndDesktop );
+    wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop );
 
     wndPtr->hwndNext          = 0;
     wndPtr->hwndChild         = 0;
@@ -272,7 +271,7 @@
  */
 HWND CreateWindow( LPSTR className, LPSTR windowName,
 		   DWORD style, short x, short y, short width, short height,
-		   HWND parent, HMENU menu, HANDLE instance, LPSTR data ) 
+		   HWND parent, HMENU menu, HANDLE instance, SEGPTR data ) 
 {
     return CreateWindowEx( 0, className, windowName, style,
 			   x, y, width, height, parent, menu, instance, data );
@@ -284,18 +283,18 @@
  */
 HWND CreateWindowEx( DWORD exStyle, LPSTR className, LPSTR windowName,
 		     DWORD style, short x, short y, short width, short height,
-		     HWND parent, HMENU menu, HANDLE instance, LPSTR data ) 
+		     HWND parent, HMENU menu, HANDLE instance, SEGPTR data ) 
 {
     HANDLE class, hwnd;
     CLASS *classPtr;
     WND *wndPtr;
     POINT maxSize, maxPos, minTrack, maxTrack;
     CREATESTRUCT *createStruct;
-    HANDLE hcreateStruct;
+    HANDLE hcreateStruct, hwinName, hclassName;
     int wmcreate;
     XSetWindowAttributes win_attr;
 
-    dprintf_win(stddeb, "CreateWindowEx: %08lX '%s' '%s' %08lX %d,%d %dx%d %04X %04X %04X %p\n",
+    dprintf_win(stddeb, "CreateWindowEx: %08lX '%s' '%s' %08lX %d,%d %dx%d %04X %04X %04X %08lx\n",
 				exStyle, className, windowName, style, x, y, width, height, 
 				parent, menu, instance, data);
 	/* 'soundrec.exe' has negative position ! 
@@ -336,12 +335,12 @@
 
       /* Create the window structure */
 
-    hwnd = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(WND)+classPtr->wc.cbWndExtra);
+    hwnd = USER_HEAP_ALLOC( sizeof(WND)+classPtr->wc.cbWndExtra );
     if (!hwnd) return 0;
 
       /* Fill the structure */
 
-    wndPtr = (WND *) USER_HEAP_ADDR( hwnd );
+    wndPtr = (WND *) USER_HEAP_LIN_ADDR( hwnd );
     wndPtr->hwndNext   = 0;
     wndPtr->hwndChild  = 0;
     wndPtr->window     = 0;
@@ -442,25 +441,21 @@
         GlobalUnlock( hCursor );
     }
     
-    dprintf_menu(stddeb,"CreateWindowEx // menu=%04X instance=%04X classmenu=%p !\n", 
-    	menu, instance, classPtr->wc.lpszMenuName);
-
-	if ((style & WS_CAPTION) && (style & WS_CHILD) == 0) {
-		if (menu != 0)
-			SetMenu(hwnd, menu);
-		else {
-			if (classPtr->wc.lpszMenuName != NULL)
-				SetMenu(hwnd, LoadMenu(instance, classPtr->wc.lpszMenuName));
-			}
-		}
-	else
-		wndPtr->wIDmenu   = menu;
+    if ((style & WS_CAPTION) && !(style & WS_CHILD))
+    {
+        if (menu) SetMenu(hwnd, menu);
+        else if (classPtr->wc.lpszMenuName)
+            SetMenu(hwnd,LoadMenu(instance,(SEGPTR)classPtr->wc.lpszMenuName));
+    }
+    else wndPtr->wIDmenu = menu;
 
       /* Send the WM_CREATE message */
 
-    hcreateStruct = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CREATESTRUCT) );
-    createStruct = (CREATESTRUCT *) USER_HEAP_ADDR( hcreateStruct );
-    createStruct->lpCreateParams = data;
+    hcreateStruct = USER_HEAP_ALLOC( sizeof(CREATESTRUCT) );
+    hclassName = USER_HEAP_ALLOC( strlen(className)+1 );
+    strcpy( USER_HEAP_LIN_ADDR(hclassName), className );
+    createStruct = (CREATESTRUCT *) USER_HEAP_LIN_ADDR( hcreateStruct );
+    createStruct->lpCreateParams = (LPSTR)data;
     createStruct->hInstance      = instance;
     createStruct->hMenu          = menu;
     createStruct->hwndParent     = parent;
@@ -469,20 +464,34 @@
     createStruct->x              = x;
     createStruct->y              = y;
     createStruct->style          = style;
-    createStruct->lpszName       = windowName;
-    createStruct->lpszClass      = className;
+    createStruct->lpszClass      = (LPSTR)USER_HEAP_SEG_ADDR(hclassName);
     createStruct->dwExStyle      = 0;
+    if (windowName)
+    {
+        hwinName = USER_HEAP_ALLOC( strlen(windowName)+1 );
+        strcpy( USER_HEAP_LIN_ADDR(hwinName), windowName );
+        createStruct->lpszName = (LPSTR)USER_HEAP_SEG_ADDR(hwinName);
+    }
+    else
+    {
+        hwinName = 0;
+        createStruct->lpszName = NULL;
+    }
 
-    wmcreate = SendMessage( hwnd, WM_NCCREATE, 0, (LONG)createStruct );
+    wmcreate = SendMessage( hwnd, WM_NCCREATE, 0,
+                            USER_HEAP_SEG_ADDR(hcreateStruct) );
     if (!wmcreate) wmcreate = -1;
     else
     {
 	WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
 			       NULL, NULL, NULL, &wndPtr->rectClient );
-	wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
+	wmcreate = SendMessage( hwnd, WM_CREATE, 0,
+                                USER_HEAP_SEG_ADDR(hcreateStruct) );
     }
 
     USER_HEAP_FREE( hcreateStruct );
+    USER_HEAP_FREE( hclassName );
+    if (hwinName) USER_HEAP_FREE( hwinName );
 
     if (wmcreate == -1)
     {
@@ -612,7 +621,7 @@
 	    if (!TitleMatch) return hwnd;
 	    if (wndPtr->hText)
 	    {
-		char *textPtr = (char *) USER_HEAP_ADDR( wndPtr->hText );
+		char *textPtr = (char *) USER_HEAP_LIN_ADDR( wndPtr->hText );
 		if (!strcmp( textPtr, TitleMatch )) return hwnd;
 	    }
 	}
@@ -725,19 +734,7 @@
     {
 	case GWL_STYLE:   return wndPtr->dwStyle;
         case GWL_EXSTYLE: return wndPtr->dwExStyle;
-	case GWL_WNDPROC: 
-		if (!IS_16_BIT_ADDRESS(wndPtr->lpfnWndProc))
-		{
-		   /* The window procedure is part of Wine.
-		      Unfortunately, MS-Windows programs can't access these
-		      adresses.
-                      FIXME: There should be a jump table somewhere in if1632
-		   */
-		   long x=pStack16Frame->cs<<16 | 0x0010;
-		   /* Just to make Borland's OWL happy */
-		   return x;
-		}
-	        else return (LONG)wndPtr->lpfnWndProc;
+	case GWL_WNDPROC: return (LONG)wndPtr->lpfnWndProc;
     }
     return 0;
 }
@@ -771,27 +768,55 @@
 /*******************************************************************
  *         GetWindowText          (USER.36)
  */
-int GetWindowText(HWND hwnd, LPSTR lpString, int nMaxCount)
+int WIN16_GetWindowText( HWND hwnd, SEGPTR lpString, int nMaxCount )
 {
     return (int)SendMessage(hwnd, WM_GETTEXT, (WORD)nMaxCount, 
 			                      (DWORD)lpString);
 }
 
+int GetWindowText( HWND hwnd, LPSTR lpString, int nMaxCount )
+{
+    int len;
+    HANDLE handle;
+
+      /* We have to allocate a buffer on the USER heap */
+      /* to be able to pass its address to 16-bit code */
+    if (!(handle = USER_HEAP_ALLOC( nMaxCount ))) return 0;
+    len = (int)SendMessage( hwnd, WM_GETTEXT, (WORD)nMaxCount, 
+                            USER_HEAP_SEG_ADDR(handle) );
+    strncpy( lpString, USER_HEAP_LIN_ADDR(handle), nMaxCount );
+    USER_HEAP_FREE( handle );
+    return len;
+}
+
+
 /*******************************************************************
  *         SetWindowText          (USER.37)
  */
-void SetWindowText(HWND hwnd, LPSTR lpString)
+void WIN16_SetWindowText( HWND hwnd, SEGPTR lpString )
 {
-    SendMessage(hwnd, WM_SETTEXT, (WORD)NULL, (DWORD)lpString);
+    SendMessage( hwnd, WM_SETTEXT, 0, (DWORD)lpString );
 }
 
+void SetWindowText( HWND hwnd, LPSTR lpString )
+{
+    HANDLE handle;
+
+      /* We have to allocate a buffer on the USER heap */
+      /* to be able to pass its address to 16-bit code */
+    if (!(handle = USER_HEAP_ALLOC( strlen(lpString)+1 ))) return;
+    strcpy( USER_HEAP_LIN_ADDR(handle), lpString );
+    SendMessage( hwnd, WM_SETTEXT, 0, USER_HEAP_SEG_ADDR(handle) );
+    USER_HEAP_FREE( handle );
+}
+
+
 /*******************************************************************
  *         GetWindowTextLength    (USER.38)
  */
 int GetWindowTextLength(HWND hwnd)
 {
-    return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, (WORD)NULL, 
-			                            (DWORD)NULL);
+    return (int)SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0 );
 }
 
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 5f71349..b1f7139 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -603,9 +603,8 @@
     HANDLE hparams;
     LONG result;
 
-    if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) )))
-	return 0;
-    params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
+    if (!(hparams = USER_HEAP_ALLOC( sizeof(*params) ))) return 0;
+    params = (NCCALCSIZE_PARAMS *) USER_HEAP_LIN_ADDR( hparams );
     params->rgrc[0] = *newWindowRect;
     if (calcValidRect)
     {
@@ -613,7 +612,8 @@
 	params->rgrc[2] = *oldClientRect;
 	params->lppos = winpos;
     }
-    result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect, (LONG)params);
+    result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect,
+                          USER_HEAP_SEG_ADDR(hparams) );
     *newClientRect = params->rgrc[0];
     USER_HEAP_FREE( hparams );
     return result;
@@ -758,61 +758,71 @@
 
 
 /***********************************************************************
- *           WINPOS_InternalSetWindowPos
- *
- * Helper function for SetWindowPos.
+ *           SetWindowPos   (USER.232)
  */
-static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
+BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
+		   INT cx, INT cy, WORD flags )
 {
-    HWND hwndAfter;
+    HLOCAL hWinPos;
+    WINDOWPOS *winpos;
     WND *wndPtr;
     RECT newWindowRect, newClientRect;
-    int flags, result;
-
-      /* Send WM_WINDOWPOSCHANGING message */
-
-    if (!(winpos->flags & SWP_NOSENDCHANGING))
-	SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winpos );
+    int result;
 
       /* Check window handle */
 
-    if (winpos->hwnd == GetDesktopWindow()) return FALSE;
-    if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
+    if (hwnd == GetDesktopWindow()) return FALSE;
+    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
 
       /* Check dimensions */
 
-    if (winpos->cx <= 0) winpos->cx = 1;
-    if (winpos->cy <= 0) winpos->cy = 1;
+    if (cx <= 0) cx = 1;
+    if (cy <= 0) cy = 1;
 
       /* Check flags */
 
-    if (winpos->hwnd == hwndActive)
-        winpos->flags |= SWP_NOACTIVATE;   /* Already active */
-    if ((wndPtr->rectWindow.right-wndPtr->rectWindow.left == winpos->cx) &&
-        (wndPtr->rectWindow.bottom-wndPtr->rectWindow.top == winpos->cy))
-        winpos->flags |= SWP_NOSIZE;    /* Already the right size */
-    if ((wndPtr->rectWindow.left == winpos->x) &&
-        (wndPtr->rectWindow.top == winpos->y))
-        winpos->flags |= SWP_NOMOVE;    /* Already the right position */
-    flags = winpos->flags;
+    if (hwnd == hwndActive) flags |= SWP_NOACTIVATE;   /* Already active */
+    if ((wndPtr->rectWindow.right - wndPtr->rectWindow.left == cx) &&
+        (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top == cy))
+        flags |= SWP_NOSIZE;    /* Already the right size */
+    if ((wndPtr->rectWindow.left == x) && (wndPtr->rectWindow.top == y))
+        flags |= SWP_NOMOVE;    /* Already the right position */
 
-      /* Check hwndAfter */
+      /* Check hwndInsertAfter */
 
-    hwndAfter = winpos->hwndInsertAfter;
-    if (!(winpos->flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
+    if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
     {
 	  /* Ignore TOPMOST flags when activating a window */
           /* _and_ moving it in Z order. */
-	if ((hwndAfter == HWND_TOPMOST) || (hwndAfter == HWND_NOTOPMOST))
-	    hwndAfter = HWND_TOP;	
+	if ((hwndInsertAfter == HWND_TOPMOST) ||
+            (hwndInsertAfter == HWND_NOTOPMOST))
+	    hwndInsertAfter = HWND_TOP;	
     }
       /* TOPMOST not supported yet */
-    if ((hwndAfter == HWND_TOPMOST) || (hwndAfter == HWND_NOTOPMOST))
-	hwndAfter = HWND_TOP;
-      /* hwndAfter must be a sibling of the window */
-    if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM) &&
-	(GetParent(winpos->hwnd) != GetParent(hwndAfter))) return FALSE;
-    winpos->hwndInsertAfter = hwndAfter;
+    if ((hwndInsertAfter == HWND_TOPMOST) ||
+        (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
+      /* hwndInsertAfter must be a sibling of the window */
+    if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM) &&
+	(GetParent(hwnd) != GetParent(hwndInsertAfter))) return FALSE;
+
+      /* Allocate the WINDOWPOS structure */
+
+    hWinPos = USER_HEAP_ALLOC( sizeof(WINDOWPOS) );
+    if (!hWinPos) return FALSE;
+    winpos = USER_HEAP_LIN_ADDR( hWinPos );
+    winpos->hwnd = hwnd;
+    winpos->hwndInsertAfter = hwndInsertAfter;
+    winpos->x = x;
+    winpos->y = y;
+    winpos->cx = cx;
+    winpos->cy = cy;
+    winpos->flags = flags;
+    
+      /* Send WM_WINDOWPOSCHANGING message */
+
+    if (!(flags & SWP_NOSENDCHANGING))
+	SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0,
+                     USER_HEAP_SEG_ADDR(hWinPos) );
 
       /* Calculate new position and size */
 
@@ -839,9 +849,9 @@
         if (wndPtr->window)
         {
             WIN_UnlinkWindow( winpos->hwnd );
-            WIN_LinkWindow( winpos->hwnd, hwndAfter );
+            WIN_LinkWindow( winpos->hwnd, hwndInsertAfter );
         }
-        else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndAfter );
+        else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndInsertAfter );
     }
 
       /* Send WM_NCCALCSIZE message to get new client area */
@@ -952,7 +962,10 @@
       /* And last, send the WM_WINDOWPOSCHANGED message */
 
     if (!(winpos->flags & SWP_NOSENDCHANGING))
-        SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winpos );
+        SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGED, 0,
+                     USER_HEAP_SEG_ADDR(hWinPos) );
+
+    USER_HEAP_FREE( hWinPos );
     return TRUE;
 }
 
@@ -966,10 +979,9 @@
     DWP *pDWP;
 
     if (count <= 0) return 0;
-    handle = USER_HEAP_ALLOC( GMEM_MOVEABLE,
-                              sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
+    handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
     if (!handle) return 0;
-    pDWP = (DWP *) USER_HEAP_ADDR( handle );
+    pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
     pDWP->actualCount    = 0;
     pDWP->suggestedCount = count;
     pDWP->valid          = TRUE;
@@ -989,7 +1001,7 @@
     int i;
     HDWP newhdwp = hdwp;
 
-    pDWP = (DWP *) USER_HEAP_ADDR( hdwp );
+    pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
     if (!pDWP) return 0;
 
       /* All the windows of a DeferWindowPos() must have the same parent */
@@ -1032,9 +1044,9 @@
     if (pDWP->actualCount >= pDWP->suggestedCount)
     {
         newhdwp = USER_HEAP_REALLOC( hdwp,
-                      sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS), 0);
+                      sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
         if (!newhdwp) return 0;
-        pDWP = (DWP *) USER_HEAP_ADDR( newhdwp );
+        pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
         pDWP->suggestedCount++;
     }
     pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
@@ -1055,14 +1067,17 @@
 BOOL EndDeferWindowPos( HDWP hdwp )
 {
     DWP *pDWP;
+    WINDOWPOS *winpos;
     BOOL res = TRUE;
     int i;
 
-    pDWP = (DWP *) USER_HEAP_ADDR( hdwp );
+    pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
     if (!pDWP) return FALSE;
-    for (i = 0; i < pDWP->actualCount; i++)
+    for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
     {
-        if (!(res = WINPOS_InternalSetWindowPos( &pDWP->winPos[i] ))) break;
+        if (!(res = SetWindowPos( winpos->hwnd, winpos->hwndInsertAfter,
+                                  winpos->x, winpos->y, winpos->cx, winpos->cy,
+                                  winpos->flags ))) break;
     }
     USER_HEAP_FREE( hdwp );
     return res;
@@ -1070,22 +1085,6 @@
 
 
 /***********************************************************************
- *           SetWindowPos   (USER.232)
- */
-BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
-		   INT cx, INT cy, WORD flags )
-{
-    HDWP hdwp;
-
-    dprintf_win(stddeb, "SetWindowPos: %04X %d %d,%d %dx%d 0x%x\n",
-            hwnd, hwndInsertAfter, x, y, cx, cy, flags );
-    if (!(hdwp = BeginDeferWindowPos( 1 ))) return FALSE;
-    if (!(hdwp = DeferWindowPos( hdwp, hwnd, hwndInsertAfter,
-                                 x, y, cx, cy, flags ))) return FALSE;
-    return EndDeferWindowPos( hdwp );
-}
-
-/***********************************************************************
  *           TileChildWindows   (USER.199)
  */
 void TileChildWindows( HWND parent, WORD action )