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/misc/atom.c b/misc/atom.c
index d6fa988..f22d99e 100644
--- a/misc/atom.c
+++ b/misc/atom.c
@@ -1,7 +1,7 @@
 /*
  * Atom table functions
  *
- * Copyright 1993 Alexandre Julliard
+ * Copyright 1993, 1994, 1995 Alexandre Julliard
  */
 
 /*
@@ -28,73 +28,76 @@
 #include <string.h>
 #include <ctype.h>
 
-#include "user.h"
 #include "atom.h"
-#include "prototypes.h"
-#ifndef WINELIB
-#include "heap.h"
-#endif
+#include "instance.h"
+#include "ldt.h"
+#include "stackframe.h"
+#include "user.h"
 
 #define DEFAULT_ATOMTABLE_SIZE    37
 #define MIN_STR_ATOM              0xc000
 
-#ifdef WINELIB
-#define ATOMTOHANDLE
-#define HANDLETOATOM
-#else
 #define ATOMTOHANDLE(atom)        ((HANDLE)(atom) << 2)
 #define HANDLETOATOM(handle)      ((ATOM)(0xc000 | ((handle) >> 2)))
-#endif
 
-#ifdef WINELIB
-static ATOMTABLE * localTable = NULL;
-#undef LOCALATOMTABLE
-#define LOCALATOMTABLE() &localTable
-#endif
+#define HAS_ATOM_TABLE(sel)  \
+          ((INSTANCEDATA*)PTR_SEG_OFF_TO_LIN(sel,0))->atomtable != 0)
 
-static ATOMTABLE * globalTable = NULL;
+#define GET_ATOM_TABLE(sel)  ((ATOMTABLE*)PTR_SEG_OFF_TO_LIN(sel, \
+          ((INSTANCEDATA*)PTR_SEG_OFF_TO_LIN(sel,0))->atomtable))
 
 
 /***********************************************************************
  *           ATOM_InitTable
  */
-static BOOL ATOM_InitTable( ATOMTABLE ** table, WORD entries )
+static WORD ATOM_InitTable( WORD selector, WORD entries )
 {
     int i;
     HANDLE handle;
+    ATOMTABLE *table;
 
-    if (table == &globalTable)
-    {
-	handle = USER_HEAP_ALLOC(LMEM_MOVEABLE, sizeof(ATOMTABLE) +
-				 (entries-1) * sizeof(HANDLE) );
-	if (!handle) 
-	    return FALSE;
-	*table = (ATOMTABLE *) USER_HEAP_ADDR( handle );
-    }
-    else
-    {
-	handle = (HANDLE) LocalAlign ( LMEM_MOVEABLE, sizeof(ATOMTABLE) +
-			     (entries-1) * sizeof(HANDLE) );
-	if (!handle) 
-	    return FALSE;
-	*table = (ATOMTABLE *) LocalLock( handle );
-    }
-    
-    (*table)->size = entries;
-    for (i = 0; i < entries; i++) 
-	(*table)->entries[i] = 0;
-    return TRUE;
-    
+      /* Allocate the table */
+
+    handle = LOCAL_Alloc( selector, LMEM_FIXED,
+                          sizeof(ATOMTABLE) + (entries-1) * sizeof(HANDLE) );
+    if (!handle) return 0;
+    table = (ATOMTABLE *)PTR_SEG_OFF_TO_LIN( selector, handle );
+    table->size = entries;
+    for (i = 0; i < entries; i++) table->entries[i] = 0;
+
+      /* Store a pointer to the table in the instance data */
+
+    ((INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( selector, 0 ))->atomtable = handle;
+    return handle;
 }
 
+
 /***********************************************************************
  *           ATOM_Init
  *
  * Global table initialisation.
  */
-BOOL ATOM_Init()
+WORD ATOM_Init()
 {
-    return ATOM_InitTable( &globalTable, DEFAULT_ATOMTABLE_SIZE );
+    return ATOM_InitTable( USER_HeapSel, DEFAULT_ATOMTABLE_SIZE );
+}
+
+
+/***********************************************************************
+ *           ATOM_GetTable
+ *
+ * Return a pointer to the atom table of a given segment, creating
+ * it if necessary.
+ */
+static ATOMTABLE * ATOM_GetTable( WORD selector, BOOL create )
+{
+    INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( selector, 0 );
+    if (!ptr->atomtable)
+    {
+        if (!create) return NULL;
+        if (!ATOM_InitTable( selector, DEFAULT_ATOMTABLE_SIZE )) return NULL;
+    }
+    return (ATOMTABLE *)((char *)ptr + ptr->atomtable);
 }
 
 
@@ -102,15 +105,10 @@
  *           ATOM_MakePtr
  *
  * Make an ATOMENTRY pointer from a handle (obtained from GetAtomHandle()).
- * Is is assumed that the atom is in the same segment as the table.
  */
-static ATOMENTRY * ATOM_MakePtr( ATOMTABLE * table, HANDLE handle )
+static ATOMENTRY * ATOM_MakePtr( WORD selector, HANDLE handle )
 {
-#ifdef WINELIB
-    return (ATOMENTRY *) LocalLock (handle);
-#else
-    return (ATOMENTRY *) (((int)table & 0xffff0000) | (int)handle);
-#endif
+    return (ATOMENTRY *)PTR_SEG_OFF_TO_LIN( selector, handle );
 }
 
 
@@ -129,11 +127,12 @@
 /***********************************************************************
  *           ATOM_AddAtom
  */
-static ATOM ATOM_AddAtom( ATOMTABLE * table, LPCSTR str )
+static ATOM ATOM_AddAtom( WORD selector, LPCSTR str )
 {
     WORD hash;
     HANDLE entry;
     ATOMENTRY * entryPtr;
+    ATOMTABLE * table;
     int len;
     
     if ((len = strlen( str )) > 255) len = 255;
@@ -142,11 +141,12 @@
 /*    if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */
     if (str[0] == '#') return atoi( &str[1] );
 
+    if (!(table = ATOM_GetTable( selector, TRUE ))) return 0;
     hash = ATOM_Hash( table->size, str, len );
     entry = table->entries[hash];
     while (entry)
     {
-	entryPtr = ATOM_MakePtr( table, entry );
+	entryPtr = ATOM_MakePtr( selector, entry );
 	if ((entryPtr->length == len) && 
 	    (!strncasecmp( entryPtr->str, str, len )))
 	{
@@ -156,19 +156,9 @@
 	entry = entryPtr->next;
     }
 
-    if (table == globalTable)
-    {
-	entry = (int) USER_HEAP_ALLOC(LMEM_MOVEABLE, 
-				      sizeof(ATOMENTRY)+len-1 ) & 0xffff;
-    }
-    else
-    {
-	entry = (int) LocalAlign(LMEM_MOVEABLE, 
-				 sizeof(ATOMENTRY)+len-1 ) & 0xffff;
-    }
-    
+    entry = LOCAL_Alloc( selector, LMEM_FIXED, sizeof(ATOMENTRY)+len-1 );
     if (!entry) return 0;
-    entryPtr = ATOM_MakePtr( table, entry );
+    entryPtr = ATOM_MakePtr( selector, entry );
     entryPtr->next = table->entries[hash];
     entryPtr->refCount = 1;
     entryPtr->length = len;
@@ -181,23 +171,25 @@
 /***********************************************************************
  *           ATOM_DeleteAtom
  */
-static ATOM ATOM_DeleteAtom( ATOMTABLE * table, ATOM atom )
+static ATOM ATOM_DeleteAtom( WORD selector, ATOM atom )
 {
     ATOMENTRY * entryPtr;
+    ATOMTABLE * table;
     HANDLE entry, *prevEntry;
     WORD hash;
     
     if (atom < MIN_STR_ATOM) return 0;  /* Integer atom */
 
+    if (!(table = ATOM_GetTable( selector, FALSE ))) return 0;
     entry = ATOMTOHANDLE( atom );
-    entryPtr = ATOM_MakePtr( table, entry );
+    entryPtr = ATOM_MakePtr( selector, entry );
 
       /* Find previous atom */
     hash = ATOM_Hash( table->size, entryPtr->str, entryPtr->length );
     prevEntry = &table->entries[hash];
     while (*prevEntry && *prevEntry != entry)
     {
-	ATOMENTRY * prevEntryPtr = ATOM_MakePtr( table, *prevEntry );
+	ATOMENTRY * prevEntryPtr = ATOM_MakePtr( selector, *prevEntry );
 	prevEntry = &prevEntryPtr->next;
     }    
     if (!*prevEntry) return atom;
@@ -205,11 +197,8 @@
       /* Delete atom */
     if (--entryPtr->refCount == 0)
     {
-	*prevEntry = entryPtr->next;	
-	if (table == globalTable)
-	    USER_HEAP_FREE(entry);
-	else
-	    LocalFree( entry );
+	*prevEntry = entryPtr->next;
+        LOCAL_Free( selector, entry );
     }    
     return 0;
 }
@@ -218,8 +207,9 @@
 /***********************************************************************
  *           ATOM_FindAtom
  */
-static ATOM ATOM_FindAtom( ATOMTABLE * table, LPCSTR str )
+static ATOM ATOM_FindAtom( WORD selector, LPCSTR str )
 {
+    ATOMTABLE * table;
     WORD hash;
     HANDLE entry;
     int len;
@@ -230,11 +220,12 @@
 /*    if (!((int)str & 0xffff0000)) return (ATOM)((int)str & 0xffff); */
     if (str[0] == '#') return atoi( &str[1] );
 
+    if (!(table = ATOM_GetTable( selector, FALSE ))) return 0;
     hash = ATOM_Hash( table->size, str, len );
     entry = table->entries[hash];
     while (entry)
     {
-	ATOMENTRY * entryPtr = ATOM_MakePtr( table, entry );
+	ATOMENTRY * entryPtr = ATOM_MakePtr( selector, entry );
 	if ((entryPtr->length == len) && 
 	    (!strncasecmp( entryPtr->str, str, len )))
 	    return HANDLETOATOM( entry );
@@ -247,9 +238,10 @@
 /***********************************************************************
  *           ATOM_GetAtomName
  */
-static WORD ATOM_GetAtomName( ATOMTABLE * table, ATOM atom,
-			      LPSTR buffer, short count )
+static WORD ATOM_GetAtomName( WORD selector, ATOM atom,
+                              LPSTR buffer, short count )
 {
+    ATOMTABLE * table;
     ATOMENTRY * entryPtr;
     HANDLE entry;
     char * strPtr;
@@ -265,8 +257,9 @@
     }
     else
     {
+        if (!(table = ATOM_GetTable( selector, FALSE ))) return 0;
 	entry = ATOMTOHANDLE( atom );
-	entryPtr = ATOM_MakePtr( table, entry );
+	entryPtr = ATOM_MakePtr( selector, entry );
 	len = entryPtr->length;
 	strPtr = entryPtr->str;
     }
@@ -280,9 +273,9 @@
 /***********************************************************************
  *           InitAtomTable   (KERNEL.68)
  */
-BOOL InitAtomTable( WORD entries )
+WORD InitAtomTable( WORD entries )
 {
-    return ATOM_InitTable( LOCALATOMTABLE(), entries );
+    return ATOM_InitTable( CURRENT_DS, entries );
 }
 
 
@@ -301,8 +294,7 @@
  */
 ATOM AddAtom( LPCSTR str )
 {
-    if (!*LOCALATOMTABLE()) InitAtomTable( DEFAULT_ATOMTABLE_SIZE );
-    return ATOM_AddAtom( *LOCALATOMTABLE(), str );
+    return ATOM_AddAtom( CURRENT_DS, str );
 }
 
 
@@ -311,8 +303,7 @@
  */
 ATOM DeleteAtom( ATOM atom )
 {
-    if (!*LOCALATOMTABLE()) InitAtomTable( DEFAULT_ATOMTABLE_SIZE );
-    return ATOM_DeleteAtom( *LOCALATOMTABLE(), atom );
+    return ATOM_DeleteAtom( CURRENT_DS, atom );
 }
 
 
@@ -321,9 +312,7 @@
  */
 ATOM FindAtom( LPCSTR str )
 {
-    if (!*LOCALATOMTABLE()) return 0;
-    /* if (!*LOCALATOMTABLE()) InitAtomTable( DEFAULT_ATOMTABLE_SIZE );*/
-    return ATOM_FindAtom( *LOCALATOMTABLE(), str );
+    return ATOM_FindAtom( CURRENT_DS, str );
 }
 
 
@@ -332,8 +321,7 @@
  */
 WORD GetAtomName( ATOM atom, LPSTR buffer, short count )
 {
-    if (!*LOCALATOMTABLE()) InitAtomTable( DEFAULT_ATOMTABLE_SIZE );
-    return ATOM_GetAtomName( *LOCALATOMTABLE(), atom, buffer, count );
+    return ATOM_GetAtomName( CURRENT_DS, atom, buffer, count );
 }
 
 
@@ -342,7 +330,7 @@
  */
 ATOM GlobalAddAtom( LPCSTR str )
 {
-    return ATOM_AddAtom( globalTable, str );
+    return ATOM_AddAtom( USER_HeapSel, str );
 }
 
 
@@ -351,7 +339,7 @@
  */
 ATOM GlobalDeleteAtom( ATOM atom )
 {
-    return ATOM_DeleteAtom( globalTable, atom );
+    return ATOM_DeleteAtom( USER_HeapSel, atom );
 }
 
 
@@ -360,7 +348,7 @@
  */
 ATOM GlobalFindAtom( LPCSTR str )
 {
-    return ATOM_FindAtom( globalTable, str );
+    return ATOM_FindAtom( USER_HeapSel, str );
 }
 
 
@@ -369,5 +357,5 @@
  */
 WORD GlobalGetAtomName( ATOM atom, LPSTR buffer, short count )
 {
-    return ATOM_GetAtomName( globalTable, atom, buffer, count );
+    return ATOM_GetAtomName( USER_HeapSel, atom, buffer, count );
 }
diff --git a/misc/clipboard.c b/misc/clipboard.c
index 51fefde..e11c4a8 100644
--- a/misc/clipboard.c
+++ b/misc/clipboard.c
@@ -14,7 +14,6 @@
 #include <unistd.h>
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
-#include "heap.h"
 #include "win.h"
 #include "message.h"
 #include "clipboard.h"
diff --git a/misc/commdlg.c b/misc/commdlg.c
index abf119f..1b6cd82 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -2,8 +2,7 @@
  * COMMDLG functions
  *
  * Copyright 1994 Martin Ayotte
-static char Copyright[] = "Copyright  Martin Ayotte, 1994";
-*/
+ */
 
 /*
 #define DEBUG_OPENDLG
@@ -18,7 +17,6 @@
 #include "user.h"
 #include "message.h"
 #include "library.h"
-#include "heap.h"
 #include "commdlg.h"
 #include "dlgs.h"
 
@@ -65,8 +63,8 @@
 	if (lpofn == NULL) return FALSE;
 	printf("GetOpenFileName // Flags=%08lX !\n", lpofn->Flags);
 	printf("GetOpenFileName // nMaxFile=%ld lpstrFile='%s' !\n", 
-						lpofn->nMaxFile, lpofn->lpstrFile);
-	printf("GetOpenFileName // lpstrInitialDir='%s' !\n", lpofn->lpstrInitialDir);
+						lpofn->nMaxFile, PTR_SEG_TO_LIN(lpofn->lpstrFile));
+	printf("GetOpenFileName // lpstrInitialDir='%s' !\n", PTR_SEG_TO_LIN(lpofn->lpstrInitialDir));
 	printf("GetOpenFileName // lpstrFilter=%p !\n", lpofn->lpstrFilter);
 	printf("GetOpenFileName // nFilterIndex=%ld !\n", lpofn->nFilterIndex);
 	if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
@@ -75,7 +73,7 @@
 	else {
 		if (lpofn->Flags & OFN_ENABLETEMPLATE) {
 			printf("GetOpenFileName // avant FindResource hInstance=%04X lpTemplateName='%s' !\n", 
-								lpofn->hInstance, lpofn->lpTemplateName);
+								lpofn->hInstance, PTR_SEG_TO_LIN(lpofn->lpTemplateName));
 			hInst = lpofn->hInstance;
 			hResInfo = FindResource(hInst, 
 				(LPSTR)lpofn->lpTemplateName, RT_DIALOG);
@@ -108,7 +106,7 @@
 	lpofn->nFileExtension = strlen(lpofn->lpstrFile) - 3;
 	bRet = TRUE;
 */
-	printf("GetOpenFileName // return lpstrFile='%s' !\n", lpofn->lpstrFile);
+	printf("GetOpenFileName // return lpstrFile='%s' !\n", PTR_SEG_TO_LIN(lpofn->lpstrFile));
 	return bRet;
 }
 
@@ -127,8 +125,8 @@
 	if (lpofn == NULL) return FALSE;
 	printf("GetSaveFileName // Flags=%08lX !\n", lpofn->Flags);
 	printf("GetSaveFileName // nMaxFile=%ld lpstrFile='%s' !\n", 
-						lpofn->nMaxFile, lpofn->lpstrFile);
-	printf("GetSaveFileName // lpstrInitialDir='%s' !\n", lpofn->lpstrInitialDir);
+						lpofn->nMaxFile, PTR_SEG_TO_LIN(lpofn->lpstrFile));
+	printf("GetSaveFileName // lpstrInitialDir='%s' !\n", PTR_SEG_TO_LIN(lpofn->lpstrInitialDir));
 	printf("GetSaveFileName // lpstrFilter=%p !\n", lpofn->lpstrFilter);
 	if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
 		hDlgTmpl = lpofn->hInstance;
@@ -136,7 +134,7 @@
 	else {
 		if (lpofn->Flags & OFN_ENABLETEMPLATE) {
 			printf("GetSaveFileName // avant FindResource lpTemplateName='%s' !\n", 
-												lpofn->lpTemplateName);
+                               PTR_SEG_TO_LIN(lpofn->lpTemplateName));
 			hInst = lpofn->hInstance;
 			hResInfo = FindResource(hInst, 
 				(LPSTR)lpofn->lpTemplateName, RT_DIALOG);
@@ -159,7 +157,7 @@
     wndPtr = WIN_FindWndPtr(lpofn->hwndOwner);
 	bRet = DialogBoxIndirectParam(wndPtr->hInstance, hDlgTmpl, 
 		lpofn->hwndOwner, (WNDPROC)FileSaveDlgProc, (DWORD)lpofn);
-	printf("GetSaveFileName // return lpstrFile='%s' !\n", lpofn->lpstrFile);
+	printf("GetSaveFileName // return lpstrFile='%s' !\n", PTR_SEG_TO_LIN(lpofn->lpstrFile));
 	return bRet;
 }
 
@@ -212,8 +210,8 @@
 			if (!FileDlg_Init(hWnd, lParam)) return TRUE;
 			SendDlgItemMessage(hWnd, cmb1, CB_RESETCONTENT, 0, 0L);
 			lpofn = (LPOPENFILENAME)lParam;
-			ptr = (LPSTR)lpofn->lpstrFilter;
-			strcpy(CurPath, lpofn->lpstrInitialDir);
+			ptr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
+			strcpy(CurPath, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir));
 #ifdef DEBUG_OPENDLG
 			printf("FileOpenDlgProc // lpstrInitialDir='%s' !\n", CurPath);
 #endif
@@ -236,7 +234,7 @@
 			nDrive = 2; 		/* Drive 'C:' */
 			SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, nDrive, 0L);
 			sprintf(str, "%c:\\%s", nDrive + 'A', DOS_GetCurrentDir(nDrive));
-			fspec = OpenDlg_GetFileType(lpofn->lpstrFilter, 
+			fspec = OpenDlg_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), 
 									lpofn->nFilterIndex);
 #ifdef DEBUG_OPENDLG
 			printf("FileOpenDlgProc // WM_INITDIALOG fspec #%d = '%s' !\n", 
@@ -263,7 +261,7 @@
 
     case WM_MEASUREITEM:
 		GetObject(hFolder2, sizeof(BITMAP), (LPSTR)&bm);
-		lpmeasure = (LPMEASUREITEMSTRUCT)lParam;
+		lpmeasure = (LPMEASUREITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
 		lpmeasure->itemHeight = bm.bmHeight;
 #ifdef DEBUG_OPENDLG_DRAW
 		printf("FileOpenDlgProc WM_MEASUREITEM Height=%d !\n", bm.bmHeight);
@@ -275,7 +273,7 @@
 		printf("FileOpenDlgProc // WM_DRAWITEM w=%04X l=%08X\n", wParam, lParam);
 #endif
 		if (lParam == 0L) break;
-		lpdis = (LPDRAWITEMSTRUCT)lParam;
+		lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
 #ifdef DEBUG_OPENDLG_DRAW
 		printf("FileOpenDlgProc // WM_DRAWITEM CtlType=%04X CtlID=%04X \n", 
 									lpdis->CtlType, lpdis->CtlID);
@@ -284,7 +282,7 @@
 			hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 			SelectObject(lpdis->hDC, hBrush);
 			FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
-			ptr = (LPSTR) lpdis->itemData;
+			ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
 			if (ptr == NULL) break;
 			TextOut(lpdis->hDC, lpdis->rcItem.left,	lpdis->rcItem.top, 
 											ptr, strlen(ptr));
@@ -293,7 +291,7 @@
 			hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 			SelectObject(lpdis->hDC, hBrush);
 			FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
-			ptr = (LPSTR) lpdis->itemData;
+			ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
 			if (ptr == NULL) break;
 			if (strcmp(ptr, "[.]") == 0) {
 				hBitmap = hFolder2;
@@ -315,7 +313,7 @@
 			hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 			SelectObject(lpdis->hDC, hBrush);
 			FillRect(lpdis->hDC, &lpdis->rcItem, hBrush);
-			ptr = (LPSTR) lpdis->itemData;
+			ptr = (LPSTR) PTR_SEG_TO_LIN(lpdis->itemData);
 			if (ptr == NULL) break;
 			switch(ptr[2]) {
 				case 'a':
@@ -434,13 +432,13 @@
 				wRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0L);
 				SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, wRet, (DWORD)str);
 				printf("FileOpenDlgProc // IDOK str='%s'\n", str);
-				strcpy(lpofn->lpstrFile, str);
+				strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), str);
 				lpofn->nFileOffset = 0;
-				lpofn->nFileExtension = strlen(lpofn->lpstrFile) - 3;
+				lpofn->nFileExtension = strlen(PTR_SEG_TO_LIN(lpofn->lpstrFile)) - 3;
 				if (lpofn->lpstrFileTitle != NULL) {
 					wRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0L);
 					SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, wRet, (DWORD)str);
-					strcpy(lpofn->lpstrFileTitle, str);
+					strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), str);
 					}
 				EndDialog(hWnd, TRUE);
 				return(TRUE);
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index 8879aa1..f275256 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -189,6 +189,11 @@
          * /windows/word)  Also set the default drive to whatever drive
          * corresponds to the directory we started in.
          */
+
+        for (x=0; x!=MAX_DOS_DRIVES; x++) 
+	  if (DosDrives[x].rootdir != NULL) 
+	    strcpy( DosDrives[x].cwd, "\\" );
+
         getcwd(temp, 254);
         strcat(temp, "/");      /* For DOS_GetDosFileName */
         strcpy(temp, DOS_GetDosFileName(temp));
@@ -292,15 +297,19 @@
 
 int DOS_ValidDrive(int drive)
 {
-    dprintf_dosfs(stddeb,"ValidDrive %c (%d)\n",'A'+drive,drive);
-	if (drive >= MAX_DOS_DRIVES)
-		return 0;
-	if (DosDrives[drive].rootdir == NULL)
-		return 0;
-	if (DosDrives[drive].disabled)
-		return 0;
+        int valid = 1;
 
-	return 1;
+        dprintf_dosfs(stddeb,"ValidDrive %c (%d) -- ",'A'+drive,drive);
+
+	if (drive >= MAX_DOS_DRIVES)
+		valid = 0;
+	if (DosDrives[drive].rootdir == NULL)
+		valid = 0;
+	if (DosDrives[drive].disabled)
+		valid = 0;
+
+        dprintf_dosfs(stddeb, "%s\n", valid ? "Valid" : "Invalid");
+	return valid;
 }
 
 
@@ -321,6 +330,45 @@
 
 
 
+/* Simplify the path in "name" by removing  "//"'s and
+   ".."'s in names like "/usr/bin/../lib/test" */
+void DOS_SimplifyPath(char *name)
+{
+  char *p = name, *q = name, *l = NULL;
+  BOOL changed;
+
+ start:
+  p = name;
+  q = name;
+  while( *p ) {
+    *q++ = *p++;
+    if( ( *p == '/' ) && ( *(p-1) == '/' ) )
+      p++;
+  }
+  *q = 0;
+
+  p = name;
+  q = name;
+  changed = FALSE;
+  while( *p ) {
+    if( (!changed) &&( *p == '/' ) && ( *(p+1) == '.' ) && ( *(p+2) == '.' ) ) {
+      if( l ) {
+	q = l;
+	p += 3;
+        changed = TRUE;
+	continue;
+      }
+    }
+    else if( *p == '/' )
+      l = q;
+    *q++ = *p++;
+  }
+  *q = 0;
+  if( changed)
+    goto start;
+}
+
+
 int DOS_GetDefaultDrive(void)
 {
     dprintf_dosfs(stddeb,"GetDefaultDrive (%c)\n",'A'+CurrentDrive);
@@ -475,18 +523,17 @@
 
 char *DOS_GetCurrentDir(int drive)
 { 
-	/* should return 'WINDOWS\SYSTEM' */
-
 	static char temp[256];
 
 	if (!DOS_ValidDrive(drive)) 
 		return 0;
 	
 	strcpy(temp, DosDrives[drive].cwd);
+	DOS_SimplifyPath( temp );
 	ToDos(temp);
 	ChopOffSlash(temp);
 
-    	dprintf_dosfs(stddeb,"DOS_GetCWD: %c: %s\n",'A'+drive, temp + 1);
+    	dprintf_dosfs(stddeb,"DOS_GetCWD: %c:%s\n", 'A'+drive, temp);
 	return (temp + 1);
 }
 
@@ -512,6 +559,7 @@
 		strcpy(DosDrives[drive].cwd, old);
 		return 0;
 	}
+        DOS_SimplifyPath(DosDrives[drive].cwd);
 	return 1;
 }
 
@@ -570,7 +618,7 @@
             return;
 
         getcwd(temp, 255);
-        if(strncmp(filename, "./", 2))
+        if(!strncmp(filename, "./", 2))
                 strcat(temp, filename + 1);
         else
         {
@@ -770,33 +818,66 @@
 
 static int match(char *filename, char *filemask)
 {
-	int x, masklength = strlen(filemask);
+        char name[12], mask[12];
+        int i;
 
-    	dprintf_dosfs(stddeb, "match: %s, %s\n", filename, filemask);
-	for (x = 0; x != masklength ; x++) {
-/*		printf("(%c%c) ", *filename, filemask[x]); 
-*/
-		if (!*filename)
-			/* stop if EOFname */
-			return 1;
-
-		if (filemask[x] == '?') {
-			/* skip the next char */
-			filename++;
-			continue;
-		}
-
-		if (filemask[x] == '*') {
-			/* skip each char until '.' or EOFname */
-			while (*filename && *filename !='.')
-				filename++;
-			continue;
-		}
-		if (filemask[x] != *filename)
-			return 0;
-
-		filename++;
+        dprintf_dosfs(stddeb, "match: %s, %s\n", filename, filemask);
+ 
+	for( i=0; i<11; i++ ) {
+	  name[i] = ' ';
+	  mask[i] = ' ';
 	}
+	name[11] = 0;
+	mask[11] = 0; 
+ 
+	for( i=0; i<8; i++ )
+	  if( !(*filename) || *filename == '.' )
+  	    break;
+	  else
+            name[i] = toupper( *filename++ );
+        while( *filename && *filename != '.' )
+	  filename++;
+        if( *filename )
+	  filename++;
+        for( i=8; i<11; i++ )
+	  if( !(*filename) )
+	    break;
+	  else
+	    name[i] = toupper( *filename++ );
+
+	for( i=0; i<8; i++ )
+	  if( !(*filemask) || *filemask == '.' )
+	    break;
+	  else if( *filemask == '*' ) {
+	    int j;
+	    for( j=i; j<8; j++ )
+	      mask[j] = '?';
+	    break;
+          }
+	  else
+	    mask[i] = toupper( *filemask++ );
+	while( *filemask && *filemask != '.' )
+	  filemask++;	   
+	if( *filemask )
+	  filemask++;
+	for( i=8; i<11; i++ )
+	  if( !(*filemask) )
+	    break;
+	  else if (*filemask == '*' ) {
+	    int j;
+	    for( j=i; j<11; j++ )
+	      mask[j] = '?';
+	    break;
+	  }
+	  else
+	    mask[i] = toupper( *filemask++ );
+	
+    	dprintf_dosfs(stddeb, "changed to: %s, %s\n", name, mask);
+
+	for( i=0; i<11; i++ )
+	  if( ( name[i] != mask[i] ) && ( mask[i] != '?' ) )
+	    return 0;
+
 	return 1;
 }
 
@@ -809,8 +890,10 @@
 	for (x=0; x != MAX_OPEN_DIRS && DosDirs[x].inuse; x++)
 		;
 
-	if (x == MAX_OPEN_DIRS)
+	if (x == MAX_OPEN_DIRS) {
+		fprintf( stderr, "DOS_opendir(): Too many open directories\n");
 		return NULL;
+	}
 
 	if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL)
 		return NULL;
@@ -832,6 +915,7 @@
 
 	DosDirs[x].inuse = 1;
 	strcpy(DosDirs[x].unixpath, temp);
+        DosDirs[x].entnum = 0;
 
 	if ((DosDirs[x].ds = opendir(temp)) == NULL)
 		return NULL;
@@ -853,6 +937,7 @@
 		if ((d = readdir(de->ds)) == NULL) 
 			return NULL;
 
+                de->entnum++;   /* Increment the directory entry number */
 		strcpy(de->filename, d->d_name);
 		if (d->d_reclen > 12)
 			de->filename[12] = '\0';
diff --git a/misc/exec.c b/misc/exec.c
index df0bee6..7d53906 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -8,7 +8,6 @@
 #include <string.h>
 #include <unistd.h>
 #include "neexe.h"
-#include "segmem.h"
 #include "prototypes.h"
 #include "dlls.h"
 #include "windows.h"
@@ -79,8 +78,8 @@
 	    }
 
 	    ds_reg = wpnt->ne->selector_table[wpnt->ne->
-					  ne_header->auto_data_seg-1].selector;
-	    cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1].selector;
+					  ne_header->auto_data_seg-1];
+	    cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1];
 	    ip_reg = wpnt->ne->ne_header->ip;
 
         dprintf_exec(stddeb, "Initializing %s, cs:ip %04x:%04x, ds %04x\n",
@@ -117,10 +116,10 @@
 	dprintf_exec(stddeb,"StartNewTask() before InitializeLoadedNewDLLs !\n");
 	InitializeLoadedNewDLLs(hInst);
 	dprintf_exec(stddeb,"StartNewTask() before setup register !\n");
-    ds_reg = (wpnt->ne->selector_table[wpnt->ne->ne_header->auto_data_seg-1].selector);
-    cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1].selector;
+    ds_reg = (wpnt->ne->selector_table[wpnt->ne->ne_header->auto_data_seg-1]);
+    cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1];
     ip_reg = wpnt->ne->ne_header->ip;
-    ss_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->ss-1].selector;
+    ss_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->ss-1];
     sp_reg = wpnt->ne->ne_header->sp;
 
 	dprintf_exec(stddeb,"StartNewTask() before CallToInit16() !\n");
diff --git a/misc/file.c b/misc/file.c
index 50cfdcd..2f3aa2f 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -51,6 +51,8 @@
   	return HFILE_ERROR;
   iReadWrite &= 0x000F;
   handle =  open (UnixFileName, iReadWrite);
+  if( ( handle == -1 ) && Options.allowReadOnly )
+    handle = open( UnixFileName, O_RDONLY );
 
   dprintf_file(stddeb, "_lopen: open: %s (handle %d)\n", UnixFileName, handle);
 
@@ -244,11 +246,12 @@
    /* Now we are actually going to open the file. According to Microsoft's
        Knowledge Basis, this is done by calling int 21h, ax=3dh. */    
 
+#if 0
     AX = 0x3d00;
     AL = (AL & 0x0f) | (wStyle & 0x70); /* Handle OF_SHARE_xxx etc. */
     AL = (AL & 0xf0) | (wStyle & 0x03); /* Handle OF_READ etc. */
-    DS = segment (ofs->szPathName);
-    DX = offset (ofs->szPathName);
+    DS = SELECTOROF(ofs->szPathName);
+    DX = OFFSETOF(ofs->szPathName);
   
     OpenExistingFile (context);
 
@@ -259,6 +262,25 @@
       }
 
     return AX;
+#endif
+      /* FIXME: Quick hack to get it to work without calling DOS  --AJ */
+    {
+        int mode, handle;
+        switch(wStyle & 3)
+        {
+            case 0: mode = O_RDONLY; break;
+            case 1: mode = O_WRONLY; break;
+            default: mode = O_RDWR; break;
+        }
+        if ((handle = open(DOS_GetUnixFileName(ofs->szPathName), mode)) == -1)
+        {
+            ofs->nErrCode = 2;  /* not found */
+            return -1;
+        }
+          /* don't bother with locking for now */
+
+        return handle;
+    }
 #endif /*WINELIB*/
 }
 
diff --git a/misc/lstr.c b/misc/lstr.c
index f188dad..41db38d 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -9,7 +9,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 
-#include "regfunc.h"
+#include "ldt.h"
 #include "windows.h"
 
 #define ToUpper(c)	toupper(c)
@@ -18,12 +18,10 @@
 /* Funny to divide them between user and kernel. */
 
 /* KERNEL.89 */
-LPSTR lstrcat(LPSTR target,LPCSTR source)
+SEGPTR lstrcat( SEGPTR target, SEGPTR source )
 {
-#ifdef DEBUG_STRING
-  fprintf(stderr,"lstrcat(%s,%s)\n",target,source);
-#endif
-  return strcat(target,source);
+    strcat( (char *)PTR_SEG_TO_LIN(target), (char *)PTR_SEG_TO_LIN(source) );
+    return target;
 }
 
 /* USER.430 */
@@ -43,15 +41,17 @@
 }
 
 /* KERNEL.88 */
-LPSTR lstrcpy(LPSTR target,LPCSTR source)
+SEGPTR lstrcpy( SEGPTR target, SEGPTR source )
 {
-  return strcpy(target,source);
+    strcpy( (char *)PTR_SEG_TO_LIN(target), (char *)PTR_SEG_TO_LIN(source) );
+    return target;
 }
 
 /* KERNEL.353 */
-LPSTR lstrcpyn(LPSTR target,LPCSTR source,int n)
+SEGPTR lstrcpyn( SEGPTR target, SEGPTR source, WORD n )
 {
-  return strncpy(target,source,n);
+    strncpy((char *)PTR_SEG_TO_LIN(target), (char *)PTR_SEG_TO_LIN(source), n);
+    return target;
 }
 
 /* KERNEL.90 */
@@ -84,29 +84,41 @@
   return islower(ch);
 }
 
-/* AnsiUpper USER.431 */
-LPSTR AnsiUpper(LPSTR strOrChar)
+/***********************************************************************
+ *           AnsiUpper   (USER.431)
+ */
+
+/* 16-bit version */
+SEGPTR WIN16_AnsiUpper( SEGPTR strOrChar )
 {
-	char *s = strOrChar;
   /* I am not sure if the locale stuff works with toupper, but then again 
      I am not sure if the Linux libc locale stuffs works at all */
 
-	/* uppercase only one char if strOrChar < 0x10000 */
-	if(HIWORD((DWORD)strOrChar)) {
-		while (*s) {
-			if (IsCharLower(*s))
-				*s = ToUpper(*s);
-			s++;
-		}
-		return strOrChar;
-	} else
-		if (IsCharLower((int)strOrChar))
-			return (LPSTR) ToUpper((int)strOrChar);
-		else 
-			return (LPSTR) strOrChar;
+    /* uppercase only one char if strOrChar < 0x10000 */
+    if (HIWORD(strOrChar))
+    {
+        char *s = PTR_SEG_TO_LIN(strOrChar);
+        while (*s) *s++ = ToUpper( *s );
+        return strOrChar;
+    }
+    else return (SEGPTR)ToUpper( (int)strOrChar );
 }
 
-/* AnsiUpperBuff USER.437 */
+/* 32-bit version */
+LPSTR AnsiUpper(LPSTR strOrChar)
+{
+    char *s = strOrChar;
+  /* I am not sure if the locale stuff works with toupper, but then again 
+     I am not sure if the Linux libc locale stuffs works at all */
+
+    while (*s) *s++ = ToUpper( *s );
+    return strOrChar;
+}
+
+
+/***********************************************************************
+ *           AnsiUpperBuff   (USER.437)
+ */
 UINT AnsiUpperBuff(LPSTR str,UINT len)
 {
   int i;
@@ -117,29 +129,41 @@
   return i;	
 }
 
-/* AnsiLower USER.432 */
-LPSTR AnsiLower(LPSTR strOrChar)
+/***********************************************************************
+ *           AnsiLower   (USER.432)
+ */
+
+/* 16-bit version */
+SEGPTR WIN16_AnsiLower(SEGPTR strOrChar)
 {
-	char *s = strOrChar;
   /* I am not sure if the locale stuff works with toupper, but then again 
      I am not sure if the Linux libc locale stuffs works at all */
 
-	/* lowercase only one char if strOrChar < 0x10000 */
-	if(HIWORD((DWORD)strOrChar)) {
-		while (*s) {
-			if (IsCharUpper(*s))
-				*s = ToLower(*s);
-			s++;
-		}
-		return strOrChar;
-	} else
-		if (IsCharUpper((int)strOrChar))
-			return (LPSTR) ToLower((int)strOrChar);
-		else 
-			return (LPSTR) strOrChar;
+    /* lowercase only one char if strOrChar < 0x10000 */
+    if (HIWORD(strOrChar))
+    {
+        char *s = PTR_SEG_TO_LIN( strOrChar );
+        while (*s) *s++ = ToLower( *s );
+        return strOrChar;
+    }
+    else return (SEGPTR)ToLower( (int)strOrChar );
 }
 
-/* AnsiLowerBuff USER.438 */
+/* 32-bit version */
+LPSTR AnsiLower(LPSTR strOrChar)
+{
+    char *s = strOrChar;
+  /* I am not sure if the locale stuff works with toupper, but then again 
+     I am not sure if the Linux libc locale stuffs works at all */
+
+    while (*s) *s++ = ToLower( *s );
+    return strOrChar;
+}
+
+
+/***********************************************************************
+ *           AnsiLowerBuff   (USER.438)
+ */
 UINT AnsiLowerBuff(LPSTR str,UINT len)
 {
   int i;
@@ -152,16 +176,17 @@
   return i;	
 }
 
+
 /* AnsiNext USER.472 */
-LPSTR AnsiNext(LPSTR current)
+SEGPTR AnsiNext(SEGPTR current)
 {
-  return (*current)?current+1:current;
+    return (*(char *)PTR_SEG_TO_LIN(current)) ? current + 1 : current;
 }
 
 /* AnsiPrev USER.473 */
-char FAR*  AnsiPrev(/*const*/ char FAR* start,char FAR* current)
+SEGPTR AnsiPrev( SEGPTR start, SEGPTR current)
 {
-  return (current==start)?start:current-1;
+    return (current==start)?start:current-1;
 }
 
 BYTE Oem2Ansi[256], Ansi2Oem[256];
diff --git a/misc/main.c b/misc/main.c
index b817401..b672f44 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -28,7 +28,7 @@
 #include "desktop.h"
 #include "prototypes.h"
 #include "texts.h"
-#include "selectors.h" /* for InitSelectors prototype */
+#include "dlls.h"
 #include "library.h"
 #define DEBUG_DEFINE_VARIABLES
 #include "stddebug.h"
@@ -74,7 +74,8 @@
     FALSE,          /* synchronous */
     FALSE,          /* backing store */
     SW_SHOWNORMAL,  /* cmdShow */
-    FALSE
+    FALSE,
+    FALSE           /* AllowReadOnly */
 };
 
 
@@ -91,7 +92,8 @@
     { "-spy",           ".spy",             XrmoptionSepArg, (caddr_t)NULL },
     { "-debug",         ".debug",           XrmoptionNoArg,  (caddr_t)"on" },
     { "-debugmsg",      ".debugmsg",        XrmoptionSepArg, (caddr_t)NULL },
-    { "-dll",           ".dll",             XrmoptionSepArg, (caddr_t)NULL }
+    { "-dll",           ".dll",             XrmoptionSepArg, (caddr_t)NULL },
+    { "-allowreadonly", ".allowreadonly",   XrmoptionNoArg,  (caddr_t)"on" }
 };
 
 #define NB_OPTIONS  (sizeof(optionsTable) / sizeof(optionsTable[0]))
@@ -112,7 +114,8 @@
   "    -spy file       Turn on message spying to the specified file\n" \
   "    -relaydbg       Obsolete. Use -debugmsg +relay instead\n" \
   "    -debugmsg name  Turn debugging-messages on or off\n" \
-  "    -dll name       Enable or disable built-in DLLs\n"
+  "    -dll name       Enable or disable built-in DLLs\n" \
+  "    -allowreadonly  Read only files may be opened in write mode\n"
 
 
 
@@ -353,6 +356,8 @@
 	Options.backingstore = TRUE;	
     if (MAIN_GetResource( db, ".debug", &value ))
 	Options.debug = TRUE;
+    if (MAIN_GetResource( db, ".allowreadonly", &value ))
+        Options.allowReadOnly = TRUE;
     if (MAIN_GetResource( db, ".spy", &value))
 	Options.spyFilename = value.addr;
     if (MAIN_GetResource( db, ".depth", &value))
@@ -514,7 +519,6 @@
     sync_profiles();
     MAIN_RestoreSetup();
     WSACleanup();
-    CleanupSelectors();
 }
 
 /***********************************************************************
@@ -569,7 +573,6 @@
     if (Options.desktopGeometry) MAIN_CreateDesktop( argc, argv );
     else rootWindow = DefaultRootWindow( display );
 
-    InitSelectors();
     MAIN_SaveSetup();
     DOS_InitFS();
     Comm_Init();
diff --git a/misc/message.c b/misc/message.c
index 0cfbf16..6daf380 100644
--- a/misc/message.c
+++ b/misc/message.c
@@ -15,10 +15,10 @@
 #include <ctype.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include "heap.h"
 #include "library.h"
 #include "win.h"
 #include "texts.h"
+#include "user.h"
 #include "stddebug.h"
 /* #define DEBUG_MSGBOX */
 #include "debug.h"
@@ -30,21 +30,21 @@
 
 ButtonTexts ButtonText = {    /* FIXME: Norwegian Translation missing */
 #if #LANG(De)
-  "&Ja",     'J',
-  "&Nein",   'N',
-  "&Ok",     'O',
-  "&Abbruch",'A',
-  "&Abbruch",'A',
-  "&Wiederholen", 'W',
-  "&Ignorieren", 'I'
+  { "&Ja",     'J' },
+  { "&Nein",   'N' },
+  { "&Ok",     'O' },
+  { "&Abbruch",'A' },
+  { "&Abbruch",'A' },
+  { "&Wiederholen", 'W' },
+  { "&Ignorieren", 'I' }
 #else
-  "&Yes",    'Y',
-  "&No",     'N',
-  "&Ok",     'O',
-  "&Cancel", 'C',
-  "&Abort",  'A',
-  "&Retry",  'R',
-  "&Ignore", 'I'
+  { "&Yes",    'Y' },
+  { "&No",     'N' },
+  { "&Ok",     'O' },
+  { "&Cancel", 'C' },
+  { "&Abort",  'A' },
+  { "&Retry",  'R' },
+  { "&Ignore", 'I' }
 #endif
 };
 
@@ -76,8 +76,9 @@
 	HWND    	hDlg, hWndOld;
 	WND	    	*wndPtr;
 	WNDCLASS  	wndClass;
-	MSG	    	msg;
-    LPMSGBOX 	lpmb;
+	MSG*	    	msg;
+        LPMSGBOX 	lpmb;
+        HANDLE          hClassName, hMsg;
 	DWORD		dwStyle;
 	HINSTANCE	hInst;
 	int			nRet;
@@ -116,24 +117,29 @@
 	wndClass.style           = CS_HREDRAW | CS_VREDRAW ;
 	wndClass.lpfnWndProc     = (WNDPROC)SystemMessageBoxProc;
 	wndClass.cbClsExtra      = 0;
-	wndClass.cbWndExtra      = 0;
+	wndClass.cbWndExtra      = 4;
 	wndClass.hInstance       = hInst;
 	wndClass.hIcon           = (HICON)NULL;
 	wndClass.hCursor         = LoadCursor((HANDLE)NULL, IDC_ARROW); 
 	wndClass.hbrBackground   = GetStockObject(WHITE_BRUSH);
 	wndClass.lpszMenuName    = NULL;
-	wndClass.lpszClassName   = "MESSAGEBOX";
+        hClassName = USER_HEAP_ALLOC( 20 );
+        strcpy( USER_HEAP_LIN_ADDR( hClassName ), "MESSAGEBOX" );
+        hMsg = USER_HEAP_ALLOC( sizeof(MSG) );
+        msg = (MSG *) USER_HEAP_LIN_ADDR( hMsg );
+	wndClass.lpszClassName = (LPSTR)USER_HEAP_SEG_ADDR( hClassName );
 	dprintf_msgbox(stddeb, "MessageBox // before RegisterClass, '%s' '%s' !\n", str, title);
 	if (!RegisterClass(&wndClass)) {
 		printf("Unable to Register class 'MESSAGEBOX' !\n");
 		if (lpmb != NULL) free(lpmb);
 		return 0;
 		}
+        USER_HEAP_FREE( hClassName );
 	dwStyle = WS_POPUP | WS_DLGFRAME | WS_VISIBLE;
 	if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) == 0) dwStyle |= WS_CAPTION;
 	hWndOld = GetFocus();
 	hDlg = CreateWindow("MESSAGEBOX", lpmb->Title, dwStyle, 100, 150, 400, 160,
-				(HWND)NULL, (HMENU)NULL, hInst, (LPSTR)lpmb);
+				(HWND)NULL, (HMENU)NULL, hInst, (SEGPTR)lpmb);
 	if (hDlg == 0) {
 		printf("Unable to create 'MESSAGEBOX' window !\n");
 		if (lpmb != NULL) free(lpmb);
@@ -142,11 +148,12 @@
 	dprintf_msgbox(stddeb, "MessageBox // before Msg Loop !\n");
 	while(TRUE) {
 		if (!lpmb->ActiveFlg) break;
-		if (!GetMessage(&msg, (HWND)NULL, 0, 0)) break;
-		TranslateMessage(&msg);
+		if (!GetMessage( USER_HEAP_SEG_ADDR(hMsg),
+                                 (HWND)NULL, 0, 0)) break;
+		TranslateMessage(msg);
 		if ((type & (MB_SYSTEMMODAL | MB_TASKMODAL)) != 0 &&
-			msg.hwnd != hDlg) {
-			switch(msg.message) {
+			msg->hwnd != hDlg) {
+			switch(msg->message) {
 				case WM_KEYDOWN:
 				case WM_LBUTTONDOWN:
 				case WM_MBUTTONDOWN:
@@ -155,8 +162,9 @@
 					break;
 				}
 			}
-		DispatchMessage(&msg);
+		DispatchMessage(msg);
 		}
+        USER_HEAP_FREE(hMsg);
 	SetFocus(hWndOld);
 	nRet = lpmb->wRetVal;
 	if (lpmb != NULL) free(lpmb);
@@ -175,7 +183,7 @@
     	printf("Bad Window handle on MessageBox !\n");
     	return 0;
     	}
-    lpmb = *((LPMSGBOX *)&wndPtr->wExtra[1]);
+    lpmb = *((LPMSGBOX *)wndPtr->wExtra);
     return lpmb;
 }
 
@@ -196,10 +204,10 @@
 	case WM_CREATE:
 		dprintf_msgbox(stddeb, "MessageBox WM_CREATE hWnd=%04X !\n", hWnd);
 		wndPtr = WIN_FindWndPtr(hWnd);
-		createStruct = (CREATESTRUCT *)lParam;
+		createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
 		lpmb = (LPMSGBOX)createStruct->lpCreateParams;
 		if (lpmb == NULL) break;
-		*((LPMSGBOX *)&wndPtr->wExtra[1]) = lpmb;
+		*((LPMSGBOX *)wndPtr->wExtra) = lpmb;
 		dprintf_msgbox(stddeb, "MessageBox WM_CREATE title='%s' str='%s' !\n", 
 									lpmb->Title, lpmb->Str);
 		GetClientRect(hWnd, &rect);
diff --git a/misc/olecli.c b/misc/olecli.c
index 249801d..8be7034 100644
--- a/misc/olecli.c
+++ b/misc/olecli.c
@@ -33,7 +33,7 @@
  */
 OLESTATUS WINAPI OleRenameClientDoc(LHCLIENTDOC hDoc, LPCSTR newName)
 {
-    dprintf_ole(stdnimp,"OleRenameClientDoc: %d %s\n",hDoc, newName);
+    dprintf_ole(stdnimp,"OleRenameClientDoc: %ld %s\n",hDoc, newName);
     return OLE_OK;
 }
 
@@ -42,6 +42,6 @@
  */
 OLESTATUS WINAPI OleRevokeClientDoc(LHCLIENTDOC hServerDoc)
 {
-    dprintf_ole(stdnimp,"OleRevokeClientDoc:%d\n",hServerDoc);
+    dprintf_ole(stdnimp,"OleRevokeClientDoc:%ld\n",hServerDoc);
     return OLE_OK;
 }
diff --git a/misc/olesvr.c b/misc/olesvr.c
index 73b57dc..53351c2 100644
--- a/misc/olesvr.c
+++ b/misc/olesvr.c
@@ -35,7 +35,7 @@
  */
 OLESTATUS WINAPI OleBlockServer(LHSERVER hServer)
 {
-    fprintf(stdnimp,"OleBlockServer:%d\n",hServer);
+    fprintf(stdnimp,"OleBlockServer:%ld\n",hServer);
     return OLE_OK;
 }
 
@@ -44,7 +44,7 @@
  */
 OLESTATUS WINAPI OleUnblockServer(LHSERVER hServer, BOOL FAR *block)
 {
-    fprintf(stdnimp,"OleUnblockServer:%d\n",hServer);
+    fprintf(stdnimp,"OleUnblockServer:%ld\n",hServer);
     /* no more blocked messages :) */
     *block=FALSE;
     return OLE_OK;
@@ -59,7 +59,7 @@
 	LPOLESERVERDOC document,
 	LHSERVERDOC FAR *hRet)
 {
-    dprintf_ole(stdnimp,"OleRegisterServerDoc:%d,%s\n", hServer, docname);
+    dprintf_ole(stdnimp,"OleRegisterServerDoc:%ld,%s\n", hServer, docname);
     *hRet=++OLE_current_handle;
     return OLE_OK;
 }
@@ -69,7 +69,7 @@
  */
 OLESTATUS WINAPI OleRevokeServerDoc(LHSERVERDOC hServerDoc)
 {
-    dprintf_ole(stdnimp,"OleRevokeServerDoc:%d\n",hServerDoc);
+    dprintf_ole(stdnimp,"OleRevokeServerDoc:%ld\n",hServerDoc);
     return OLE_OK;
 }
 
@@ -78,6 +78,6 @@
  */
 OLESTATUS WINAPI OleRevokeServer(LHSERVER hServer)
 {
-    dprintf_ole(stdnimp,"OleRevokeServer:%d\n",hServer);
+    dprintf_ole(stdnimp,"OleRevokeServer:%ld\n",hServer);
     return OLE_OK;
 }
diff --git a/misc/property.c b/misc/property.c
index 4a93716..e97c3ea 100644
--- a/misc/property.c
+++ b/misc/property.c
@@ -9,7 +9,6 @@
 #include <string.h>
 #include <unistd.h>
 #include "windows.h"
-#include "heap.h"
 #include "win.h"
 #include "callback.h"
 #include "stddebug.h"
diff --git a/misc/shell.c b/misc/shell.c
index c4c4a46..e5c8043 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -48,7 +48,8 @@
       lphTopKey->lpSubKey = TopKeyName;
       lphTopKey->dwType = 0;
       lphTopKey->lpValue = NULL;
-      lphTopKey->lpSubLvl = lphRootKey; lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL;
+      lphTopKey->lpSubLvl = lphRootKey;
+      lphTopKey->lpNextKey = lphTopKey->lpPrevKey = NULL;
 
       dprintf_reg(stddeb,"SHELL_RegCheckForRoot: Root/Top created\n");
     }
@@ -403,7 +404,7 @@
         case WM_INITDIALOG:
 		sprintf(temp, "About %s", AppName);
 		SetWindowText(hWnd, temp);
-		SetDlgItemText(hWnd, 100, AppMisc);
+                SetWindowText(GetDlgItem(hWnd,100), AppMisc );
 		break;
 
         case WM_COMMAND:
diff --git a/misc/user.c b/misc/user.c
index b32b57c..91cc3d9 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -7,9 +7,9 @@
 #include "atom.h"
 #include "gdi.h"
 #include "dlls.h"
-#include "selectors.h"
 #include "sysmetrics.h"
 #include "menu.h"
+#include "dce.h"
 #include "dialog.h"
 #include "syscolor.h"
 #include "win.h"
@@ -17,9 +17,58 @@
 #include "prototypes.h"
 #include "user.h"
 #include "message.h"
+#include "toolhelp.h"
 
 #define USER_HEAP_SIZE          0x10000
-MDESC *USER_Heap = NULL;
+
+LPSTR USER_Heap = NULL;
+WORD USER_HeapSel = 0;
+
+
+/***********************************************************************
+ *           GetFreeSystemResources   (USER.284)
+ */
+WORD GetFreeSystemResources( WORD resType )
+{
+    DWORD user, gdi;
+
+    switch(resType)
+    {
+    case GFSR_USERRESOURCES:
+        user = GetHeapSpaces( USER_HeapSel );
+        gdi  = 0xffffffff;
+        break;
+
+    case GFSR_GDIRESOURCES:
+        gdi  = GetHeapSpaces( GDI_HeapSel );
+        user = 0xffffffff;
+        break;
+
+    case GFSR_SYSTEMRESOURCES:
+        user = GetHeapSpaces( USER_HeapSel );
+        gdi  = GetHeapSpaces( GDI_HeapSel );
+        break;
+
+    default:
+        return 0;
+    }
+    if (user > gdi) return LOWORD(gdi) * 100 / HIWORD(gdi);
+    else return LOWORD(user) * 100 / HIWORD(user);
+}
+
+
+/***********************************************************************
+ *           SystemHeapInfo   (TOOLHELP.71)
+ */
+BOOL SystemHeapInfo( SYSHEAPINFO *pHeapInfo )
+{
+    pHeapInfo->wUserFreePercent = GetFreeSystemResources( GFSR_USERRESOURCES );
+    pHeapInfo->wGDIFreePercent  = GetFreeSystemResources( GFSR_GDIRESOURCES );
+    pHeapInfo->hUserSegment = USER_HeapSel;
+    pHeapInfo->hGDISegment  = GDI_HeapSel;
+    return TRUE;
+}
+
 
 #ifndef WINELIB
 /***********************************************************************
@@ -27,10 +76,9 @@
  */
 static BOOL USER_HeapInit(void)
 {
-    struct segment_descriptor_s * s;
-    s = GetNextSegment( 0, 0x10000 );
-    if (s == NULL) return FALSE;
-    HEAP_Init( &USER_Heap, s->base_addr, USER_HEAP_SIZE );
+    if (!(USER_HeapSel = GlobalAlloc(GMEM_FIXED,USER_HEAP_SIZE))) return FALSE;
+    USER_Heap = GlobalLock( USER_HeapSel );
+    LocalInit( USER_HeapSel, 0, USER_HEAP_SIZE-1 );
     return TRUE;
 }
 #endif
diff --git a/misc/winsocket.c b/misc/winsocket.c
index 5578804..551ac41 100644
--- a/misc/winsocket.c
+++ b/misc/winsocket.c
@@ -19,7 +19,6 @@
 #include <errno.h>
 #include <netdb.h>
 #include <unistd.h>
-#include "heap.h"
 #include "winsock.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -883,7 +882,6 @@
 INT WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData)
 {
     int HeapHandle;
-    MDESC *MyHeap;
 
     dprintf_winsock(stddeb, "WSAStartup: verReq=%x\n", wVersionRequested);
 
@@ -901,9 +899,6 @@
 	return WSASYSNOTREADY;
 
     heap = (struct WinSockHeap *) GlobalLock(HeapHandle);
-#ifndef WINELIB
-    HEAP_Init(&MyHeap, heap, sizeof(struct WinSockHeap));
-#endif
     bcopy(&WINSOCK_data, lpWSAData, sizeof(WINSOCK_data));
 
     /* ipc stuff */