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/ANNOUNCE b/ANNOUNCE
index 7ba5a18..8b5e519 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,16 @@
-This is release 950302 of Wine the MS Windows emulator.  This is still a
+This is release 950319 of Wine the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work.
 
 Patches should be submitted to "wine-new@amscons.com".  Please don't forget
 to include a ChangeLog entry.  I'll make a new release every other Sunday.
 
-WHAT'S NEW with Wine-950302: (see ChangeLog for details)
-	- You now need libXpm to be able to compile.
-	- OLE stubs and run-time option to disable them.
-	- Support for special selectors like __0040H.
+WHAT'S NEW with Wine-950319: (see ChangeLog for details)
+	- New memory management scheme. This will probably cause many
+	  new problems, please report them. I'm particularly interested
+	  to hear how it works for the *BSD people.
+	- Many fixes in file and directory handling.
+	- Handling of additive fixup records.
 	- Lots of bug fixes
 
 See the README file in the distribution for installation instructions.
@@ -17,11 +19,12 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-	sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950302.tar.gz
-	aris.com:/pub/linux/ALPHA/Wine/development/Wine-950302.tar.gz
-	tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950302.tar.gz
-	ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950302.tar.gz
-	ftp.wonderland.org:/Wine/Wine-950302.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950319.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950319.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950319.tar.gz
+    ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950319.tar.gz
+
+It should also be available from any site that mirrors tsx-11 or sunsite.
 
 If you submitted a patch, please check to make sure it has been
 included in the new release.
diff --git a/ChangeLog b/ChangeLog
index f2fa6a3..1f66b98 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,103 @@
 ----------------------------------------------------------------------
+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.
+
+----------------------------------------------------------------------
 Thu Mar  2 17:44:32 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)
 
 	* [loader/resource.c] [objects/oembitmap.c]
diff --git a/Configure b/Configure
index cbbadd1..b1b4a6d 100644
--- a/Configure
+++ b/Configure
@@ -194,11 +194,6 @@
 	fi
 fi
 
-if grep -s seg_not_present /usr/include/linux/ldt.h 2> /dev/null
-then
-	ALLDEFINES="$ALLDEFINES -DNEW_LDT_STRUCT"
-fi
-
 cat > autoconf.h << EOF
 /* autoconf.h generated automatically.  Run Configure. */
 $WINELIB
diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS
index b090fea..96e1713 100644
--- a/DEVELOPERS-HINTS
+++ b/DEVELOPERS-HINTS
@@ -1,54 +1,45 @@
-This is intend to be a document to help new developers get started.
+This is intended to be a document to help new developers get started.
 Existing developers should feel free to add their comments.
 
 MEMORY AND SEGMENTS:
 
 NE (Win16) executables consist of multiple segments.  The Wine loader
-loads each segment into a unique location the Wine processes memory
-and assigns a selector to that segment.  To make address conversion
-simpler, Wine loads the segments in such a way that the segmented
-address (16:16) is stored in memory the same way as the 32-bit linear
-address.  For example, the segmented address 1237:89AB can be at the
-address 0x123789AB in the Wine process space.
+loads each segment into a unique location in the Wine processes memory
+and assigns a selector to that segment.  Because of this, it's not
+possible to exchange addresses freely between 16-bit and 32-bit code.
+Addresses used by 16-bit code are segmented addresses (16:16), formed
+by a 16-bit selector and a 16-bit offset.  Those used by the Wine code
+are regular 32-bit linear addresses.
 
-This also implies that a Win16 program cannot access any arbitrary
-memory location.  If a pointer needs to be returned to a Win16 program,
-then the memory block must be allocated using either GlobalAlloc()
-or HEAP_Alloc().  The HEAP_* functions are faster than the Global*
-functions but are only capable of managing a 64k memory block.  The
-HEAP_* functions are used to implement local heaps.  Wine should
-never call Local* functions.  These functions are reserved for use
-by Win16 programs only!
+There's three ways to obtain a segmented pointer:
+  - Allocate a block of memory from the global heap and use
+    WIN16_GlobalLock to get its segmented address.
+  - Allocate a block of memory from a local heap, and build the
+    segmented address from the local heap selector (see the
+    USER_HEAP_* macros for an example of this).
+  - Declare the argument as 'segptr' instead of 'ptr' in the spec file
+    for a given API function.
 
-The following code fragment should be used to establish a new Wine
-local heap:
+Once you have a segmented pointer, it must be converted to a linear
+pointer before you can use it from 32-bit code.  This can be done with
+the PTR_SEG_TO_LIN() and PTR_SEG_OFF_TO_LIN() macros.  The linear
+pointer can then be used freely with standard Unix functions like
+memcpy() etc. without worrying about 64k boundaries.  Note: there's no
+easy way to convert back from a linear to a segmented address.
 
-	#include "heap.h"
+In most cases, you don't need to worry about segmented address, as the
+conversion is made automatically by the callback code and the API
+functions only see linear addresses. However, in some cases it is
+necessary to manipulate segmented addresses; the most frequent cases
+are:
+  - API functions that return a pointer
+  - lParam of Windows messages that point to a structure
+  - Pointers contained inside structures accessed by 16-bit code.
 
-	#define MY_HEAP_SIZE	0x10000		/* Must be <= 64k */
-
-	int MyHeapHandle;
-	void *MyHeapBase;
-	MDESC *MyHeap;
-
-		...
-
-	int InitMyHeap()
-	{
-	    MyHeapHandle = GlobalAlloc(GMEM_FIXED, MY_HEAP_SIZE);
-	    if (MyHeapHandle == 0)
-		return -1;
-	    MyHeapBase = GlobalLock(MyHeapHandle);
-	    HEAP_Init(&MyHeap, MyHeapBase, MY_HEAP_SIZE);
-	    return 0;
-	}
-
-Memory blocks greater than 64 kilobytes in length must be allocated
-using GlobalAlloc().  Because of our special memory mapping, GlobalLock()
-cannot be used to obtain the address of a linearly accessible memory
-block that is greater than 64kB in length.  Instead GlobalLinearLock()
-should be used.  The inverse function GlobalLinearUnlock() must be 
-called before the block can be freed with GlobalFree().
+It is usually a good practice to used the type 'SEGPTR' for segmented
+pointers, instead of something like 'LPSTR' or 'char *'.  As SEGPTR is
+defined as a DWORD, you'll get a compilation warning if you mistakenly
+use it as a regular 32-bit pointer.
 
 API ENTRY POINTS:
 
@@ -69,7 +60,7 @@
 REGISTER FUNCTIONS:
 
 Some functions are defined as type "register" in the DLL specification files.
-Inorder to return values in the registers to the WIN16 program, the handler
+In order to return values in the registers to the WIN16 program, the handler
 function must exit by calling ReturnFromRegisterFunc().  Look at the function
 DOS3Call() for an example of how this works.
 
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index a207fa7..8d53b91 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -5,8 +5,8 @@
 primary source of information to developers is the ChangeLog (next to
 the source, of course).
 
-1. make: No rule to make target xxx/xxx.o. Stop.
-This frequently happens when a prior attempt to make xxx.o failed.
+1. make: No rule to make target foo/foo.o. Stop.
+This frequently happens when a prior attempt to make foo.o failed.
 In the current setup, make does not terminate then, but continues and
 realises the problem later on. 'make' again and watch the output. Be
 sure to analyze the problem before you report it to the newsgroup.
@@ -26,4 +26,8 @@
 debugging, feel free to add it.
 Config file: Sets the Wine environment. See README for details.
 
+3. BAR.EXE used to work, but does not work anymore
+Look at the ChangeLog to see what files have been changed. Try to undo
+the particular patch and go partially back to the previous version. If
+you have any suspicions, report them to the author or to the newsgroup.
 
diff --git a/controls/button.c b/controls/button.c
index 32b8fed..f15d5ff 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -180,7 +180,7 @@
                 break;
 
         case WM_SETTEXT:
-		DEFWND_SetText( hWnd, (LPSTR)lParam );
+		DEFWND_SetText( hWnd, (LPSTR)PTR_SEG_TO_LIN(lParam) );
                 PAINT_BUTTON( hWnd, style, ODA_DRAWENTIRE );
 		return 0;
 
@@ -306,7 +306,7 @@
     else GRAPH_DrawReliefRect( hDC, &rc, 2, 2, FALSE );
     
     /* draw button label, if any: */
-    text = USER_HEAP_ADDR( wndPtr->hText );
+    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
     if (text[0])
     {
         SetTextColor( hDC, (wndPtr->dwStyle & WS_DISABLED) ?
@@ -356,7 +356,7 @@
 
     GetTextMetrics(hDC, &tm);
     delta = (rc.bottom - rc.top - tm.tmHeight) >> 1;
-    text = USER_HEAP_ADDR( wndPtr->hText );
+    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
     textlen = strlen( text );
 
       /* Draw the check-box bitmap */
@@ -433,7 +433,7 @@
     LineTo( hDC, rc.left, rc.bottom-1 );
     LineTo( hDC, rc.left, rc.top+2 );
 
-    text = USER_HEAP_ADDR( wndPtr->hText );
+    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
     GetTextExtentPoint(hDC, text, strlen(text), &size);
     rc.left  += 10;
     rc.right  = rc.left + size.cx + 1;
@@ -481,9 +481,8 @@
     WND *wndPtr = WIN_FindWndPtr( hWnd );
     BUTTONINFO *infoPtr = (BUTTONINFO *)wndPtr->wExtra;
 
-    if (!(hDis = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT))))
-        return;
-    lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_ADDR(hDis);
+    if (!(hDis = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) ))) return;
+    lpdis = (LPDRAWITEMSTRUCT)USER_HEAP_LIN_ADDR(hDis);
     lpdis->CtlType    = ODT_BUTTON;
     lpdis->CtlID      = wndPtr->wIDmenu;
     lpdis->itemID     = 0;
@@ -495,7 +494,7 @@
     lpdis->hDC        = hDC;
     GetClientRect( hWnd, &lpdis->rcItem );
     lpdis->itemData   = 0;
-    SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, (LPARAM)lpdis); 
+    SendMessage(GetParent(hWnd), WM_DRAWITEM, 1, USER_HEAP_SEG_ADDR(hDis) );
     USER_HEAP_FREE(hDis);
 }
 
diff --git a/controls/combo.c b/controls/combo.c
index 34cece2..f61d8e4 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -14,7 +14,6 @@
 #include "windows.h"
 #include "combo.h"
 #include "user.h"
-#include "heap.h"
 #include "win.h"
 #include "stddebug.h"
 /* #define DEBUG_COMBO */
@@ -40,10 +39,11 @@
 	LPHEADCOMBO lphc;
 	HDC		hDC;
 	BITMAP	bm;
-	char	str[128];
 	PAINTSTRUCT paintstruct;
 	LPDRAWITEMSTRUCT lpdis;
 	DWORD       dwStyle;
+        HANDLE hStr;
+
 	switch(message) {
 		case WM_CREATE:
 			wndPtr = WIN_FindWndPtr(hwnd);
@@ -95,7 +95,7 @@
 			lphc->hWndLBox = CreateWindow("LISTBOX", "", dwStyle,
 				rect.left, rect.top + bm.bmHeight,
 				width, height, wndPtr->hwndParent, 0,
-				wndPtr->hInstance, (LPSTR)MAKELONG(0, hwnd));
+				wndPtr->hInstance, (SEGPTR)MAKELONG(0, hwnd));
 			ShowWindow(lphc->hWndLBox, SW_HIDE);
 			dprintf_combo(stddeb,"Combo Creation LBox=%X!\n", lphc->hWndLBox);
 			return 0;
@@ -126,15 +126,16 @@
 		lphc = ComboGetStorageHeader(hwnd);
 		if (lphc == NULL || wndPtr == NULL) return 0;
 		if (LOWORD(lParam) == lphc->hWndLBox) {
+                    hStr = USER_HEAP_ALLOC( 256 );
 			switch(HIWORD(lParam)) {
 				case LBN_SELCHANGE:
 					lphc->dwState = lphc->dwState & (CB_SHOWDROPDOWN ^ 0xFFFFFFFFL);
 					ShowWindow(lphc->hWndLBox, SW_HIDE);
 					y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 					if (y != LB_ERR) {
-						SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
+						SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 						if (lphc->hWndEdit != 0) 
-							SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+							SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 						else {
 							InvalidateRect(hwnd, NULL, TRUE);
 							UpdateWindow(hwnd);
@@ -148,6 +149,7 @@
 										MAKELONG(hwnd, CBN_DBLCLK));
 					break;
 	        	}
+                    USER_HEAP_FREE( hStr );
             }
 		break;
     case WM_LBUTTONDOWN:
@@ -174,9 +176,11 @@
 			dprintf_combo(stddeb,"before Combo List GetCurSel !\n");
 			y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 			if (y != LB_ERR) {
+                                hStr = USER_HEAP_ALLOC( 256 );
 				dprintf_combo(stddeb,"before Combo List GetText !\n");
-				SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+				SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+                                USER_HEAP_FREE( hStr );
 				}
 			dprintf_combo(stddeb,"End of Combo List Hide !\n");
 			}
@@ -211,9 +215,11 @@
 				ShowWindow(lphc->hWndLBox, SW_HIDE);
 				y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 				if (y != LB_ERR) {
-					SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
+                                        hStr = USER_HEAP_ALLOC( 256 );
+					SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 					if (lphc->hWndEdit != 0) 
-						SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+						SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+                                        USER_HEAP_FREE( hStr );
 					}
 				}
 		    }
@@ -236,11 +242,13 @@
 			if (y >= count) y = count - 1;
 			lphc->LastSel = y;
 			SendMessage(lphc->hWndLBox, LB_SETCURSEL, y, 0L);
-			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
+                        hStr = USER_HEAP_ALLOC( 256 );
+			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 			if (lphc->hWndEdit != 0) 
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
 			SendMessage(GetParent(hwnd), WM_COMMAND, wndPtr->wIDmenu,
 			MAKELONG(hwnd, CBN_SELCHANGE));
+                        USER_HEAP_FREE( hStr );
 			}
 		break;
     case WM_MEASUREITEM:
@@ -258,7 +266,7 @@
 		dprintf_combo(stddeb,"ComboBoxWndProc // WM_DRAWITEM w=%04X l=%08lX\n", wParam, lParam);
 		wndPtr = WIN_FindWndPtr(hwnd);
 		if (wndPtr == NULL) break;
-		lpdis = (LPDRAWITEMSTRUCT)lParam;
+		lpdis = (LPDRAWITEMSTRUCT)PTR_SEG_TO_LIN(lParam);
 		if (lpdis == NULL) break;
 		lpdis->CtlType = ODT_COMBOBOX;
 		lpdis->CtlID = wndPtr->wIDmenu;
@@ -299,13 +307,15 @@
 		ShowWindow(lphc->hWndLBox, SW_HIDE);
 		y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 		if (y != LB_ERR) {
-			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, (LPARAM)str);
-			if (lphc->hWndEdit != 0)
-				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, (LPARAM)str);
+                        hStr = USER_HEAP_ALLOC( 256 );
+			SendMessage(lphc->hWndLBox, LB_GETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+			if (lphc->hWndEdit != 0) 
+				SendMessage(lphc->hWndEdit, WM_SETTEXT, (WORD)y, USER_HEAP_SEG_ADDR(hStr));
+                        USER_HEAP_FREE( hStr );
 			}
 		break;
 	case CB_ADDSTRING:
-		dprintf_combo(stddeb,"CB_ADDSTRING '%s' !\n", (LPSTR)lParam);
+		dprintf_combo(stddeb,"CB_ADDSTRING '%s' !\n", (LPSTR)PTR_SEG_TO_LIN(lParam));
 		lphc = ComboGetStorageHeader(hwnd);
 		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_ADDSTRING, wParam, lParam));
@@ -320,7 +330,7 @@
 		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_GETTEXTLEN, wParam, lParam));
     case CB_INSERTSTRING:
-		dprintf_combo(stddeb,"CB_INSERTSTRING '%s' !\n",(LPSTR)lParam);
+		dprintf_combo(stddeb,"CB_INSERTSTRING '%s' !\n",(LPSTR)PTR_SEG_TO_LIN(lParam));
 		lphc = ComboGetStorageHeader(hwnd);
 		if (lphc == NULL) return 0;
 		return(SendMessage(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam));
@@ -463,7 +473,6 @@
 	HDC     hDC;
 	HBRUSH  hBrush;
 	short   y;
-	char    str[64];
 	LPSTR   ptr = NULL;
 	HANDLE  hTemp;
 	WND       *wndPtr;
@@ -471,7 +480,6 @@
 	dprintf_combo(stddeb,"ComboBoxStaticOwnerDraw(%04X, %p) !\n", hWnd, lphc);
 	y = SendMessage(lphc->hWndLBox, LB_GETCURSEL, 0, 0L);
 	if (y != LB_ERR) {
-		SendMessage(lphc->hWndLBox, LB_GETTEXT, y, (LPARAM)str);
 		ptr = (LPSTR)SendMessage(lphc->hWndLBox, LB_GETITEMDATA, y, 0L);
 		}
 	hDC = GetDC(hWnd);
@@ -480,8 +488,8 @@
 	if (hBrush == (HBRUSH)NULL)  hBrush = GetStockObject(WHITE_BRUSH);
 	wndPtr = WIN_FindWndPtr(hWnd);
 	if (wndPtr == NULL) return;
-	hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(DRAWITEMSTRUCT));
-	lpdis = (LPDRAWITEMSTRUCT) USER_HEAP_ADDR(hTemp);
+	hTemp = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) );
+	lpdis = (LPDRAWITEMSTRUCT) USER_HEAP_LIN_ADDR(hTemp);
 	if (lpdis == NULL) {
 		printf("ComboBox Ownerdraw // Error allocating DRAWITEMSTRUCT !\n");
                 ReleaseDC( hWnd, hDC );
@@ -495,7 +503,7 @@
 	lpdis->itemAction = ODA_DRAWENTIRE;
 	lpdis->CtlType = ODT_COMBOBOX;
 	lpdis->CtlID = wndPtr->wIDmenu;
-	SendMessage(GetParent(hWnd), WM_DRAWITEM, y, (LPARAM)lpdis);
+	SendMessage(GetParent(hWnd), WM_DRAWITEM, y,USER_HEAP_SEG_ADDR(hTemp));
 	USER_HEAP_FREE(hTemp);
 	ReleaseDC(hWnd, hDC);
 }
@@ -515,13 +523,13 @@
 /************************************************************************
  * 					DlgDirListComboBox     [USER.195]
  */
-int DlgDirListComboBox(HWND hDlg, LPSTR lpPathSpec, 
+int DlgDirListComboBox(HWND hDlg, SEGPTR lpPathSpec, 
 	int nIDLBox, int nIDStat, WORD wType)
 {
 	HWND		hWnd;
 	LPHEADCOMBO lphc;
 	dprintf_combo(stddeb,"DlgDirListComboBox(%04X, '%s', %d, %d, %04X) \n",
-			hDlg, lpPathSpec, nIDLBox, nIDStat, wType);
+			hDlg, (char *)PTR_SEG_TO_LIN(lpPathSpec), nIDLBox, nIDStat, wType);
 	hWnd = GetDlgItem(hDlg, nIDLBox);
 	lphc = ComboGetStorageHeader(hWnd);
 	if (lphc == NULL) return 0;
diff --git a/controls/edit.c b/controls/edit.c
index 42981bd..5a42a13 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -12,7 +12,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <windows.h>
-#include <heap.h>
+#include "local.h"
 #include "win.h"
 #include "class.h"
 #include "user.h"
@@ -231,7 +231,7 @@
 	break;
 
     case EM_GETRECT:
-	GetWindowRect(hwnd, (LPRECT)lParam);
+	GetWindowRect(hwnd, (LPRECT)PTR_SEG_TO_LIN(lParam));
 	break;
 
     case EM_GETSEL:
@@ -359,7 +359,7 @@
 	textPtr = EDIT_HeapAddr(hwnd, es->hText);
 	if ((int)wParam > (len = strlen(textPtr)))
 	{
-	    strcpy((char *)lParam, textPtr);
+	    strcpy((char *)PTR_SEG_TO_LIN(lParam), textPtr);
 	    lResult = (DWORD)len ;
 	}
 	else
@@ -469,7 +469,7 @@
 
 long EDIT_NCCreateMsg(HWND hwnd, LONG lParam)
 {
-    CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam;
+    CREATESTRUCT *createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
     WND *wndPtr = WIN_FindWndPtr(hwnd);
     EDITSTATE *es;
     unsigned int *textPtrs;
@@ -477,6 +477,7 @@
 
     /* store pointer to local or global heap in window structure so that */
     /* EDITSTATE structure itself can be stored on local heap  */
+#if 0
     if (HEAP_LocalFindHeap(createStruct->hInstance)!=NULL)
       (MDESC **)*(LONG *)(wndPtr->wExtra + 2) = 
 	&HEAP_LocalFindHeap(createStruct->hInstance)->free_list;
@@ -486,6 +487,7 @@
 	  GlobalLock(createStruct->hInstance);
 	/* GlobalUnlock(createStruct->hInstance); */
       }
+#endif
     /* allocate space for state variable structure */
     (HANDLE)(*(wndPtr->wExtra)) = EDIT_HeapAlloc(hwnd, sizeof(EDITSTATE));
     es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
@@ -507,21 +509,21 @@
     }
     else
     {
-	if (strlen(createStruct->lpszName) < EditBufLen(wndPtr))
+        char *windowName = (char *)PTR_SEG_TO_LIN( createStruct->lpszName );
+	if (strlen(windowName) < EditBufLen(wndPtr))
 	{
 	    es->textlen = EditBufLen(wndPtr) + 1;
 	    es->hText = EDIT_HeapAlloc(hwnd, EditBufLen(wndPtr) + 2);
 	    text = EDIT_HeapAddr(hwnd, es->hText);
-	    strcpy(text, createStruct->lpszName);
+	    strcpy(text, windowName);
 	    *(text + es->textlen) = '\0';
 	}
 	else
 	{
-	    es->hText = EDIT_HeapAlloc(hwnd, 
-				       strlen(createStruct->lpszName) + 2);
+	    es->hText = EDIT_HeapAlloc(hwnd, strlen(windowName) + 2);
 	    text = EDIT_HeapAddr(hwnd, es->hText);
-	    strcpy(text, createStruct->lpszName);
-	    es->textlen = strlen(createStruct->lpszName) + 1;
+	    strcpy(text, windowName);
+	    es->textlen = strlen(windowName) + 1;
 	}
 	*(text + es->textlen + 1) = '\0';
 	EDIT_BuildTextPointers(hwnd);
@@ -970,10 +972,10 @@
 	    }
 	}
     }
-    else
+    else 
 	EDIT_WriteText(hwnd, lp, off, len, y - es->wtop, rc.left, &rc,
 		       TRUE, FALSE);
-	      
+
     EDIT_HeapFree(hwnd, hLine);
 }
 
@@ -998,7 +1000,7 @@
     HDC hdc;
     HANDLE hStr;
     char *str, *cp, *cp1;
-    int diff, num_spaces, tabwidth, scol;
+    int diff=0, num_spaces, tabwidth, scol;
     HRGN hrgnClip;
     COLORREF oldTextColor, oldBkgdColor;
     HFONT oldfont;
@@ -1010,6 +1012,12 @@
 
     dprintf_edit(stddeb,"EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp, off, len, row, col, reverse);
 
+    if( off < 0 ) {
+      len += off;
+      col -= off;
+      off = 0;
+    }
+	
     hdc = GetDC(hwnd);
     hStr = EDIT_GetStr(hwnd, lp, off, len, &diff);
     str = (char *)EDIT_HeapAddr(hwnd, hStr);
@@ -1166,7 +1174,7 @@
 	break;
 
     default:
-	if (wParam >= 20 && wParam <= 126)
+	if (wParam >= 20 && wParam <= 254 && wParam != 127 )
 	    EDIT_KeyTyped(hwnd, wParam);
 	break;
     }
@@ -2232,15 +2240,15 @@
     EDITSTATE *es = 
 	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
-    if (strlen((char *)lParam) <= es->MaxTextLen)
+    if (strlen((char *)PTR_SEG_TO_LIN(lParam)) <= es->MaxTextLen)
     {
-	len = ( lParam? strlen((char *)lParam) : 0 );
+	len = ( lParam? strlen((char *)PTR_SEG_TO_LIN(lParam)) : 0 );
 	EDIT_ClearText(hwnd);
 	es->textlen = len;
 	es->hText = EDIT_HeapReAlloc(hwnd, es->hText, len + 3);
 	text = EDIT_HeapAddr(hwnd, es->hText);
 	if (lParam)
-	    strcpy(text, (char *)lParam);
+	    strcpy(text, (char *)PTR_SEG_TO_LIN(lParam));
 	text[len]     = '\0';
 	text[len + 1] = '\0';
 	text[len + 2] = '\0';
@@ -2392,7 +2400,7 @@
 	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     /* check for (0,0) */
-    if (!off)
+    if (!off || !es->wlines)
     {
 	*line = 0;
 	*col = 0;
@@ -2739,7 +2747,8 @@
 void EDIT_ReplaceSel(HWND hwnd, LONG lParam)
 {
     EDIT_DeleteSel(hwnd);
-    EDIT_InsertText(hwnd, (char *)lParam, strlen((char *)lParam));
+    EDIT_InsertText(hwnd, (char *)PTR_SEG_TO_LIN(lParam),
+                    strlen((char *)PTR_SEG_TO_LIN(lParam)));
     InvalidateRect(hwnd, NULL, TRUE);
     UpdateWindow(hwnd);
 }
@@ -3000,9 +3009,8 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
     unsigned int ret;
-    ret = ((unsigned int)HEAP_Alloc((MDESC **)
-				     *(LONG *)(wndPtr->wExtra + 2), 
-				     GMEM_MOVEABLE, bytes) & 0xffff);
+
+    ret = LOCAL_Alloc( wndPtr->hInstance, LMEM_FIXED, bytes );
     if (ret == 0)
       printf("EDIT_HeapAlloc: Out of heap-memory\n");
     return ret;
@@ -3018,10 +3026,7 @@
 void *EDIT_HeapAddr(HWND hwnd, unsigned int handle)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-
-    return ((void *)((handle) ? ((handle) | ((unsigned int)
-		    (*(MDESC **)*(LONG *)(wndPtr->wExtra + 2))   
-		     & 0xffff0000)) : 0));
+    return handle ? PTR_SEG_OFF_TO_LIN( wndPtr->hInstance, handle ) : 0;
 }
 
 
@@ -3035,10 +3040,7 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
-    return ((unsigned int)HEAP_ReAlloc((MDESC **)
-				       *(LONG *)(wndPtr->wExtra + 2), 
-				       EDIT_HeapAddr(hwnd, handle),
-				       bytes, GMEM_MOVEABLE) & 0xffff);
+    return LOCAL_ReAlloc( wndPtr->hInstance, handle, bytes, LMEM_FIXED );
 }
 
 
@@ -3052,8 +3054,7 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
-    HEAP_Free((MDESC **)*(LONG *)(wndPtr->wExtra + 2), 
-	      EDIT_HeapAddr(hwnd, handle));
+    LOCAL_Free( wndPtr->hInstance, handle );
 }
 
 
@@ -3067,7 +3068,10 @@
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
 
+#if 0
     return HEAP_LocalSize((MDESC **)*(LONG *)(wndPtr->wExtra + 2), handle);
+#endif
+    return LOCAL_Size( wndPtr->hInstance, handle );
 }
 
 
diff --git a/controls/listbox.c b/controls/listbox.c
index 14bed8f..ebfab3a 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -8,11 +8,12 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include "windows.h"
 #include "user.h"
-#include "heap.h"
 #include "win.h"
 #include "msdos.h"
 #include "listbox.h"
@@ -47,16 +48,24 @@
 	LPHEADLIST lphl, LPLISTSTRUCT lpls);
 int ListBoxFindNextMatch(HWND hwnd, WORD wChar);
 int ListMaxFirstVisible(LPHEADLIST lphl);
+void ListBoxSendNotification(HWND hwnd, WORD code);
 
 #define HasStrings(wndPtr) ( \
   ( ((wndPtr->dwStyle & LBS_OWNERDRAWFIXED) != LBS_OWNERDRAWFIXED) && \
     ((wndPtr->dwStyle & LBS_OWNERDRAWVARIABLE) != LBS_OWNERDRAWVARIABLE) ) || \
   ((wndPtr->dwStyle & LBS_HASSTRINGS) == LBS_HASSTRINGS) )
 
+#if 0
 #define LIST_HEAP_ALLOC(lphl,f,size) ((int)HEAP_Alloc(&lphl->Heap,f,size) & 0xffff)
 #define LIST_HEAP_FREE(lphl,handle) (HEAP_Free(&lphl->Heap,LIST_HEAP_ADDR(lphl,handle)))
 #define LIST_HEAP_ADDR(lphl,handle) \
     ((void *)((handle) ? ((handle) | ((int)lphl->Heap & 0xffff0000)) : 0))
+#else
+#define LIST_HEAP_ALLOC(lphl,f,size) USER_HEAP_ALLOC(size)
+#define LIST_HEAP_FREE(lphl,handle)  USER_HEAP_FREE(handle)
+#define LIST_HEAP_ADDR(lphl,handle)  USER_HEAP_LIN_ADDR(handle)
+#endif
+
 #define LIST_HEAP_SIZE 0x10000
 
 /***********************************************************************
@@ -79,7 +88,7 @@
 		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
 		dprintf_listbox(stddeb,"ListBox WM_CREATE %p !\n", lphl);
 		if (lphl == NULL) return 0;
-		createStruct = (CREATESTRUCT *)lParam;
+		createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
 		if (HIWORD(createStruct->lpCreateParams) != 0)
 			lphl->hWndLogicParent = (HWND)HIWORD(createStruct->lpCreateParams);
 		else
@@ -198,12 +207,10 @@
 		    wRet = ListBoxGetSel(hwnd, y);
 		    ListBoxSetSel(hwnd, y, !wRet);
 		    }
-		else {
+		else
 		    ListBoxSetCurSel(hwnd, y);
-		    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-				SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-	    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
-		    }
+		if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL)
+		  ListBoxSendNotification( hwnd, LBN_SELCHANGE );
 		ListBoxGetItemRect(hwnd, y, &rectsel);
 		InvalidateRect(hwnd, NULL, TRUE);
 		UpdateWindow(hwnd);
@@ -213,8 +220,7 @@
 		lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
 		if (lphl == NULL) return 0;
 		if (lphl->PrevFocused != lphl->ItemFocused)
-			SendMessage(lphl->hWndLogicParent, WM_COMMAND, wndPtr->wIDmenu,
-											MAKELONG(hwnd, LBN_SELCHANGE));
+		  ListBoxSendNotification( hwnd, LBN_SELCHANGE );
 		return 0;
 	case WM_RBUTTONUP:
 	case WM_LBUTTONDBLCLK:
@@ -252,13 +258,10 @@
 					wRet = ListBoxFindMouse(hwnd, LOWORD(lParam), HIWORD(lParam));
 					if ((wndPtr->dwStyle & LBS_MULTIPLESEL) == LBS_MULTIPLESEL) {
 						lphl->ItemFocused = wRet;
+						ListBoxSendNotification(hwnd, LBN_SELCHANGE);
 						}
-					else {
+					else
 						ListBoxSetCurSel(hwnd, wRet);
-					    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-							SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-				    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
-						}
 					ListBoxGetItemRect(hwnd, wRet, &rectsel);
 					InvalidateRect(hwnd, NULL, TRUE);
 					UpdateWindow(hwnd);
@@ -325,9 +328,7 @@
 		if (lphl->FirstVisible < 1) lphl->FirstVisible = 1;
 		if ((wndPtr->dwStyle & LBS_MULTIPLESEL) != LBS_MULTIPLESEL) {
 			ListBoxSetCurSel(hwnd, lphl->ItemFocused);
-		    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-				SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-	    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
+			ListBoxSendNotification(hwnd, LBN_SELCHANGE);
 			}
                 SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
 		InvalidateRect(hwnd, NULL, TRUE);
@@ -376,25 +377,29 @@
 		return 0;
     case LB_DIR:
 		dprintf_listbox(stddeb,"ListBox LB_DIR !\n");
-		wRet = ListBoxDirectory(hwnd, wParam, (LPSTR)lParam);
+		wRet = ListBoxDirectory(hwnd, wParam,
+                                        (LPSTR)PTR_SEG_TO_LIN(lParam));
 		InvalidateRect(hwnd, NULL, TRUE);
 		UpdateWindow(hwnd);
 		return wRet;
 	case LB_ADDSTRING:
-		wRet = ListBoxAddString(hwnd, (LPSTR)lParam);
+		wRet = ListBoxAddString(hwnd, (LPSTR)PTR_SEG_TO_LIN(lParam));
 		return wRet;
 	case LB_GETTEXT:
 		dprintf_listbox(stddeb, "LB_GETTEXT  wParam=%d\n",wParam);
-		wRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam, FALSE);
+		wRet = ListBoxGetText(hwnd, wParam,
+                                      (LPSTR)PTR_SEG_TO_LIN(lParam), FALSE);
                 return wRet;
 	case LB_INSERTSTRING:
-		wRet = ListBoxInsertString(hwnd, wParam, (LPSTR)lParam);
+		wRet = ListBoxInsertString(hwnd, wParam,
+                                           (LPSTR)PTR_SEG_TO_LIN(lParam));
 		return wRet;
 	case LB_DELETESTRING:
 		wRet = ListBoxDeleteString(hwnd, wParam);
 		return wRet;
 	case LB_FINDSTRING:
-		wRet = ListBoxFindString(hwnd, wParam, (LPSTR)lParam);
+		wRet = ListBoxFindString(hwnd, wParam,
+                                         (LPSTR)PTR_SEG_TO_LIN(lParam));
 		return wRet;
 	case LB_GETCARETINDEX:
 		return wRet;
@@ -410,13 +415,14 @@
 		return wRet;
 	case LB_GETITEMDATA:
 		dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam);
-		lRet = ListBoxGetText(hwnd, wParam, (LPSTR)lParam, TRUE);
+		lRet = ListBoxGetText(hwnd, wParam,
+                                      (LPSTR)PTR_SEG_TO_LIN(lParam), TRUE);
 		return lRet;
 	case LB_GETITEMHEIGHT:
                 ListBoxGetItemRect(hwnd, wParam, &rect);
                 return (rect.bottom - rect.top);
 	case LB_GETITEMRECT:
-                ListBoxGetItemRect(hwnd, wParam, (LPRECT)lParam);
+                ListBoxGetItemRect(hwnd,wParam,(LPRECT)PTR_SEG_TO_LIN(lParam));
                 return 0;
 	case LB_GETSEL:
 		wRet = ListBoxGetSel(hwnd, wParam);
@@ -601,6 +607,7 @@
 	HDC 	hdc;
 	RECT 	rect;
 	int     i, h, h2, maxwidth;
+        HANDLE hDrawItemStruct;
 	h = 0;
 	hdc = BeginPaint(hwnd, &ps);
 	if (!IsWindowVisible(hwnd)) {
@@ -621,6 +628,7 @@
 	lpls = lphl->lpFirst;
 	if (lpls == NULL) goto EndOfPaint;
 	lphl->ItemsVisible = 0;
+        hDrawItemStruct = USER_HEAP_ALLOC( sizeof(DRAWITEMSTRUCT) );
 	for (i = 1; i <= lphl->ItemsCount; i++) {
 	    if (i >= lphl->FirstVisible) {
 		lpls->dis.hDC = hdc;
@@ -655,8 +663,10 @@
 			itemData = lpls->dis.itemData;
 			lpls->dis.itemData = (DWORD)lpls->itemText;
 			}
+                memcpy( USER_HEAP_LIN_ADDR(hDrawItemStruct), &lpls->dis,
+                        sizeof(DRAWITEMSTRUCT) );
 		SendMessage(lphl->hWndLogicParent, WM_DRAWITEM, 
-							i-1, (LPARAM)&lpls->dis);
+                            i-1, (LPARAM)USER_HEAP_SEG_ADDR(hDrawItemStruct));
 		if (HasStrings(wndPtr))
 			lpls->dis.itemData = itemData;
 
@@ -667,11 +677,12 @@
 		lphl->ItemsVisible++;
 		/* if (h > rect.bottom) goto EndOfPaint;*/
 		}
-	    if (lpls->lpNext == NULL) goto EndOfPaint;
+	    if (lpls->lpNext == NULL) break;
 	    lpls = (LPLISTSTRUCT)lpls->lpNext;
 	}
+        USER_HEAP_FREE( hDrawItemStruct );
 EndOfPaint:
-    EndPaint( hwnd, &ps );
+        EndPaint( hwnd, &ps );
 }
 
 
@@ -717,8 +728,6 @@
 {
 	WND  *wndPtr;
 	LPHEADLIST lphl;
-	int HeapHandle;
-	void *HeapBase;
 	wndPtr = WIN_FindWndPtr(hwnd);
 	lphl = (LPHEADLIST)malloc(sizeof(HEADLIST));
 	lphl->lpFirst = NULL;
@@ -734,9 +743,11 @@
 	lphl->SelCount = 0;
 	lphl->DrawCtlType = ODT_LISTBOX;
 	lphl->bRedrawFlag = TRUE;
+#if 0
 	HeapHandle = GlobalAlloc(GMEM_FIXED, LIST_HEAP_SIZE);
 	HeapBase = GlobalLock(HeapHandle);
 	HEAP_Init(&lphl->Heap, HeapBase, LIST_HEAP_SIZE);
+#endif
 	return TRUE;
 }
 
@@ -744,8 +755,8 @@
 void ListBoxAskMeasure(WND *wndPtr, LPHEADLIST lphl, LPLISTSTRUCT lpls)  
 {
 	MEASUREITEMSTRUCT 	*lpmeasure;
-	HANDLE hTemp = USER_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(MEASUREITEMSTRUCT));
-	lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_ADDR(hTemp);
+	HANDLE hTemp = USER_HEAP_ALLOC( sizeof(MEASUREITEMSTRUCT) );
+	lpmeasure = (MEASUREITEMSTRUCT *) USER_HEAP_LIN_ADDR(hTemp);
 	if (lpmeasure == NULL) {
 		fprintf(stderr,"ListBoxAskMeasure() // Bad allocation of Measure struct !\n");
 		return;
@@ -759,7 +770,8 @@
 		lpmeasure->itemData = (DWORD)lpls->itemText;
 	else
 		lpmeasure->itemData = lpls->dis.itemData;
-	SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM, 0, (DWORD)lpmeasure);
+	SendMessage(lphl->hWndLogicParent, WM_MEASUREITEM,
+                    0, USER_HEAP_SEG_ADDR(hTemp));
 	lpls->dis.rcItem.right = lpls->dis.rcItem.left + lpmeasure->itemWidth;
 	lpls->dis.rcItem.bottom = lpls->dis.rcItem.top + lpmeasure->itemHeight;
 	USER_HEAP_FREE(hTemp);			
@@ -1002,9 +1014,6 @@
     lphl->ItemsCount = 0;
     lphl->ItemFocused = -1;
     lphl->PrevFocused = -1;
-    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-	SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
     SetScrollRange(hwnd, SB_VERT, 1, ListMaxFirstVisible(lphl), TRUE);
     if (lphl->ItemsPerColumn != 0)
 	SetScrollRange(hwnd, SB_HORZ, 1, lphl->ItemsVisible / 
@@ -1023,6 +1032,8 @@
     UINT	i;
     lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
     if (lphl == NULL) return LB_ERR;
+    if( (wIndex != (WORD)(-1)) && (wIndex > lphl->ItemsCount) )
+      return LB_ERR;
     lphl->ItemFocused = LB_ERR; 
     if (wIndex >= lphl->ItemsCount) return LB_ERR;
     lpls = lphl->lpFirst;
@@ -1038,10 +1049,7 @@
 	if (lpls == NULL)  break;
     }
     lphl->ItemFocused = wIndex;
-    if ((wndPtr->dwStyle && LBS_NOTIFY) != 0)
-	SendMessage(lphl->hWndLogicParent, WM_COMMAND, 
-    	    wndPtr->wIDmenu, MAKELONG(hwnd, LBN_SELCHANGE));
-    return LB_ERR;
+    return wIndex;
 }
 
 
@@ -1093,57 +1101,85 @@
 
 int ListBoxDirectory(HWND hwnd, UINT attrib, LPSTR filespec)
 {
-	struct dosdirent *dp;
-	int	x, wRet = LB_OKAY;
-	BOOL    OldFlag;
-	char 	temp[256];
-    LPHEADLIST 	lphl;
-	dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
-    lphl = ListBoxGetStorageHeader(hwnd);
-    if (lphl == NULL) return LB_ERR;
-	if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
-	OldFlag = lphl->bRedrawFlag;
-	lphl->bRedrawFlag = FALSE;
-	while ((dp = (struct dosdirent *)DOS_readdir(dp))) {
-		if (!dp->inuse) break;
-		dprintf_listbox(stddeb,"ListBoxDirectory %p '%s' !\n", dp->filename, dp->filename);
-		if (dp->attribute & FA_DIREC) {
-			if (attrib & DDL_DIRECTORY &&
-					strcmp(dp->filename, ".")) {
-				sprintf(temp, "[%s]", dp->filename);
-				if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
-				}
-			} 
-		else {
-			if (attrib & DDL_EXCLUSIVE) {
-				if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | 
-					    DDL_SYSTEM) )
-					if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
-					    == LB_ERR) break;
-				} 
-			else {
-				if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
-					== LB_ERR) break;
-				}
-			}
-		}
-	DOS_closedir(dp);
+  struct dosdirent *dp, *dp_old;
+  int	x, wRet = LB_OKAY;
+  BOOL    OldFlag;
+  char 	temp[256];
+  LPHEADLIST 	lphl;
+  int drive;
 
-	if (attrib & DDL_DRIVES) {
-		for (x=0;x!=MAX_DOS_DRIVES;x++) {
-			if (DOS_ValidDrive(x)) {
-				sprintf(temp, "[-%c-]", 'a'+x);
-				if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
-				}		
-			}
-		}
-	lphl->bRedrawFlag = OldFlag;
-	if (OldFlag) {
-		InvalidateRect(hwnd, NULL, TRUE);
-		UpdateWindow(hwnd);
-		}
-	dprintf_listbox(stddeb,"End of ListBoxDirectory !\n");
-	return wRet;
+  dprintf_listbox(stddeb,"ListBoxDirectory: %s, %4x\n",filespec,attrib);
+
+  if( strchr( filespec, '\\' ) || strchr( filespec, ':' ) ) {
+    drive = DOS_GetDefaultDrive();
+    if( filespec[1] == ':' ) {
+      drive = toupper(filespec[0]) - 'A';
+      filespec += 2;
+    }
+    if( !strchr( filespec, '\\' ) ) 
+      DOS_SetDefaultDrive( drive );
+    else {
+      int i;
+      strcpy( temp, filespec );
+      for( i=0; i<strlen(temp); i++ )
+	if( temp[i] == '\\' ) {
+	  temp[i] = 0;
+	  filespec += ( i+1 );
+	  break;
+	}
+      DOS_ChangeDir( drive, temp );
+      DOS_SetDefaultDrive( drive );
+    }
+    dprintf_listbox(stddeb,"Changing directory to %c:%s, filemask is %s\n",
+		    drive+'A', temp, filespec );
+  }
+  lphl = ListBoxGetStorageHeader(hwnd);
+  if (lphl == NULL) return LB_ERR;
+  if ((dp = (struct dosdirent *)DOS_opendir(filespec)) ==NULL) return 0;
+  dp_old = dp;
+  OldFlag = lphl->bRedrawFlag;
+  lphl->bRedrawFlag = FALSE;
+  while ((dp = (struct dosdirent *)DOS_readdir(dp))) {
+    if (!dp->inuse) break;
+    dprintf_listbox( stddeb, "ListBoxDirectory %p '%s' !\n", dp->filename, 
+		    dp->filename);
+    if (dp->attribute & FA_DIREC) {
+      if (attrib & DDL_DIRECTORY &&
+	  strcmp(dp->filename, ".")) {
+	sprintf(temp, "[%s]", dp->filename);
+	if ( (wRet = ListBoxAddString(hwnd, temp)) == LB_ERR) break;
+      }
+    } 
+    else {
+      if (attrib & DDL_EXCLUSIVE) {
+	if (attrib & (DDL_READWRITE | DDL_READONLY | DDL_HIDDEN | 
+		      DDL_SYSTEM) )
+	  if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
+	      == LB_ERR) break;
+      } 
+      else {
+	if ( (wRet = ListBoxAddString(hwnd, dp->filename)) 
+	    == LB_ERR) break;
+      }
+    }
+  }
+  DOS_closedir(dp_old);
+  
+  if (attrib & DDL_DRIVES) {
+    for (x=0;x!=MAX_DOS_DRIVES;x++) {
+      if (DOS_ValidDrive(x)) {
+	sprintf(temp, "[-%c-]", 'a'+x);
+	if((wRet = ListBoxInsertString(hwnd, (UINT)-1, temp)) == LB_ERR) break;
+      }		
+    }
+  }
+  lphl->bRedrawFlag = OldFlag;
+  if (OldFlag) {
+    InvalidateRect(hwnd, NULL, TRUE);
+    UpdateWindow(hwnd);
+  }
+  dprintf_listbox(stddeb,"End of ListBoxDirectory !\n");
+  return 1;  /* FIXME: Should be 0 if "filespec" is invalid */
 }
 
 
@@ -1290,8 +1326,40 @@
  */
 BOOL DlgDirSelect(HWND hDlg, LPSTR lpStr, int nIDLBox)
 {
-	fprintf(stdnimp,"DlgDirSelect(%04X, '%s', %d) \n", hDlg, lpStr, nIDLBox);
-	return FALSE;
+  HWND hwnd;
+  LPHEADLIST lphl;
+  char s[130];
+
+  dprintf_listbox( stddeb, "DlgDirSelect(%04X, '%s', %d) \n", hDlg, lpStr, 
+		  nIDLBox );
+
+  hwnd = GetDlgItem(hDlg, nIDLBox);
+  lphl = ListBoxGetStorageHeader(hwnd);
+  if( lphl->ItemFocused == -1 ) {
+    dprintf_listbox( stddeb, "Nothing selected!\n" );
+    return FALSE;
+  }
+  ListBoxGetText(hwnd, lphl->ItemFocused, (LPSTR)s, FALSE);
+  dprintf_listbox( stddeb, "Selection is %s\n", s );
+  if( s[0] == '[' ) {
+    if( s[1] == '-' ) {
+      strncpy( lpStr, s+2, strlen(s)-4 );    /* device name */
+      lpStr[ strlen(s)-4 ] = 0;
+      strcat( lpStr, ":" );
+    }
+    else {
+      strncpy( lpStr, s+1, strlen(s)-2 );    /* directory name */
+      lpStr[ strlen(s)-2 ] = 0;
+      strcat( lpStr, "\\" );
+    }
+    dprintf_listbox( stddeb, "Returning %s\n", lpStr );
+    return TRUE;
+  }
+  else {
+    strcpy( lpStr, s );                     /* file name */
+    dprintf_listbox( stddeb, "Returning %s\n", lpStr );
+    return FALSE;
+  }
 }
 
 
@@ -1318,9 +1386,20 @@
 	if (nIDStat)
 	  {
 	    int drive;
+	    char temp[255];
 	    drive = DOS_GetDefaultDrive();
-	    SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, 
-			       (LONG) DOS_GetCurrentDir(drive) );
+	    strcpy( temp+3, DOS_GetCurrentDir(drive) );
+	    if( temp[3] == '\\' ) {
+	      temp[1] = 'A'+drive;
+	      temp[2] = ':';
+	      SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, (LONG)(temp+1));
+	    }
+	    else {
+	      temp[0] = 'A'+drive;
+	      temp[1] = ':';
+	      temp[2] = '\\';
+	      SendDlgItemMessage(hDlg, nIDStat, WM_SETTEXT, 0, (LONG) temp );
+	    }
 	  } 
 	return ret;
 }
@@ -1331,3 +1410,16 @@
     int m = lphl->ItemsCount-lphl->ItemsVisible+1;
     return (m < 1) ? 1 : m;
 }
+
+
+/* Send notification "code" as part of a WM_COMMAND-message if hwnd
+   has the LBS_NOTIFY style */
+void ListBoxSendNotification(HWND hwnd, WORD code)
+{
+  WND  *wndPtr;
+  LPHEADLIST  lphl;
+  lphl = ListBoxGetWindowAndStorage(hwnd, &wndPtr);
+  if( wndPtr && ( (wndPtr->dwStyle && LBS_NOTIFY) != 0) )
+    SendMessage(lphl->hWndLogicParent, WM_COMMAND,
+		wndPtr->wIDmenu, MAKELONG(hwnd, code));
+} 
diff --git a/controls/menu.c b/controls/menu.c
index bfe0fbf..ac118e9 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -141,8 +141,8 @@
     MENUITEM *item;
     int i;
 
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR(*hmenu))) return NULL;
-    item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR(*hmenu))) return NULL;
+    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if (wFlags & MF_BYPOSITION)
     {
 	if (*nPos >= menu->nItems) return NULL;
@@ -187,7 +187,7 @@
     if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return NULL;
     x -= wndPtr->rectWindow.left;
     y -= wndPtr->rectWindow.top;
-    item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     for (i = 0; i < menu->nItems; i++, item++)
     {
 	if ((x >= item->rect.left) && (x < item->rect.right) &&
@@ -214,8 +214,8 @@
     int i;
     LONG menuchar;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
-    lpitem = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
+    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     key = toupper(key);
     for (i = 0; i < menu->nItems; i++, lpitem++)
     {
@@ -308,7 +308,7 @@
 
     lppop->Width = lppop->Height = 0;
     if (lppop->nItems == 0) return;
-    items = (MENUITEM *)USER_HEAP_ADDR( lppop->hItems );
+    items = (MENUITEM *)USER_HEAP_LIN_ADDR( lppop->hItems );
     hdc = GetDC( 0 );
     maxX = start = 0;
     while (start < lppop->nItems)
@@ -363,7 +363,7 @@
     if (lppop->nItems == 0) return;
 	dprintf_menucalc(stddeb,"MenuBarCalcSize left=%d top=%d right=%d bottom=%d !\n", 
 		lprect->left, lprect->top, lprect->right, lprect->bottom);
-    items = (MENUITEM *)USER_HEAP_ADDR( lppop->hItems );
+    items = (MENUITEM *)USER_HEAP_LIN_ADDR( lppop->hItems );
     lppop->Width  = lprect->right - lprect->left;
     lppop->Height = 0;
     maxY = lprect->top;
@@ -562,9 +562,9 @@
 
     GetClientRect( hwnd, &rect );
     FillRect( hdc, &rect, sysColorObjects.hbrushMenu );
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu || !menu->nItems) return;
-    item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     for (i = menu->nItems; i > 0; i--, item++)
 	MENU_DrawMenuItem( hdc, item, menu->Height, FALSE );
 }
@@ -582,7 +582,7 @@
     int i;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     
-    lppop = (LPPOPUPMENU) USER_HEAP_ADDR( wndPtr->wIDmenu );
+    lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR( wndPtr->wIDmenu );
     if (lppop == NULL || lprect == NULL) return SYSMETRICS_CYMENU;
     dprintf_menu(stddeb,"MENU_DrawMenuBar(%04X, %p, %p); !\n", 
 		 hDC, lprect, lppop);
@@ -596,7 +596,7 @@
     LineTo( hDC, lprect->right, lprect->bottom );
 
     if (lppop->nItems == 0) return SYSMETRICS_CYMENU;
-    lpitem = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
     for (i = 0; i < lppop->nItems; i++, lpitem++)
     {
 	MENU_DrawMenuItem( hDC, lpitem, lppop->Height, TRUE );
@@ -614,10 +614,10 @@
 {
     POPUPMENU *menu;
 
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return FALSE;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     if (menu->FocusedItem != NO_SELECTED_ITEM)
     {
-	MENUITEM *item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+	MENUITEM *item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
 	item[menu->FocusedItem].item_flags &= ~(MF_HILITE | MF_MOUSESELECT);
 	menu->FocusedItem = NO_SELECTED_ITEM;
     }
@@ -632,8 +632,7 @@
 				   WS_POPUP | WS_BORDER, x, y, 
 				   menu->Width + 2*SYSMETRICS_CXBORDER,
 				   menu->Height + 2*SYSMETRICS_CYBORDER,
-				   0, 0, wndPtr->hInstance,
-				   (LPSTR)(DWORD)hmenu );
+				   0, 0, wndPtr->hInstance, (SEGPTR)hmenu );
 	if (!menu->hWnd) return FALSE;
     }
     else SetWindowPos( menu->hWnd, 0, x, y,
@@ -659,9 +658,9 @@
     LPPOPUPMENU lppop;
     HDC hdc;
 
-    lppop = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    lppop = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!lppop->nItems) return;
-    items = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+    items = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
     if ((wIndex != NO_SELECTED_ITEM) && 
 	(wIndex != SYSMENU_SELECTED) &&
 	(items[wIndex].item_flags & MF_SEPARATOR))
@@ -712,9 +711,9 @@
     MENUITEM *items;
     POPUPMENU *menu;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu->nItems) return;
-    items = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    items = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
 	(menu->FocusedItem != SYSMENU_SELECTED))
     {
@@ -753,9 +752,9 @@
     MENUITEM *items;
     POPUPMENU *menu;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu->nItems) return;
-    items = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    items = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
 	(menu->FocusedItem != SYSMENU_SELECTED))
     {
@@ -795,12 +794,12 @@
     POPUPMENU *menu;
     MENUITEM *item;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (menu->FocusedItem == NO_SELECTED_ITEM) return 0;
     else if (menu->FocusedItem == SYSMENU_SELECTED)
 	return GetSystemMenu( menu->hWnd, FALSE );
 
-    item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
     if (!(item->item_flags & MF_POPUP) || !(item->item_flags & MF_MOUSESELECT))
 	return 0;
     return item->item_id;
@@ -818,7 +817,7 @@
     POPUPMENU *menu, *submenu;
     HMENU hsubmenu;
 
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return;
     if (menu->FocusedItem == NO_SELECTED_ITEM) return;
     if (menu->FocusedItem == SYSMENU_SELECTED)
     {
@@ -826,13 +825,13 @@
     }
     else
     {
-	item = ((MENUITEM *)USER_HEAP_ADDR(menu->hItems)) + menu->FocusedItem;
+	item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
 	if (!(item->item_flags & MF_POPUP) ||
 	    !(item->item_flags & MF_MOUSESELECT)) return;
 	item->item_flags &= ~MF_MOUSESELECT;
 	hsubmenu = item->item_id;
     }
-    submenu = (POPUPMENU *) USER_HEAP_ADDR( hsubmenu );
+    submenu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hsubmenu );
     MENU_HideSubPopups( hsubmenu );
     if (submenu->hWnd) ShowWindow( submenu->hWnd, SW_HIDE );
     MENU_SelectItem( hsubmenu, NO_SELECTED_ITEM );
@@ -851,7 +850,7 @@
     MENUITEM *item;
     WND *wndPtr;
 
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return hmenu;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return hmenu;
     if (!(wndPtr = WIN_FindWndPtr( menu->hWnd ))) return hmenu;
     if (menu->FocusedItem == NO_SELECTED_ITEM) return hmenu;
     if (menu->FocusedItem == SYSMENU_SELECTED)
@@ -861,7 +860,7 @@
 	if (selectFirst) MENU_SelectNextItem( wndPtr->hSysMenu );
 	return wndPtr->hSysMenu;
     }
-    item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
     if (!(item->item_flags & MF_POPUP) ||
 	(item->item_flags & (MF_GRAYED | MF_DISABLED))) return hmenu;
     item->item_flags |= MF_MOUSESELECT;
@@ -895,7 +894,7 @@
     if (!(hwnd = WindowFromPoint( pt ))) return 0;
     while (hmenu)
     {
-	menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+	menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
 	if (menu->hWnd == hwnd)
 	{
 	    if (!(menu->wFlags & MF_POPUP))
@@ -929,10 +928,10 @@
 				  HMENU *hmenuCurrent )
 {
     MENUITEM *item;
-    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     if (!menu || !menu->nItems || (menu->FocusedItem == NO_SELECTED_ITEM) ||
 	(menu->FocusedItem == SYSMENU_SELECTED)) return TRUE;
-    item = ((MENUITEM *)USER_HEAP_ADDR( menu->hItems )) + menu->FocusedItem;
+    item = ((MENUITEM *)USER_HEAP_LIN_ADDR(menu->hItems)) + menu->FocusedItem;
     if (!(item->item_flags & MF_POPUP))
     {
 	if (!(item->item_flags & (MF_GRAYED | MF_DISABLED)))
@@ -966,7 +965,7 @@
     WORD id;
 
     if (!hmenu) return FALSE;  /* Outside all menus */
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     item = MENU_FindItemByCoords( menu, pt.x, pt.y, &id );
     if (!item)  /* Maybe in system menu */
     {
@@ -1017,7 +1016,7 @@
     WORD id;
 
     if (!hmenu) return FALSE;  /* Outside all menus */
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     item = MENU_FindItemByCoords( menu, pt.x, pt.y, &id );
     if (!item)  /* Maybe in system menu */
     {
@@ -1054,7 +1053,7 @@
 			    POINT pt )
 {
     MENUITEM *item;
-    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     WORD id = NO_SELECTED_ITEM;
 
     if (hmenu)
@@ -1092,7 +1091,7 @@
     POPUPMENU *menu;
     HMENU hmenutmp, hmenuprev;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     hmenuprev = hmenutmp = hmenu;
     while (hmenutmp != *hmenuCurrent)
     {
@@ -1126,7 +1125,7 @@
     POPUPMENU *menu;
     HMENU hmenutmp;
 
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
 
     if ((menu->wFlags & MF_POPUP) || (*hmenuCurrent != hmenu))
     {
@@ -1175,32 +1174,36 @@
 static BOOL MENU_TrackMenu( HMENU hmenu, WORD wFlags, int x, int y,
 			    HWND hwnd, LPRECT lprect )
 {
-    MSG msg;
+    MSG *msg;
+    HLOCAL hMsg;
     POPUPMENU *menu;
     HMENU hmenuCurrent = hmenu;
-    BOOL fClosed = FALSE;
+    BOOL fClosed = FALSE, fRemove;
     WORD pos;
 
     fEndMenuCalled = FALSE;
-    if (!(menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu ))) return FALSE;
+    if (!(menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     if (x && y)
     {
 	POINT pt = { x, y };
 	MENU_ButtonDown( hwnd, hmenu, &hmenuCurrent, pt );
     }
     SetCapture( hwnd );
-
+    hMsg = USER_HEAP_ALLOC( sizeof(MSG) );
+    msg = (MSG *)USER_HEAP_LIN_ADDR( hMsg );
     while (!fClosed)
     {
-	if (!MSG_InternalGetMessage( &msg, 0, hwnd, MSGF_MENU, 0, TRUE ))
+	if (!MSG_InternalGetMessage( USER_HEAP_SEG_ADDR(hMsg), 0,
+                                     hwnd, MSGF_MENU, 0, TRUE ))
 	    break;
 
-	if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
+        fRemove = FALSE;
+	if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
 	{
 	      /* Find the sub-popup for this mouse event (if any) */
-	    HMENU hsubmenu = MENU_FindMenuByCoords( hmenu, msg.pt );
+	    HMENU hsubmenu = MENU_FindMenuByCoords( hmenu, msg->pt );
 
-	    switch(msg.message)
+	    switch(msg->message)
 	    {
 	    case WM_RBUTTONDOWN:
 	    case WM_NCRBUTTONDOWN:
@@ -1209,7 +1212,7 @@
 	    case WM_LBUTTONDOWN:
 	    case WM_NCLBUTTONDOWN:
 		fClosed = !MENU_ButtonDown( hwnd, hsubmenu,
-					    &hmenuCurrent, msg.pt );
+					    &hmenuCurrent, msg->pt );
 		break;
 		
 	    case WM_RBUTTONUP:
@@ -1219,28 +1222,30 @@
 	    case WM_LBUTTONUP:
 	    case WM_NCLBUTTONUP:
 		  /* If outside all menus but inside lprect, ignore it */
-		if (!hsubmenu && lprect && PtInRect( lprect, msg.pt )) break;
+		if (!hsubmenu && lprect && PtInRect( lprect, msg->pt )) break;
 		fClosed = !MENU_ButtonUp( hwnd, hsubmenu,
-					  &hmenuCurrent, msg.pt );
+					  &hmenuCurrent, msg->pt );
+                fRemove = TRUE;  /* Remove event even if outside menu */
 		break;
 		
 	    case WM_MOUSEMOVE:
 	    case WM_NCMOUSEMOVE:
-		if ((msg.wParam & MK_LBUTTON) ||
-		    ((wFlags & TPM_RIGHTBUTTON) && (msg.wParam & MK_RBUTTON)))
+		if ((msg->wParam & MK_LBUTTON) ||
+		    ((wFlags & TPM_RIGHTBUTTON) && (msg->wParam & MK_RBUTTON)))
 		{
 		    fClosed = !MENU_MouseMove( hwnd, hsubmenu,
-					       &hmenuCurrent, msg.pt );
+					       &hmenuCurrent, msg->pt );
 		}
 		break;
 	    }
 	}
-	else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST))
+	else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
 	{
-	    switch(msg.message)
+            fRemove = TRUE;  /* Keyboard messages are always removed */
+	    switch(msg->message)
 	    {
 	    case WM_KEYDOWN:
-		switch(msg.wParam)
+		switch(msg->wParam)
 		{
 		case VK_HOME:
 		    MENU_SelectItem( hmenuCurrent, NO_SELECTED_ITEM );
@@ -1288,7 +1293,7 @@
 		break;  /* WM_KEYDOWN */
 
 	    case WM_SYSKEYDOWN:
-		switch(msg.wParam)
+		switch(msg->wParam)
 		{
 		case VK_MENU:
 		    fClosed = TRUE;
@@ -1301,8 +1306,8 @@
 		{
 		      /* Hack to avoid control chars. */
 		      /* We will find a better way real soon... */
-		    if ((msg.wParam <= 32) || (msg.wParam >= 127)) break;
-		    pos = MENU_FindItemByKey( hwnd, hmenuCurrent, msg.wParam );
+		    if ((msg->wParam <= 32) || (msg->wParam >= 127)) break;
+		    pos = MENU_FindItemByKey( hwnd, hmenuCurrent, msg->wParam );
 		    if (pos == (WORD)-2) fClosed = TRUE;
 		    else if (pos == (WORD)-1) MessageBeep(0);
 		    else
@@ -1314,17 +1319,19 @@
 		    }
 		}		    
 		break;  /* WM_CHAR */
-	    }  /* switch(msg.message) */
+	    }  /* switch(msg->message) */
 	}
 	else
 	{
-	    DispatchMessage( &msg );
+	    DispatchMessage( msg );
 	}
 	if (fEndMenuCalled) fClosed = TRUE;
+	if (!fClosed) fRemove = TRUE;
 
-	if (!fClosed)  /* Remove the message from the queue */
-	    PeekMessage( &msg, 0, 0, 0, PM_REMOVE );
+        if (fRemove)  /* Remove the message from the queue */
+	    PeekMessage( msg, 0, msg->message, msg->message, PM_REMOVE );
     }
+    USER_HEAP_FREE( hMsg );
     ReleaseCapture();
     MENU_HideSubPopups( hmenu );
     if (menu->wFlags & MF_POPUP) ShowWindow( menu->hWnd, SW_HIDE );
@@ -1388,7 +1395,7 @@
     {
     case WM_CREATE:
 	{
-	    CREATESTRUCT *createStruct = (CREATESTRUCT *)lParam;
+	    CREATESTRUCT *createStruct = (CREATESTRUCT*)PTR_SEG_TO_LIN(lParam);
 	    HMENU hmenu = (HMENU) ((int)createStruct->lpCreateParams & 0xffff);
 	    SetWindowWord( hwnd, 0, hmenu );
 	    return 0;
@@ -1427,7 +1434,7 @@
     LPPOPUPMENU lppop;
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
-    if (!(lppop = (LPPOPUPMENU)USER_HEAP_ADDR( wndPtr->wIDmenu ))) return 0;
+    if (!(lppop = (LPPOPUPMENU)USER_HEAP_LIN_ADDR(wndPtr->wIDmenu))) return 0;
     hdc = GetDC( hwnd );
     SetRect( &rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU );
     MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd );
@@ -1442,17 +1449,18 @@
 BOOL ChangeMenu(HMENU hMenu, WORD nPos, LPSTR lpNewItem, 
 			WORD wItemID, WORD wFlags)
 {
+	dprintf_menu(stddeb,"ChangeMenu(%04X, %X, '%s', %X, %X)\n",
+		hMenu, nPos, lpNewItem, wItemID, wFlags);
 	if (wFlags & MF_APPEND)
 		return AppendMenu(hMenu, wFlags, wItemID, lpNewItem);
 	if (wFlags & MF_DELETE)
 		return DeleteMenu(hMenu, wItemID, wFlags);
-	if (wFlags & MF_INSERT) 
-		return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
 	if (wFlags & MF_CHANGE) 
 		return ModifyMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
 	if (wFlags & MF_REMOVE) 
 		return RemoveMenu(hMenu, wItemID, wFlags);
-	return FALSE;
+	/* Default: MF_INSERT */
+	return InsertMenu(hMenu, nPos, wFlags, wItemID, lpNewItem);
 }
 
 
@@ -1534,7 +1542,7 @@
     dprintf_menu(stddeb,"HiliteMenuItem(%04X, %04X, %04X, %04X);\n", 
 						hWnd, hMenu, wItemID, wHilite);
     if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wHilite ))) return FALSE;
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return FALSE;
     if (menu->FocusedItem == wItemID) return TRUE;
     MENU_HideSubPopups( hMenu );
     MENU_SelectItem( hMenu, wItemID );
@@ -1553,7 +1561,7 @@
     if (!(lpitem = MENU_FindItem( &hMenu, &wItemID, wFlags ))) return -1;
     if (lpitem->item_flags & MF_POPUP)
     {
-	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_ADDR( lpitem->item_id );
+	POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( lpitem->item_id );
 	if (!menu) return -1;
 	else return (menu->nItems << 8) | (menu->wFlags & 0xff);
     }
@@ -1568,7 +1576,7 @@
 {
 	LPPOPUPMENU	menu;
 	dprintf_menu(stddeb,"GetMenuItemCount(%04X);\n", hMenu);
-	menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+	menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
 	if (menu == NULL) return (WORD)-1;
 	dprintf_menu(stddeb,"GetMenuItemCount(%04X) return %d \n", 
 		     hMenu, menu->nItems);
@@ -1585,9 +1593,9 @@
     MENUITEM *item;
 
     dprintf_menu(stddeb,"GetMenuItemID(%04X, %d);\n", hMenu, nPos);
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return -1;
+    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return -1;
     if ((nPos < 0) || (nPos >= menu->nItems)) return -1;
-    item = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+    item = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
     if (item[nPos].item_flags & MF_POPUP) return -1;
     return item[nPos].item_id;
 }
@@ -1613,28 +1621,45 @@
 
       /* Find where to insert new item */
 
-    if ((wFlags & MF_BYPOSITION) && (nPos == (WORD)-1))
+    if ((wFlags & MF_BYPOSITION) && 
+        ((nPos == (WORD)-1) || (nPos == GetMenuItemCount(hMenu))))
     {
-	  /* Special case: append to menu */
-	if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
-	nPos = menu->nItems;
+          /* Special case: append to menu 
+             Some programs specify the menu length to do that */
+        if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) 
+        {
+            dprintf_menu(stddeb,"InsertMenu: %04X not a menu handle\n", hMenu);
+            return FALSE;
+        }
+        nPos = menu->nItems;
     }
     else
     {
-	if (!MENU_FindItem( &hMenu, &nPos, wFlags )) return FALSE;
-	if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+        if (!MENU_FindItem( &hMenu, &nPos, wFlags )) 
+        {
+            dprintf_menu(stddeb,"InsertMenu: Item %X not found\n", nPos);
+            return FALSE;
+        }
+        if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu)))
+        {
+            dprintf_menu(stddeb,"InsertMenu: %04X not a menu handle\n", hMenu);
+            return FALSE;
+        }
     }
 
       /* Create new items array */
 
-    hNewItems = USER_HEAP_ALLOC( GMEM_MOVEABLE,
-				 sizeof(MENUITEM) * (menu->nItems+1) );
-    if (!hNewItems) return FALSE;
-    newItems = (MENUITEM *) USER_HEAP_ADDR( hNewItems );
+    hNewItems = USER_HEAP_ALLOC( sizeof(MENUITEM) * (menu->nItems+1) );
+    if (!hNewItems)
+    {
+        dprintf_menu(stddeb,"InsertMenu: allocation failed\n");
+        return FALSE;
+    }
+    newItems = (MENUITEM *) USER_HEAP_LIN_ADDR( hNewItems );
     if (menu->nItems > 0)
     {
 	  /* Copy the old array into the new */
-	MENUITEM *oldItems = (MENUITEM *) USER_HEAP_ADDR( menu->hItems );
+	MENUITEM *oldItems = (MENUITEM *) USER_HEAP_LIN_ADDR( menu->hItems );
 	if (nPos > 0) memcpy( newItems, oldItems, nPos * sizeof(MENUITEM) );
 	if (nPos < menu->nItems) memcpy( &newItems[nPos+1], &oldItems[nPos],
 					(menu->nItems-nPos)*sizeof(MENUITEM) );
@@ -1658,15 +1683,15 @@
 	    lpitem->item_flags |= MF_HELP;
 	    lpNewItem++;
 	}
-	lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 );
-	lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText );
+	lpitem->hText = USER_HEAP_ALLOC( strlen(lpNewItem)+1 );
+	lpitem->item_text = (char *)USER_HEAP_LIN_ADDR( lpitem->hText );
 	strcpy( lpitem->item_text, lpNewItem );
     }
     else if (wFlags & MF_BITMAP) lpitem->hText = LOWORD((DWORD)lpNewItem);
     else lpitem->item_text = lpNewItem;
 
     if (wFlags & MF_POPUP)  /* Set the MF_POPUP flag on the popup-menu */
-	((POPUPMENU *)USER_HEAP_ADDR(wItemID))->wFlags |= MF_POPUP;
+	((POPUPMENU *)USER_HEAP_LIN_ADDR(wItemID))->wFlags |= MF_POPUP;
 
     SetRectEmpty( &lpitem->rect );
     lpitem->hCheckBit   = hStdCheck;
@@ -1694,7 +1719,7 @@
 	dprintf_menu(stddeb,"RemoveMenu (%04X, %04X, %04X) !\n", 
 		     hMenu, nPos, wFlags);
     if (!(lpitem = MENU_FindItem( &hMenu, &nPos, wFlags ))) return FALSE;
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return FALSE;
+    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return FALSE;
     
       /* Remove item */
 
@@ -1713,8 +1738,7 @@
 	    nPos++;
 	}
 	menu->hItems = USER_HEAP_REALLOC( menu->hItems,
-					  menu->nItems * sizeof(MENUITEM),
-					  GMEM_MOVEABLE );
+					  menu->nItems * sizeof(MENUITEM) );
     }
     return TRUE;
 }
@@ -1754,8 +1778,8 @@
 
     if (IS_STRING_ITEM(wFlags))
     {
-	lpitem->hText = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(lpNewItem)+1 );
-	lpitem->item_text = (char *)USER_HEAP_ADDR( lpitem->hText );
+	lpitem->hText = USER_HEAP_ALLOC( strlen(lpNewItem)+1 );
+	lpitem->item_text = (char *)USER_HEAP_LIN_ADDR( lpitem->hText );
 	strcpy( lpitem->item_text, lpNewItem );
     }
     else if (wFlags & MF_BITMAP) lpitem->hText = LOWORD((DWORD)lpNewItem);
@@ -1774,7 +1798,7 @@
     POPUPMENU *menu;
 
     if (!(hmenu = CreateMenu())) return 0;
-    menu = (POPUPMENU *) USER_HEAP_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
     menu->wFlags |= MF_POPUP;
     return hmenu;
 }
@@ -1825,9 +1849,9 @@
     HMENU hMenu;
     LPPOPUPMENU menu;
     dprintf_menu(stddeb,"CreateMenu !\n");
-    if (!(hMenu = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(POPUPMENU) )))
+    if (!(hMenu = USER_HEAP_ALLOC( sizeof(POPUPMENU) )))
 	return 0;
-    menu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+    menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
     menu->hNext  = 0;
     menu->wFlags = 0;
     menu->wMagic = MENU_MAGIC;
@@ -1851,7 +1875,7 @@
 	LPPOPUPMENU lppop;
 	dprintf_menu(stddeb,"DestroyMenu (%04X) !\n", hMenu);
 	if (hMenu == 0) return FALSE;
-	lppop = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+	lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
 	if (lppop == NULL) return FALSE;
 	if ((lppop->wFlags & MF_POPUP) && lppop->hWnd)
             DestroyWindow( lppop->hWnd );
@@ -1859,7 +1883,7 @@
 	if (lppop->hItems)
 	{
 	    int i;
-	    MENUITEM *item = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+	    MENUITEM *item = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
 	    for (i = lppop->nItems; i > 0; i--, item++)
 	    {
 		if (item->item_flags & MF_POPUP)
@@ -1929,7 +1953,7 @@
 	wndPtr->wIDmenu = hMenu;
 	if (hMenu != 0)
 	{
-	    lpmenu = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu);
+	    lpmenu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
 	    if (lpmenu == NULL) {
 		fprintf(stderr,"SetMenu(%04X, %04X) // Bad menu handle !\n", 
 			hWnd, hMenu);
@@ -1954,9 +1978,9 @@
     LPPOPUPMENU lppop;
     LPMENUITEM 	lpitem;
     dprintf_menu(stddeb,"GetSubMenu (%04X, %04X) !\n", hMenu, nPos);
-    if (!(lppop = (LPPOPUPMENU) USER_HEAP_ADDR(hMenu))) return 0;
+    if (!(lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu))) return 0;
     if ((WORD)nPos >= lppop->nItems) return 0;
-    lpitem = (MENUITEM *) USER_HEAP_ADDR( lppop->hItems );
+    lpitem = (MENUITEM *) USER_HEAP_LIN_ADDR( lppop->hItems );
     if (!(lpitem[nPos].item_flags & MF_POPUP)) return 0;
     return lpitem[nPos].item_id;
 }
@@ -1975,7 +1999,7 @@
 		wndPtr->wIDmenu != 0) {
 		dprintf_menu(stddeb,"DrawMenuBar wIDmenu=%04X \n", 
 			     wndPtr->wIDmenu);
-		lppop = (LPPOPUPMENU) USER_HEAP_ADDR(wndPtr->wIDmenu);
+		lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(wndPtr->wIDmenu);
 		if (lppop == NULL) return;
 
 		lppop->Height = 0; /* Make sure we call MENU_MenuBarCalcSize */
@@ -2035,7 +2059,7 @@
 	dprintf_menu(stddeb,"No SYSMENU\n");
 	return 0;
     }
-    menu = (POPUPMENU*) USER_HEAP_ADDR(hMenu);
+    menu = (POPUPMENU*) USER_HEAP_LIN_ADDR(hMenu);
     menu->wFlags |= MF_SYSMENU|MF_POPUP;
     dprintf_menu(stddeb,"CopySysMenu hMenu=%04X !\n", hMenu);
     return hMenu;
@@ -2088,6 +2112,6 @@
 BOOL IsMenu( HMENU hmenu )
 {
     LPPOPUPMENU menu;
-    if (!(menu = (LPPOPUPMENU) USER_HEAP_ADDR( hmenu ))) return FALSE;
+    if (!(menu = (LPPOPUPMENU) USER_HEAP_LIN_ADDR( hmenu ))) return FALSE;
     return (menu->wMagic == MENU_MAGIC);
 }
diff --git a/controls/scroll.c b/controls/scroll.c
index e335ade..b6a7e3c 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -109,9 +109,9 @@
 
     if (!handle)  /* Create the info structure if needed */
     {
-        if ((handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(SCROLLINFO) )))
+        if ((handle = USER_HEAP_ALLOC( sizeof(SCROLLINFO) )))
         {
-            SCROLLINFO *infoPtr = (SCROLLINFO *) USER_HEAP_ADDR( handle );
+            SCROLLINFO *infoPtr = (SCROLLINFO *) USER_HEAP_LIN_ADDR( handle );
             infoPtr->MinVal = infoPtr->CurVal = 0;
             infoPtr->MaxVal = 100;
             infoPtr->flags  = ESB_ENABLE_BOTH;
@@ -120,7 +120,7 @@
         }
         if (!hUpArrow) SCROLL_LoadBitmaps();
     }
-    return (SCROLLINFO *) USER_HEAP_ADDR( handle );
+    return (SCROLLINFO *) USER_HEAP_LIN_ADDR( handle );
 }
 
 
@@ -204,7 +204,7 @@
  * from the top of the scroll-bar.
  */
 static UINT SCROLL_GetThumbVal( SCROLLINFO *infoPtr, RECT *rect,
-                                WORD arrowSize, BOOL vertical, WORD pos )
+                                BOOL vertical, WORD pos )
 {
     int pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
     if ((pixels -= 3*SYSMETRICS_CXVSCROLL+1) <= 0) return infoPtr->MinVal;
@@ -631,7 +631,7 @@
                 SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize,
                                        trackThumbPos + pos - lastClickPos );
                 lastMousePos = pos;
-                val = SCROLL_GetThumbVal( infoPtr, &rect, vertical, arrowSize,
+                val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
                                  trackThumbPos + lastMousePos - lastClickPos );
                 SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                              SB_THUMBTRACK, MAKELONG( val, hwndCtl ));
@@ -673,7 +673,7 @@
     {
         if (trackHitTest == SCROLL_THUMB)
         {
-            UINT val = SCROLL_GetThumbVal( infoPtr, &rect, vertical, arrowSize,
+            UINT val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
                                  trackThumbPos + lastMousePos - lastClickPos );
             SendMessage( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
                          SB_THUMBPOSITION, MAKELONG( val, hwndCtl ) );
@@ -697,7 +697,7 @@
     {
     case WM_CREATE:
         {
-	    CREATESTRUCT *lpCreat = (CREATESTRUCT *)lParam;
+	    CREATESTRUCT *lpCreat = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
             if (lpCreat->style & SBS_SIZEBOX)
             {
                 fprintf( stdnimp, "Unimplemented style SBS_SIZEBOX.\n" );
diff --git a/controls/static.c b/controls/static.c
index 3191604..063ad23 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -88,10 +88,10 @@
         case WM_NCCREATE:
 	    if (style == SS_ICON)
             {
-		CREATESTRUCT * createStruct = (CREATESTRUCT *)lParam;
+		CREATESTRUCT * createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
 		if (createStruct->lpszName)
                     STATIC_SetIcon( hWnd, LoadIcon( createStruct->hInstance,
-                                                    createStruct->lpszName ));
+                                             (SEGPTR)createStruct->lpszName ));
                 return 1;
             }
             return DefWindowProc(hWnd, uMsg, wParam, lParam);
@@ -136,9 +136,9 @@
 	case WM_SETTEXT:
 	    if (style == SS_ICON)
                 STATIC_SetIcon( hWnd, LoadIcon( wndPtr->hInstance,
-                                                (LPSTR)lParam ) );
+                                                (SEGPTR)lParam ));
             else
-                DEFWND_SetText( hWnd, (LPSTR)lParam );
+                DEFWND_SetText( hWnd, (LPSTR)PTR_SEG_TO_LIN(lParam) );
 	    InvalidateRect( hWnd, NULL, FALSE );
 	    UpdateWindow( hWnd );
 	    break;
@@ -192,7 +192,7 @@
     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
 
     GetClientRect(hwnd, &rc);
-    text = USER_HEAP_ADDR( wndPtr->hText );
+    text = USER_HEAP_LIN_ADDR( wndPtr->hText );
 
     switch (style & 0x0000000F)
     {
diff --git a/controls/widgets.c b/controls/widgets.c
index 932594e..20e22dc 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -13,6 +13,7 @@
 #include "desktop.h"
 #include "mdi.h"
 #include "gdi.h"
+#include "user.h"
 
 LONG ListBoxWndProc  ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
 LONG ComboBoxWndProc ( HWND hwnd, WORD message, WORD wParam, LONG lParam );
@@ -34,7 +35,7 @@
       0, 0, 0, 0, NULL, "LISTBOX" },
     { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, ComboBoxWndProc, 0, 8,
       0, 0, 0, 0, NULL, "COMBOBOX" },
-    { CS_GLOBALCLASS | CS_PARENTDC, EditWndProc, 0, 4, 
+    { CS_GLOBALCLASS | CS_PARENTDC, EditWndProc, 0, sizeof(WORD), 
       0, 0, 0, 0, NULL, "EDIT" },
     { CS_GLOBALCLASS | CS_SAVEBITS, PopupMenuWndProc, 0, 8,
       0, 0, 0, 0, NULL, POPUPMENU_CLASS_NAME },
@@ -58,12 +59,19 @@
 BOOL WIDGETS_Init(void)
 {
     int i;
+    HANDLE hName;
+    char *name;
     WNDCLASS *class = WIDGETS_BuiltinClasses;
 
+    if (!(hName = USER_HEAP_ALLOC( 20 ))) return FALSE;
+    name = USER_HEAP_LIN_ADDR( hName );
     for (i = 0; i < NB_BUILTIN_CLASSES; i++, class++)
     {
+        strcpy( name, class->lpszClassName );
+        class->lpszClassName = (LPSTR)USER_HEAP_SEG_ADDR( hName );
 	class->hCursor = LoadCursor( 0, IDC_ARROW );
 	if (!RegisterClass( class )) return FALSE;
     }
+    USER_HEAP_FREE( hName );
     return TRUE;
 }
diff --git a/debugger/break.c b/debugger/break.c
index 2c276da..b3945ee 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -6,6 +6,7 @@
 #include <sys/utsname.h>
 #endif
 #include <windows.h>
+#include "db_disasm.h"
 
 #define N_BP 25
 
@@ -140,7 +141,7 @@
    unsigned int addr;
    addr=wbp[num].addr;
    if(wbp[num].next_addr == 0)
-	wbp[num].next_addr=addr+print_insn(addr,addr,stderr,dbg_mode);
+	wbp[num].next_addr = db_disasm( addr, 0, (dbg_mode == 16) );
    wbp[num].addr=wbp[num].next_addr;
    wbp[num].next_addr=addr;
 }
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 5cb26fd..568a933 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -72,6 +72,7 @@
 #endif
 #include <stdio.h>
 #include "db_disasm.h"
+#include "ldt.h"
 
 /*
  * Switch to disassemble 16-bit code.
@@ -888,9 +889,10 @@
 	10,	/* EXTR */
 };
 
-unsigned int db_get_task_value(unsigned int loc, int size, int is_signed)
+static unsigned int db_get_task_value(unsigned int loc, int size, int is_signed)
 {
   unsigned int result;
+  if (db_disasm_16) loc = (unsigned int)PTR_SEG_TO_LIN(loc);
   switch(size)
     {
     case 4:
@@ -921,7 +923,8 @@
 
 #define	get_value_inc(result, loc, size, is_signed) \
 	result = db_get_task_value((loc), (size), (is_signed)); \
-	(loc) += (size);
+        if (!db_disasm_16) (loc) += (size); \
+        else (loc) = ((loc) & 0xffff0000) | (((loc) + (size)) & 0xffff);
 
 /*
  * Read address at location and return updated location.
@@ -1011,6 +1014,23 @@
 	return (loc);
 }
 
+static void db_task_printsym(unsigned int addr, int size)
+{
+    extern void print_address(unsigned int addr, FILE * outfile, int addrlen);
+    switch(size)
+    {
+    case BYTE:
+        fprintf(stderr, "0x%2.2x", addr & 0xff );
+        break;
+    case WORD:
+        fprintf(stderr, "0x%4.4x", addr & 0xffff );
+        break;
+    case LONG:
+        print_address(addr, stderr, db_disasm_16 ? 16 : 32);
+        break;
+    }
+}
+
 void
 db_print_address(seg, size, addrp)
 	char *		seg;
@@ -1035,7 +1055,7 @@
 		fprintf(stderr,",%s,%d", addrp->index, 1<<addrp->ss);
 	    fprintf(stderr,")");
 	} else
-	    db_task_printsym((db_addr_t)addrp->disp);
+	    db_task_printsym((db_addr_t)addrp->disp, size);
 }
 
 /*
@@ -1418,7 +1438,8 @@
 		    if (seg)
 			fprintf(stderr,"%s:%d",seg, displ);
 		    else
-			db_task_printsym((db_addr_t)displ);
+			db_task_printsym((db_addr_t)displ,
+                                         short_addr ? WORD : LONG);
 		    break;
 
 		case Db:
@@ -1430,7 +1451,8 @@
 		    }
 		    else
 			displ = displ + loc;
-		    db_task_printsym((db_addr_t)displ);
+		    db_task_printsym((db_addr_t)displ,
+                                     short_addr ? WORD : LONG);
 		    break;
 
 		case Dl:
@@ -1444,7 +1466,8 @@
 			get_value_inc(displ, loc, 4, TRUE);
 			displ = displ + loc;
 		    }
-		    db_task_printsym((db_addr_t)displ);
+		    db_task_printsym((db_addr_t)displ,
+                                     short_addr ? WORD : LONG);
 		    break;
 
 		case o1:
diff --git a/debugger/dbg.y b/debugger/dbg.y
index d1992f6..54d5992 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -10,6 +10,7 @@
 
 #include <stdio.h>
 #include <signal.h>
+#include "ldt.h"
 
 #define YYSTYPE int
 
@@ -116,8 +117,8 @@
 	
  infocmd: INFO REGS     { info_reg(); }
 	| INFO STACK    { info_stack(); }
+	| INFO SEGMENTS { LDT_Print(); }
 	| INFO BREAK    { info_break(); }
-	| INFO SEGMENTS { print_ldt(); }
 
 
 %%
@@ -197,7 +198,7 @@
 	    int bpnum;
 	    addr = SC_EIP(dbg_mask);
 	    if((addr & 0xffff0000) == 0 && dbg_mode == 16)
-	      addr |= SC_CS << 16;
+	      addr = PTR_SEG_OFF_TO_LIN( SC_CS, addr );
 	    if(should_continue(bpnum=get_bpnum(addr))){
 		insert_break(1);
 		return;
diff --git a/debugger/hash.c b/debugger/hash.c
index cba6ce2..1bce11a 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -10,7 +10,6 @@
 #include <string.h>
 #include <sys/types.h>
 #include <neexe.h>
-#include <segmem.h>
 #include "selectors.h"
 #include <wine.h>
 #include <dlls.h>
@@ -168,7 +167,7 @@
 			j = GetEntryPointFromOrdinal(wpnt, ordinal);		
 			address  = j & 0xffff;
 			j = j >> 16;
-			address |= (wpnt->ne->selector_table[j].selector) << 16;
+			address |= wpnt->ne->selector_table[j] << 16;
 			fprintf(stderr,"%s -> %x\n", buffer, address);
 			add_hash(buffer, (unsigned int *) address);
 			cpnt += len + 2;
diff --git a/debugger/info.c b/debugger/info.c
index 3f640da..9506240 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -6,6 +6,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include "ldt.h"
 #include "db_disasm.h"
 #include "regpos.h"
 
@@ -18,60 +19,24 @@
   fprintf(stderr,"Application not running\n");
 }
 
-void print_address(unsigned int addr, FILE * outfile){
-	char * name;
-	extern char * find_nearest_symbol(unsigned int *);
+void print_address(unsigned int addr, FILE * outfile, int addrlen)
+{
+    if (addrlen == 16)
+    {
+        fprintf( outfile, "%4.4x:%4.4x", addr >> 16, addr & 0xffff );
+    }
+    else
+    {
+        extern char * find_nearest_symbol(unsigned int *);
 
-	name = find_nearest_symbol((unsigned int *) addr);
+        char * name = find_nearest_symbol((unsigned int *) addr);
 	if(name)
 		fprintf(outfile,"0x%8.8x(%s)", addr, name);
 	else
 		fprintf(outfile,"0x%8.8x", addr);
-
+    }
 }
 
-#ifdef GNU_DISASM
-void print_address_info(bfd_vma addr, disassemble_info * info){
-	print_address((unsigned int) addr, info->stream);
-}
-
-int print_insn(char *realmemaddr, char *memaddr, FILE *stream, int addrlen){
-	static disassemble_info info;
-	static int initialized = 0;
-
-	if (!initialized) {
-		INIT_DISASSEMBLE_INFO(info, stderr);
-		info.print_address_func = print_address_info;
-		initialized = 1;
-	}
-	info.stream = stream;
-	info.buffer = memaddr;
-	info.buffer_vma = (bfd_vma) realmemaddr;
-	info.buffer_length = 1024;
-	if (addrlen == 16)
-		return print_insn_i286((bfd_vma) realmemaddr, &info);
-	if (addrlen == 32)
-		return print_insn_i386((bfd_vma) realmemaddr, &info);
-	fprintf(stderr, "invalid address length %d.\n", addrlen);
-	return 0;
-}
-#else
-void db_task_printsym(unsigned int addr){
-  print_address(addr, stderr);
-}
-
-int print_insn(char *realmemaddr, char *memaddr, FILE *stream, int addrlen)
-{
-	if (addrlen == 16)
-		return db_disasm((unsigned int) realmemaddr, 0, 1) - 
-			((unsigned int) realmemaddr);
-	if (addrlen == 32)
-	    return db_disasm((unsigned int) realmemaddr, 0, 0) -
-	      ((unsigned int) realmemaddr);
-	fprintf(stderr, "invalid address length %d.\n", addrlen);
-	return 0;
-}
-#endif
 
 void info_reg(){
 
@@ -128,18 +93,17 @@
 	int i;
 
 	if((addr & 0xffff0000) == 0 && dbg_mode == 16)
-	        addr |= (format == 'i' ? SC_CS : SC_DS) << 16;
-
+            addr |= (format == 'i' ? SC_CS : SC_DS) << 16;
 
 	if(format != 'i' && count > 1) {
-		print_address(addr, stderr);
+		print_address(addr, stderr, dbg_mode);
 		fprintf(stderr,":  ");
 	};
 
-
 	switch(format){
 	case 's':
-		pnt = (char *) addr;
+		pnt = dbg_mode == 16 ? (char *)PTR_SEG_TO_LIN(addr)
+                                     : (char *)addr;
 		if (count == 1) count = 256;
 	        while(*pnt && count) {
 			fputc( *pnt++, stderr);
@@ -150,20 +114,22 @@
 
 	case 'i':
 		for(i=0; i<count; i++) {
-			print_address(addr, stderr);
+			print_address(addr, stderr, dbg_mode);
 			fprintf(stderr,":  ");
-			addr += print_insn((char *) addr, (char *) addr, stderr, dbg_mode);
+			addr = db_disasm( addr, 0, (dbg_mode == 16) );
 			fprintf(stderr,"\n");
 		};
 		return;
 	case 'x':
-		dump = (unsigned int *) addr;
+		dump = dbg_mode == 16 ? (unsigned int *)PTR_SEG_TO_LIN(addr)
+                                      : (unsigned int *)addr;
 		for(i=0; i<count; i++) 
 		{
 			fprintf(stderr," %8.8x", *dump++);
+                        addr += 4;
 			if ((i % 8) == 7) {
 				fprintf(stderr,"\n");
-				print_address((unsigned int) dump, stderr);
+				print_address(addr, stderr, dbg_mode);
 				fprintf(stderr,":  ");
 			};
 		}
@@ -171,13 +137,15 @@
 		return;
 	
 	case 'd':
-		dump = (unsigned int *) addr;
+		dump = dbg_mode == 16 ? (unsigned int *)PTR_SEG_TO_LIN(addr)
+                                      : (unsigned int *)addr;
 		for(i=0; i<count; i++) 
 		{
 			fprintf(stderr," %d", *dump++);
+                        addr += 4;
 			if ((i % 8) == 7) {
 				fprintf(stderr,"\n");
-				print_address((unsigned int) dump, stderr);
+				print_address(addr, stderr, dbg_mode);
 				fprintf(stderr,":  ");
 			};
 		}
@@ -185,13 +153,15 @@
 		return;
 	
 	case 'w':
-		wdump = (unsigned short int *) addr;
+		wdump = dbg_mode == 16 ? (unsigned short *)PTR_SEG_TO_LIN(addr)
+                                       : (unsigned short *)addr;
 		for(i=0; i<count; i++) 
 		{
 			fprintf(stderr," %x", *wdump++);
+                        addr += 2;
 			if ((i % 10) == 7) {
 				fprintf(stderr,"\n");
-				print_address((unsigned int) wdump, stderr);
+				print_address(addr, stderr, dbg_mode);
 				fprintf(stderr,":  ");
 			};
 		}
@@ -199,7 +169,8 @@
 		return;
 	
 	case 'c':
-		pnt = (char *) addr;
+		pnt = dbg_mode == 16 ? (char *)PTR_SEG_TO_LIN(addr)
+                                     : (char *)addr;
 		for(i=0; i<count; i++) 
 		{
 			if(*pnt < 0x20) {
@@ -207,9 +178,10 @@
 				pnt++;
 			} else
 				fprintf(stderr," %c", *pnt++);
+                        addr++;
 			if ((i % 32) == 7) {
 				fprintf(stderr,"\n");
-				print_address((unsigned int) pnt, stderr);
+				print_address(addr, stderr, dbg_mode);
 				fprintf(stderr,":  ");
 			};
 		}
@@ -217,13 +189,15 @@
 		return;
 	
 	case 'b':
-		pnt = (char *) addr;
+		pnt = dbg_mode == 16 ? (char *)PTR_SEG_TO_LIN(addr)
+                                     : (char *)addr;
 		for(i=0; i<count; i++) 
 		{
 			fprintf(stderr," %02x", (*pnt++) & 0xff);
+                        addr++;
 			if ((i % 32) == 7) {
 				fprintf(stderr,"\n");
-				print_address((unsigned int) pnt, stderr);
+				print_address(addr, stderr, dbg_mode);
 				fprintf(stderr,":  ");
 			};
 		}
@@ -293,26 +267,32 @@
     return;
   }
 
-  frame = (struct frame *) ((SC_EBP(dbg_mask) & ~1) | (SC_SS << 16));
+  if (dbg_mode == 16)
+      frame = (struct frame *)PTR_SEG_OFF_TO_LIN( SC_SS, SC_BP & ~1 );
+  else
+      frame = (struct frame *)SC_EBP(dbg_mask);
 
   fprintf(stderr,"Backtrace:\n");
-  fprintf(stderr,"%d ",frameno);
-  print_address(frame->u.win32.saved_ip,stderr);
   cs = SC_CS;
   while((cs & 3) == 3) {
     /* See if in 32 bit mode or not.  Assume GDT means 32 bit. */
     if ((cs & 7) != 7) {
       void CallTo32();
-      fprintf(stderr,"\n%d ",frameno++);
-      print_address(frame->u.win32.saved_ip,stderr);
+      fprintf(stderr,"%d ",frameno++);
+      print_address(frame->u.win32.saved_ip,stderr,32);
+      fprintf( stderr, "\n" );
       if(frame->u.win32.saved_ip<((unsigned long)CallTo32+1000))break;
       frame = (struct frame *) frame->u.win32.saved_bp;
     } else {
-      cs = frame->u.win16.saved_cs;
+      if (frame->u.win16.saved_bp & 1) cs = frame->u.win16.saved_cs;
       fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
 	      frame->u.win16.saved_ip);
-      frame = (struct frame *) ((frame->u.win16.saved_bp & ~1) |
-				(SC_SS << 16));
+      frame = (struct frame *) PTR_SEG_OFF_TO_LIN( SC_SS, frame->u.win16.saved_bp & ~1);
+      if ((cs & 7) != 7)  /* switching to 32-bit mode */
+      {
+          extern int IF1632_Saved32_ebp;
+          frame = (struct frame *)IF1632_Saved32_ebp;
+      }
     }
   }
   putchar('\n');
diff --git a/debugger/regpos.h b/debugger/regpos.h
index 01d2e00..39d4b5e 100644
--- a/debugger/regpos.h
+++ b/debugger/regpos.h
@@ -64,6 +64,14 @@
 #define  SC_EDX(dbg_mask)	(regval[RN_EDX] & dbg_mask)
 #define  SC_ECX(dbg_mask)	(regval[RN_ECX] & dbg_mask)
 #define  SC_EAX(dbg_mask)	(regval[RN_EAX] & dbg_mask)
+#define  SC_DI                  (regval[RN_EDI] & 0xffff)
+#define  SC_SI                  (regval[RN_ESI] & 0xffff)
+#define  SC_BP                  (regval[RN_EBP] & 0xffff)
+#define  SC_SP                  (regval[RN_ESP] & 0xffff)
+#define  SC_BX                  (regval[RN_EBX] & 0xffff)
+#define  SC_DX                  (regval[RN_EDX] & 0xffff)
+#define  SC_CX                  (regval[RN_ECX] & 0xffff)
+#define  SC_AX                  (regval[RN_EAX] & 0xffff)
 #define  SC_TRAPNO		regval[RN_TRAPNO]
 #define  SC_ERR			regval[RN_ERR]
 #define  SC_EIP(dbg_mask)	(regval[RN_EIP] & dbg_mask)
diff --git a/if1632/Imakefile b/if1632/Imakefile
index 4f13cb9..85ef1ea 100644
--- a/if1632/Imakefile
+++ b/if1632/Imakefile
@@ -14,6 +14,7 @@
 CALLOBJS = call.o
 DLLOBJS = \
 	dll_commdlg.o \
+	dll_compobj.o \
 	dll_gdi.o \
 	dll_kernel.o \
 	dll_keyboard.o \
@@ -28,10 +29,10 @@
 	dll_olesvr.o \
 	dll_shell.o \
 	dll_sound.o \
+	dll_storage.o \
 	dll_stress.o \
 	dll_system.o \
 	dll_toolhelp.o \
-	dll_unixlib.o \
 	dll_user.o \
 	dll_win87em.o \
 	dll_winsock.o
@@ -47,6 +48,7 @@
  * If you add a new spec file, copy one of these lines
  */
 MakeDllFromSpec(commdlg)
+MakeDllFromSpec(compobj)
 MakeDllFromSpec(gdi)
 MakeDllFromSpec(kernel)
 MakeDllFromSpec(keyboard)
@@ -61,10 +63,10 @@
 MakeDllFromSpec(olecli)
 MakeDllFromSpec(olesvr)
 MakeDllFromSpec(sound)
+MakeDllFromSpec(storage)
 MakeDllFromSpec(stress)
 MakeDllFromSpec(system)
 MakeDllFromSpec(toolhelp)
-MakeDllFromSpec(unixlib)
 MakeDllFromSpec(user)
 MakeDllFromSpec(win87em)
 MakeDllFromSpec(winsock)
diff --git a/if1632/call.S b/if1632/call.S
index d1958d3..e6ab7b3 100644
--- a/if1632/call.S
+++ b/if1632/call.S
@@ -321,7 +321,6 @@
  	 * Save registers.  286 mode does not have fs or gs.
 	 */
 	pushw	%ds
-	pushw	%es
 
 	/*
 	 * Restore segment registers.
@@ -372,7 +371,6 @@
 	popw	A(IF1632_Saved16_bp)
 	popw	A(IF1632_Saved16_sp)
 
-	popw	%es
 	popw	%ds
 	popw	%bp
 
@@ -423,7 +421,6 @@
  	 * Save registers.  286 mode does not have fs or gs.
 	 */
 	pushw	%ds
-	pushw	%es
 
 	/*
 	 * Restore segment registers.
@@ -474,7 +471,6 @@
 	popw	A(IF1632_Saved16_bp)
 	popw	A(IF1632_Saved16_sp)
 
-	popw	%es
 	popw	%ds
 	popw	%bp
 
@@ -515,7 +511,6 @@
 	popw	A(IF1632_Saved16_bp)
 	popw	A(IF1632_Saved16_sp)
 
-	popw	%es
 	popw	%ds
 	popw	%bp
 
diff --git a/if1632/callback.c b/if1632/callback.c
index 2bb4dbc..db210f2 100644
--- a/if1632/callback.c
+++ b/if1632/callback.c
@@ -6,32 +6,39 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <strings.h>
 #include "windows.h"
 #include "callback.h"
 #include "wine.h"
-#include "segmem.h"
 #include <setjmp.h>
+#include "ldt.h"
 #include "stackframe.h"
 #include "dlls.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "if1632.h"
 
-extern unsigned short IF1632_Saved16_ss;
-extern unsigned short IF1632_Saved16_bp;
-extern unsigned short IF1632_Saved16_sp;
 extern unsigned short IF1632_Saved32_ss;
 extern unsigned long  IF1632_Saved32_ebp;
 extern unsigned long  IF1632_Saved32_esp;
 
-extern struct segment_descriptor_s *MakeProcThunks;
+static WORD ThunkSelector = 0;
 
 struct thunk_s
 {
     int used;
-    unsigned char thunk[10];
+    unsigned char thunk[8];
 };
 
+#ifdef __ELF__
+#define FIRST_SELECTOR 2
+#define IS_16_BIT_ADDRESS(addr)  \
+    (((unsigned int)(addr) < 0x8000000) || ((unsigned int)(addr) >= 0x8400000))
+#else
+#define FIRST_SELECTOR	8
+#define IS_16_BIT_ADDRESS(addr)  \
+     ((unsigned int)(addr) >= (((FIRST_SELECTOR << __AHSHIFT) | 7) << 16))
+#endif
 
 /**********************************************************************
  *					PushOn16
@@ -39,8 +46,7 @@
 static void
 PushOn16(int size, unsigned int value)
 {
-    char *p = (char *) (((unsigned int)IF1632_Saved16_ss << 16) +
-			IF1632_Saved16_sp);
+    char *p = PTR_SEG_OFF_TO_LIN( IF1632_Saved16_ss, IF1632_Saved16_sp );
     if (size)
     {
 	unsigned long *lp = (unsigned long *) p - 1;
@@ -67,7 +73,8 @@
     va_list ap;
     int i;
     int arg_type, arg_value;
-    
+    WORD ds = CURRENT_DS;
+
     va_start(ap, n_args);
 
     for (i = 0; i < n_args; i++)
@@ -79,36 +86,50 @@
 
     va_end(ap);
 
-    return CallTo16((unsigned int) func, pStack16Frame->ds );
+    return CallTo16((unsigned int) func, ds );
 }
 
 /**********************************************************************
- *					CALLBACK_MakeProcInstance
+ *					MakeProcInstance
  */
-void *
-CALLBACK_MakeProcInstance(void *func, int instance)
+FARPROC MakeProcInstance( FARPROC func, WORD instance )
 {
+    char *thunks;
     struct thunk_s *tp;
     int i;
-    
-    tp = (struct thunk_s *) MakeProcThunks->base_addr;
+
+    if (!ThunkSelector)
+    {
+        ldt_entry entry;
+
+          /* Allocate a segment for thunks */
+        ThunkSelector = AllocSelector( 0 );
+        entry.base           = (unsigned long) malloc( 0x10000 );
+        entry.limit          = 0xffff;
+        entry.seg_32bit      = 0;
+        entry.limit_in_pages = 0;
+        entry.type           = SEGMENT_CODE;
+        entry.read_only      = 0;
+        memset( (char *)entry.base, 0, 0x10000 );
+        LDT_SetEntry( SELECTOR_TO_ENTRY(ThunkSelector), &entry );
+    }
+
+    thunks = (char *)PTR_SEG_OFF_TO_LIN( ThunkSelector, 0 );
+    tp = (struct thunk_s *) thunks;
     for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
 	if (!tp->used)
 	    break;
     
-    if (tp->used)
-	return (void *) 0;
+    if (tp->used) return (FARPROC)0;
     
-    tp->thunk[0] = 0xb8;
+    tp->thunk[0] = 0xb8;    /* movw instance, %ax */
     tp->thunk[1] = (unsigned char) instance;
     tp->thunk[2] = (unsigned char) (instance >> 8);
-    tp->thunk[3] = 0x8e;
-    tp->thunk[4] = 0xd8;
-    tp->thunk[5] = 0xea;
-    memcpy(&tp->thunk[6], &func, 4);
+    tp->thunk[3] = 0xea;    /* ljmp func */
+    *(LONG *)&tp->thunk[4] = (LONG)func;
     tp->used = 1;
 
-    return tp->thunk;
+    return (FARPROC)MAKELONG( (char *)tp->thunk - thunks, ThunkSelector );
 }
 
 /**********************************************************************
@@ -119,7 +140,7 @@
     struct thunk_s *tp;
     int i;
     
-    tp = (struct thunk_s *) MakeProcThunks->base_addr;
+    tp = (struct thunk_s *) PTR_SEG_OFF_TO_LIN( ThunkSelector, 0 );
     for (i = 0; i < 0x10000 / sizeof(*tp); i++, tp++)
     {
 	if ((void *) tp->thunk == (void *) func)
@@ -183,13 +204,14 @@
     }
     else if (IS_16_BIT_ADDRESS(func))
     {	
+        WORD ds = CURRENT_DS;
 	dprintf_callback(stddeb, "CallWindowProc // 16bit func=%08x ds=%04x!\n", 
-		(unsigned int) func, pStack16Frame->ds );
+		(unsigned int) func, ds );
 	PushOn16( CALLBACK_SIZE_WORD, hwnd );
 	PushOn16( CALLBACK_SIZE_WORD, message );
 	PushOn16( CALLBACK_SIZE_WORD, wParam );
 	PushOn16( CALLBACK_SIZE_LONG, lParam );
-	return CallTo16((unsigned int) func, pStack16Frame->ds );
+	return CallTo16((unsigned int) func, ds );
     }
     else
     {
@@ -204,12 +226,13 @@
  */
 void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam)
 {
+    WORD ds = CURRENT_DS;
     if (IS_16_BIT_ADDRESS(func))
     {
 	PushOn16( CALLBACK_SIZE_WORD, xPos );
 	PushOn16( CALLBACK_SIZE_WORD, yPos );
 	PushOn16( CALLBACK_SIZE_LONG, lParam );
-	CallTo16((unsigned int) func, pStack16Frame->ds );
+	CallTo16((unsigned int) func, ds );
     }
     else
     {
@@ -222,12 +245,13 @@
  */
 DWORD CallHookProc( HOOKPROC func, short code, WPARAM wParam, LPARAM lParam )
 {
+    WORD ds = CURRENT_DS;
     if (IS_16_BIT_ADDRESS(func))
     {
 	PushOn16( CALLBACK_SIZE_WORD, code );
 	PushOn16( CALLBACK_SIZE_WORD, wParam );
 	PushOn16( CALLBACK_SIZE_LONG, lParam );
-	return CallTo16((unsigned int) func, pStack16Frame->ds );
+	return CallTo16((unsigned int) func, ds );
     }
     else
     {
@@ -240,12 +264,13 @@
  */
 BOOL CallGrayStringProc(FARPROC func, HDC hdc, LPARAM lParam, INT cch )
 {
+    WORD ds = CURRENT_DS;
     if (IS_16_BIT_ADDRESS(func))
     {
 	PushOn16( CALLBACK_SIZE_WORD, hdc );
 	PushOn16( CALLBACK_SIZE_LONG, lParam );
 	PushOn16( CALLBACK_SIZE_WORD, cch );
-	return CallTo16((unsigned int) func, pStack16Frame->ds );
+	return CallTo16((unsigned int) func, ds );
     }
     else
     {
diff --git a/if1632/commdlg.spec b/if1632/commdlg.spec
index c52227b..d988e11 100644
--- a/if1632/commdlg.spec
+++ b/if1632/commdlg.spec
@@ -1,31 +1,31 @@
 # $Id: commdlg.spec,v 1.3 1994/20/08 04:04:21 root Exp root $
 #
 name	commdlg
-id	15
+id	14
 length	31
 
-  1   pascal  GETOPENFILENAME(ptr) GetOpenFileName(1)
-  2   pascal  GETSAVEFILENAME(ptr) GetSaveFileName(1)
-  5   pascal  CHOOSECOLOR(ptr) ChooseColor(1)
-  6   pascal  FILEOPENDLGPROC(word word word long) FileOpenDlgProc(1 2 3 4)
-  7   pascal  FILESAVEDLGPROC(word word word long) FileSaveDlgProc(1 2 3 4)
-  8   pascal  COLORDLGPROC(word word word long) ColorDlgProc(1 2 3 4)
+  1   pascal  GETOPENFILENAME(ptr) GetOpenFileName
+  2   pascal  GETSAVEFILENAME(ptr) GetSaveFileName
+  5   pascal  CHOOSECOLOR(ptr) ChooseColor
+  6   pascal  FILEOPENDLGPROC(word word word long) FileOpenDlgProc
+  7   pascal  FILESAVEDLGPROC(word word word long) FileSaveDlgProc
+  8   pascal  COLORDLGPROC(word word word long) ColorDlgProc
 #  9   pascal  LOADALTERBITMAP exported, shared data
- 11   pascal  FINDTEXT(ptr) FindText(1)
- 12   pascal  REPLACETEXT(ptr) ReplaceText(1)
- 13   pascal  FINDTEXTDLGPROC(word word word long) FindTextDlgProc(1 2 3 4)
- 14   pascal  REPLACETEXTDLGPROC(word word word long) ReplaceTextDlgProc(1 2 3 4)
+ 11   pascal  FINDTEXT(ptr) FindText
+ 12   pascal  REPLACETEXT(ptr) ReplaceText
+ 13   pascal  FINDTEXTDLGPROC(word word word long) FindTextDlgProc
+ 14   pascal  REPLACETEXTDLGPROC(word word word long) ReplaceTextDlgProc
 # 15   pascal  CHOOSEFONT exported, shared data
 # 16   pascal  FORMATCHARDLGPROC exported, shared data
 # 18   pascal  FONTSTYLEENUMPROC exported, shared data
 # 19   pascal  FONTFAMILYENUMPROC exported, shared data
- 20   pascal  PRINTDLG(ptr) PrintDlg(1)
- 21   pascal  PRINTDLGPROC(word word word long) PrintDlgProc(1 2 3 4)
- 22   pascal  PRINTSETUPDLGPROC(word word word long) PrintSetupDlgProc(1 2 3 4)
+ 20   pascal  PRINTDLG(ptr) PrintDlg
+ 21   pascal  PRINTDLGPROC(word word word long) PrintDlgProc
+ 22   pascal  PRINTSETUPDLGPROC(word word word long) PrintSetupDlgProc
 # 23   pascal  EDITINTEGERONLY exported, shared data
 # 25   pascal  WANTARROWS exported, shared data
- 26   pascal  COMMDLGEXTENDEDERROR() CommDlgExtendError()
- 27   pascal  GETFILETITLE(ptr ptr word) GetFileTitle(1 2 3)
+ 26   pascal  COMMDLGEXTENDEDERROR() CommDlgExtendError
+ 27   pascal  GETFILETITLE(ptr ptr word) GetFileTitle
 # 28   pascal  WEP exported, shared data
 # 29   pascal  DWLBSUBCLASS exported, shared data
 # 30   pascal  DWUPARROWHACK exported, shared data
diff --git a/if1632/compobj.spec b/if1632/compobj.spec
new file mode 100644
index 0000000..a4b0993
--- /dev/null
+++ b/if1632/compobj.spec
@@ -0,0 +1,146 @@
+name	compobj
+id	22
+length	163
+
+#1 COBUILDVERSION
+#2 COINITIALIZE
+#3 COUNINITIALIZE
+#4 COGETMALLOC
+#5 COREGISTERCLASSOBJECT
+#6 COREVOKECLASSOBJECT
+#7 COGETCLASSOBJECT
+#8 COMARSHALINTERFACE
+#9 COUNMARSHALINTERFACE
+#10 COLOADLIBRARY
+#11 COFREELIBRARY
+#12 COFREEALLLIBRARIES
+#13 COCREATEINSTANCE
+#14 STRINGFROMIID
+#15 CODISCONNECTOBJECT
+#16 CORELEASEMARSHALDATA
+#17 COFREEUNUSEDLIBRARIES
+#18 ISEQUALGUID
+#19 STRINGFROMCLSID
+#20 CLSIDFROMSTRING
+#21 ISVALIDPTRIN
+#22 ISVALIDPTROUT
+#23 ISVALIDINTERFACE
+#24 ISVALIDIID
+#25 RESULTFROMSCODE
+#26 GETSCODE
+#27 COREGISTERMESSAGEFILTER
+#28 COISHANDLERCONNECTED
+#29 WEP
+#30 COFILETIMETODOSDATETIME
+#31 CODOSDATETIMETOFILETIME
+#32 COMARSHALHRESULT
+#33 COUNMARSHALHRESULT
+#34 COGETCURRENTPROCESS
+#35 ___EXPORTEDSTUB
+#36 COISOLE1CLASS
+#37 _GUID_NULL
+#38 _IID_IUNKNOWN
+#39 _IID_ICLASSFACTORY
+#40 _IID_IMALLOC
+#41 _IID_IMARSHAL
+#42 _IID_IRPCCHANNEL
+#43 _IID_IRPCSTUB
+#44 _IID_ISTUBMANAGER
+#45 _IID_IRPCPROXY
+#46 _IID_IPROXYMANAGER
+#47 _IID_IPSFACTORY
+#48 _IID_ILOCKBYTES
+#49 _IID_ISTORAGE
+#50 _IID_ISTREAM
+#51 _IID_IENUMSTATSTG
+#52 _IID_IBINDCTX
+#53 _IID_IMONIKER
+#54 _IID_IRUNNINGOBJECTTABLE
+#55 _IID_IINTERNALMONIKER
+#56 _IID_IROOTSTORAGE
+#57 _IID_IDFRESERVED1
+#58 _IID_IDFRESERVED2
+#59 _IID_IDFRESERVED3
+#60 _IID_IMESSAGEFILTER
+#61 CLSIDFROMPROGID
+#62 PROGIDFROMCLSID
+#63 COLOCKOBJECTEXTERNAL
+#64 _CLSID_STDMARSHAL
+#65 COGETTREATASCLASS
+#66 COTREATASCLASS
+#67 COGETSTANDARDMARSHAL
+#68 PROPAGATERESULT
+#69 IIDFROMSTRING
+#70 _IID_ISTDMARSHALINFO
+#71 COCREATESTANDARDMALLOC
+#72 _IID_IEXTERNALCONNECTION
+#73 COCREATEGUID
+#75 FNASSERT
+#76 STRINGFROMGUID2
+#77 COGETCLASSEXT
+#78 OLE1CLASSFROMCLSID2
+#79 CLSIDFROMOLE1CLASS
+#80 COOPENCLASSKEY
+#81 GUIDFROMSTRING
+#82 COFILETIMENOW
+#83 REMALLOCOID
+#84 REMFREEOID
+#85 REMCREATEREMOTEHANDLER
+#86 REMCONNECTTOOBJECT
+#87 REMGETINFOFORCID
+#88 LRPCCALL
+#89 LRPCDISPATCH
+#90 LRPCREGISTERMONITOR
+#91 LRPCREVOKEMONITOR
+#92 LRPCGETTHREADWINDOW
+#93 TIMERCALLBACKPROC
+#94 LOOKUPETASK
+#95 SETETASK
+#96 LRPCFREEMONITORDATA
+#97 REMLOOKUPSHUNK
+#100 ??0CARRAYFVALUE@@REC@KI@Z
+#101 ??1CARRAYFVALUE@@REC@XZ
+#102 ?ASSERTVALID@CARRAYFVALUE@@RFCXXZ
+#103 ?FREEEXTRA@CARRAYFVALUE@@RECXXZ
+#104 ?_GETAT@CARRAYFVALUE@@RFCPEXH@Z
+#105 ?GETSIZE@CARRAYFVALUE@@RFCHXZ
+#108 ?INDEXOF@CARRAYFVALUE@@RECHPEXII@Z
+#109 ?INSERTAT@CARRAYFVALUE@@RECHHPEXH@Z
+#111 ?REMOVEAT@CARRAYFVALUE@@RECXHH@Z
+#112 ?SETAT@CARRAYFVALUE@@RECXHPEX@Z
+#113 ?SETATGROW@CARRAYFVALUE@@RECHHPEX@Z
+#114 ?SETSIZE@CARRAYFVALUE@@RECHHH@Z
+#120 ?GETASSOCAT@CMAPKEYTOVALUE@@BFCPEUCASSOC@1@PEXIAEI@Z
+#121 ?SETASSOCKEY@CMAPKEYTOVALUE@@BFCHPEUCASSOC@1@PEXI@Z
+#122 ??1CMAPKEYTOVALUE@@REC@XZ
+#123 ?GETASSOCKEYPTR@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEPEXPEI@Z
+#124 ?NEWASSOC@CMAPKEYTOVALUE@@BECPEUCASSOC@1@IPEXI0@Z
+#125 ?SIZEASSOC@CMAPKEYTOVALUE@@BFCIXZ
+#126 ?FREEASSOC@CMAPKEYTOVALUE@@BECXPEUCASSOC@1@@Z
+#127 ?GETSTARTPOSITION@CMAPKEYTOVALUE@@RFCPEXXZ
+#128 ?GETNEXTASSOC@CMAPKEYTOVALUE@@RFCXPEPEXPEXPEI1@Z
+#129 ?COMPAREASSOCKEY@CMAPKEYTOVALUE@@BFCHPEUCASSOC@1@PEXI@Z
+#130 ?REMOVEHKEY@CMAPKEYTOVALUE@@RECHK@Z
+#131 ?GETHKEY@CMAPKEYTOVALUE@@RFCKPEXI@Z
+#132 ?GETCOUNT@CMAPKEYTOVALUE@@RFCHXZ
+#133 ?LOOKUP@CMAPKEYTOVALUE@@RFCHPEXI0@Z
+#134 ?GETASSOCVALUE@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEX@Z
+#135 ?REMOVEKEY@CMAPKEYTOVALUE@@RECHPEXI@Z
+#136 ?REMOVEALL@CMAPKEYTOVALUE@@RECXXZ
+#138 ?FREEASSOCKEY@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@@Z
+#139 ?SETAT@CMAPKEYTOVALUE@@RECHPEXI0@Z
+#140 ?LOOKUPHKEY@CMAPKEYTOVALUE@@RFCHKPEX@Z
+#141 ?ASSERTVALID@CMAPKEYTOVALUE@@RFCXXZ
+#142 ?SETASSOCVALUE@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEX@Z
+#143 ?SETATHKEY@CMAPKEYTOVALUE@@RECHKPEX@Z
+#144 ??0CMAPKEYTOVALUE@@REC@KIIHP7CIPEXI@ZI@Z
+#145 ?INITHASHTABLE@CMAPKEYTOVALUE@@BECHXZ
+#146 ?GETASSOCVALUEPTR@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEPEX@Z
+#147 ?LOOKUPADD@CMAPKEYTOVALUE@@RFCHPEXI0@Z
+#148 MKVDEFAULTHASHKEY
+#150 COMEMCTXOF
+#151 COMEMALLOC
+#152 COMEMFREE
+#160 CORUNMODALLOOP
+#161 COHANDLEINCOMINGCALL
+#162 COSETACKSTATE
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 45f5c94..ea11970 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -4,167 +4,159 @@
 id	3
 length	490
 
-1   pascal SetBkColor(word long) SetBkColor(1 2)
-2   pascal16 SetBkMode(word word) SetBkMode(1 2)
-3   pascal16 SetMapMode(word word) SetMapMode(1 2)
-4   pascal16 SetROP2(word word) SetROP2(1 2)
-5   pascal16 SetRelAbs(word word) SetRelAbs(1 2)
-6   pascal16 SetPolyFillMode(word word) SetPolyFillMode(1 2)
-7   pascal16 SetStretchBltMode(word word) SetStretchBltMode(1 2)
-8   pascal16 SetTextCharacterExtra(word s_word) SetTextCharacterExtra(1 2)
-9   pascal SetTextColor(word long) SetTextColor(1 2)
-10  pascal16 SetTextJustification(word s_word s_word) SetTextJustification(1 2 3)
-11  pascal SetWindowOrg(word s_word s_word) SetWindowOrg(1 2 3)
-12  pascal SetWindowExt(word s_word s_word) SetWindowExt(1 2 3)
-13  pascal SetViewportOrg(word s_word s_word) SetViewportOrg(1 2 3)
-14  pascal SetViewportExt(word s_word s_word) SetViewportExt(1 2 3)
-15  pascal OffsetWindowOrg(word s_word s_word) OffsetWindowOrg(1 2 3)
-16  pascal ScaleWindowExt(word s_word s_word s_word s_word)
-	   ScaleWindowExt(1 2 3 4 5)
-17  pascal OffsetViewportOrg(word s_word s_word) OffsetViewportOrg(1 2 3)
-18  pascal ScaleViewportExt(word s_word s_word s_word s_word)
-	   ScaleViewportExt(1 2 3 4 5)
-19  pascal16 LineTo(word s_word s_word) LineTo(1 2 3)
-20  pascal MoveTo(word s_word s_word) MoveTo(1 2 3)
-21  pascal16 ExcludeClipRect(word s_word s_word s_word s_word)
-	     ExcludeClipRect(1 2 3 4 5)
+1   pascal SetBkColor(word long) SetBkColor
+2   pascal16 SetBkMode(word word) SetBkMode
+3   pascal16 SetMapMode(word word) SetMapMode
+4   pascal16 SetROP2(word word) SetROP2
+5   pascal16 SetRelAbs(word word) SetRelAbs
+6   pascal16 SetPolyFillMode(word word) SetPolyFillMode
+7   pascal16 SetStretchBltMode(word word) SetStretchBltMode
+8   pascal16 SetTextCharacterExtra(word s_word) SetTextCharacterExtra
+9   pascal SetTextColor(word long) SetTextColor
+10  pascal16 SetTextJustification(word s_word s_word) SetTextJustification
+11  pascal SetWindowOrg(word s_word s_word) SetWindowOrg
+12  pascal SetWindowExt(word s_word s_word) SetWindowExt
+13  pascal SetViewportOrg(word s_word s_word) SetViewportOrg
+14  pascal SetViewportExt(word s_word s_word) SetViewportExt
+15  pascal OffsetWindowOrg(word s_word s_word) OffsetWindowOrg
+16  pascal ScaleWindowExt(word s_word s_word s_word s_word) ScaleWindowExt
+17  pascal OffsetViewportOrg(word s_word s_word) OffsetViewportOrg
+18  pascal ScaleViewportExt(word s_word s_word s_word s_word) ScaleViewportExt
+19  pascal16 LineTo(word s_word s_word) LineTo
+20  pascal MoveTo(word s_word s_word) MoveTo
+21  pascal16 ExcludeClipRect(word s_word s_word s_word s_word) ExcludeClipRect
 22  pascal16 IntersectClipRect(word s_word s_word s_word s_word)
-	     IntersectClipRect(1 2 3 4 5)
+             IntersectClipRect
 23  pascal16 Arc(word s_word s_word s_word s_word s_word s_word s_word s_word)
-	     Arc(1 2 3 4 5 6 7 8 9)
-24  pascal16 Ellipse(word s_word s_word s_word s_word) Ellipse(1 2 3 4 5)
-25  pascal16 FloodFill(word s_word s_word long) FloodFill(1 2 3 4)
+             Arc
+24  pascal16 Ellipse(word s_word s_word s_word s_word) Ellipse
+25  pascal16 FloodFill(word s_word s_word long) FloodFill
 26  pascal16 Pie(word s_word s_word s_word s_word s_word s_word s_word s_word)
-	     Pie(1 2 3 4 5 6 7 8 9)
-27  pascal16 Rectangle(word s_word s_word s_word s_word) Rectangle(1 2 3 4 5)
+             Pie
+27  pascal16 Rectangle(word s_word s_word s_word s_word) Rectangle
 28  pascal16 RoundRect(word s_word s_word s_word s_word s_word s_word)
-	     RoundRect(1 2 3 4 5 6 7)
-29  pascal16 PatBlt(word s_word s_word s_word s_word long) PatBlt(1 2 3 4 5 6)
-30  pascal16 SaveDC(word) SaveDC(1)
-31  pascal SetPixel(word s_word s_word long) SetPixel(1 2 3 4)
-32  pascal16 OffsetClipRgn(word s_word s_word) OffsetClipRgn(1 2 3)
-33  pascal16 TextOut(word s_word s_word ptr word) TextOut(1 2 3 4 5)
+             RoundRect
+29  pascal16 PatBlt(word s_word s_word s_word s_word long) PatBlt
+30  pascal16 SaveDC(word) SaveDC
+31  pascal SetPixel(word s_word s_word long) SetPixel
+32  pascal16 OffsetClipRgn(word s_word s_word) OffsetClipRgn
+33  pascal16 TextOut(word s_word s_word ptr word) TextOut
 34  pascal16 BitBlt( word s_word s_word s_word s_word word s_word s_word long)
-	     BitBlt(1 2 3 4 5 6 7 8 9)
-35  pascal16 StretchBlt( word s_word s_word s_word s_word word s_word s_word s_word s_word long)
-             StretchBlt(1 2 3 4 5 6 7 8 9 10 11)
-36  pascal16 Polygon (word ptr word) Polygon (1 2 3)
-37  pascal16 Polyline (word ptr word) Polyline (1 2 3)
-38  pascal Escape(word word word ptr ptr) Escape(1 2 3 4 5)
-39  pascal16 RestoreDC(word s_word) RestoreDC(1 2)
-40  pascal16 FillRgn(word word word) FillRgn(1 2 3)
+             BitBlt
+35  pascal16 StretchBlt(word s_word s_word s_word s_word word s_word s_word
+                        s_word s_word long) StretchBlt
+36  pascal16 Polygon (word ptr word) Polygon 
+37  pascal16 Polyline (word ptr word) Polyline 
+38  pascal Escape(word word word ptr ptr) Escape
+39  pascal16 RestoreDC(word s_word) RestoreDC
+40  pascal16 FillRgn(word word word) FillRgn
 #41  pascal FrameRgn
-42  pascal16 InvertRgn(word word) InvertRgn(1 2)
-43  pascal16 PaintRgn(word word) PaintRgn(1 2)
-44  pascal16 SelectClipRgn(word word) SelectClipRgn(1 2)
-45  pascal16 SelectObject(word word) SelectObject(1 2)
+42  pascal16 InvertRgn(word word) InvertRgn
+43  pascal16 PaintRgn(word word) PaintRgn
+44  pascal16 SelectClipRgn(word word) SelectClipRgn
+45  pascal16 SelectObject(word word) SelectObject
 #46  pascal __GP?
-47  pascal16 CombineRgn(word word word word) CombineRgn(1 2 3 4)
-48  pascal16 CreateBitmap(word word word word ptr) CreateBitmap(1 2 3 4 5)
-49  pascal16 CreateBitmapIndirect(ptr) CreateBitmapIndirect(1)
-50  pascal16 CreateBrushIndirect(ptr) CreateBrushIndirect(1)
-51  pascal16 CreateCompatibleBitmap(word word word) CreateCompatibleBitmap(1 2 3)
-52  pascal16 CreateCompatibleDC(word) CreateCompatibleDC(1)
-53  pascal16 CreateDC(ptr ptr ptr ptr) CreateDC(1 2 3 4)
-54  pascal16 CreateEllipticRgn(s_word s_word s_word s_word)
-	     CreateEllipticRgn(1 2 3 4)
-55  pascal16 CreateEllipticRgnIndirect(ptr) CreateEllipticRgnIndirect(1)
-56  pascal16 CreateFont(s_word s_word s_word s_word s_word word word word 
-	                word word word word word ptr)
-	     CreateFont(1 2 3 4 5 6 7 8 9 10 11 12 13 14)
-57  pascal16 CreateFontIndirect(ptr) CreateFontIndirect(1)
-58  pascal16 CreateHatchBrush(word long) CreateHatchBrush(1 2)
-60  pascal16 CreatePatternBrush(word) CreatePatternBrush(1)
-61  pascal16 CreatePen(s_word s_word long) CreatePen(1 2 3)
-62  pascal16 CreatePenIndirect(ptr) CreatePenIndirect(1)
-63  pascal16 CreatePolygonRgn(ptr word word) CreatePolygonRgn(1 2 3)
-64  pascal16 CreateRectRgn(s_word s_word s_word s_word) CreateRectRgn(1 2 3 4)
-65  pascal16 CreateRectRgnIndirect(ptr) CreateRectRgnIndirect(1)
-66  pascal16 CreateSolidBrush(long) CreateSolidBrush(1)
-67  pascal16 DPtoLP(word ptr s_word) DPtoLP(1 2 3)
-68  pascal16 DeleteDC(word) DeleteDC(1)
-69  pascal16 DeleteObject(word) DeleteObject(1)
-70  pascal16 EnumFonts(word ptr ptr ptr) EnumFonts(1 2 3 4)
-71  pascal16 EnumObjects(word word ptr ptr) EnumObjects(1 2 3 4)
-72  pascal16 EqualRgn(word word) EqualRgn(1 2)
-73  pascal16 ExcludeVisRect(word s_word s_word s_word s_word)
-	     ExcludeVisRect(1 2 3 4 5)
-74  pascal GetBitmapBits(word long ptr) GetBitmapBits(1 2 3)
-75  pascal GetBkColor(word) GetBkColor(1)
-76  pascal16 GetBkMode(word) GetBkMode(1)
-77  pascal16 GetClipBox(word ptr) GetClipBox(1 2)
-78  pascal GetCurrentPosition(word) GetCurrentPosition(1)
-79  pascal GetDCOrg(word) GetDCOrg(1)
-80  pascal16 GetDeviceCaps(word s_word) GetDeviceCaps(1 2)
-81  pascal16 GetMapMode(word) GetMapMode(1)
-82  pascal16 GetObject(word word ptr) GetObject(1 2 3)
-83  pascal GetPixel(word s_word s_word) GetPixel(1 2 3)
-84  pascal16 GetPolyFillMode(word) GetPolyFillMode(1)
-85  pascal16 GetROP2(word) GetROP2(1)
-86  pascal16 GetRelAbs(word) GetRelAbs(1)
-87  pascal16 GetStockObject(word) GetStockObject(1)
-88  pascal16 GetStretchBltMode(word) GetStretchBltMode(1)
-89  pascal16 GetTextCharacterExtra(word) GetTextCharacterExtra(1)
-90  pascal GetTextColor(word) GetTextColor(1)
-91  pascal GetTextExtent(word ptr s_word) GetTextExtent(1 2 3)
-92  pascal16 GetTextFace(word s_word ptr) GetTextFace(1 2 3)
-93  pascal16 GetTextMetrics(word ptr) GetTextMetrics(1 2)
-94  pascal GetViewportExt(word) GetViewportExt(1)
-95  pascal GetViewportOrg(word) GetViewportOrg(1)
-96  pascal GetWindowExt(word) GetWindowExt(1)
-97  pascal GetWindowOrg(word) GetWindowOrg(1)
+47  pascal16 CombineRgn(word word word word) CombineRgn
+48  pascal16 CreateBitmap(word word word word ptr) CreateBitmap
+49  pascal16 CreateBitmapIndirect(ptr) CreateBitmapIndirect
+50  pascal16 CreateBrushIndirect(ptr) CreateBrushIndirect
+51  pascal16 CreateCompatibleBitmap(word word word) CreateCompatibleBitmap
+52  pascal16 CreateCompatibleDC(word) CreateCompatibleDC
+53  pascal16 CreateDC(ptr ptr ptr ptr) CreateDC
+54  pascal16 CreateEllipticRgn(s_word s_word s_word s_word) CreateEllipticRgn
+55  pascal16 CreateEllipticRgnIndirect(ptr) CreateEllipticRgnIndirect
+56  pascal16 CreateFont(s_word s_word s_word s_word s_word word word word
+                        word word word word word ptr) CreateFont
+57  pascal16 CreateFontIndirect(ptr) CreateFontIndirect
+58  pascal16 CreateHatchBrush(word long) CreateHatchBrush
+60  pascal16 CreatePatternBrush(word) CreatePatternBrush
+61  pascal16 CreatePen(s_word s_word long) CreatePen
+62  pascal16 CreatePenIndirect(ptr) CreatePenIndirect
+63  pascal16 CreatePolygonRgn(ptr word word) CreatePolygonRgn
+64  pascal16 CreateRectRgn(s_word s_word s_word s_word) CreateRectRgn
+65  pascal16 CreateRectRgnIndirect(ptr) CreateRectRgnIndirect
+66  pascal16 CreateSolidBrush(long) CreateSolidBrush
+67  pascal16 DPtoLP(word ptr s_word) DPtoLP
+68  pascal16 DeleteDC(word) DeleteDC
+69  pascal16 DeleteObject(word) DeleteObject
+70  pascal16 EnumFonts(word ptr segptr long) EnumFonts
+71  pascal16 EnumObjects(word word ptr long) EnumObjects
+72  pascal16 EqualRgn(word word) EqualRgn
+73  pascal16 ExcludeVisRect(word s_word s_word s_word s_word) ExcludeVisRect
+74  pascal GetBitmapBits(word long ptr) GetBitmapBits
+75  pascal GetBkColor(word) GetBkColor
+76  pascal16 GetBkMode(word) GetBkMode
+77  pascal16 GetClipBox(word ptr) GetClipBox
+78  pascal GetCurrentPosition(word) GetCurrentPosition
+79  pascal GetDCOrg(word) GetDCOrg
+80  pascal16 GetDeviceCaps(word s_word) GetDeviceCaps
+81  pascal16 GetMapMode(word) GetMapMode
+82  pascal16 GetObject(word word ptr) GetObject
+83  pascal GetPixel(word s_word s_word) GetPixel
+84  pascal16 GetPolyFillMode(word) GetPolyFillMode
+85  pascal16 GetROP2(word) GetROP2
+86  pascal16 GetRelAbs(word) GetRelAbs
+87  pascal16 GetStockObject(word) GetStockObject
+88  pascal16 GetStretchBltMode(word) GetStretchBltMode
+89  pascal16 GetTextCharacterExtra(word) GetTextCharacterExtra
+90  pascal GetTextColor(word) GetTextColor
+91  pascal GetTextExtent(word ptr s_word) GetTextExtent
+92  pascal16 GetTextFace(word s_word ptr) GetTextFace
+93  pascal16 GetTextMetrics(word ptr) GetTextMetrics
+94  pascal GetViewportExt(word) GetViewportExt
+95  pascal GetViewportOrg(word) GetViewportOrg
+96  pascal GetWindowExt(word) GetWindowExt
+97  pascal GetWindowOrg(word) GetWindowOrg
 98  pascal16 IntersectVisRect(word s_word s_word s_word s_word)
-	     IntersectVisRect(1 2 3 4 5)
-99  pascal16 LPtoDP(word ptr s_word) LPtoDP(1 2 3)
-100 pascal16 LineDDA(s_word s_word s_word s_word ptr long)
-	     LineDDA(1 2 3 4 5 6)
-101 pascal16 OffsetRgn(word s_word s_word) OffsetRgn(1 2 3)
-102 pascal16 OffsetVisRgn(word s_word s_word) OffsetVisRgn(1 2 3)
-103 pascal16 PtVisible(word s_word s_word) PtVisible(1 2 3)
-104 pascal16 RectVisibleOld(word ptr) RectVisible(1 2)
-105 pascal16 SelectVisRgn(word word) SelectVisRgn(1 2)
-106 pascal SetBitmapBits(word long ptr) SetBitmapBits(1 2 3)
-117 pascal SetDCOrg(word s_word s_word) SetDCOrg(1 2 3)
-119 pascal16 AddFontResource(ptr) AddFontResource(1)
+             IntersectVisRect
+99  pascal16 LPtoDP(word ptr s_word) LPtoDP
+100 pascal16 LineDDA(s_word s_word s_word s_word segptr long) LineDDA
+101 pascal16 OffsetRgn(word s_word s_word) OffsetRgn
+102 pascal16 OffsetVisRgn(word s_word s_word) OffsetVisRgn
+103 pascal16 PtVisible(word s_word s_word) PtVisible
+104 pascal16 RectVisibleOld(word ptr) RectVisible
+105 pascal16 SelectVisRgn(word word) SelectVisRgn
+106 pascal SetBitmapBits(word long ptr) SetBitmapBits
+117 pascal SetDCOrg(word s_word s_word) SetDCOrg
+119 pascal16 AddFontResource(ptr) AddFontResource
 #121 pascal Death
 #122 pascal ReSurRection
-123 pascal16 PlayMetaFile(word word) PlayMetaFile(1 2)
-124 pascal16 GetMetaFile(ptr) GetMetaFile(1)
-125 pascal16 CreateMetaFile(ptr) CreateMetaFile(1)
-126 pascal16 CloseMetaFile(word) CloseMetaFile(1)
-127 pascal16 DeleteMetaFile(word) DeleteMetaFile(1)
-128 pascal MulDiv(s_word s_word s_word) MulDiv(1 2 3)
-129 pascal16 SaveVisRgn(word) SaveVisRgn(1)
-130 pascal16 RestoreVisRgn(word) RestoreVisRgn(1)
-131 pascal16 InquireVisRgn(word) InquireVisRgn(1)
-132 pascal16 SetEnvironment(ptr ptr word) SetEnvironment(1 2 3)
-133 pascal16 GetEnvironment(ptr ptr word) GetEnvironment(1 2 3)
-134 pascal16 GetRgnBox(word ptr) GetRgnBox(1 2)
+123 pascal16 PlayMetaFile(word word) PlayMetaFile
+124 pascal16 GetMetaFile(ptr) GetMetaFile
+125 pascal16 CreateMetaFile(ptr) CreateMetaFile
+126 pascal16 CloseMetaFile(word) CloseMetaFile
+127 pascal16 DeleteMetaFile(word) DeleteMetaFile
+128 pascal MulDiv(s_word s_word s_word) MulDiv
+129 pascal16 SaveVisRgn(word) SaveVisRgn
+130 pascal16 RestoreVisRgn(word) RestoreVisRgn
+131 pascal16 InquireVisRgn(word) InquireVisRgn
+132 pascal16 SetEnvironment(ptr ptr word) SetEnvironment
+133 pascal16 GetEnvironment(ptr ptr word) GetEnvironment
+134 pascal16 GetRgnBox(word ptr) GetRgnBox
 #135 pascal ScanLr
-136 pascal16 RemoveFontResource(ptr) RemoveFontResource(1)
-148 pascal SetBrushOrg(word s_word s_word) SetBrushOrg(1 2 3)
-149 pascal GetBrushOrg(word) GetBrushOrg(1)
-150 pascal16 UnrealizeObject(word) UnrealizeObject(1)
+136 pascal16 RemoveFontResource(ptr) RemoveFontResource
+148 pascal SetBrushOrg(word s_word s_word) SetBrushOrg
+149 pascal GetBrushOrg(word) GetBrushOrg
+150 pascal16 UnrealizeObject(word) UnrealizeObject
 #151 pascal CopyMetaFile
-153 pascal16 CreateIC(ptr ptr ptr ptr) CreateIC(1 2 3 4)
-154 pascal GetNearestColor(word long) GetNearestColor(1 2)
+153 pascal16 CreateIC(ptr ptr ptr ptr) CreateIC
+154 pascal GetNearestColor(word long) GetNearestColor
 #155 pascal QueryAbort
-156 pascal16 CreateDiscardableBitmap(word word word) 
-	     CreateDiscardableBitmap(1 2 3)
+156 pascal16 CreateDiscardableBitmap(word word word) CreateDiscardableBitmap
 #159 pascal GetMetaFileBits
 #160 pascal SetMetaFileBits
-161 pascal16 PtInRegion(word s_word s_word) PtInRegion(1 2 3)
-162 pascal GetBitmapDimension(word) GetBitmapDimension(1)
-163 pascal SetBitmapDimension(word s_word s_word) SetBitmapDimension(1 2 3)
+161 pascal16 PtInRegion(word s_word s_word) PtInRegion
+162 pascal GetBitmapDimension(word) GetBitmapDimension
+163 pascal SetBitmapDimension(word s_word s_word) SetBitmapDimension
 #169 pascal IsDCDirty
 #170 pascal SetDCStatus
-172 pascal16 SetRectRgn(word s_word s_word s_word s_word) SetRectRgn(1 2 3 4 5)
-173 pascal16 GetClipRgn(word) GetClipRgn(1)
+172 pascal16 SetRectRgn(word s_word s_word s_word s_word) SetRectRgn
+173 pascal16 GetClipRgn(word) GetClipRgn
 #175 pascal EnumMetaFile
-176 pascal16 PlayMetaFileRecord(word ptr ptr word) PlayMetaFileRecord(1 2 3 4)
-179 pascal16 GetDCState(word) GetDCState(1)
-180 pascal16 SetDCState(word word) SetDCState(1 2)
-181 pascal16 RectInRegionOld(word ptr) RectInRegion(1 2)
+176 pascal16 PlayMetaFileRecord(word ptr ptr word) PlayMetaFileRecord
+179 pascal16 GetDCState(word) GetDCState
+180 pascal16 SetDCState(word word) SetDCState
+181 pascal16 RectInRegionOld(word ptr) RectInRegion
 #190 pascal SetDCHook
 #191 pascal GetDCHook
 #192 pascal SetHookFlags
@@ -204,7 +196,7 @@
 #246 pascal STARTSPOOLPAGE
 #247 pascal ENDSPOOLPAGE
 #248 pascal QUERYJOB
-250 pascal16 Copy(ptr ptr word) Copy(1 2 3)
+250 pascal16 Copy(ptr ptr word) Copy
 #253 pascal DeleteSpoolPage
 #254 pascal SpoolFile
 #300 pascal ENGINEENUMERATEFONT
@@ -222,32 +214,31 @@
 #312 pascal CONVERTOUTLINEFONTFILE
 #313 pascal GETRASTERIZERCAPS
 #314 pascal ENGINEEXTTEXTOUT
-330 pascal16 EnumFontFamilies(word ptr ptr ptr) EnumFontFamilies(1 2 3 4)
+330 pascal16 EnumFontFamilies(word ptr segptr long) EnumFontFamilies
 #332 pascal GETKERNINGPAIRS
-345 pascal16 GetTextAlign(word) GetTextAlign(1)
-346 pascal16 SetTextAlign(word word) SetTextAlign(1 2)
-348 pascal16 Chord(word s_word s_word s_word s_word s_word s_word s_word s_word)
-	     Chord(1 2 3 4 5 6 7 8 9)
-349 pascal SetMapperFlags(word word) SetMapperFlags(1 2)
-350 pascal16 GetCharWidth(word word word ptr) GetCharWidth(1 2 3 4)
-351 pascal16 ExtTextOut(word s_word s_word word ptr ptr s_word ptr) 
-             ExtTextOut(1 2 3 4 5 6 7 8)
+345 pascal16 GetTextAlign(word) GetTextAlign
+346 pascal16 SetTextAlign(word word) SetTextAlign
+348 pascal16 Chord(word s_word s_word s_word s_word s_word s_word
+                   s_word s_word) Chord
+349 pascal SetMapperFlags(word word) SetMapperFlags
+350 pascal16 GetCharWidth(word word word ptr) GetCharWidth
+351 pascal16 ExtTextOut(word s_word s_word word ptr ptr s_word ptr) ExtTextOut
 #352 pascal GETPHYSICALFONTHANDLE
 #353 pascal GETASPECTRATIOFILTER
 #354 pascal SHRINKGDIHEAP
-360 pascal16 CreatePalette(ptr) CreatePalette(1)
-361 pascal16 GDISelectPalette(word word) GDISelectPalette(1 2)
-362 pascal16 GDIRealizePalette(word) GDIRealizePalette(1)
-363 pascal16 GetPaletteEntries(word word word ptr) GetPaletteEntries(1 2 3 4)
-364 pascal16 SetPaletteEntries(word word word ptr) SetPaletteEntries(1 2 3 4)
-365 pascal16 RealizeDefaultPalette(word) RealizeDefaultPalette(1)
+360 pascal16 CreatePalette(ptr) CreatePalette
+361 pascal16 GDISelectPalette(word word) GDISelectPalette
+362 pascal16 GDIRealizePalette(word) GDIRealizePalette
+363 pascal16 GetPaletteEntries(word word word ptr) GetPaletteEntries
+364 pascal16 SetPaletteEntries(word word word ptr) SetPaletteEntries
+365 pascal16 RealizeDefaultPalette(word) RealizeDefaultPalette
 #366 pascal UPDATECOLORS
 #367 pascal ANIMATEPALETTE
 #368 pascal RESIZEPALETTE
-370 pascal16 GetNearestPaletteIndex(word long) GetNearestPaletteIndex(1 2)
-372 pascal16 ExtFloodFill(word s_word s_word long word) ExtFloodFill(1 2 3 4)
+370 pascal16 GetNearestPaletteIndex(word long) GetNearestPaletteIndex
+372 pascal16 ExtFloodFill(word s_word s_word long word) ExtFloodFill
 375 pascal16 GetSystemPaletteEntries(word word word ptr)
-	     GetSystemPaletteEntries(1 2 3 4)
+             GetSystemPaletteEntries
 #376 pascal RESETDC
 #377 pascal STARTDOC
 #378 pascal ENDDOC
@@ -262,53 +253,47 @@
 #407 pascal CREATEUSERBITMAP
 #409 pascal CREATEUSERDISCARDABLEBITMAP
 #410 pascal ISVALIDMETAFILE
-411 pascal16 GetCurLogFont(word) GetCurLogFont(1)
+411 pascal16 GetCurLogFont(word) GetCurLogFont
 #412 pascal ISDCCURRENTPALETTE
 #439 pascal STRETCHDIBITS
-440 pascal16 SetDIBits(word word word word ptr ptr word) SetDIBits(1 2 3 4 5 6 7)
-441 pascal16 GetDIBits(word word word word ptr ptr word) GetDIBits(1 2 3 4 5 6 7)
-442 pascal16 CreateDIBitmap(word ptr long ptr ptr word)
-	     CreateDIBitmap(1 2 3 4 5 6)
-443 pascal16 SetDIBitsToDevice(word s_word s_word word word word word word
-                               word ptr ptr word)
-	     SetDIBitsToDevice(1 2 3 4 5 6 7 8 9 10 11 12)
+440 pascal16 SetDIBits(word word word word ptr ptr word) SetDIBits
+441 pascal16 GetDIBits(word word word word ptr ptr word) GetDIBits
+442 pascal16 CreateDIBitmap(word ptr long ptr ptr word) CreateDIBitmap
+443 pascal16 SetDIBitsToDevice(word s_word s_word word word word word
+                               word word ptr ptr word) SetDIBitsToDevice
 444 pascal16 CreateRoundRectRgn(s_word s_word s_word s_word s_word s_word)
-	     CreateRoundRectRgn(1 2 3 4 5 6)
-445 pascal16 CreateDIBPatternBrush(word word) CreateDIBPatternBrush(1 2)
+             CreateRoundRectRgn
+445 pascal16 CreateDIBPatternBrush(word word) CreateDIBPatternBrush
 #449 pascal DEVICECOLORMATCH
-450 pascal16 PolyPolygon(word ptr ptr word) PolyPolygon(1 2 3 4)
-451 pascal16 CreatePolyPolygonRgn(ptr ptr word word)
-	     CreatePolyPolygonRgn(1 2 3 4)
+450 pascal16 PolyPolygon(word ptr ptr word) PolyPolygon
+451 pascal16 CreatePolyPolygonRgn(ptr ptr word word) CreatePolyPolygonRgn
 #452 pascal GDISEEGDIDO
 #460 pascal GDITASKTERMINATION
 461 return SetObjectOwner 4 0
-462 pascal16 IsGDIObject(word) IsGDIObject(1)
+462 pascal16 IsGDIObject(word) IsGDIObject
 #463 pascal MAKEOBJECTPRIVATE
 #464 pascal FIXUPBOGUSPUBLISHERMETAFILE
-465 pascal16 RectVisible(word ptr) RectVisible(1 2)
-466 pascal16 RectInRegion(word ptr) RectInRegion(1 2)
+465 pascal16 RectVisible(word ptr) RectVisible
+466 pascal16 RectInRegion(word ptr) RectInRegion
 #467 pascal UNICODETOANSI
-468 pascal16 GetBitmapDimensionEx(word ptr) GetBitmapDimensionEx(1 2)
-469 pascal16 GetBrushOrgEx(word ptr) GetBrushOrgEx(1 2)
-470 pascal16 GetCurrentPositionEx(word ptr) GetCurrentPositionEx(1 2)
-471 pascal16 GetTextExtentPoint(word ptr s_word ptr) GetTextExtentPoint(1 2 3 4)
-472 pascal16 GetViewportExtEx(word ptr) GetViewportExtEx(1 2)
-473 pascal16 GetViewportOrgEx(word ptr) GetViewportOrgEx(1 2)
-474 pascal16 GetWindowExtEx(word ptr) GetWindowExtEx(1 2)
-475 pascal16 GetWindowOrgEx(word ptr) GetWindowOrgEx(1 2)
-476 pascal16 OffsetViewportOrgEx(word s_word s_word ptr)
-	     OffsetViewportOrgEx(1 2 3 4)
-477 pascal16 OffsetWindowOrgEx(word s_word s_word ptr)
-             OffsetWindowOrgEx(1 2 3 4)
-478 pascal16 SetBitmapDimensionEx(word s_word s_word ptr)
-	     SetBitmapDimensionEx(1 2 3 4)
-479 pascal16 SetViewportExtEx(word s_word s_word ptr) SetViewportExtEx(1 2 3 4)
-480 pascal16 SetViewportOrgEx(word s_word s_word ptr) SetViewportOrgEx(1 2 3 4)
-481 pascal16 SetWindowExtEx(word s_word s_word ptr) SetWindowExtEx(1 2 3 4)
-482 pascal16 SetWindowOrgEx(word s_word s_word ptr) SetWindowOrgEx(1 2 3 4)
-483 pascal16 MoveToEx(word s_word s_word ptr) MoveToEx(1 2 3 4)
+468 pascal16 GetBitmapDimensionEx(word ptr) GetBitmapDimensionEx
+469 pascal16 GetBrushOrgEx(word ptr) GetBrushOrgEx
+470 pascal16 GetCurrentPositionEx(word ptr) GetCurrentPositionEx
+471 pascal16 GetTextExtentPoint(word ptr s_word ptr) GetTextExtentPoint
+472 pascal16 GetViewportExtEx(word ptr) GetViewportExtEx
+473 pascal16 GetViewportOrgEx(word ptr) GetViewportOrgEx
+474 pascal16 GetWindowExtEx(word ptr) GetWindowExtEx
+475 pascal16 GetWindowOrgEx(word ptr) GetWindowOrgEx
+476 pascal16 OffsetViewportOrgEx(word s_word s_word ptr) OffsetViewportOrgEx
+477 pascal16 OffsetWindowOrgEx(word s_word s_word ptr) OffsetWindowOrgEx
+478 pascal16 SetBitmapDimensionEx(word s_word s_word ptr) SetBitmapDimensionEx
+479 pascal16 SetViewportExtEx(word s_word s_word ptr) SetViewportExtEx
+480 pascal16 SetViewportOrgEx(word s_word s_word ptr) SetViewportOrgEx
+481 pascal16 SetWindowExtEx(word s_word s_word ptr) SetWindowExtEx
+482 pascal16 SetWindowOrgEx(word s_word s_word ptr) SetWindowOrgEx
+483 pascal16 MoveToEx(word s_word s_word ptr) MoveToEx
 484 pascal16 ScaleViewportExtEx(word s_word s_word s_word s_word ptr)
-	     ScaleViewportExtEx(1 2 3 4 5 6)
+             ScaleViewportExtEx
 485 pascal16 ScaleWindowExtEx(word s_word s_word s_word s_word ptr)
-	     ScaleWindowExtEx(1 2 3 4 5 6)
+             ScaleWindowExtEx
 #486 pascal GETASPECTRATIOFILEREX
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index d3b738c..a9eec05 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -6,151 +6,145 @@
 
 #1 FATALEXIT
 #2 EXITKERNEL
-3   pascal GetVersion() GetVersion()
-4   pascal16 LocalInit(word word word) WIN16_LocalInit(1 2 3)
-5   pascal16 LocalAlloc(word word) WIN16_LocalAlloc(1 2)
-6   pascal16 LocalReAlloc(word word word) WIN16_LocalReAlloc(1 2 3)
-7   pascal16 LocalFree(word) WIN16_LocalFree(1)
-8   pascal LocalLock(word) WIN16_LocalLock(1)
-9   pascal16 LocalUnlock(word) WIN16_LocalUnlock(1)
-10  pascal LocalSize(word) WIN16_LocalSize(1)
-11  pascal16 LocalHandle(word) ReturnArg(1)
-12  pascal16 LocalFlags(word) WIN16_LocalFlags(1)
-13  pascal16 LocalCompact(word) WIN16_LocalCompact(1)
-14  return LocalNotify 4 0
-15  pascal16 GlobalAlloc(word long) WIN16_GlobalAlloc(1 2)
-16  pascal16 GlobalReAlloc(word long word) GlobalReAlloc(1 2 3)
-17  pascal16 GlobalFree(word) GlobalFree(1)
-18  pascal GlobalLock(word) GlobalLock(1)
-19  pascal16 GlobalUnlock(word) GlobalUnlock(1)
-20  pascal GlobalSize(word) GlobalSize(1)
-21  pascal GlobalHandle(word) GlobalHandle(1)
-22  pascal16 GlobalFlags(word) GlobalFlags(1)
-23  pascal16 LockSegment(s_word) KERNEL_LockSegment(1)
-24  pascal UnlockSegment(s_word) KERNEL_UnlockSegment(1)
-25  pascal GlobalCompact(long) GlobalCompact(1)
+3   pascal GetVersion() GetVersion
+4   pascal16 LocalInit(word word word) LocalInit
+5   pascal16 LocalAlloc(word word) LocalAlloc
+6   pascal16 LocalReAlloc(word word word) LocalReAlloc
+7   pascal16 LocalFree(word) LocalFree
+8   pascal16 LocalLock(word) LocalLock
+9   pascal16 LocalUnlock(word) LocalUnlock
+10  pascal16 LocalSize(word) LocalSize
+11  pascal16 LocalHandle(word) LocalHandle
+12  pascal16 LocalFlags(word) LocalFlags
+13  pascal16 LocalCompact(word) LocalCompact
+14  pascal16 LocalNotify(long) LocalNotify
+15  pascal16 GlobalAlloc(word long) GlobalAlloc
+16  pascal16 GlobalReAlloc(word long word) GlobalReAlloc
+17  pascal16 GlobalFree(word) GlobalFree
+18  pascal GlobalLock(word) WIN16_GlobalLock
+19  pascal16 GlobalUnlock(word) GlobalUnlock
+20  pascal GlobalSize(word) GlobalSize
+21  pascal GlobalHandle(word) GlobalHandle
+22  pascal16 GlobalFlags(word) GlobalFlags
+23  pascal16 LockSegment(word) LockSegment
+24  pascal16 UnlockSegment(word) UnlockSegment
+25  pascal GlobalCompact(long) GlobalCompact
 #26 GLOBALFREEALL
 #28 GLOBALMASTERHANDLE
 29  return Yield 0 0
-30  pascal WaitEvent(word) KERNEL_WaitEvent(1)
+30  pascal WaitEvent(word) KERNEL_WaitEvent
 #31 POSTEVENT
 #32 SETPRIORITY
 #33 LOCKCURRENTTASK
-34  pascal SetTaskQueue(word word) SetTaskQueue(1 2)
-35  pascal GetTaskQueue(word) GetTaskQueue(1)
-36  pascal16 GetCurrentTask() GetCurrentTask()
-37  pascal16 GetCurrentPDB() GetCurrentPDB()
+34  pascal SetTaskQueue(word word) SetTaskQueue
+35  pascal GetTaskQueue(word) GetTaskQueue
+36  pascal16 GetCurrentTask() GetCurrentTask
+37  pascal16 GetCurrentPDB() GetCurrentPDB
 #38 SETTASKSIGNALPROC
-#41 ENABLEDOS
-#42 DISABLEDOS
-45  pascal16 LoadModule(ptr ptr) LoadModule(1 2)
-46  pascal16 FreeModule(word) FreeLibrary(1)
-47  pascal16 GetModuleHandle(ptr) GetModuleHandle(1)
-48  pascal16 GetModuleUsage(word) GetModuleUsage(1)
-49  pascal16 GetModuleFileName(word ptr s_word) GetModuleFileName(1 2 3)
-50  pascal GetProcAddress(word ptr) GetProcAddress(1 2)
-51  pascal MakeProcInstance(ptr word) CALLBACK_MakeProcInstance(1 2)
-52  pascal FreeProcInstance(ptr) FreeProcInstance(1)
+41  return EnableDos 0 0
+42  return DisableDos 0 0
+45  pascal16 LoadModule(ptr ptr) LoadModule
+46  pascal16 FreeModule(word) FreeLibrary
+47  pascal16 GetModuleHandle(ptr) GetModuleHandle
+48  pascal16 GetModuleUsage(word) GetModuleUsage
+49  pascal16 GetModuleFileName(word ptr s_word) GetModuleFileName
+50  pascal GetProcAddress(word ptr) GetProcAddress
+51  pascal MakeProcInstance(segptr word) MakeProcInstance
+52  pascal FreeProcInstance(segptr) FreeProcInstance
 #53 CALLPROCINSTANCE
 #54 pascal16 GETINSTANCEDATA
-55  pascal16 Catch(ptr) Catch (1)
-56  pascal Throw(ptr word) Throw(1 2)
-57  pascal16 GetProfileInt(ptr ptr word) GetProfileInt(1 2 3)
-58  pascal16 GetProfileString(ptr ptr ptr ptr word) GetProfileString(1 2 3 4 5)
-59  pascal16 WriteProfileString(ptr ptr ptr) WriteProfileString(1 2 3)
-60  pascal16 FindResource(word ptr ptr) FindResource(1 2 3)
-61  pascal16 LoadResource(word word) LoadResource(1 2)
-62  pascal LockResource(word) LockResource(1)
-63  pascal16 FreeResource(word) FreeResource(1)
-64  pascal16 AccessResource(word word) AccessResource(1 2)
-65  pascal SizeofResource(word word) SizeofResource(1 2)
-66  pascal16 AllocResource(word word long) AllocResource(1 2 3)
+55  pascal16 Catch(ptr) Catch 
+56  pascal Throw(ptr word) Throw
+57  pascal16 GetProfileInt(ptr ptr word) GetProfileInt
+58  pascal16 GetProfileString(ptr ptr ptr ptr word) GetProfileString
+59  pascal16 WriteProfileString(ptr ptr ptr) WriteProfileString
+60  pascal16 FindResource(word segptr segptr) FindResource
+61  pascal16 LoadResource(word word) LoadResource
+62  pascal LockResource(word) WIN16_LockResource
+63  pascal16 FreeResource(word) FreeResource
+64  pascal16 AccessResource(word word) AccessResource
+65  pascal SizeofResource(word word) SizeofResource
+66  pascal16 AllocResource(word word long) AllocResource
 #67 SETRESOURCEHANDLER
-68  pascal16 InitAtomTable(word) InitAtomTable(1)
-69  pascal16 FindAtom(ptr) FindAtom(1)
-70  pascal16 AddAtom(ptr) AddAtom(1)
-71  pascal16 DeleteAtom(word) DeleteAtom(1)
-72  pascal16 GetAtomName(word ptr word) GetAtomName(1 2 3)
-73  pascal16 GetAtomHandle(word) GetAtomHandle(1)
-74  pascal16 OpenFile(ptr ptr word) OpenFile(1 2 3)
+68  pascal16 InitAtomTable(word) InitAtomTable
+69  pascal16 FindAtom(ptr) FindAtom
+70  pascal16 AddAtom(ptr) AddAtom
+71  pascal16 DeleteAtom(word) DeleteAtom
+72  pascal16 GetAtomName(word ptr word) GetAtomName
+73  pascal16 GetAtomHandle(word) GetAtomHandle
+74  pascal16 OpenFile(ptr ptr word) OpenFile
 #75 OPENPATHNAME
 #76 DELETEPATHNAME
 #77 RESERVED1
 #78 RESERVED2
 #79 RESERVED3
 #80 RESERVED4
-81  pascal16 _lclose(word) _lclose(1)
-82  pascal16 _lread(word ptr word) _lread(1 2 3)
-83  pascal16 _lcreat(ptr word) _lcreat(1 2)
-84  pascal _llseek(word long word) _llseek(1 2 3)
-85  pascal16 _lopen(ptr word) _lopen(1 2)
-86  pascal16 _lwrite(word ptr word) _lwrite(1 2 3)
+81  pascal16 _lclose(word) _lclose
+82  pascal16 _lread(word ptr word) _lread
+83  pascal16 _lcreat(ptr word) _lcreat
+84  pascal _llseek(word long word) _llseek
+85  pascal16 _lopen(ptr word) _lopen
+86  pascal16 _lwrite(word ptr word) _lwrite
 #87 RESERVED5
-88  pascal lstrcpy(ptr ptr) lstrcpy(1 2)
-89  pascal lstrcat(ptr ptr) lstrcat(1 2)
-90  pascal16 lstrlen(ptr) lstrlen(1)
-91  register InitTask(word word word word word
-		      word word word word word) 
-	     KERNEL_InitTask()
-92  pascal16 GetTempDrive(byte) GetTempDrive(1)
-93 pascal16 GetCodeHandle(ptr) GetCodeHandle(1)
+88  pascal lstrcpy(segptr segptr) lstrcpy
+89  pascal lstrcat(segptr segptr) lstrcat
+90  pascal16 lstrlen(ptr) lstrlen
+91  register InitTask() KERNEL_InitTask
+92  pascal16 GetTempDrive(byte) GetTempDrive
+93 pascal16 GetCodeHandle(ptr) GetCodeHandle
 #94 DEFINEHANDLETABLE
-95  pascal16 LoadLibrary(ptr) LoadLibrary(1)
-96  pascal16 FreeLibrary(word) FreeLibrary(1)
-97  pascal16 GetTempFileName(byte ptr word ptr) GetTempFileName(1 2 3 4)
+95  pascal16 LoadLibrary(ptr) LoadLibrary
+96  pascal16 FreeLibrary(word) FreeLibrary
+97  pascal16 GetTempFileName(byte ptr word ptr) GetTempFileName
 #98 GETLASTDISKCHANGE
 #99 GETLPERRMODE
 #100 VALIDATECODESEGMENTS
 #101 NOHOOKDOSCALL
-102 register DOS3Call(word word word word word
-		      word word word word word) 
-	     DOS3Call()
+102 register DOS3Call() DOS3Call
 #103 NETBIOSCALL
 #104 GETCODEINFO
 #105 GETEXEVERSION
-106 pascal SetSwapAreaSize(word) SetSwapAreaSize(1)
-107 pascal SetErrorMode(word) SetErrorMode(1)
+106 pascal SetSwapAreaSize(word) SetSwapAreaSize
+107 pascal SetErrorMode(word) SetErrorMode
 #108 SWITCHSTACKTO
 #109 SWITCHSTACKBACK
 #110 PATCHCODEHANDLE
-111 pascal GlobalWire(word) GlobalLock(1)
-112 pascal16 GlobalUnWire(word) GlobalUnlock(1)
+111 pascal GlobalWire(word) GlobalWire
+112 pascal16 GlobalUnWire(word) GlobalUnWire
 113 equate __AHSHIFT 3
 114 equate __AHINCR 8
-115 pascal OutputDebugString(ptr) OutputDebugString(1)
+115 pascal OutputDebugString(ptr) OutputDebugString
 #116 INITLIB
 117 return OldYield 0 0
 #118 GETTASKQUEUEDS
 #119 GETTASKQUEUEES
 #120 UNDEFDYNLINK
-121 return LocalShrink 4 0
+121 pascal16 LocalShrink(word word) LocalShrink
 #122 ISTASKLOCKED
 #123 KBDRST
-#124 ENABLEKERNEL
-#125 DISABLEKERNEL
+124 return EnableKernel 0 0
+125 return DisableKernel 0 0
 #126 MEMORYFREED
-127 pascal16 GetPrivateProfileInt(ptr ptr s_word ptr)
-	     GetPrivateProfileInt(1 2 3 4)
+127 pascal16 GetPrivateProfileInt(ptr ptr s_word ptr) GetPrivateProfileInt
 128 pascal16 GetPrivateProfileString(ptr ptr ptr ptr s_word ptr)
-	     GetPrivateProfileString(1 2 3 4 5 6)
+             GetPrivateProfileString
 129 pascal16 WritePrivateProfileString(ptr ptr ptr ptr)
-	     WritePrivateProfileString(1 2 3 4)
-130 pascal FileCDR(ptr) FileCDR(1)
-131 pascal GetDOSEnvironment() GetDOSEnvironment()
-132 pascal GetWinFlags() GetWinFlags()
+             WritePrivateProfileString
+130 pascal FileCDR(ptr) FileCDR
+131 pascal GetDOSEnvironment() GetDOSEnvironment
+132 pascal GetWinFlags() GetWinFlags
 #133 GETEXEPTR
-134 pascal16 GetWindowsDirectory(ptr word) GetWindowsDirectory(1 2)
-135 pascal16 GetSystemDirectory(ptr word) GetSystemDirectory(1 2)
-136 pascal16 GetDriveType(byte) GetDriveType(1)
-137 pascal FatalAppExit(word ptr) FatalAppExit(1 2)
-#138 GETHEAPSPACES - This is not correct but may fake out most apps
-138 return GetHeapSpaces 2 0x80004000
+134 pascal16 GetWindowsDirectory(ptr word) GetWindowsDirectory
+135 pascal16 GetSystemDirectory(ptr word) GetSystemDirectory
+136 pascal16 GetDriveType(byte) GetDriveType
+137 pascal FatalAppExit(word ptr) FatalAppExit
+138 pascal GetHeapSpaces(word) GetHeapSpaces
 #139 DOSIGNAL
 #140 SETSIGHANDLER
 #141 INITTASK1
 150 return DirectedYield 2 0
 #151 WINOLDAPCALL
-152 pascal16 GetNumTasks() GetNumTasks()
+152 pascal16 GetNumTasks() GetNumTasks
 154 return GlobalNotify 4 0
 #155 GETTASKDS
 #156 LIMITEMSPAGES
@@ -158,62 +152,62 @@
 #158 ISWINOLDAPTASK
 #159 GLOBALHANDLENORIP
 #160 EMSCOPY
-#161 LOCALCOUNTFREE
-#162 LOCALHEAPSIZE
-163 pascal16 GlobalLRUOldest(word) ReturnArg(1)
-164 pascal16 GlobalLRUNewest(word) ReturnArg(1)
+161 pascal16 LocalCountFree() LocalCountFree
+162 pascal16 LocalHeapSize() LocalHeapSize
+163 pascal16 GlobalLRUOldest(word) GlobalLRUOldest
+164 pascal16 GlobalLRUNewest(word) GlobalLRUNewest
 #165 A20PROC
-166 pascal16 WinExec(ptr word) WinExec(1 2)
+166 pascal16 WinExec(ptr word) WinExec
 #167 GETEXPWINVER
 #168 DIRECTRESALLOC
-169 pascal GetFreeSpace(word) GetFreeSpace(1)
-170 pascal AllocCStoDSAlias(word) AllocDStoCSAlias(1)
-171 pascal AllocDStoCSAlias(word) AllocDStoCSAlias(1)
-#172 ALLOCALIAS
+169 pascal GetFreeSpace(word) GetFreeSpace
+170 pascal16 AllocCStoDSAlias(word) AllocCStoDSAlias
+171 pascal16 AllocDStoCSAlias(word) AllocDStoCSAlias
+172 pascal16 AllocAlias(word) AllocCStoDSAlias
 #173 __ROMBIOS
 #174 __A000H
-175 pascal16 AllocSelector(word) AllocSelector(1)
-176 pascal16 FreeSelector(word) FreeSelector(1)
-177 pascal16 PrestoChangoSelector(word word) PrestoChangoSelector(1 2)
+175 pascal16 AllocSelector(word) AllocSelector
+176 pascal16 FreeSelector(word) FreeSelector
+177 pascal16 PrestoChangoSelector(word word) PrestoChangoSelector
 178 equate __WINFLAGS 0x413
 #179 __D000H
-#180 LONGPTRADD
+180 pascal16 LongPtrAdd(long long) LongPtrAdd
 #181 __B000H
 #182 __B800H
 #183 __0000H
-184 return GlobalDOSAlloc 4 0
-185 return GlobalDOSFree 2 0
-186 pascal16 GetSelectorBase(word) GetSelectorBase(1)
-187 pascal16 SetSelectorBase(word long) SetSelectorBase(1 2)
-188 pascal GetSelectorLimit(word) GetSelectorLimit(1)
-189 pascal16 SetSelectorLimit(word long) SetSelectorLimit(1 2)
+184 pascal GlobalDOSAlloc(long) GlobalDOSAlloc
+185 pascal16 GlobalDOSFree(word) GlobalDOSFree
+186 pascal GetSelectorBase(word) GetSelectorBase
+187 pascal16 SetSelectorBase(word long) SetSelectorBase
+188 pascal GetSelectorLimit(word) GetSelectorLimit
+189 pascal16 SetSelectorLimit(word long) SetSelectorLimit
 #190 __E000H
-191 pascal GlobalPageLock(word) GlobalLock(1)
-192 pascal GlobalPageUnlock(word) GlobalUnlock(1)
+191 pascal16 GlobalPageLock(word) GlobalPageLock
+192 pascal16 GlobalPageUnlock(word) GlobalPageUnlock
 #193 __0040H
 #194 __F000H
 #195 __C000H
-#196 SELECTORACCESSRIGHTS
-197 pascal GlobalFix(word) GlobalLock(1)
-198 pascal GlobalUnfix(word) GlobalUnlock(1)
-199 pascal16 SetHandleCount(word) SetHandleCount(1)
+196 pascal16 SelectorAccessRights(word word word) SelectorAccessRights
+197 pascal16 GlobalFix(word) GlobalFix
+198 pascal16 GlobalUnfix(word) GlobalUnfix
+199 pascal16 SetHandleCount(word) SetHandleCount
 #200 VALIDATEFREESPACES
 #201 REPLACEINST
 #202 REGISTERPTRACE
 #203 DEBUGBREAK
 #204 SWAPRECORDING
 #205 CVWBREAK
-#206 ALLOCSELECTORARRAY
+206 pascal16 AllocSelectorArray(word) AllocSelectorArray
 207 return IsDBCSLeadByte 2 0
-310 pascal LocalHandleDelta(word) WIN16_LocalHandleDelta(1)
+310 pascal16 LocalHandleDelta(word) LocalHandleDelta
 #311 GETSETKERNELDOSPROC
 #314 DEBUGDEFINESEGMENT
-315 pascal WriteOutProfiles() sync_profiles()
+315 pascal WriteOutProfiles() sync_profiles
 #316 GETFREEMEMINFO
 #318 FATALEXITHOOK
 #319 FLUSHCACHEDFILEHANDLE
 #320 ISTASK
-323 pascal IsRomModule() IsRomModule()
+323 pascal IsRomModule() IsRomModule
 #324 LOGERROR
 #325 LOGPARAMERROR
 #326 ISROMFILE
@@ -221,10 +215,10 @@
 #328 _DEBUGOUTPUT
 #329 K329
 #332 THHOOK
-334 pascal IsBadReadPtr(ptr word) IsBadReadPtr(1 2)
-335 pascal IsBadWritePtr(ptr word) IsBadWritePtr(1 2)
-336 pascal IsBadCodePtr(ptr) IsBadCodePtr(1)
-337 pascal IsBadStringPtr(ptr word) IsBadStringPtr(1 2)
+334 pascal16 IsBadReadPtr(segptr word) IsBadReadPtr
+335 pascal16 IsBadWritePtr(segptr word) IsBadWritePtr
+336 pascal16 IsBadCodePtr(segptr) IsBadCodePtr
+337 pascal16 IsBadStringPtr(segptr word) IsBadStringPtr
 #338 HASGPHANDLER
 #339 DIAGQUERY
 #340 DIAGOUTPUT
@@ -233,13 +227,13 @@
 #343 REGISTERWINOLDAPHOOK
 #344 GETWINOLDAPHOOKS
 #345 ISSHAREDSELECTOR
-346 pascal IsBadHugeReadPtr(ptr long) IsBadHugeReadPtr(1 2)
-347 pascal IsBadHugeWritePtr(ptr long) IsBadHugeWritePtr(1 2)
-348 pascal hmemcpy(ptr ptr long) hmemcpy(1 2 3)
-349 pascal16 _hread(word ptr long) _hread(1 2 3)
-350 pascal16 _hwrite(word ptr long) _hwrite(1 2 3)
+346 pascal16 IsBadHugeReadPtr(segptr long) IsBadHugeReadPtr
+347 pascal16 IsBadHugeWritePtr(segptr long) IsBadHugeWritePtr
+348 pascal hmemcpy(ptr ptr long) hmemcpy
+349 pascal16 _hread(word ptr long) _hread
+350 pascal16 _hwrite(word ptr long) _hwrite
 #351 BUNNY_351
-353 pascal lstrcpyn(ptr ptr word) lstrcpyn(1 2 3)
+353 pascal lstrcpyn(segptr segptr word) lstrcpyn
 #354 GETAPPCOMPATFLAGS
 #355 GETWINDEBUGINFO
 #356 SETWINDEBUGINFO
diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec
index e090c34..a23cf06 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -1,27 +1,27 @@
 # $Id: keyboard.spec,v 1.1 1993/09/10 05:32:12 scott Exp $
 #
 name	keyboard
-id	8
+id	7
 length	137
 
 #1	pascal	Inquire
 #2	pascal	Enable
 #3	pascal	Disable
-4	pascal	ToAscii(word word ptr ptr word) ToAscii(1 2 3 4 5)
-5	pascal	AnsiToOem(ptr ptr) AnsiToOem(1 2)
-6	pascal	OemToAnsi(ptr ptr) OemToAnsi(1 2)
+4	pascal	ToAscii(word word ptr ptr word) ToAscii
+5	pascal	AnsiToOem(ptr ptr) AnsiToOem
+6	pascal	OemToAnsi(ptr ptr) OemToAnsi
 #7	pascal	SetSpeed
 #100	pascal	ScreenSwitchEnable
 #126	pascal	GetTableSeg
 #127	pascal	NewTable
-128	pascal	OemKeyScan(word) OemKeyScan(1)
-129	pascal	VkKeyScan(byte) VkKeyScan(1)
-130	pascal	GetKeyboardType(byte) GetKeyboardType(1)
-131	pascal	MapVirtualKey(word word) MapVirtualKey(1 2)
-132	pascal	GetKbCodePage() GetKbCodePage()
-133	pascal	GetKeyNameText(long ptr word) GetKeyNameText(1 2 3)
-134	pascal	AnsiToOemBuff(ptr ptr word) AnsiToOemBuff(1 2 3)
-135	pascal	OemToAnsiBuff(ptr ptr word) OemToAnsiBuff(1 2 3)
+128	pascal	OemKeyScan(word) OemKeyScan
+129	pascal	VkKeyScan(byte) VkKeyScan
+130	pascal	GetKeyboardType(byte) GetKeyboardType
+131	pascal	MapVirtualKey(word word) MapVirtualKey
+132	pascal	GetKbCodePage() GetKbCodePage
+133	pascal	GetKeyNameText(long ptr word) GetKeyNameText
+134	pascal	AnsiToOemBuff(ptr ptr word) AnsiToOemBuff
+135	pascal	OemToAnsiBuff(ptr ptr word) OemToAnsiBuff
 #136	pascal	EnableKbSysReq
 #137	pascal	GetBiosKeyProc
 
diff --git a/if1632/mmsystem.spec b/if1632/mmsystem.spec
index d074cae..9814960 100644
--- a/if1632/mmsystem.spec
+++ b/if1632/mmsystem.spec
@@ -1,129 +1,130 @@
 # $Id: mmsystem.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	mmsystem
-id	11
+id	10
 length 1226
 
-1      pascal  MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP(1 2 3 4)
-2      pascal  SNDPLAYSOUND(ptr word) sndPlaySound(1 2)
-5      pascal  MMSYSTEMGETVERSION() mmsystemGetVersion()
-6      pascal  DriverProc(long word word long long) DriverProc(1 2 3 4 5)
-30     pascal  OUTPUTDEBUGSTR(ptr) OutputDebugStr(1)
-31     pascal  DriverCallback(long word word word long long long) DriverCallback(1 2 3 4 5 6 7)
-#32    pascal  STACKENTER()
-#33    pascal  STACKLEAVE()
-#34    pascal  MMDRVINSTALL()
-101    pascal  JOYGETNUMDEVS() JoyGetNumDevs()
-102    pascal  JOYGETDEVCAPS(word ptr word) JoyGetDevCaps(1 2 3)
-103    pascal  JOYGETPOS(word ptr) JoyGetPos(1 2)
-104    pascal  JOYGETTHRESHOLD(word ptr) JoyGetThreshold(1 2)
-105    pascal  JOYRELEASECAPTURE(word) JoyReleaseCapture(1)
-106    pascal  JOYSETCAPTURE(word word word word) JoySetCapture(1 2 3 4)
-107    pascal  JOYSETTHRESHOLD(word word) JoySetThreshold(1 2)
-109    pascal  JOYSETCALIBRATION(word) JoySetCalibration(1)
-201    pascal  MIDIOUTGETNUMDEVS() midiOutGetNumDevs()
-202    pascal  MIDIOUTGETDEVCAPS(word ptr word) midiOutGetDevCaps(1 2 3)
-203    pascal  MIDIOUTGETERRORTEXT(word ptr word) midiOutGetErrorText(1 2 3)
-204    pascal  MIDIOUTOPEN(ptr word ptr long long long) midiOutOpen(1 2 3 4 5 6)
-205    pascal  MIDIOUTCLOSE(word) midiOutClose(1)
-206    pascal  MIDIOUTPREPAREHEADER(word ptr word) midiOutPrepareHeader(1 2 3)
-207    pascal  MIDIOUTUNPREPAREHEADER(word ptr word) midiOutUnprepareHeader(1 2 3)
-208    pascal  MIDIOUTSHORTMSG(word long) midiOutShortMsg(1 2)
-209    pascal  MIDIOUTLONGMSG(word ptr word) midiOutLongMsg(1 2 3)
-210    pascal  MIDIOUTRESET(word) midiOutReset(1)
-211    pascal  MIDIOUTGETVOLUME(word ptr) midiOutGetVolume(1 2)
-212    pascal  MIDIOUTSETVOLUME(word long) midiOutSetVolume(1 2)
-215    pascal  MIDIOUTGETID(word ptr) midiOutGetID(1 2)
-216    pascal  MIDIOUTMESSAGE(word word long long) midiOutMessage(1 2 3 4)
-301    pascal  MIDIINGETNUMDEVS() midiInGetNumDevs()
-302    pascal  MIDIINGETDEVCAPS(word ptr word) midiInGetDevCaps(1 2 3)
-303    pascal  MIDIINGETERRORTEXT(word ptr word) midiInGetErrorText(1 2 3)
-304    pascal  MIDIINOPEN(ptr word ptr long long long) midiInOpen(1 2 3 4 5 6)
-305    pascal  MIDIINCLOSE(word) midiInClose(1)
-306    pascal  MIDIINPREPAREHEADER(word ptr word) midiInPrepareHeader(1 2 3)
-307    pascal  MIDIINUNPREPAREHEADER(word ptr word) midiInUnprepareHeader(1 2 3)
-309    pascal  MIDIINSTART(word) midiInStart(1)
-310    pascal  MIDIINSTOP(word) midiInStop(1)
-311    pascal  MIDIINRESET(word) midiInReset(1)
-312    pascal  MIDIINGETID(word ptr) midiInGetID(1 2)
-313    pascal  MIDIINMESSAGE(word word long long) midiInMessage(1 2 3 4)
-350    pascal  AUXGETNUMDEVS() auxGetNumDevs()
-351    pascal  AUXGETDEVCAPS(word ptr word) auxGetDevCaps(1 2 3)
-352    pascal  AUXGETVOLUME(word ptr) auxGetVolume(1 2)
-353    pascal  AUXSETVOLUME(word long) auxSetVolume(1 2)
-354    pascal  AUXOUTMESSAGE(word word long long) auxOutMessage(1 2 3 4)
-401    pascal  WAVEOUTGETNUMDEVS() waveOutGetNumDevs()
-402    pascal  WAVEOUTGETDEVCAPS(word ptr word) waveOutGetDevCaps(1 2 3)
-403    pascal  WAVEOUTGETERRORTEXT(word ptr word) waveOutGetErrorText(1 2 3)
-404    pascal  WAVEOUTOPEN(ptr word ptr long long long) waveOutOpen(1 2 3 4 5 6)
-405    pascal  WAVEOUTCLOSE(word) waveOutClose(1)
-406    pascal  WAVEOUTPREPAREHEADER(word ptr word) waveOutPrepareHeader(1 2 3)
-407    pascal  WAVEOUTUNPREPAREHEADER(word ptr word) waveOutUnprepareHeader(1 2 3)
-408    pascal  WAVEOUTWRITE(word ptr word) waveOutWrite(1 2 3)
-409    pascal  WAVEOUTPAUSE(word) waveOutPause(1)
-410    pascal  WAVEOUTRESTART(word) waveOutRestart(1)
-411    pascal  WAVEOUTRESET(word) waveOutReset(1)
-412    pascal  WAVEOUTGETPOSITION(word ptr word) waveOutGetPosition(1 2 3)
-413    pascal  WAVEOUTGETPITCH(word ptr) waveOutGetPitch(1 2)
-414    pascal  WAVEOUTSETPITCH(word long) waveOutSetPitch(1 2)
-415    pascal  WAVEOUTGETVOLUME(word ptr) waveOutGetVolume(1 2)
-416    pascal  WAVEOUTSETVOLUME(word long) waveOutSetVolume(1 2)
-417    pascal  WAVEOUTGETPLAYBACKRATE(word ptr) waveOutGetPlaybackRate(1 2)
-418    pascal  WAVEOUTSETPLAYBACKRATE(word long) waveOutSetPlaybackRate(1 2)
-419    pascal  WAVEOUTBREAKLOOP(word) waveOutBreakLoop(1)
-420    pascal  WAVEOUTGETID(word ptr) waveOutGetID(1 2)
-421    pascal  WAVEOUTMESSAGE(word word long long) waveOutMessage(1 2 3 4)
-501    pascal  WAVEINGETNUMDEVS() waveInGetNumDevs()
-502    pascal  WAVEINGETDEVCAPS(word ptr word) waveInGetDevCaps(1 2 3)
-503    pascal  WAVEINGETERRORTEXT(word ptr word) waveInGetErrorText(1 2 3)
-504    pascal  WAVEINOPEN(ptr word ptr long long long) waveInOpen(1 2 3 4 5 6)
-505    pascal  WAVEINCLOSE(word) waveInClose(1)
-506    pascal  WAVEINPREPAREHEADER(word ptr word) waveInPrepareHeader(1 2 3)
-507    pascal  WAVEINUNPREPAREHEADER(word ptr word) waveInUnprepareHeader(1 2 3)
-508    pascal  WAVEINADDBUFFER(word ptr word) waveInAddBuffer(1 2 3)
-509    pascal  WAVEINSTART(word) waveInStart(1)
-510    pascal  WAVEINSTOP(word) waveInStop(1)
-511    pascal  WAVEINRESET(word) waveInReset(1)
-512    pascal  WAVEINGETPOSITION(word ptr word) waveInGetPosition(1 2 3)
-513    pascal  WAVEINGETID(word ptr) waveInGetID(1 2)
-514    pascal  WAVEINMESSAGE(word word long long) waveInMessage(1 2 3 4)
-601    pascal  timeGetSystemTime(ptr word) timeGetSystemTime(1 2)
-602    pascal  timeSetEvent(word word ptr long word) timeSetEvent(1 2 3 4 5)
-603    pascal  timeKillEvent(word) timeKillEvent(1)
-604    pascal  timeGetDevCaps(ptr word) timeGetDevCaps(1 2)
-605    pascal  timeBeginPeriod(word) timeBeginPeriod(1)
-606    pascal  timeEndPeriod(word) timeEndPeriod(1)
-607    pascal  timeGetTime() timeGetTime()
-701    pascal  MCISENDCOMMAND(word word long long) mciSendCommand(1 2 3 4)
-702    pascal  MCISENDSTRING(ptr ptr word word) mciSendString(1 2 3 4)
-703    pascal  MCIGETDEVICEID(ptr) mciSendCommand(1)
-706    pascal  MCIGETERRORSTRING(long ptr word) mciGetErrorString(1 2 3)
-#900   pascal  MMTASKCREATE()
-#902   pascal  MMTASKBLOCK()
-#903   pascal  MMTASKSIGNAL()
-#904   pascal  MMGETCURRENTTASK()
-#905   pascal  MMTASKYIELD()
-1100   pascal  DRVOPEN(ptr ptr long) DrvOpen(1 2 3)
-1101   pascal  DRVCLOSE(word long long) DrvClose(1 2 3)
-1102   pascal  DRVSENDMESSAGE(word word long long) DrvSendMessage(1 2 3 4)
-1103   pascal  DRVGETMODULEHANDLE(word) DrvGetModuleHandle(1)
-1104   pascal  DRVDEFDRIVERPROC(long word word long long) DrvDefDriverProc(1 2 3 4 5)
-1210   pascal  MMIOOPEN(ptr ptr long) mmioOpen(1 2 3)
-1211   pascal  MMIOCLOSE(word word) mmioClose(1 2)
-1212   pascal  MMIOREAD(word ptr long) mmioRead(1 2 3)
-1213   pascal  MMIOWRITE(word ptr long) mmioWrite(1 2 3)
-1214   pascal  MMIOSEEK(word long word) mmioSeek(1 2 3)
-1215   pascal  MMIOGETINFO(word ptr word) mmioGetInfo(1 2 3)
-1216   pascal  MMIOSETINFO(word ptr word) mmioSetInfo(1 2 3)
-1217   pascal  MMIOSETBUFFER(word ptr long word) mmioSetBuffer(1 2 3 4)
-1218   pascal  MMIOFLUSH(word word) mmioFlush(1 2)
-1219   pascal  MMIOADVANCE(word ptr word) mmioAdvance(1 2 3)
-1220   pascal  MMIOSTRINGTOFOURCC(ptr word) mmioStringToFOURCC(1 2)
-1221   pascal  MMIOINSTALLIOPROC(long ptr long) mmioInstallIOProc(1 2 3)
-1222   pascal  MMIOSENDMESSAGE(word word long long) mmioSendMessage(1 2 3 4)
-1223   pascal  MMIODESCEND(word ptr ptr word) mmioDescend(1 2 3 4)
-1224   pascal  MMIOASCEND(word ptr word) mmioAscend(1 2 3)
-1225   pascal  MMIOCREATECHUNK(word ptr word) mmioCreateChunk(1 2 3)
-1226   pascal  MMIORENAME(ptr ptr ptr long) mmioRename(1 2 3 4)
+1      pascal  MMSYSTEM_WEP(word word word ptr) MMSYSTEM_WEP
+2      pascal  SNDPLAYSOUND(ptr word) sndPlaySound
+5      pascal  MMSYSTEMGETVERSION() mmsystemGetVersion
+6      pascal  DriverProc(long word word long long) DriverProc
+30     pascal  OUTPUTDEBUGSTR(ptr) OutputDebugStr
+31     pascal  DriverCallback(long word word word long long long)
+               DriverCallback
+#32    pascal  STACKENTER
+#33    pascal  STACKLEAVE
+#34    pascal  MMDRVINSTALL
+101    pascal  JOYGETNUMDEVS() JoyGetNumDevs
+102    pascal  JOYGETDEVCAPS(word ptr word) JoyGetDevCaps
+103    pascal  JOYGETPOS(word ptr) JoyGetPos
+104    pascal  JOYGETTHRESHOLD(word ptr) JoyGetThreshold
+105    pascal  JOYRELEASECAPTURE(word) JoyReleaseCapture
+106    pascal  JOYSETCAPTURE(word word word word) JoySetCapture
+107    pascal  JOYSETTHRESHOLD(word word) JoySetThreshold
+109    pascal  JOYSETCALIBRATION(word) JoySetCalibration
+201    pascal  MIDIOUTGETNUMDEVS() midiOutGetNumDevs
+202    pascal  MIDIOUTGETDEVCAPS(word ptr word) midiOutGetDevCaps
+203    pascal  MIDIOUTGETERRORTEXT(word ptr word) midiOutGetErrorText
+204    pascal  MIDIOUTOPEN(ptr word ptr long long long) midiOutOpen
+205    pascal  MIDIOUTCLOSE(word) midiOutClose
+206    pascal  MIDIOUTPREPAREHEADER(word ptr word) midiOutPrepareHeader
+207    pascal  MIDIOUTUNPREPAREHEADER(word ptr word) midiOutUnprepareHeader
+208    pascal  MIDIOUTSHORTMSG(word long) midiOutShortMsg
+209    pascal  MIDIOUTLONGMSG(word ptr word) midiOutLongMsg
+210    pascal  MIDIOUTRESET(word) midiOutReset
+211    pascal  MIDIOUTGETVOLUME(word ptr) midiOutGetVolume
+212    pascal  MIDIOUTSETVOLUME(word long) midiOutSetVolume
+215    pascal  MIDIOUTGETID(word ptr) midiOutGetID
+216    pascal  MIDIOUTMESSAGE(word word long long) midiOutMessage
+301    pascal  MIDIINGETNUMDEVS() midiInGetNumDevs
+302    pascal  MIDIINGETDEVCAPS(word ptr word) midiInGetDevCaps
+303    pascal  MIDIINGETERRORTEXT(word ptr word) midiInGetErrorText
+304    pascal  MIDIINOPEN(ptr word ptr long long long) midiInOpen
+305    pascal  MIDIINCLOSE(word) midiInClose
+306    pascal  MIDIINPREPAREHEADER(word ptr word) midiInPrepareHeader
+307    pascal  MIDIINUNPREPAREHEADER(word ptr word) midiInUnprepareHeader
+309    pascal  MIDIINSTART(word) midiInStart
+310    pascal  MIDIINSTOP(word) midiInStop
+311    pascal  MIDIINRESET(word) midiInReset
+312    pascal  MIDIINGETID(word ptr) midiInGetID
+313    pascal  MIDIINMESSAGE(word word long long) midiInMessage
+350    pascal  AUXGETNUMDEVS() auxGetNumDevs
+351    pascal  AUXGETDEVCAPS(word ptr word) auxGetDevCaps
+352    pascal  AUXGETVOLUME(word ptr) auxGetVolume
+353    pascal  AUXSETVOLUME(word long) auxSetVolume
+354    pascal  AUXOUTMESSAGE(word word long long) auxOutMessage
+401    pascal  WAVEOUTGETNUMDEVS() waveOutGetNumDevs
+402    pascal  WAVEOUTGETDEVCAPS(word ptr word) waveOutGetDevCaps
+403    pascal  WAVEOUTGETERRORTEXT(word ptr word) waveOutGetErrorText
+404    pascal  WAVEOUTOPEN(ptr word ptr long long long) waveOutOpen
+405    pascal  WAVEOUTCLOSE(word) waveOutClose
+406    pascal  WAVEOUTPREPAREHEADER(word ptr word) waveOutPrepareHeader
+407    pascal  WAVEOUTUNPREPAREHEADER(word ptr word) waveOutUnprepareHeader
+408    pascal  WAVEOUTWRITE(word ptr word) waveOutWrite
+409    pascal  WAVEOUTPAUSE(word) waveOutPause
+410    pascal  WAVEOUTRESTART(word) waveOutRestart
+411    pascal  WAVEOUTRESET(word) waveOutReset
+412    pascal  WAVEOUTGETPOSITION(word ptr word) waveOutGetPosition
+413    pascal  WAVEOUTGETPITCH(word ptr) waveOutGetPitch
+414    pascal  WAVEOUTSETPITCH(word long) waveOutSetPitch
+415    pascal  WAVEOUTGETVOLUME(word ptr) waveOutGetVolume
+416    pascal  WAVEOUTSETVOLUME(word long) waveOutSetVolume
+417    pascal  WAVEOUTGETPLAYBACKRATE(word ptr) waveOutGetPlaybackRate
+418    pascal  WAVEOUTSETPLAYBACKRATE(word long) waveOutSetPlaybackRate
+419    pascal  WAVEOUTBREAKLOOP(word) waveOutBreakLoop
+420    pascal  WAVEOUTGETID(word ptr) waveOutGetID
+421    pascal  WAVEOUTMESSAGE(word word long long) waveOutMessage
+501    pascal  WAVEINGETNUMDEVS() waveInGetNumDevs
+502    pascal  WAVEINGETDEVCAPS(word ptr word) waveInGetDevCaps
+503    pascal  WAVEINGETERRORTEXT(word ptr word) waveInGetErrorText
+504    pascal  WAVEINOPEN(ptr word ptr long long long) waveInOpen
+505    pascal  WAVEINCLOSE(word) waveInClose
+506    pascal  WAVEINPREPAREHEADER(word ptr word) waveInPrepareHeader
+507    pascal  WAVEINUNPREPAREHEADER(word ptr word) waveInUnprepareHeader
+508    pascal  WAVEINADDBUFFER(word ptr word) waveInAddBuffer
+509    pascal  WAVEINSTART(word) waveInStart
+510    pascal  WAVEINSTOP(word) waveInStop
+511    pascal  WAVEINRESET(word) waveInReset
+512    pascal  WAVEINGETPOSITION(word ptr word) waveInGetPosition
+513    pascal  WAVEINGETID(word ptr) waveInGetID
+514    pascal  WAVEINMESSAGE(word word long long) waveInMessage
+601    pascal  timeGetSystemTime(ptr word) timeGetSystemTime
+602    pascal  timeSetEvent(word word ptr long word) timeSetEvent
+603    pascal  timeKillEvent(word) timeKillEvent
+604    pascal  timeGetDevCaps(ptr word) timeGetDevCaps
+605    pascal  timeBeginPeriod(word) timeBeginPeriod
+606    pascal  timeEndPeriod(word) timeEndPeriod
+607    pascal  timeGetTime() timeGetTime
+701    pascal  MCISENDCOMMAND(word word long long) mciSendCommand
+702    pascal  MCISENDSTRING(ptr ptr word word) mciSendString
+703    pascal  MCIGETDEVICEID(ptr) mciSendCommand
+706    pascal  MCIGETERRORSTRING(long ptr word) mciGetErrorString
+#900   pascal  MMTASKCREATE
+#902   pascal  MMTASKBLOCK
+#903   pascal  MMTASKSIGNAL
+#904   pascal  MMGETCURRENTTASK
+#905   pascal  MMTASKYIELD
+1100   pascal  DRVOPEN(ptr ptr long) DrvOpen
+1101   pascal  DRVCLOSE(word long long) DrvClose
+1102   pascal  DRVSENDMESSAGE(word word long long) DrvSendMessage
+1103   pascal  DRVGETMODULEHANDLE(word) DrvGetModuleHandle
+1104   pascal  DRVDEFDRIVERPROC(long word word long long) DrvDefDriverProc
+1210   pascal  MMIOOPEN(ptr ptr long) mmioOpen
+1211   pascal  MMIOCLOSE(word word) mmioClose
+1212   pascal  MMIOREAD(word ptr long) mmioRead
+1213   pascal  MMIOWRITE(word ptr long) mmioWrite
+1214   pascal  MMIOSEEK(word long word) mmioSeek
+1215   pascal  MMIOGETINFO(word ptr word) mmioGetInfo
+1216   pascal  MMIOSETINFO(word ptr word) mmioSetInfo
+1217   pascal  MMIOSETBUFFER(word ptr long word) mmioSetBuffer
+1218   pascal  MMIOFLUSH(word word) mmioFlush
+1219   pascal  MMIOADVANCE(word ptr word) mmioAdvance
+1220   pascal  MMIOSTRINGTOFOURCC(ptr word) mmioStringToFOURCC
+1221   pascal  MMIOINSTALLIOPROC(long ptr long) mmioInstallIOProc
+1222   pascal  MMIOSENDMESSAGE(word word long long) mmioSendMessage
+1223   pascal  MMIODESCEND(word ptr ptr word) mmioDescend
+1224   pascal  MMIOASCEND(word ptr word) mmioAscend
+1225   pascal  MMIOCREATECHUNK(word ptr word) mmioCreateChunk
+1226   pascal  MMIORENAME(ptr ptr ptr long) mmioRename
 
 
diff --git a/if1632/mouse.spec b/if1632/mouse.spec
index 6d15268..c387396 100644
--- a/if1632/mouse.spec
+++ b/if1632/mouse.spec
@@ -1,5 +1,5 @@
 name	mouse
-id	14
+id	13
 length	8
 
 #1 pascal INQUIRE
diff --git a/if1632/ole2.spec b/if1632/ole2.spec
index 30b7b9d..8d63886 100644
--- a/if1632/ole2.spec
+++ b/if1632/ole2.spec
@@ -1,5 +1,5 @@
 name	OLE2
-id	16
+id	15
 length	161
 
 #1 OLEBUILDVERSION
diff --git a/if1632/ole2conv.spec b/if1632/ole2conv.spec
index 107890b..9a61768 100644
--- a/if1632/ole2conv.spec
+++ b/if1632/ole2conv.spec
@@ -1,5 +1,5 @@
 name	ole2conv
-id	17
+id	16
 length	10
 #1 GETFILTERINFO
 #2 IMPORTGR
diff --git a/if1632/ole2disp.spec b/if1632/ole2disp.spec
index cf98d97..b4fdeba 100644
--- a/if1632/ole2disp.spec
+++ b/if1632/ole2disp.spec
@@ -1,5 +1,5 @@
 name	ole2disp
-id	18
+id	17
 length	110
 #1 DLLGETCLASSOBJECT
 #2 SYSALLOCSTRING
diff --git a/if1632/ole2nls.spec b/if1632/ole2nls.spec
index 7fc4a3a..2ee586e 100644
--- a/if1632/ole2nls.spec
+++ b/if1632/ole2nls.spec
@@ -1,5 +1,5 @@
 name	ole2nls
-id	19
+id	18
 length	11
 #1 GETUSERDEFAULTLCID
 #2 GETSYSTEMDEFAULTLCID
diff --git a/if1632/ole2prox.spec b/if1632/ole2prox.spec
index ecc1ebd..8328722 100644
--- a/if1632/ole2prox.spec
+++ b/if1632/ole2prox.spec
@@ -1,5 +1,5 @@
 name	ole2prox
-id	20
+id	19
 length	3
 #1 DLLGETCLASSOBJECT
 #2 WEP
diff --git a/if1632/olecli.spec b/if1632/olecli.spec
index 7d0e13e..ea21107 100644
--- a/if1632/olecli.spec
+++ b/if1632/olecli.spec
@@ -1,6 +1,9 @@
 name	olecli
-id	21
-length	954
+id	20
+length	43
+## 954 is too large for now
+##length	954
+
 #1 WEP
 #2 OLEDELETE
 #3 OLESAVETOSTREAM
@@ -40,9 +43,9 @@
 #38 OLECREATEFROMFILE
 #39 OLECREATELINKFROMFILE
 #40 OLERELEASE
-41  pascal OleRegisterClientDoc(ptr ptr long ptr) OleRegisterClientDoc(1 2 3 4)
-42  pascal OleRevokeClientDoc(long) OleRevokeClientDoc(1)
-43  pascal OleRenameClientDoc(long ptr) OleRenameClientDoc(1 2)
+41  pascal OleRegisterClientDoc(ptr ptr long ptr) OleRegisterClientDoc
+42  pascal OleRevokeClientDoc(long) OleRevokeClientDoc
+43  pascal OleRenameClientDoc(long ptr) OleRenameClientDoc
 #44 OLEREVERTCLIENTDOC
 #45 OLESAVEDCLIENTDOC
 #46 OLERENAME
diff --git a/if1632/olesvr.spec b/if1632/olesvr.spec
index cc4e167..75d471c 100644
--- a/if1632/olesvr.spec
+++ b/if1632/olesvr.spec
@@ -1,13 +1,13 @@
 name	olesvr
-id	22
+id	21
 length	31
 #1 WEP
-2  pascal OleRegisterServer(ptr ptr ptr word word) OleRegisterServer(1 2 3 4 5)
-3  pascal OleRevokeServer(long) OleRevokeServer(1)
-4  pascal OleBlockServer(long) OleBlockServer(1)
-5  pascal OleUnblockServer(long ptr) OleUnblockServer(1 2)
-6  pascal OleRegisterServerDoc(long ptr ptr ptr) OleRegisterServerDoc(1 2 3 4)
-7  pascal OleRevokeServerDoc(long) OleRevokeServerDoc(1)
+2  pascal OleRegisterServer(ptr ptr ptr word word) OleRegisterServer
+3  pascal OleRevokeServer(long) OleRevokeServer
+4  pascal OleBlockServer(long) OleBlockServer
+5  pascal OleUnblockServer(long ptr) OleUnblockServer
+6  pascal OleRegisterServerDoc(long ptr ptr ptr) OleRegisterServerDoc
+7  pascal OleRevokeServerDoc(long) OleRevokeServerDoc
 #8 OLERENAMESERVERDOC
 #9 OLEREVERTSERVERDOC
 #10 OLESAVEDSERVERDOC
diff --git a/if1632/relay.c b/if1632/relay.c
index 744ef2c..e717b5a 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -17,8 +17,9 @@
 #include <linux/ldt.h>
 #endif
 
+#include "ldt.h"
+
 #include "neexe.h"
-#include "segmem.h"
 #include "prototypes.h"
 #include "dlls.h"
 #include "options.h"
@@ -45,25 +46,26 @@
     { "KERNEL",  WineLibSkip(KERNEL_table), 	410, 1, 1 },
     { "USER",    WineLibSkip(USER_table), 	540, 2, 1 },
     { "GDI",     WineLibSkip(GDI_table), 	490, 3, 1 },
-    { "UNIXLIB", WineLibSkip(UNIXLIB_table),  10, 4, 1 },
-    { "WIN87EM", WineLibSkip(WIN87EM_table),  10, 5, 1 },
-    { "SHELL",   WineLibSkip(SHELL_table),   103, 6, 1 },
-    { "SOUND",   WineLibSkip(SOUND_table),    20, 7, 1 },
-    { "KEYBOARD",WineLibSkip(KEYBOARD_table),137, 8, 1 },
-    { "WINSOCK", WineLibSkip(WINSOCK_table), 155, 9, 1 },
-    { "STRESS",  WineLibSkip(STRESS_table),   15, 10, 1},
-    { "MMSYSTEM",WineLibSkip(MMSYSTEM_table),1226,11, 1},
-    { "SYSTEM",  WineLibSkip(SYSTEM_table),   20 ,12, 1},
-    { "TOOLHELP",WineLibSkip(TOOLHELP_table), 83, 13, 1},
-    { "MOUSE",   WineLibSkip(MOUSE_table),     8, 14, 1},
-    { "COMMDLG", WineLibSkip(COMMDLG_table),  31, 15, 1},
-    { "OLE2",    WineLibSkip(OLE2_table),     31, 16, 1},
-    { "OLE2CONV",WineLibSkip(OLE2CONV_table), 31, 17, 1},
-    { "OLE2DISP",WineLibSkip(OLE2DISP_table), 31, 18, 1},
-    { "OLE2NLS", WineLibSkip(OLE2NLS_table),  31, 19, 1},
-    { "OLE2PROX",WineLibSkip(OLE2PROX_table), 31, 20, 1},
-    { "OLECLI",  WineLibSkip(OLECLI_table),   31, 21, 1},
-    { "OLESVR",  WineLibSkip(OLESVR_table),   31, 22, 1},
+    { "WIN87EM", WineLibSkip(WIN87EM_table),  10, 4, 1 },
+    { "SHELL",   WineLibSkip(SHELL_table),   103, 5, 1 },
+    { "SOUND",   WineLibSkip(SOUND_table),    20, 6, 1 },
+    { "KEYBOARD",WineLibSkip(KEYBOARD_table),137, 7, 1 },
+    { "WINSOCK", WineLibSkip(WINSOCK_table), 155, 8, 1 },
+    { "STRESS",  WineLibSkip(STRESS_table),   15, 9, 1},
+    { "MMSYSTEM",WineLibSkip(MMSYSTEM_table),1226,10, 1},
+    { "SYSTEM",  WineLibSkip(SYSTEM_table),   20 ,11, 1},
+    { "TOOLHELP",WineLibSkip(TOOLHELP_table), 83, 12, 1},
+    { "MOUSE",   WineLibSkip(MOUSE_table),     8, 13, 1},
+    { "COMMDLG", WineLibSkip(COMMDLG_table),  31, 14, 1},
+    { "OLE2",    WineLibSkip(OLE2_table),     31, 15, 1},
+    { "OLE2CONV",WineLibSkip(OLE2CONV_table), 31, 16, 1},
+    { "OLE2DISP",WineLibSkip(OLE2DISP_table), 31, 17, 1},
+    { "OLE2NLS", WineLibSkip(OLE2NLS_table),  31, 18, 1},
+    { "OLE2PROX",WineLibSkip(OLE2PROX_table), 31, 19, 1},
+    { "OLECLI",  WineLibSkip(OLECLI_table),   31, 20, 1},
+    { "OLESVR",  WineLibSkip(OLESVR_table),   31, 21, 1},
+    { "COMPOBJ", WineLibSkip(COMPOBJ_table),  31, 22, 1},
+    { "STORAGE", WineLibSkip(STORAGE_table),  31, 23, 1}
 };
 /* don't forget to increase N_BUILTINS in dll.h if you add a dll */
 
@@ -72,38 +74,53 @@
 	unsigned short *dst_args;   /*  Offsets to arguments on stack */
 	unsigned char *src_types;   /* Argument types              */
 } dll_conversion_table[N_BUILTINS]= {
-  KERNEL_offsets,   KERNEL_types,   /* KERNEL     */
-  USER_offsets,     USER_types,     /* USER       */
-  GDI_offsets,      GDI_types,      /* GDI        */
-  UNIXLIB_offsets,  UNIXLIB_types,  /* UNIXLIB    */
-  WIN87EM_offsets,  WIN87EM_types,  /* WIN87EM    */
-  SHELL_offsets,    SHELL_types,    /* SHELL      */
-  SOUND_offsets,    SOUND_types,    /* SOUND      */
-  KEYBOARD_offsets, KEYBOARD_types, /* KEYBOARD   */
-  WINSOCK_offsets,  WINSOCK_types,  /* WINSOCK    */
-  STRESS_offsets,   STRESS_types,   /* STRESS,     */
-  MMSYSTEM_offsets, MMSYSTEM_types, /* MMSYSTEM   */
-  SYSTEM_offsets,   SYSTEM_types,   /* SYSTEM     */
-  TOOLHELP_offsets, TOOLHELP_types, /* TOOLHELP   */
-  MOUSE_offsets,    MOUSE_types,    /* MOUSE      */
-  COMMDLG_offsets,  COMMDLG_types,  /* EMUCOMMDLG */
-  OLE2_offsets,     OLE2_types,     /* OLE2       */
-  OLE2CONV_offsets, OLE2CONV_types, /* OLE2CONV   */
-  OLE2DISP_offsets, OLE2DISP_types, /* OLE2DISP   */
-  OLE2NLS_offsets,  OLE2NLS_types,  /* OLE2NLS    */
-  OLE2DISP_offsets, OLE2DISP_types, /* OLE2PROX   */
-  OLECLI_offsets,   OLECLI_types,   /* OLE2CLI    */
-  OLESVR_offsets,   OLESVR_types    /* OLE2CLI    */
+  { KERNEL_offsets,   KERNEL_types },   /* KERNEL     */
+  { USER_offsets,     USER_types },     /* USER       */
+  { GDI_offsets,      GDI_types },      /* GDI        */
+  { WIN87EM_offsets,  WIN87EM_types },  /* WIN87EM    */
+  { SHELL_offsets,    SHELL_types },    /* SHELL      */
+  { SOUND_offsets,    SOUND_types },    /* SOUND      */
+  { KEYBOARD_offsets, KEYBOARD_types }, /* KEYBOARD   */
+  { WINSOCK_offsets,  WINSOCK_types },  /* WINSOCK    */
+  { STRESS_offsets,   STRESS_types },   /* STRESS,     */
+  { MMSYSTEM_offsets, MMSYSTEM_types }, /* MMSYSTEM   */
+  { SYSTEM_offsets,   SYSTEM_types },   /* SYSTEM     */
+  { TOOLHELP_offsets, TOOLHELP_types }, /* TOOLHELP   */
+  { MOUSE_offsets,    MOUSE_types },    /* MOUSE      */
+  { COMMDLG_offsets,  COMMDLG_types },  /* EMUCOMMDLG */
+  { OLE2_offsets,     OLE2_types },     /* OLE2       */
+  { OLE2CONV_offsets, OLE2CONV_types }, /* OLE2CONV   */
+  { OLE2DISP_offsets, OLE2DISP_types }, /* OLE2DISP   */
+  { OLE2NLS_offsets,  OLE2NLS_types },  /* OLE2NLS    */
+  { OLE2DISP_offsets, OLE2DISP_types }, /* OLE2PROX   */
+  { OLECLI_offsets,   OLECLI_types },   /* OLE2CLI    */
+  { OLESVR_offsets,   OLESVR_types },   /* OLE2CLI    */
+  { COMPOBJ_offsets,  COMPOBJ_types },  /* COMPOBJ    */
+  { STORAGE_offsets,  STORAGE_types }   /* STORAGE    */
 };
 
 
 #ifndef WINELIB
-STACK16FRAME *pStack16Frame;
 
 extern unsigned short IF1632_Saved16_sp;
 extern unsigned short IF1632_Saved16_bp;
 extern unsigned short IF1632_Saved16_ss;
 
+void RelayDebug( unsigned int func_num )
+{
+    unsigned int dll_id, ordinal;
+
+    if (debugging_relay)
+    {
+        dll_id  = ((func_num >> 16) & 0xffff) - 1;
+        ordinal = func_num & 0xffff;
+        printf( "Calling %s.%d\n",
+               dll_builtin_table[dll_id].dll_table[ordinal].export_name,
+               ordinal );
+    }
+}
+
+
 /**********************************************************************
  *					DLLRelay
  *
@@ -126,7 +143,7 @@
 DLLRelay(unsigned int func_num, unsigned int seg_off)
 {
     struct dll_table_entry_s *dll_p;
-    STACK16FRAME *pOldStack16Frame;
+    STACK16FRAME *pStack16Frame;
     unsigned int offset;
     unsigned int dll_id;
     unsigned int ordinal;
@@ -138,12 +155,12 @@
     int conv_ref;
     unsigned char *type_conv;
     unsigned short *offset_conv;
+    STACK16FRAME stackFrameCopy;
 
     /*
      * Determine address of arguments.
      */
-    pOldStack16Frame = pStack16Frame;
-    pStack16Frame = (STACK16FRAME *) seg_off;
+    pStack16Frame = (STACK16FRAME *) PTR_SEG_TO_LIN(seg_off);
     arg_ptr = (void *)pStack16Frame->args;
 
     /*
@@ -153,31 +170,27 @@
     ordinal = func_num & 0xffff;
     dll_p   = &dll_builtin_table[dll_id].dll_table[ordinal];
 
-    if (debugging_relay)
-    {
-	printf( "Call %s (%s.%d), stack=%04x:%04x, ret=%04x:%04x",
-	       dll_p->export_name,
-	       dll_builtin_table[dll_id].dll_name, ordinal,
-	       seg_off >> 16, seg_off & 0xffff,
-               pStack16Frame->cs, pStack16Frame->ip );
-	printf(" bp=%04x ds=%04x args=%d\n",
-               pStack16Frame->bp, pStack16Frame->ds,
-               pStack16Frame->arg_length );
+    dprintf_relay( stddeb, "Call %s (%s.%d), stack=%04x:%04x ret=%04x:%04x ds=%04x bp=%04x args=%d\n",
+                  dll_p->export_name,
+                  dll_builtin_table[dll_id].dll_name, ordinal,
+                  seg_off >> 16, seg_off & 0xffff,
+                  pStack16Frame->cs, pStack16Frame->ip,
+                  pStack16Frame->ds, pStack16Frame->bp,
+                  pStack16Frame->arg_length );
 
-	if(debugging_stack)
+    if(debugging_stack)
+    {
+        unsigned short *stack_p = (unsigned short *) pStack16Frame;
+        /* FIXME: Is there an end-of-stack-pointer somewhere ? */
+        int n = min(24, (0x10000 - (seg_off & 0xffff)) / sizeof(*stack_p));
+        for (i = 0; i < n; i++, stack_p++)
         {
-            unsigned short *stack_p = (unsigned short *) seg_off;
-	    /* FIXME: Is there an end-of-stack-pointer somewhere ? */
-	    int n = min(24, (0x10000 - (seg_off & 0xffff)) / sizeof(*stack_p));
-            for (i = 0; i < n; i++, stack_p++)
-            {
-                printf("%04x ", *stack_p);
-                if ((i & 7) == 7)
-                    printf("\n");
-            }
-            printf("\n");
-	}
-    } /* DEBUG_RELAY */
+            printf("%04x ", *stack_p);
+            if ((i & 7) == 7)
+                printf("\n");
+        }
+        printf("\n");
+    }
 
     /*
      * Make sure we have a handler defined for this call.
@@ -202,7 +215,10 @@
     if (dll_p->n_args == 0)
     {
 	ret_val = (*func_ptr)(arg_ptr);
-        pStack16Frame = pOldStack16Frame;
+	dprintf_relay( stddeb, "Returning %08x from %s (%s.%d) ds=%04x\n",
+                       ret_val, dll_p->export_name,
+                       dll_builtin_table[dll_id].dll_name, ordinal,
+                       pStack16Frame->ds );
 	return ret_val;
     }
 
@@ -238,14 +254,14 @@
 
 	  case DLL_ARGTYPE_FARPTR:
 	    ip = (int *) ((char *) arg_ptr + offset);
-	    if (*ip & 0xffff0000)
-		arg_table[i] = FIXPTR(*ip);
-	    else
-		arg_table[i] = *ip;
+            arg_table[i] = (unsigned int) PTR_SEG_TO_LIN( *ip );
 	    break;
 	}
     }
 
+    if (debugging_relay)
+        memcpy( &stackFrameCopy, pStack16Frame, sizeof(stackFrameCopy) );
+
     /*
      * Call the handler
      */
@@ -256,10 +272,12 @@
 			  arg_table[12], arg_table[13], arg_table[14], 
 			  arg_table[15]);
 
-    pStack16Frame = pOldStack16Frame;
-
     if (debugging_relay)
     {
+        if (memcmp( &stackFrameCopy, pStack16Frame, sizeof(stackFrameCopy) ))
+        {
+            printf( "**** 16-bit stack corrupted!\n" );
+        }
 	printf("Returning %08x from %s (%s.%d) ds=%04x\n",
 	       ret_val,
 	       dll_p->export_name,
diff --git a/if1632/shell.spec b/if1632/shell.spec
index fb44c1c..f559912 100644
--- a/if1632/shell.spec
+++ b/if1632/shell.spec
@@ -1,7 +1,7 @@
 # $Id: shell.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	shell
-id	6
+id	5
 length	103
 
 #
@@ -9,24 +9,24 @@
 # 			proper parameters. It's just to have stub for PROGMAN.EXE ...
 #
 
-  1 pascal RegOpenKey(word ptr ptr) RegOpenKey(1 2 3)
-  2 pascal RegCreateKey(word ptr ptr) RegCreateKey(1 2 3)
-  3 pascal RegCloseKey(word) RegCloseKey(1)
-  4 pascal RegDeleteKey(word ptr) RegDeleteKey(1 2)
-  5 pascal RegSetValue(word ptr long ptr long) RegSetValue(1 2 3 4 5)
-  6 pascal RegQueryValue(word ptr ptr ptr) RegQueryValue(1 2 3 4)
-  7 pascal RegEnumKey(word long ptr long) RegEnumKey(1 2 3 4)
-  9 pascal DragAcceptFiles(word word) DragAcceptFiles(1 2)
- 11 pascal DragQueryFile(word s_word ptr s_word) DragQueryFile(1 2 3 4)
- 12 pascal DragFinish(word) DragFinish(1)
- 13 pascal DragQueryPoint(word ptr) DragQueryPoint(1 2)
- 20 pascal ShellExecute(word ptr ptr ptr ptr s_word) ShellExecute(1 2 3 4 5 6) 
- 21 pascal FindExecutable(ptr ptr ptr) FindExecutable(1 2 3)
- 22 pascal ShellAbout(word ptr ptr word) ShellAbout(1 2 3 4)
- 33 pascal AboutDlgProc(word word word long) AboutDlgProc(1 2 3 4)
- 34 pascal ExtractIcon(word ptr s_word) ExtractIcon(1 2 3)
-102 pascal RegisterShellHook(ptr) RegisterShellHook(1)
-103 pascal ShellHookProc() ShellHookProc()
+  1 pascal RegOpenKey(word ptr ptr) RegOpenKey
+  2 pascal RegCreateKey(word ptr ptr) RegCreateKey
+  3 pascal RegCloseKey(word) RegCloseKey
+  4 pascal RegDeleteKey(word ptr) RegDeleteKey
+  5 pascal RegSetValue(word ptr long ptr long) RegSetValue
+  6 pascal RegQueryValue(word ptr ptr ptr) RegQueryValue
+  7 pascal RegEnumKey(word long ptr long) RegEnumKey
+  9 pascal DragAcceptFiles(word word) DragAcceptFiles
+ 11 pascal DragQueryFile(word s_word ptr s_word) DragQueryFile
+ 12 pascal DragFinish(word) DragFinish
+ 13 pascal DragQueryPoint(word ptr) DragQueryPoint
+ 20 pascal ShellExecute(word ptr ptr ptr ptr s_word) ShellExecute 
+ 21 pascal FindExecutable(ptr ptr ptr) FindExecutable
+ 22 pascal ShellAbout(word ptr ptr word) ShellAbout
+ 33 pascal AboutDlgProc(word word word long) AboutDlgProc
+ 34 pascal ExtractIcon(word ptr s_word) ExtractIcon
+102 pascal RegisterShellHook(ptr) RegisterShellHook
+103 pascal ShellHookProc() ShellHookProc
 
 #  8   7  0000  WEP exported, shared data
 #100   4  0550  HERETHARBETYGARS exported, shared data
diff --git a/if1632/sound.spec b/if1632/sound.spec
index 9ce9349..825fc4e 100644
--- a/if1632/sound.spec
+++ b/if1632/sound.spec
@@ -1,24 +1,24 @@
 # $Id: sound.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
 #
 name	sound
-id	7
+id	6
 length	20
 
-1    pascal  OPENSOUND() OpenSound()
-2    pascal  CLOSESOUND() CloseSound()
-3    pascal  SETVOICEQUEUESIZE(word word) SetVoiceQueueSize(1 2)
-4    pascal  SETVOICENOTE(word word word word) SetVoiceNote(1 2 3 4)
+1    pascal  OPENSOUND() OpenSound
+2    pascal  CLOSESOUND() CloseSound
+3    pascal  SETVOICEQUEUESIZE(word word) SetVoiceQueueSize
+4    pascal  SETVOICENOTE(word word word word) SetVoiceNote
 5    pascal  SETVOICEACCENT(word word word word word) 
-		       SetVoiceAccent(1 2 3 4 5)
-6    pascal  SETVOICEENVELOPE(word word word) SetVoiceEnvelope(1 2 3)
-7    pascal  SETSOUNDNOISE(word word) SetSoundNoise(1 2)
-8    pascal  SETVOICESOUND(word long word) SetVoiceSound(1 2 3)
-9    pascal  STARTSOUND() StartSound()
-10   pascal  STOPSOUND() StopSound()
-11   pascal  WAITSOUNDSTATE(word) WaitSoundState(1)
-12   pascal  SYNCALLVOICES() SyncAllVoices()
-13   pascal  COUNTVOICENOTES(word) CountVoiceNotes(1)
-14   pascal  GETTHRESHOLDEVENT() GetThresholdEvent()
-15   pascal  GETTHRESHOLDSTATUS() GetThresholdStatus()
-16   pascal  SETVOICETHRESHOLD(word word) SetVoiceThreshold(1 2)
-17   pascal  DOBEEP() DoBeep()
+		       SetVoiceAccent
+6    pascal  SETVOICEENVELOPE(word word word) SetVoiceEnvelope
+7    pascal  SETSOUNDNOISE(word word) SetSoundNoise
+8    pascal  SETVOICESOUND(word long word) SetVoiceSound
+9    pascal  STARTSOUND() StartSound
+10   pascal  STOPSOUND() StopSound
+11   pascal  WAITSOUNDSTATE(word) WaitSoundState
+12   pascal  SYNCALLVOICES() SyncAllVoices
+13   pascal  COUNTVOICENOTES(word) CountVoiceNotes
+14   pascal  GETTHRESHOLDEVENT() GetThresholdEvent
+15   pascal  GETTHRESHOLDSTATUS() GetThresholdStatus
+16   pascal  SETVOICETHRESHOLD(word word) SetVoiceThreshold
+17   pascal  DOBEEP() DoBeep
diff --git a/if1632/storage.spec b/if1632/storage.spec
new file mode 100644
index 0000000..8876ef9
--- /dev/null
+++ b/if1632/storage.spec
@@ -0,0 +1,14 @@
+name	storage
+id	23
+length	104
+ 
+#1 STGCREATEDOCFILE
+#2 STGCREATEDOCFILEONILOCKBYTES
+#3 STGOPENSTORAGE
+#4 STGOPENSTORAGEONILOCKBYTES
+#5 STGISSTORAGEFILE
+#6 STGISSTORAGEILOCKBYTES
+#7 STGSETTIMES
+#8 WEP
+#9 ___EXPORTEDSTUB
+#103 DLLGETCLASSOBJECT
diff --git a/if1632/stress.spec b/if1632/stress.spec
index 8c93cb7..2e2e880 100644
--- a/if1632/stress.spec
+++ b/if1632/stress.spec
@@ -1,18 +1,18 @@
 # summary: resource modification dll
 #
 name	stress
-id	10
+id	9
 length	15
 
-2   pascal allocmem(long)		AllocMem(1)
-3   pascal freeallmem()			FreeAllMem()
-6   pascal allocfilehandles(word)	AllocFileHandles(1)
-7   pascal unallocfilehandles()		UnAllocFileHandles()
-8   pascal getfreefilehandles()		GetFreeFileHandles()
-10  pascal allocdiskspace(long word)	AllocDiskSpace(1 2)
-11  pascal unallocdiskspace(word)	UnAllocDiskSpace(1)
-12  pascal allocusermem(word)		AllocUserMem(1)
-13  pascal freeallusermem()		FreeAllUserMem()
-14  pascal allocgdimem(word)		AllocGDIMem(1)
-15  pascal freeallgdimem()		FreeAllGDIMem()
+2   pascal allocmem(long)		AllocMem
+3   pascal freeallmem()			FreeAllMem
+6   pascal allocfilehandles(word)	AllocFileHandles
+7   pascal unallocfilehandles()		UnAllocFileHandles
+8   pascal getfreefilehandles()		GetFreeFileHandles
+10  pascal allocdiskspace(long word)	AllocDiskSpace
+11  pascal unallocdiskspace(word)	UnAllocDiskSpace
+12  pascal allocusermem(word)		AllocUserMem
+13  pascal freeallusermem()		FreeAllUserMem
+14  pascal allocgdimem(word)		AllocGDIMem
+15  pascal freeallgdimem()		FreeAllGDIMem
 
diff --git a/if1632/system.spec b/if1632/system.spec
index e54f67f..4f2b816 100644
--- a/if1632/system.spec
+++ b/if1632/system.spec
@@ -1,5 +1,5 @@
 name	system
-id	12
+id	11
 length	20
 
-6 pascal GetSystemmsecCount() GetTickCount()
+6 pascal GetSystemmsecCount() GetTickCount
diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec
index 4380277..775ee81 100644
--- a/if1632/toolhelp.spec
+++ b/if1632/toolhelp.spec
@@ -1,37 +1,37 @@
 name	toolhelp
-id	13
+id	12
 length	83
 
-# 50   1  057b  GLOBALHANDLETOSEL exported, shared data
+50 pascal16 GlobalHandleToSel(word) GlobalHandleToSel
 # 51   1  0318  GLOBALFIRST exported, shared data
 # 52   1  0399  GLOBALNEXT exported, shared data
 # 53   1  02a2  GLOBALINFO exported, shared data
 # 54   1  0417  GLOBALENTRYHANDLE exported, shared data
 # 55   1  04a9  GLOBALENTRYMODULE exported, shared data
-# 56   1  090e  LOCALINFO exported, shared data
-# 57   1  095e  LOCALFIRST exported, shared data
-# 58   1  09e9  LOCALNEXT exported, shared data
-59 pascal ModuleFirst(ptr) ModuleFirst(1)
-60 pascal ModuleNext(ptr) ModuleNext(1)
-61 pascal ModuleFindName(ptr ptr) ModuleFindName(1 2)
-62 pascal ModuleFindHandle(ptr word) ModuleFindHandle(1 2)
-63 pascal16 TaskFirst(ptr) TaskFirst(1)
-64 pascal16 TaskNext(ptr) TaskNext(1)
-65 pascal16 TaskFindHandle(ptr word) TaskFindHandle(1 2)
+56 pascal16 LocalInfo(ptr word) LocalInfo
+57 pascal16 LocalFirst(ptr word) LocalFirst
+58 pascal16 LocalNext(ptr) LocalNext
+59 pascal16 ModuleFirst(ptr) ModuleFirst
+60 pascal16 ModuleNext(ptr) ModuleNext
+61 pascal16 ModuleFindName(ptr ptr) ModuleFindName
+62 pascal16 ModuleFindHandle(ptr word) ModuleFindHandle
+63 pascal16 TaskFirst(ptr) TaskFirst
+64 pascal16 TaskNext(ptr) TaskNext
+65 pascal16 TaskFindHandle(ptr word) TaskFindHandle
 # 66   1  0f1c  STACKTRACEFIRST exported, shared data
 # 67   1  0f67  STACKTRACECSIPFIRST exported, shared data
 # 68   1  0fca  STACKTRACENEXT exported, shared data
-# 69   1  28b0  CLASSFIRST exported, shared data
-# 70   1  2925  CLASSNEXT exported, shared data
-# 71   1  11ce  SYSTEMHEAPINFO exported, shared data
-72 pascal16 MemManInfo(ptr) MemManInfo(1)
+69 pascal16 ClassFirst(ptr) ClassFirst
+70 pascal16 ClassNext(ptr) ClassNext
+71 pascal16 SystemHeapInfo(ptr) SystemHeapInfo
+#72 pascal16 MemManInfo(ptr) MemManInfo
 # 73   1  1b72  NOTIFYREGISTER exported, shared data
 # 74   1  1c29  NOTIFYUNREGISTER exported, shared data
 # 75   1  2060  INTERRUPTREGISTER exported, shared data
 # 76   1  2111  INTERRUPTUNREGISTER exported, shared data
 # 77   1  26ea  TERMINATEAPP exported, shared data
-# 78   1  29c4  MEMORYREAD exported, shared data
-# 79   1  2b6c  MEMORYWRITE exported, shared data
+78 pascal MemoryRead(word long ptr long) MemoryRead
+79 pascal MemoryWrite(word long ptr long) MemoryWrite
 # 80   1  2dae  TIMERCOUNT exported, shared data
 # 81   1  0d68  TASKSETCSIP exported, shared data
 # 82   1  0d97  TASKGETCSIP exported, shared data
diff --git a/if1632/unixlib.spec b/if1632/unixlib.spec
deleted file mode 100644
index a8b408a..0000000
--- a/if1632/unixlib.spec
+++ /dev/null
@@ -1,7 +0,0 @@
-# $Id: unixlib.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
-#
-name	unixlib
-id	4
-length	10
-
-1   c _DebugPrintString(ptr) DebugPrintString(1)
diff --git a/if1632/user.spec b/if1632/user.spec
index ac57b7b..73de7b6 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -4,406 +4,393 @@
 id	2
 length	540
 
-1   pascal MessageBox(word ptr ptr word) MessageBox(1 2 3 4)
+1   pascal MessageBox(word ptr ptr word) MessageBox
 #2 OLDEXITWINDOWS
 #3 ENABLEOEMLAYER
 #4 DISABLEOEMLAYER
-5   pascal InitApp(word) USER_InitApp(1)
-6   pascal PostQuitMessage(word) PostQuitMessage(1)
-7   pascal ExitWindows(long word) ExitWindows(1 2)
-10  pascal SetTimer(word word word ptr) SetTimer(1 2 3 4)
-11  pascal SetSystemTimer(word word word ptr) SetSystemTimer(1 2 3 4)
-12  pascal KillTimer(word word) KillTimer(1 2)
-13  pascal GetTickCount() GetTickCount()
-14  pascal GetTimerResolution() GetTimerResolution()
-15  pascal GetCurrentTime() GetTickCount()
-16  pascal ClipCursor(ptr) ClipCursor(1)
-17  pascal GetCursorPos(ptr) GetCursorPos(1)
-18  pascal SetCapture(word) SetCapture(1)
-19  pascal ReleaseCapture() ReleaseCapture()
-20  pascal SetDoubleClickTime(word) SetDoubleClickTime(1)
-21  pascal GetDoubleClickTime() GetDoubleClickTime()
-22  pascal SetFocus(word) SetFocus(1)
-23  pascal GetFocus() GetFocus()
-24  pascal RemoveProp(word ptr) RemoveProp(1 2)
-25  pascal GetProp(word ptr) GetProp(1 2)
-26  pascal SetProp(word ptr word) SetProp(1 2 3)
-27  pascal EnumProps(word ptr) EnumProps(1 2)
-28  pascal ClientToScreen(word ptr) ClientToScreen(1 2)
-29  pascal ScreenToClient(word ptr) ScreenToClient(1 2)
-30  pascal WindowFromPoint(long) WindowFromPoint(1)
-31  pascal IsIconic(word) IsIconic(1)
-32  pascal GetWindowRect(word ptr) GetWindowRect(1 2)
-33  pascal GetClientRect(word ptr) GetClientRect(1 2)
-34  pascal EnableWindow(word word) EnableWindow(1 2)
-35  pascal IsWindowEnabled(word) IsWindowEnabled(1)
-36  pascal GetWindowText(word ptr word) GetWindowText(1 2 3)
-37  pascal SetWindowText(word ptr) SetWindowText(1 2)
-38  pascal GetWindowTextLength(word) GetWindowTextLength(1)
-39  pascal BeginPaint(word ptr) BeginPaint(1 2)
-40  pascal EndPaint(word ptr) EndPaint(1 2)
-41  pascal CreateWindow(ptr ptr long s_word s_word s_word s_word word word word ptr) 
-	   CreateWindow(1 2 3 4 5 6 7 8 9 10 11)
-42  pascal ShowWindow(word word) ShowWindow(1 2)
-43  pascal CloseWindow(word) CloseWindow(1)
-44  pascal OpenIcon(word) OpenIcon(1)
-45  pascal BringWindowToTop(word) BringWindowToTop(1)
-46  pascal GetParent(word) GetParent(1)
-47  pascal IsWindow(word) IsWindow(1)
-48  pascal IsChild(word word) IsChild(1 2)
-49  pascal IsWindowVisible(word) IsWindowVisible(1)
-50  pascal FindWindow(ptr ptr) FindWindow(1 2)
+5   pascal InitApp(word) USER_InitApp
+6   pascal PostQuitMessage(word) PostQuitMessage
+7   pascal ExitWindows(long word) ExitWindows
+10  pascal SetTimer(word word word segptr) SetTimer
+11  pascal SetSystemTimer(word word word segptr) SetSystemTimer
+12  pascal KillTimer(word word) KillTimer
+13  pascal GetTickCount() GetTickCount
+14  pascal GetTimerResolution() GetTimerResolution
+15  pascal GetCurrentTime() GetTickCount
+16  pascal ClipCursor(ptr) ClipCursor
+17  pascal GetCursorPos(ptr) GetCursorPos
+18  pascal SetCapture(word) SetCapture
+19  pascal ReleaseCapture() ReleaseCapture
+20  pascal SetDoubleClickTime(word) SetDoubleClickTime
+21  pascal GetDoubleClickTime() GetDoubleClickTime
+22  pascal SetFocus(word) SetFocus
+23  pascal GetFocus() GetFocus
+24  pascal RemoveProp(word ptr) RemoveProp
+25  pascal GetProp(word ptr) GetProp
+26  pascal SetProp(word ptr word) SetProp
+27  pascal EnumProps(word ptr) EnumProps
+28  pascal ClientToScreen(word ptr) ClientToScreen
+29  pascal ScreenToClient(word ptr) ScreenToClient
+30  pascal WindowFromPoint(long) WindowFromPoint
+31  pascal IsIconic(word) IsIconic
+32  pascal GetWindowRect(word ptr) GetWindowRect
+33  pascal GetClientRect(word ptr) GetClientRect
+34  pascal EnableWindow(word word) EnableWindow
+35  pascal IsWindowEnabled(word) IsWindowEnabled
+36  pascal GetWindowText(word segptr word) WIN16_GetWindowText
+37  pascal SetWindowText(word segptr) WIN16_SetWindowText
+38  pascal GetWindowTextLength(word) GetWindowTextLength
+39  pascal BeginPaint(word ptr) BeginPaint
+40  pascal EndPaint(word ptr) EndPaint
+41  pascal CreateWindow(ptr ptr long s_word s_word s_word s_word
+	                word word word segptr) CreateWindow
+42  pascal ShowWindow(word word) ShowWindow
+43  pascal CloseWindow(word) CloseWindow
+44  pascal OpenIcon(word) OpenIcon
+45  pascal BringWindowToTop(word) BringWindowToTop
+46  pascal GetParent(word) GetParent
+47  pascal IsWindow(word) IsWindow
+48  pascal IsChild(word word) IsChild
+49  pascal IsWindowVisible(word) IsWindowVisible
+50  pascal FindWindow(ptr ptr) FindWindow
 #51 BEAR51
-52  pascal AnyPopup() AnyPopup()
-53  pascal DestroyWindow(word) DestroyWindow(1)
-54  pascal EnumWindows(ptr long) EnumWindows(1 2)
-55  pascal EnumChildWindows(word ptr long) EnumChildWindows(1 2 3)
-56  pascal MoveWindow(word word word word word word) 
-           MoveWindow(1 2 3 4 5 6)
-57  pascal RegisterClass(ptr) RegisterClass(1)
-58  pascal GetClassName(word ptr word) GetClassName(1 2 3)
-59  pascal SetActiveWindow(word) SetActiveWindow(1)
-60  pascal GetActiveWindow() GetActiveWindow()
-61  pascal ScrollWindow(word s_word s_word ptr ptr) ScrollWindow(1 2 3 4 5)
-62  pascal SetScrollPos(word word s_word word) SetScrollPos(1 2 3 4)
-63  pascal GetScrollPos(word word) GetScrollPos(1 2)
-64  pascal SetScrollRange(word word s_word s_word word) SetScrollRange(1 2 3 4 5)
-65  pascal GetScrollRange(word word ptr ptr) GetScrollRange(1 2 3 4)
-66  pascal GetDC(word) GetDC(1)
-67  pascal GetWindowDC(word) GetWindowDC(1)
-68  pascal ReleaseDC(word word) ReleaseDC(1 2)
-69  pascal SetCursor(word) SetCursor(1)
-70  pascal SetCursorPos(word word) SetCursorPos(1 2)
-71  pascal ShowCursor(word) ShowCursor(1)
-72  pascal SetRect(ptr s_word s_word s_word s_word) SetRect(1 2 3 4 5)
-73  pascal SetRectEmpty(ptr) SetRectEmpty(1)
-74  pascal CopyRect(ptr ptr) CopyRect(1 2)
-75  pascal IsRectEmpty(ptr) IsRectEmpty(1)
-76  pascal PtInRect(ptr long) PtInRect(1 2)
-77  pascal OffsetRect(ptr s_word s_word) OffsetRect(1 2 3)
-78  pascal InflateRect(ptr s_word s_word) InflateRect(1 2 3)
-79  pascal IntersectRect(ptr ptr ptr) IntersectRect(1 2 3)
-80  pascal UnionRect(ptr ptr ptr) UnionRect(1 2 3)
-81  pascal FillRect(word ptr word) FillRect(1 2 3)
-82  pascal InvertRect(word ptr) InvertRect(1 2)
-83  pascal FrameRect(word ptr word) FrameRect(1 2 3)
-84  pascal DrawIcon(word s_word s_word word) DrawIcon(1 2 3 4)
-85  pascal DrawText(word ptr s_word ptr word) DrawText(1 2 3 4 5)
-87  pascal DialogBox(word ptr word ptr) DialogBox(1 2 3 4)
-88  pascal EndDialog(word s_word) EndDialog(1 2)
-89  pascal CreateDialog(word ptr word ptr) CreateDialog(1 2 3 4)
-90  pascal IsDialogMessage(word ptr) IsDialogMessage(1 2)
-91  pascal GetDlgItem(word word) GetDlgItem(1 2)
-92  pascal SetDlgItemText(word word ptr) SetDlgItemText(1 2 3)
-93  pascal GetDlgItemText(word word ptr word) GetDlgItemText(1 2 3 4)
-94  pascal SetDlgItemInt(word word word word) SetDlgItemInt(1 2 3 4)
-95  pascal GetDlgItemInt(word word ptr word) GetDlgItemInt(1 2 3 4)
-96  pascal CheckRadioButton(word word word word) CheckRadioButton(1 2 3 4)
-97  pascal CheckDlgButton(word word word) CheckDlgButton(1 2 3)
-98  pascal IsDlgButtonChecked(word word) IsDlgButtonChecked(1 2)
-99  pascal DlgDirSelect(word ptr word) DlgDirSelect(1 2 3)
-100 pascal DlgDirList(word ptr word word word) DlgDirList(1 2 3 4 5)
-101 pascal SendDlgItemMessage(word word word word long)
-	   SendDlgItemMessage(1 2 3 4 5)
-102 pascal AdjustWindowRect(ptr long word) AdjustWindowRect(1 2 3)
-103 pascal MapDialogRect(word ptr) MapDialogRect(1 2)
-104 pascal MessageBeep(word) MessageBeep(1)
-105 pascal FlashWindow(word word) FlashWindow(1 2)
-106 pascal GetKeyState(word) GetKeyState(1)
-107 pascal DefWindowProc(word word word long) DefWindowProc(1 2 3 4)
-108 pascal GetMessage(ptr word word word) GetMessage(1 2 3 4)
-109 pascal PeekMessage(ptr word word word word) PeekMessage(1 2 3 4 5)
-110 pascal PostMessage(word word word long) PostMessage(1 2 3 4)
-111 pascal SendMessage(word word word long) SendMessage(1 2 3 4)
-112 pascal WaitMessage() WaitMessage()
-113 pascal TranslateMessage(ptr) TranslateMessage(1)
-114 pascal DispatchMessage(ptr) DispatchMessage(1)
+52  pascal AnyPopup() AnyPopup
+53  pascal DestroyWindow(word) DestroyWindow
+54  pascal EnumWindows(ptr long) EnumWindows
+55  pascal EnumChildWindows(word ptr long) EnumChildWindows
+56  pascal MoveWindow(word word word word word word) MoveWindow
+57  pascal RegisterClass(ptr) RegisterClass
+58  pascal GetClassName(word ptr word) GetClassName
+59  pascal SetActiveWindow(word) SetActiveWindow
+60  pascal GetActiveWindow() GetActiveWindow
+61  pascal ScrollWindow(word s_word s_word ptr ptr) ScrollWindow
+62  pascal SetScrollPos(word word s_word word) SetScrollPos
+63  pascal GetScrollPos(word word) GetScrollPos
+64  pascal SetScrollRange(word word s_word s_word word) SetScrollRange
+65  pascal GetScrollRange(word word ptr ptr) GetScrollRange
+66  pascal GetDC(word) GetDC
+67  pascal GetWindowDC(word) GetWindowDC
+68  pascal ReleaseDC(word word) ReleaseDC
+69  pascal SetCursor(word) SetCursor
+70  pascal SetCursorPos(word word) SetCursorPos
+71  pascal ShowCursor(word) ShowCursor
+72  pascal SetRect(ptr s_word s_word s_word s_word) SetRect
+73  pascal SetRectEmpty(ptr) SetRectEmpty
+74  pascal CopyRect(ptr ptr) CopyRect
+75  pascal IsRectEmpty(ptr) IsRectEmpty
+76  pascal PtInRect(ptr long) PtInRect
+77  pascal OffsetRect(ptr s_word s_word) OffsetRect
+78  pascal InflateRect(ptr s_word s_word) InflateRect
+79  pascal IntersectRect(ptr ptr ptr) IntersectRect
+80  pascal UnionRect(ptr ptr ptr) UnionRect
+81  pascal FillRect(word ptr word) FillRect
+82  pascal InvertRect(word ptr) InvertRect
+83  pascal FrameRect(word ptr word) FrameRect
+84  pascal DrawIcon(word s_word s_word word) DrawIcon
+85  pascal DrawText(word ptr s_word ptr word) DrawText
+87  pascal16 DialogBox(word segptr word segptr) DialogBox
+88  pascal EndDialog(word s_word) EndDialog
+89  pascal16 CreateDialog(word segptr word segptr) CreateDialog
+90  pascal IsDialogMessage(word ptr) IsDialogMessage
+91  pascal GetDlgItem(word word) GetDlgItem
+92  pascal SetDlgItemText(word word segptr) SetDlgItemText
+93  pascal GetDlgItemText(word word segptr word) GetDlgItemText
+94  pascal SetDlgItemInt(word word word word) SetDlgItemInt
+95  pascal GetDlgItemInt(word word ptr word) GetDlgItemInt
+96  pascal CheckRadioButton(word word word word) CheckRadioButton
+97  pascal CheckDlgButton(word word word) CheckDlgButton
+98  pascal IsDlgButtonChecked(word word) IsDlgButtonChecked
+99  pascal DlgDirSelect(word ptr word) DlgDirSelect
+100 pascal DlgDirList(word ptr word word word) DlgDirList
+101 pascal SendDlgItemMessage(word word word word long) SendDlgItemMessage
+102 pascal AdjustWindowRect(ptr long word) AdjustWindowRect
+103 pascal MapDialogRect(word ptr) MapDialogRect
+104 pascal MessageBeep(word) MessageBeep
+105 pascal FlashWindow(word word) FlashWindow
+106 pascal GetKeyState(word) GetKeyState
+107 pascal DefWindowProc(word word word long) DefWindowProc
+108 pascal GetMessage(segptr word word word) GetMessage
+109 pascal PeekMessage(ptr word word word word) PeekMessage
+110 pascal PostMessage(word word word long) PostMessage
+111 pascal SendMessage(word word word long) SendMessage
+112 pascal WaitMessage() WaitMessage
+113 pascal TranslateMessage(ptr) TranslateMessage
+114 pascal DispatchMessage(ptr) DispatchMessage
 #115 REPLYMESSAGE
 #116 POSTAPPMESSAGE
-118 pascal RegisterWindowMessage(ptr) RegisterWindowMessage(1)
-119 pascal GetMessagePos() GetMessagePos()
-120 pascal GetMessageTime() GetMessageTime()
-121 pascal SetWindowsHook(s_word ptr) SetWindowsHook(1 2)
-122 pascal CallWindowProc(ptr word word word long) CallWindowProc(1 2 3 4 5)
-123 pascal CallMsgFilter(ptr s_word) CallMsgFilter(1 2)
-124 pascal UpdateWindow(word) UpdateWindow(1)
-125 pascal InvalidateRect(word ptr word) InvalidateRect(1 2 3)
-126 pascal InvalidateRgn(word word word) InvalidateRgn(1 2 3)
-127 pascal ValidateRect(word ptr) ValidateRect(1 2)
-128 pascal ValidateRgn(word word) ValidateRgn(1 2)
-129 pascal GetClassWord(word s_word) GetClassWord(1 2)
-130 pascal SetClassWord(word s_word word) SetClassWord(1 2 3)
-131 pascal GetClassLong(word s_word) GetClassLong(1 2)
-132 pascal SetClassLong(word s_word long) SetClassLong(1 2 3)
-133 pascal GetWindowWord(word s_word) GetWindowWord(1 2)
-134 pascal SetWindowWord(word s_word word) SetWindowWord(1 2 3)
-135 pascal GetWindowLong(word s_word) GetWindowLong(1 2)
-136 pascal SetWindowLong(word s_word long) SetWindowLong(1 2 3)
-137 pascal OpenClipboard(word) OpenClipboard(1)
-138 pascal CloseClipboard() CloseClipboard()
-139 pascal EmptyClipboard() EmptyClipboard()
-140 pascal GetClipboardOwner() GetClipboardOwner()
-141 pascal SetClipboardData(word word) SetClipboardData(1 2)
-142 pascal GetClipboardData(word) GetClipboardData(1)
-143 pascal CountClipboardFormats() CountClipboardFormats()
-144 pascal EnumClipboardFormats(word) EnumClipboardFormats(1)
-145 pascal RegisterClipboardFormat(ptr) RegisterClipboardFormat(1)
-146 pascal GetClipboardFormatName(word ptr s_word) GetClipboardFormatName(1 2 3)
-147 pascal SetClipboardViewer(word) SetClipboardViewer(1)
-148 pascal GetClipboardViewer() GetClipboardViewer()
-149 pascal ChangeClipboardChain(word ptr) ChangeClipboardChain(1 2)
-150 pascal LoadMenu(word ptr) LoadMenu(1 2)
-151 pascal CreateMenu() CreateMenu()
-152 pascal DestroyMenu(word) DestroyMenu(1)
-153 pascal ChangeMenu(word word ptr word word) ChangeMenu(1 2 3 4 5)
-154 pascal CheckMenuItem(word word word) CheckMenuItem(1 2 3)
-155 pascal EnableMenuItem(word word word) EnableMenuItem(1 2 3)
-156 pascal GetSystemMenu(word word) GetSystemMenu(1 2)
-157 pascal GetMenu(word) GetMenu(1)
-158 pascal SetMenu(word word) SetMenu(1 2)
-159 pascal GetSubMenu(word word) GetSubMenu(1 2)
-160 pascal DrawMenuBar(word) DrawMenuBar(1)
-161 pascal GetMenuString(word word ptr s_word word) GetMenuString(1 2 3 4 5)
-162 pascal HiliteMenuItem(word word word word) HiliteMenuItem(1 2 3 4)
-163 pascal CreateCaret(word word word word) CreateCaret(1 2 3 4)
-164 pascal DestroyCaret() DestroyCaret()
-165 pascal SetCaretPos(word word) SetCaretPos(1 2)
-166 pascal HideCaret(word) HideCaret(1)
-167 pascal ShowCaret(word) ShowCaret(1)
-168 pascal SetCaretBlinkTime(word) SetCaretBlinkTime(1)
-169 pascal GetCaretBlinkTime() GetCaretBlinkTime()
-170 pascal ArrangeIconicWindows(word) ArrangeIconicWindows(1)
-171 pascal WinHelp(word ptr word long) WinHelp(1 2 3 4)
+118 pascal RegisterWindowMessage(ptr) RegisterWindowMessage
+119 pascal GetMessagePos() GetMessagePos
+120 pascal GetMessageTime() GetMessageTime
+121 pascal SetWindowsHook(s_word segptr) SetWindowsHook
+122 pascal CallWindowProc(segptr word word word long) CallWindowProc
+123 pascal CallMsgFilter(segptr s_word) CallMsgFilter
+124 pascal UpdateWindow(word) UpdateWindow
+125 pascal InvalidateRect(word ptr word) InvalidateRect
+126 pascal InvalidateRgn(word word word) InvalidateRgn
+127 pascal ValidateRect(word ptr) ValidateRect
+128 pascal ValidateRgn(word word) ValidateRgn
+129 pascal GetClassWord(word s_word) GetClassWord
+130 pascal SetClassWord(word s_word word) SetClassWord
+131 pascal GetClassLong(word s_word) GetClassLong
+132 pascal SetClassLong(word s_word long) SetClassLong
+133 pascal GetWindowWord(word s_word) GetWindowWord
+134 pascal SetWindowWord(word s_word word) SetWindowWord
+135 pascal GetWindowLong(word s_word) GetWindowLong
+136 pascal SetWindowLong(word s_word long) SetWindowLong
+137 pascal OpenClipboard(word) OpenClipboard
+138 pascal CloseClipboard() CloseClipboard
+139 pascal EmptyClipboard() EmptyClipboard
+140 pascal GetClipboardOwner() GetClipboardOwner
+141 pascal SetClipboardData(word word) SetClipboardData
+142 pascal GetClipboardData(word) GetClipboardData
+143 pascal CountClipboardFormats() CountClipboardFormats
+144 pascal EnumClipboardFormats(word) EnumClipboardFormats
+145 pascal RegisterClipboardFormat(ptr) RegisterClipboardFormat
+146 pascal GetClipboardFormatName(word ptr s_word) GetClipboardFormatName
+147 pascal SetClipboardViewer(word) SetClipboardViewer
+148 pascal GetClipboardViewer() GetClipboardViewer
+149 pascal ChangeClipboardChain(word ptr) ChangeClipboardChain
+150 pascal LoadMenu(word segptr) LoadMenu
+151 pascal CreateMenu() CreateMenu
+152 pascal DestroyMenu(word) DestroyMenu
+153 pascal ChangeMenu(word word ptr word word) ChangeMenu
+154 pascal CheckMenuItem(word word word) CheckMenuItem
+155 pascal EnableMenuItem(word word word) EnableMenuItem
+156 pascal GetSystemMenu(word word) GetSystemMenu
+157 pascal GetMenu(word) GetMenu
+158 pascal SetMenu(word word) SetMenu
+159 pascal GetSubMenu(word word) GetSubMenu
+160 pascal DrawMenuBar(word) DrawMenuBar
+161 pascal GetMenuString(word word ptr s_word word) GetMenuString
+162 pascal HiliteMenuItem(word word word word) HiliteMenuItem
+163 pascal CreateCaret(word word word word) CreateCaret
+164 pascal DestroyCaret() DestroyCaret
+165 pascal SetCaretPos(word word) SetCaretPos
+166 pascal HideCaret(word) HideCaret
+167 pascal ShowCaret(word) ShowCaret
+168 pascal SetCaretBlinkTime(word) SetCaretBlinkTime
+169 pascal GetCaretBlinkTime() GetCaretBlinkTime
+170 pascal ArrangeIconicWindows(word) ArrangeIconicWindows
+171 pascal WinHelp(word ptr word long) WinHelp
 #172 SWITCHTOTHISWINDOW
-173 pascal LoadCursor(word ptr) LoadCursor(1 2)
-174 pascal LoadIcon(word ptr) LoadIcon(1 2)
-175 pascal LoadBitmap(word ptr) LoadBitmap(1 2)
-176 pascal16 LoadString(word word ptr s_word) LoadString(1 2 3 4)
-177 pascal LoadAccelerators(word ptr) LoadAccelerators(1 2)
-178 pascal TranslateAccelerator(word word ptr) TranslateAccelerator(1 2 3)
-179 pascal GetSystemMetrics(word) GetSystemMetrics(1)
-180 pascal GetSysColor(word) GetSysColor(1)
-181 pascal SetSysColors(word ptr ptr) SetSysColors(1 2 3)
-182 pascal KillSystemTimer(word word) KillSystemTimer(1 2)
-183 pascal GetCaretPos(ptr) GetCaretPos(1)
+173 pascal16 LoadCursor(word segptr) LoadCursor
+174 pascal16 LoadIcon(word segptr) LoadIcon
+175 pascal16 LoadBitmap(word segptr) LoadBitmap
+176 pascal16 LoadString(word word ptr s_word) LoadString
+177 pascal16 LoadAccelerators(word segptr) LoadAccelerators
+178 pascal TranslateAccelerator(word word ptr) TranslateAccelerator
+179 pascal GetSystemMetrics(word) GetSystemMetrics
+180 pascal GetSysColor(word) GetSysColor
+181 pascal SetSysColors(word ptr ptr) SetSysColors
+182 pascal KillSystemTimer(word word) KillSystemTimer
+183 pascal GetCaretPos(ptr) GetCaretPos
 #184 QUERYSENDMESSAGE
-185 pascal GrayString(word word ptr ptr word word word word word)
-	   GrayString(1 2 3 4 5 6 7 8 9)
-186 pascal SwapMouseButton(word) SwapMouseButton(1)
-187 pascal EndMenu() EndMenu()
-188 pascal SetSysModalWindow(word) SetSysModalWindow(1)
-189 pascal GetSysModalWindow() GetSysModalWindow()
-190 pascal GetUpdateRect(word ptr word) GetUpdateRect(1 2 3)
-191 pascal ChildWindowFromPoint(word long) ChildWindowFromPoint(1 2)
-#192 INSENDMESSAGE
-193 pascal IsClipboardFormatAvailable(word) IsClipboardFormatAvailable(1)
-194  pascal DlgDirSelectComboBox(word ptr word) DlgDirSelectComboBox(1 2 3)
-195 pascal DlgDirListComboBox(word ptr word word word) DlgDirListComboBox(1 2 3 4 5)
+185 pascal GrayString(word word ptr ptr word word word word word) GrayString
+186 pascal SwapMouseButton(word) SwapMouseButton
+187 pascal EndMenu() EndMenu
+188 pascal SetSysModalWindow(word) SetSysModalWindow
+189 pascal GetSysModalWindow() GetSysModalWindow
+190 pascal GetUpdateRect(word ptr word) GetUpdateRect
+191 pascal ChildWindowFromPoint(word long) ChildWindowFromPoint
+192 pascal16 InSendMessage() InSendMessage
+193 pascal IsClipboardFormatAvailable(word) IsClipboardFormatAvailable
+194 pascal DlgDirSelectComboBox(word ptr word) DlgDirSelectComboBox
+195 pascal DlgDirListComboBox(word segptr word word word) DlgDirListComboBox
 196 pascal TabbedTextOut(word s_word s_word ptr s_word s_word ptr s_word)
-		TabbedTextOut(1 2 3 4 5 6 7 8)
-197 pascal GETTABBEDTEXTEXTENT(word ptr word word ptr)
-	   GetTabbedTextExtent(1 2 3 4 5)
-198 pascal CascadeChildWindows(word word) CascadeChildWindows(1 2)
-199 pascal TileChildWindows(word word) TileChildWindows(1 2)
-200 pascal OpenComm(ptr word word) OpenComm(1 2 3)
-201 pascal SetCommState(ptr) SetCommState(1)
-202 pascal GetCommState(word ptr) GetCommState(1 2)
-203 pascal GetCommError(word ptr) GetCommError(1 2)
-204 pascal ReadComm(word ptr word) ReadComm(1 2 3)
-205 pascal WriteComm(word ptr word) WriteComm(1 2 3)
-206 pascal TransmitCommChar(word byte) TransmitCommChar (1 2)
-207 pascal CloseComm(word) CloseComm(1)
-208 pascal SetCommEventMask(word word) SetCommEventMask(1 2)
-209 pascal GetCommEventMask(word word) GetCommEventMask(1 2)
-210 pascal SetCommBreak(word) SetCommBreak(1)
-211 pascal ClearCommBreak(word) ClearCommBreak(1)
-212 pascal UngetCommChar(word byte) UngetCommChar(1 2)
-213 pascal BuildCommDCB(ptr ptr) BuildCommDCB(1 2)
-214 pascal EscapeCommFunction(word word) EscapeCommFunction(1 2)
-215 pascal FlushComm(word word) FlushComm(1 2)
+           TabbedTextOut
+197 pascal GetTabbedTextExtent(word ptr word word ptr) GetTabbedTextExtent
+198 pascal CascadeChildWindows(word word) CascadeChildWindows
+199 pascal TileChildWindows(word word) TileChildWindows
+200 pascal OpenComm(ptr word word) OpenComm
+201 pascal SetCommState(ptr) SetCommState
+202 pascal GetCommState(word ptr) GetCommState
+203 pascal GetCommError(word ptr) GetCommError
+204 pascal ReadComm(word ptr word) ReadComm
+205 pascal WriteComm(word ptr word) WriteComm
+206 pascal TransmitCommChar(word byte) TransmitCommChar 
+207 pascal CloseComm(word) CloseComm
+208 pascal SetCommEventMask(word word) SetCommEventMask
+209 pascal GetCommEventMask(word word) GetCommEventMask
+210 pascal SetCommBreak(word) SetCommBreak
+211 pascal ClearCommBreak(word) ClearCommBreak
+212 pascal UngetCommChar(word byte) UngetCommChar
+213 pascal BuildCommDCB(ptr ptr) BuildCommDCB
+214 pascal EscapeCommFunction(word word) EscapeCommFunction
+215 pascal FlushComm(word word) FlushComm
 #216 USERSEEUSERDO
-217 pascal LookupMenuHandle(word s_word) LookupMenuHandle(1 2)
-218 pascal DialogBoxIndirect(word word word ptr) DialogBoxIndirect(1 2 3 4)
-219 pascal CreateDialogIndirect(word ptr word ptr)
-	   CreateDialogIndirect(1 2 3 4)
-220 pascal LoadMenuIndirect(ptr) LoadMenuIndirect(1)
-221 pascal ScrollDC(word s_word s_word ptr ptr word ptr) 
-	   ScrollDC(1 2 3 4 5 6 7)
-222 pascal16 GetKeyboardState(ptr) GetKeyboardState(1)
+217 pascal LookupMenuHandle(word s_word) LookupMenuHandle
+218 pascal16 DialogBoxIndirect(word word word segptr) DialogBoxIndirect
+219 pascal16 CreateDialogIndirect(word ptr word segptr) CreateDialogIndirect
+220 pascal LoadMenuIndirect(ptr) LoadMenuIndirect
+221 pascal ScrollDC(word s_word s_word ptr ptr word ptr) ScrollDC
+222 pascal16 GetKeyboardState(ptr) GetKeyboardState
 #223 SETKEYBOARDSTATE
-224 pascal16 GetWindowTask(word) GetWindowTask(1)
-225 pascal EnumTaskWindows(word ptr long) EnumTaskWindows(1 2 3)
+224 pascal16 GetWindowTask(word) GetWindowTask
+225 pascal EnumTaskWindows(word segptr long) EnumTaskWindows
 #226 LOCKINPUT
-227 pascal GetNextDlgGroupItem(word word word) GetNextDlgGroupItem(1 2 3)
-228 pascal GetNextDlgTabItem(word word word) GetNextDlgTabItem(1 2 3)
-229 pascal GetTopWindow(word) GetTopWindow(1)
-230 pascal GetNextWindow(word word) GetNextWindow(1 2)
+227 pascal GetNextDlgGroupItem(word word word) GetNextDlgGroupItem
+228 pascal GetNextDlgTabItem(word word word) GetNextDlgTabItem
+229 pascal GetTopWindow(word) GetTopWindow
+230 pascal GetNextWindow(word word) GetNextWindow
 #231 GETSYSTEMDEBUGSTATE
-232 pascal SetWindowPos(word word word word word word word) 
-           SetWindowPos(1 2 3 4 5 6 7)
-233 pascal SetParent(word word) SetParent(1 2)
-234 pascal UnhookWindowsHook(s_word ptr) UnhookWindowsHook(1 2)
-235 pascal DefHookProc(s_word word long ptr) DefHookProc(1 2 3 4)
-236 pascal GetCapture() GetCapture()
-237 pascal GetUpdateRgn(word word word) GetUpdateRgn(1 2 3)
-238 pascal ExcludeUpdateRgn(word word) ExcludeUpdateRgn(1 2)
-239 pascal DialogBoxParam(word ptr word ptr long) DialogBoxParam(1 2 3 4 5)
-240 pascal DialogBoxIndirectParam(word word word ptr long)
-	   DialogBoxIndirectParam(1 2 3 4 5)
-241 pascal CreateDialogParam(word ptr word ptr long)
-	   CreateDialogParam(1 2 3 4 5)
-242 pascal CreateDialogIndirectParam(word ptr word ptr long)
-	   CreateDialogIndirectParam(1 2 3 4 5)
-243 pascal GetDialogBaseUnits() GetDialogBaseUnits()
-244 pascal EqualRect(ptr ptr) EqualRect(1 2)
+232 pascal SetWindowPos(word word word word word word word) SetWindowPos
+233 pascal SetParent(word word) SetParent
+234 pascal UnhookWindowsHook(s_word segptr) UnhookWindowsHook
+235 pascal DefHookProc(s_word word long ptr) DefHookProc
+236 pascal GetCapture() GetCapture
+237 pascal GetUpdateRgn(word word word) GetUpdateRgn
+238 pascal ExcludeUpdateRgn(word word) ExcludeUpdateRgn
+239 pascal16 DialogBoxParam(word segptr word segptr long) DialogBoxParam
+240 pascal16 DialogBoxIndirectParam(word word word segptr long)
+             DialogBoxIndirectParam
+241 pascal16 CreateDialogParam(word segptr word segptr long) CreateDialogParam
+242 pascal16 CreateDialogIndirectParam(word ptr word segptr long)
+             CreateDialogIndirectParam
+243 pascal GetDialogBaseUnits() GetDialogBaseUnits
+244 pascal EqualRect(ptr ptr) EqualRect
 #245 ENABLECOMMNOTIFICATION
 #246 EXITWINDOWSEXEC
-247 pascal GetCursor() GetCursor()
-248 pascal GetOpenClipboardWindow() GetOpenClipboardWindow()
-249 pascal GetAsyncKeyState(word) GetAsyncKeyState(1)
-250 pascal GetMenuState(word word word) GetMenuState(1 2 3)
-251 pascal SendDriverMessage(word word long long) SendDriverMessage(1 2 3 4)
-252 pascal OpenDriver(ptr ptr long) OpenDriver(1 2 3)
-253 pascal CloseDriver(word word long) CloseDriver(1 2 3)
-254 pascal GetDriverModuleHandle(word) GetDriverModuleHandle(1)
-255 pascal DefDriverProc(long word word long long) DefDriverProc(1 2 3 4 5)
-256 pascal GetDriverInfo(word ptr) GetDriverInfo(1 2)
-257 pascal GetNextDriver(word long) GetNextDriver(1 2)
-258 pascal MapWindowPoints(word word ptr word) MapWindowPoints(1 2 3 4)
-259 pascal16 BeginDeferWindowPos(s_word) BeginDeferWindowPos(1)
+247 pascal GetCursor() GetCursor
+248 pascal GetOpenClipboardWindow() GetOpenClipboardWindow
+249 pascal GetAsyncKeyState(word) GetAsyncKeyState
+250 pascal GetMenuState(word word word) GetMenuState
+251 pascal SendDriverMessage(word word long long) SendDriverMessage
+252 pascal OpenDriver(ptr ptr long) OpenDriver
+253 pascal CloseDriver(word word long) CloseDriver
+254 pascal GetDriverModuleHandle(word) GetDriverModuleHandle
+255 pascal DefDriverProc(long word word long long) DefDriverProc
+256 pascal GetDriverInfo(word ptr) GetDriverInfo
+257 pascal GetNextDriver(word long) GetNextDriver
+258 pascal MapWindowPoints(word word ptr word) MapWindowPoints
+259 pascal16 BeginDeferWindowPos(s_word) BeginDeferWindowPos
 260 pascal16 DeferWindowPos(word word word s_word s_word s_word s_word word)
-             DeferWindowPos(1 2 3 4 5 6 7 8)
-261 pascal16 EndDeferWindowPos(word) EndDeferWindowPos(1)
-262 pascal GetWindow(word word) GetWindow(1 2)
-263 pascal GetMenuItemCount(word) GetMenuItemCount(1)
-264 pascal GetMenuItemID(word word) GetMenuItemID(1 2)
+             DeferWindowPos
+261 pascal16 EndDeferWindowPos(word) EndDeferWindowPos
+262 pascal GetWindow(word word) GetWindow
+263 pascal GetMenuItemCount(word) GetMenuItemCount
+264 pascal GetMenuItemID(word word) GetMenuItemID
 #265 SHOWOWNEDPOPUPS
-266 pascal SetMessageQueue(word) SetMessageQueue(1)
-267 pascal ShowScrollBar(word word word) ShowScrollBar(1 2 3)
-268 pascal GlobalAddAtom(ptr) GlobalAddAtom(1)
-269 pascal GlobalDeleteAtom(word) GlobalDeleteAtom(1)
-270 pascal GlobalFindAtom(ptr) GlobalFindAtom(1)
-271 pascal GlobalGetAtomName(word ptr s_word) GlobalGetAtomName(1 2 3)
-272 pascal IsZoomed(word) IsZoomed(1)
+266 pascal SetMessageQueue(word) SetMessageQueue
+267 pascal ShowScrollBar(word word word) ShowScrollBar
+268 pascal GlobalAddAtom(ptr) GlobalAddAtom
+269 pascal GlobalDeleteAtom(word) GlobalDeleteAtom
+270 pascal GlobalFindAtom(ptr) GlobalFindAtom
+271 pascal GlobalGetAtomName(word ptr s_word) GlobalGetAtomName
+272 pascal IsZoomed(word) IsZoomed
 #273 CONTROLPANELINFO
 #274 GETNEXTQUEUEWINDOW
 #275 REPAINTSCREEN
 #276 LOCKMYTASK
-277 pascal GetDlgCtrlID(word) GetDlgCtrlID(1)
-278 pascal GetDeskTopHwnd() GetDesktopWindow()
+277 pascal GetDlgCtrlID(word) GetDlgCtrlID
+278 pascal GetDeskTopHwnd() GetDesktopWindow
 #279 OLDSETDESKPATTERN
 #280 SETSYSTEMMENU
-281 pascal GetSysColorBrush(word) GetSysColorBrush(1)
-282 pascal SelectPalette(word word word) SelectPalette(1 2 3)
-283 pascal RealizePalette(word) RealizePalette(1)
-284 pascal16 GetFreeSystemResources(word) GetFreeSystemResources(1)
+281 pascal GetSysColorBrush(word) GetSysColorBrush
+282 pascal SelectPalette(word word word) SelectPalette
+283 pascal RealizePalette(word) RealizePalette
+284 pascal16 GetFreeSystemResources(word) GetFreeSystemResources
 #285 BEAR285
-286 pascal GetDesktopWindow() GetDesktopWindow()
-287 pascal GetLastActivePopup(word) GetLastActivePopup(1)
-288 pascal GetMessageExtraInfo() GetMessageExtraInfo()
+286 pascal GetDesktopWindow() GetDesktopWindow
+287 pascal GetLastActivePopup(word) GetLastActivePopup
+288 pascal GetMessageExtraInfo() GetMessageExtraInfo
 #289 KEYB_EVENT
-290 pascal RedrawWindow(word ptr word word) RedrawWindow(1 2 3 4)
-291 pascal SetWindowsHookEx(s_word ptr word word) SetWindowsHookEx(1 2 3 4)
-292 pascal UnhookWindowsHookEx(ptr) UnhookWindowsHookEx(1)
-293 pascal CallNextHookEx(ptr s_word word long) CallNextHookEx(1 2 3 4)
+290 pascal RedrawWindow(word ptr word word) RedrawWindow
+291 pascal SetWindowsHookEx(s_word segptr word word) SetWindowsHookEx
+292 pascal UnhookWindowsHookEx(segptr) UnhookWindowsHookEx
+293 pascal CallNextHookEx(segptr s_word word long) CallNextHookEx
 #294 LOCKWINDOWUPDATE
 #299 MOUSE_EVENT
 #301 BOZOSLIVEHERE :-))
 #306 BEAR306
-308 pascal DefDlgProc(word word word long) DefDlgProc(1 2 3 4)
+308 pascal DefDlgProc(word word word long) DefDlgProc
 #314 SIGNALPROC
-319 pascal ScrollWindowEx(word s_word s_word ptr ptr word ptr word) 
-	   ScrollWindowEx(1 2 3 4 5 6 7 8)
+319 pascal ScrollWindowEx(word s_word s_word ptr ptr word ptr word)
+           ScrollWindowEx
 #320 SYSERRORBOX
 #321 SETEVENTHOOK
 #322 WINOLDAPPHACKOMATIC
 #323 GETMESSAGE2
-324 pascal FillWindow(word word word word) FillWindow(1 2 3 4)
-325 pascal PaintRect(word word word word ptr) PaintRect(1 2 3 4 5)
-326 pascal16 GetControlBrush(word word word) GetControlBrush(1 2 3)
-331 pascal EnableHardwareInput(word) EnableHardwareInput(1)
+324 pascal FillWindow(word word word word) FillWindow
+325 pascal PaintRect(word word word word ptr) PaintRect
+326 pascal16 GetControlBrush(word word word) GetControlBrush
+331 pascal EnableHardwareInput(word) EnableHardwareInput
 332 return UserYield 0 0
 #333 ISUSERIDLE
-334 pascal GetQueueStatus(word) GetQueueStatus(1)
-335 pascal GetInputState() GetInputState()
+334 pascal GetQueueStatus(word) GetQueueStatus
+335 pascal GetInputState() GetInputState
 #336 LOADCURSORICONHANDLER
 #337 GETMOUSEEVENTPROC
 #341 _FFFE_FARFRAME
 #343 GETFILEPORTNAME
 #356 LOADDIBCURSORHANDLER
 #357 LOADDIBICONHANDLER
-358 pascal IsMenu(word) IsMenu(1)
-359 pascal GetDCEx(word word long) GetDCEx(1 2 3)
+358 pascal IsMenu(word) IsMenu
+359 pascal GetDCEx(word word long) GetDCEx
 #362 DCHOOK
 #368 COPYICON
 #369 COPYCURSOR
-370 pascal GetWindowPlacement(word ptr) GetWindowPlacement(1 2)
-371 pascal SetWindowPlacement(word ptr) SetWindowPlacement(1 2)
+370 pascal GetWindowPlacement(word ptr) GetWindowPlacement
+371 pascal SetWindowPlacement(word ptr) SetWindowPlacement
 #372 GETINTERNALICONHEADER
-373 pascal SubtractRect(ptr ptr ptr) SubtractRect(1 2 3)
+373 pascal SubtractRect(ptr ptr ptr) SubtractRect
 #400 FINALUSERINIT
-402 pascal GetPriorityClipboardFormat(word ptr s_word) 
-	GetPriorityClipboardFormat(1 2 3)
-403 pascal UnregisterClass(ptr word) UnregisterClass(1 2)
-404 pascal GetClassInfo(word ptr ptr) GetClassInfo(1 2 3)
-406 pascal CreateCursor(word word word word word ptr ptr) 
-	CreateCursor(1 2 3 4 5 6 7)
-407 pascal CreateIcon(word word word byte byte ptr ptr)
-           CreateIcon(1 2 3 4 5 6 7)
+402 pascal GetPriorityClipboardFormat(word ptr s_word)
+           GetPriorityClipboardFormat
+403 pascal UnregisterClass(ptr word) UnregisterClass
+404 pascal GetClassInfo(word ptr ptr) GetClassInfo
+406 pascal CreateCursor(word word word word word ptr ptr) CreateCursor
+407 pascal CreateIcon(word word word byte byte ptr ptr) CreateIcon
 #408 CREATECURSORICONINDIRECT
-410 pascal InsertMenu(word word word word ptr) InsertMenu(1 2 3 4 5)
-411 pascal AppendMenu(word word word ptr) AppendMenu(1 2 3 4)
-412 pascal RemoveMenu(word word word) RemoveMenu(1 2 3)
-413 pascal DeleteMenu(word word word) DeleteMenu(1 2 3)
-414 pascal ModifyMenu(word word word word ptr) ModifyMenu(1 2 3 4 5)
-415 pascal CreatePopupMenu() CreatePopupMenu()
-416 pascal TrackPopupMenu(word word word word word word ptr) 
-	   TrackPopupMenu(1 2 3 4 5 6 7)
-417 pascal GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions()
-418 pascal SetMenuItemBitmaps(word word word word word) 
-	   SetMenuItemBitmaps(1 2 3 4 5)
-420 pascal wsprintf() windows_wsprintf()
+410 pascal InsertMenu(word word word word ptr) InsertMenu
+411 pascal AppendMenu(word word word ptr) AppendMenu
+412 pascal RemoveMenu(word word word) RemoveMenu
+413 pascal DeleteMenu(word word word) DeleteMenu
+414 pascal ModifyMenu(word word word word ptr) ModifyMenu
+415 pascal CreatePopupMenu() CreatePopupMenu
+416 pascal TrackPopupMenu(word word word word word word ptr) TrackPopupMenu
+417 pascal GetMenuCheckMarkDimensions() GetMenuCheckMarkDimensions
+418 pascal SetMenuItemBitmaps(word word word word word) SetMenuItemBitmaps
+420 pascal wsprintf() windows_wsprintf
 # windows_wsprintf() handles arguments itself, as libc can't handle an
 # 16-bit stack. DLLRelay() will pass 16-bit stack pointer as 1st arg.
-421 pascal wvsprintf(ptr ptr ptr) wvsprintf(1 2 3)
+421 pascal wvsprintf(ptr ptr ptr) wvsprintf
 #422 DLGDIRSELECTEX
 #423 DLGDIRSELECTCOMBOBOXEX
-430 pascal16 lstrcmp(ptr ptr) lstrcmp(1 2)
-431 pascal AnsiUpper(ptr) AnsiUpper(1)
-432 pascal AnsiLower(ptr) AnsiLower(1)
-433 pascal16 IsCharAlpha(byte) IsCharAlpha(1)
-434 pascal16 IsCharAlphanumeric(byte) IsCharAlphanumeric(1)
-435 pascal16 IsCharUpper(byte) IsCharUpper(1)
-436 pascal16 IsCharLower(byte) IsCharLower(1)
-437 pascal16 AnsiUpperBuff(ptr word) AnsiUpperBuff(1 2)
-438 pascal16 AnsiLowerBuff(ptr word) AnsiLowerBuff(1 2)
-445 pascal DefFrameProc(word word word word long) DefFrameProc(1 2 3 4 5)
-447 pascal DefMDIChildProc(word word word long) DefMDIChildProc(1 2 3 4)
-451 pascal TranslateMDISysAccel(word ptr) TranslateMDISysAccel(1 2)
-452 pascal CreateWindowEx(long ptr ptr long s_word s_word s_word s_word 
-	                  word word word ptr) 
-	   CreateWindowEx(1 2 3 4 5 6 7 8 9 10 11 12)
-454 pascal AdjustWindowRectEx(ptr long word long) AdjustWindowRectEx(1 2 3 4)
+430 pascal16 lstrcmp(ptr ptr) lstrcmp
+431 pascal AnsiUpper(segptr) WIN16_AnsiUpper
+432 pascal AnsiLower(segptr) WIN16_AnsiLower
+433 pascal16 IsCharAlpha(byte) IsCharAlpha
+434 pascal16 IsCharAlphanumeric(byte) IsCharAlphanumeric
+435 pascal16 IsCharUpper(byte) IsCharUpper
+436 pascal16 IsCharLower(byte) IsCharLower
+437 pascal16 AnsiUpperBuff(ptr word) AnsiUpperBuff
+438 pascal16 AnsiLowerBuff(ptr word) AnsiLowerBuff
+445 pascal DefFrameProc(word word word word long) DefFrameProc
+447 pascal DefMDIChildProc(word word word long) DefMDIChildProc
+451 pascal TranslateMDISysAccel(word ptr) TranslateMDISysAccel
+452 pascal CreateWindowEx(long ptr ptr long s_word s_word s_word s_word
+                          word word word segptr) CreateWindowEx
+454 pascal AdjustWindowRectEx(ptr long word long) AdjustWindowRectEx
 #455 GETICONID
 #456 LOADICONHANDLER
-457 pascal DestroyIcon(word) DestroyIcon(1)
-458 pascal DestroyCursor(word) DestroyCursor(1)
+457 pascal DestroyIcon(word) DestroyIcon
+458 pascal DestroyCursor(word) DestroyCursor
 #459 DUMPICON
-460 pascal GetInternalWindowPos(word ptr ptr) GetInternalWindowPos(1 2 3)
-461 pascal SetInternalWindowPos(word word ptr ptr) SetInternalWindowPos(1 2 3 4)
+460 pascal GetInternalWindowPos(word ptr ptr) GetInternalWindowPos
+461 pascal SetInternalWindowPos(word word ptr ptr) SetInternalWindowPos
 #462 CALCCHILDSCROLL
 #463 SCROLLCHILDREN
 #464 DRAGOBJECT
 #465 DRAGDETECT
-466 pascal DrawFocusRect(word ptr) DrawFocusRect(1 2)
+466 pascal DrawFocusRect(word ptr) DrawFocusRect
 #470 STRINGFUNC
-471 pascal16 lstrcmpi(ptr ptr) lstrcmpi(1 2)
-472 pascal AnsiNext(ptr) AnsiNext(1 )
-473 pascal AnsiPrev(ptr ptr) AnsiPrev(1 2)
+471 pascal16 lstrcmpi(ptr ptr) lstrcmpi
+472 pascal AnsiNext(segptr) AnsiNext
+473 pascal AnsiPrev(segptr segptr) AnsiPrev
 #480 GETUSERLOCALOBJTYPE
 #481 HARDWARE_EVENT
-482 pascal16 EnableScrollBar(word word word) EnableScrollBar(1 2 3)
-483 pascal SystemParametersInfo(word word ptr word) SystemParametersInfo(1 2 3 4)
+482 pascal16 EnableScrollBar(word word word) EnableScrollBar
+483 pascal SystemParametersInfo(word word ptr word) SystemParametersInfo
 #484 __GP
 #499 WNETERRORTEXT
 #501 WNETOPENJOB
@@ -417,13 +404,13 @@
 #509 WNETUNWATCHQUEUE
 #510 WNETLOCKQUEUEDATA
 #511 WNETUNLOCKQUEUEDATA
-512 pascal16 WNetGetConnection(ptr ptr ptr) WNetGetConnection(1 2 3)
-513 pascal WNetGetCaps(word) WNetGetCaps(1)
+512 pascal16 WNetGetConnection(ptr ptr ptr) WNetGetConnection
+513 pascal WNetGetCaps(word) WNetGetCaps
 #514 WNETDEVICEMODE
 #515 WNETBROWSEDIALOG
-516 pascal WNetGetUser(ptr ptr ptr) WNetGetUser(1 2 3)
-517 pascal16 WNetAddConnection(ptr ptr ptr) WNetAddConnection(1 2 3)
-518 pascal16 WNetCancelConnection(ptr word) WNetCancelConnection(1 2)
+516 pascal WNetGetUser(ptr ptr ptr) WNetGetUser
+517 pascal16 WNetAddConnection(ptr ptr ptr) WNetAddConnection
+518 pascal16 WNetCancelConnection(ptr word) WNetCancelConnection
 #519 WNETGETERROR
 #520 WNETGETERRORTEXT
 #521 WNETENABLE
diff --git a/if1632/win87em.spec b/if1632/win87em.spec
index 6e71cbc..1db0d41 100644
--- a/if1632/win87em.spec
+++ b/if1632/win87em.spec
@@ -1,11 +1,8 @@
-# $Id: win87em.spec,v 1.3 1993/07/04 04:04:21 root Exp root $
-#
 name	win87em
-id	5
+id	4
 length	10
 
-1	register _fpMath(word word word word
-			 word word word word) WIN87_fpmath()
-3	pascal 	 __WinEm87Info(ptr word) WIN87_WinEm87Info(1 2)
-4	pascal	 __WinEm87Restore(ptr word) WIN87_WinEm87Restore(1 2)
-5	pascal	 __WinEm87Save(ptr word) WIN87_WinEm87Save(1 2)
+1 register _fpMath() WIN87_fpmath
+3 pascal __WinEm87Info(ptr word) WIN87_WinEm87Info
+4 pascal __WinEm87Restore(ptr word) WIN87_WinEm87Restore
+5 pascal __WinEm87Save(ptr word) WIN87_WinEm87Save
diff --git a/if1632/winsock.spec b/if1632/winsock.spec
index 12913f2..75edb2d 100644
--- a/if1632/winsock.spec
+++ b/if1632/winsock.spec
@@ -4,64 +4,59 @@
 #      Summary: Module definition file for Windows Sockets DLL.  
 #  
 name	winsock
-id	9
+id	8
 length	155
 
-1   pascal16 accept(word ptr ptr) WINSOCK_accept(1 2 3)
-2   pascal16 bind(word ptr word) WINSOCK_bind(1 2 3)
-3   pascal16 closesocket(word) WINSOCK_closesocket(1)
-4   pascal16 connect(word ptr word) WINSOCK_connect(1 2 3)
-5   pascal16 getpeername(word ptr ptr) WINSOCK_getpeername(1 2 3)
-6   pascal16 getsockname(word ptr ptr) WINSOCK_getsockname(1 2 3)
-7   pascal16 getsockopt(word word word ptr ptr) WINSOCK_getsockopt(1 2 3 4 5)
-8   pascal   htonl(long) WINSOCK_htonl(1)
-9   pascal16 htons(word) WINSOCK_htons(1)
-10  pascal   inet_addr(long) WINSOCK_inet_addr(1)
-11  pascal   inet_ntoa(long) WINSOCK_inet_ntoa(1)
-12  pascal16 ioctlsocket(word long ptr) WINSOCK_ioctlsocket(1 2 3)
-13  pascal16 listen(word word) WINSOCK_listen(1 2)
-14  pascal   ntohl(long) WINSOCK_ntohl(1)
-15  pascal16 ntohs(word) WINSOCK_ntohs(1)
-16  pascal16 recv(word ptr word word) WINSOCK_recv(1 2 3 4)
-17  pascal16 recvfrom(word ptr word word ptr ptr)
-             WINSOCK_recvfrom(1 2 3 4 5 6)
-18  pascal16 select(word ptr ptr ptr ptr word)
-             WINSOCK_select(1 2 3 4 5 6)
-19  pascal16 send(word ptr word word) WINSOCK_send(1 2 3 4)
-20  pascal16 sendto(word ptr word word ptr ptr)
-             WINSOCK_sendto(1 2 3 4 5 6)
-21  pascal16 setsockopt(word word word ptr word)
-             WINSOCK_setsockopt(1 2 3 4 5)
-22  pascal16 shutdown(word word) WINSOCK_shutdown(1 2)
-23  pascal16 socket(word word word) WINSOCK_socket(1 2 3)
-51  pascal   gethostbyaddr(ptr word word) WINSOCK_gethostbyaddr(1 2 3)
-52  pascal   gethostbyname(ptr) WINSOCK_gethostbyname(1)
-53  pascal   getprotobyname(ptr) WINSOCK_getprotobyname(1)
-54  pascal   getprotobynumber(word) WINSOCK_getprotobynumber(1)
-55  pascal   getservbyname(ptr ptr) WINSOCK_getservbyname(1 2)
-56  pascal   getservbyport(word ptr) WINSOCK_getservbyport(1 2)
-57  pascal   gethostname(ptr word) WINSOCK_gethostname(1 2)
-101 pascal16 WSAAsyncSelect(word word word long)
-             WSAAsyncSelect(1 2 3 4)
+1   pascal16 accept(word ptr ptr) WINSOCK_accept
+2   pascal16 bind(word ptr word) WINSOCK_bind
+3   pascal16 closesocket(word) WINSOCK_closesocket
+4   pascal16 connect(word ptr word) WINSOCK_connect
+5   pascal16 getpeername(word ptr ptr) WINSOCK_getpeername
+6   pascal16 getsockname(word ptr ptr) WINSOCK_getsockname
+7   pascal16 getsockopt(word word word ptr ptr) WINSOCK_getsockopt
+8   pascal   htonl(long) WINSOCK_htonl
+9   pascal16 htons(word) WINSOCK_htons
+10  pascal   inet_addr(long) WINSOCK_inet_addr
+11  pascal   inet_ntoa(long) WINSOCK_inet_ntoa
+12  pascal16 ioctlsocket(word long ptr) WINSOCK_ioctlsocket
+13  pascal16 listen(word word) WINSOCK_listen
+14  pascal   ntohl(long) WINSOCK_ntohl
+15  pascal16 ntohs(word) WINSOCK_ntohs
+16  pascal16 recv(word ptr word word) WINSOCK_recv
+17  pascal16 recvfrom(word ptr word word ptr ptr) WINSOCK_recvfrom
+18  pascal16 select(word ptr ptr ptr ptr word) WINSOCK_select
+19  pascal16 send(word ptr word word) WINSOCK_send
+20  pascal16 sendto(word ptr word word ptr ptr) WINSOCK_sendto
+21  pascal16 setsockopt(word word word ptr word) WINSOCK_setsockopt
+22  pascal16 shutdown(word word) WINSOCK_shutdown
+23  pascal16 socket(word word word) WINSOCK_socket
+51  pascal   gethostbyaddr(ptr word word) WINSOCK_gethostbyaddr
+52  pascal   gethostbyname(ptr) WINSOCK_gethostbyname
+53  pascal   getprotobyname(ptr) WINSOCK_getprotobyname
+54  pascal   getprotobynumber(word) WINSOCK_getprotobynumber
+55  pascal   getservbyname(ptr ptr) WINSOCK_getservbyname
+56  pascal   getservbyport(word ptr) WINSOCK_getservbyport
+57  pascal   gethostname(ptr word) WINSOCK_gethostname
+101 pascal16 WSAAsyncSelect(word word word long) WSAAsyncSelect
 102 pascal16 WSAAsyncGetHostByAddr(word word ptr word word ptr word)
-             WSAAsyncGetHostByAddr(1 2 3 4 5 6 7)
+             WSAAsyncGetHostByAddr
 103 pascal16 WSAAsyncGetHostByName(word word ptr ptr word)
-             WSAAsyncGetHostByName(1 2 3 4 5)
+             WSAAsyncGetHostByName
 104 pascal16 WSAAsyncGetProtoByNumber(word word word ptr word)
-             WSAAsyncGetProtoByNumber(1 2 3 4 5)
+             WSAAsyncGetProtoByNumber
 105 pascal16 WSAAsyncGetProtoByName(word word ptr ptr word)
-             WSAAsyncGetProtoByName(1 2 3 4 5)
+             WSAAsyncGetProtoByName
 106 pascal16 WSAAsyncGetServByPort(word word word ptr ptr word)
-             WSAAsyncGetServByPort(1 2 3 4 5 6)
+             WSAAsyncGetServByPort
 107 pascal16 WSAAsyncGetServByName(word word ptr ptr ptr word)
-             WSAAsyncGetServByName(1 2 3 4 5 6)
-108 pascal16 WSACancelAsyncRequest(word) WSACancelAsyncRequest(1)
-109 pascal16 WSASetBlockingHook() WSASetBlockingHook()
-110 pascal16 WSAUnhookBlockingHook() WSAUnhookBlockingHook()
-111 pascal16 WSAGetLastError() WSAGetLastError()
-112 pascal   WSASetLastError(word) WSASetLastError(1)
-113 pascal16 WSACancelBlockingCall() WSACancelBlockingCall()
-114 pascal16 WSAIsBlocking() WSAIsBlocking()
-115 pascal   WSAStartup(word ptr) WSAStartup(1 2)
-116 pascal   WSACleanup() WSACleanup()
-151 pascal16 __WSAFDIsSet(word ptr) WSAFDIsSet(1 2)
+             WSAAsyncGetServByName
+108 pascal16 WSACancelAsyncRequest(word) WSACancelAsyncRequest
+109 pascal16 WSASetBlockingHook() WSASetBlockingHook
+110 pascal16 WSAUnhookBlockingHook() WSAUnhookBlockingHook
+111 pascal16 WSAGetLastError() WSAGetLastError
+112 pascal   WSASetLastError(word) WSASetLastError
+113 pascal16 WSACancelBlockingCall() WSACancelBlockingCall
+114 pascal16 WSAIsBlocking() WSAIsBlocking
+115 pascal   WSAStartup(word ptr) WSAStartup
+116 pascal   WSACleanup() WSACleanup
+151 pascal16 __WSAFDIsSet(word ptr) WSAFDIsSet
diff --git a/include/atom.h b/include/atom.h
index 0336837..045c343 100644
--- a/include/atom.h
+++ b/include/atom.h
@@ -28,10 +28,7 @@
 #ifdef WINELIB
 #define LocalAlign(flags,bytes) LocalAlloc (flags|LMEM_WINE_ALIGN,bytes)
 #else
-#define LocalAlign(flags,bytes) WIN16_LocalAlloc((flags),(bytes))
-#define LocalAlloc		WIN16_LocalAlloc
-#define LocalLock		WIN16_LocalLock
-#define LocalFree		WIN16_LocalFree
+#define LocalAlign(flags,bytes) LocalAlloc((flags),(bytes))
 #endif
 
 #endif  /* ATOM_H */
diff --git a/include/dce.h b/include/dce.h
index d95c781..e38c194 100644
--- a/include/dce.h
+++ b/include/dce.h
@@ -29,6 +29,7 @@
 } DCE;
 
 
+extern void DCE_Init(void);
 extern HANDLE DCE_AllocDCE( DCE_TYPE type );
 extern void DCE_FreeDCE( HANDLE hdce );
 
diff --git a/include/debug.h b/include/debug.h
index 15c0b3a..34493c8 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -32,6 +32,7 @@
 #undef DEBUG_FIXUP
 #undef DEBUG_FONT
 #undef DEBUG_GDI
+#undef DEBUG_GLOBAL
 #undef DEBUG_GRAPHICS
 #undef DEBUG_HEAP
 #undef DEBUG_ICON
@@ -40,6 +41,7 @@
 #undef DEBUG_KEYBOARD
 #undef DEBUG_LDT
 #undef DEBUG_LISTBOX
+#undef DEBUG_LOCAL
 #undef DEBUG_MALLOC
 #undef DEBUG_MCI
 #undef DEBUG_MCIANIM
@@ -65,6 +67,7 @@
 #undef DEBUG_RELAY
 #undef DEBUG_RESOURCE
 #undef DEBUG_SCROLL
+#undef DEBUG_SELECTOR
 #undef DEBUG_SELECTORS
 #undef DEBUG_STACK
 #undef DEBUG_STRESS
@@ -72,6 +75,7 @@
 #undef DEBUG_TASK
 #undef DEBUG_TEXT
 #undef DEBUG_TIMER
+#undef DEBUG_TOOLHELP
 #undef DEBUG_UTILITY
 #undef DEBUG_WIN
 #undef DEBUG_WINSOCK
@@ -104,6 +108,7 @@
 #define DEBUG_FIXUP
 #define DEBUG_FONT
 #define DEBUG_GDI
+#define DEBUG_GLOBAL
 #define DEBUG_GRAPHICS
 #define DEBUG_HEAP
 #define DEBUG_ICON
@@ -112,6 +117,7 @@
 #define DEBUG_KEYBOARD
 #define DEBUG_LDT
 #define DEBUG_LISTBOX
+#define DEBUG_LOCAL
 #define DEBUG_MALLOC
 #define DEBUG_MCI
 #define DEBUG_MCIANIM
@@ -137,6 +143,7 @@
 #define DEBUG_RELAY
 #define DEBUG_RESOURCE
 #define DEBUG_SCROLL
+#define DEBUG_SELECTOR
 #define DEBUG_SELECTORS
 #define DEBUG_STACK
 #define DEBUG_STRESS
@@ -144,6 +151,7 @@
 #define DEBUG_TASK
 #define DEBUG_TEXT
 #define DEBUG_TIMER
+#define DEBUG_TOOLHELP
 #define DEBUG_UTILITY
 #define DEBUG_WIN
 #define DEBUG_WINSOCK
@@ -282,6 +290,11 @@
 #else
     0,
 #endif
+#ifdef DEBUG_GLOBAL
+    1,
+#else
+    0,
+#endif
 #ifdef DEBUG_GRAPHICS
     1,
 #else
@@ -322,6 +335,11 @@
 #else
     0,
 #endif
+#ifdef DEBUG_LOCAL
+    1,
+#else
+    0,
+#endif
 #ifdef DEBUG_MALLOC
     1,
 #else
@@ -447,6 +465,11 @@
 #else
     0,
 #endif
+#ifdef DEBUG_SELECTOR
+    1,
+#else
+    0,
+#endif
 #ifdef DEBUG_SELECTORS
     1,
 #else
@@ -482,6 +505,11 @@
 #else
     0,
 #endif
+#ifdef DEBUG_TOOLHELP
+    1,
+#else
+    0,
+#endif
 #ifdef DEBUG_UTILITY
     1,
 #else
@@ -843,8 +871,21 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_graphics if(!debug_msg_enabled[26]) ; else fprintf
-#define debugging_graphics debug_msg_enabled[26]
+#define dprintf_global if(!debug_msg_enabled[26]) ; else fprintf
+#define debugging_global debug_msg_enabled[26]
+#else
+#ifdef DEBUG_GLOBAL
+#define dprintf_global fprintf
+#define debugging_global 1
+#else
+#define dprintf_global while(0) fprintf
+#define debugging_global 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_graphics if(!debug_msg_enabled[27]) ; else fprintf
+#define debugging_graphics debug_msg_enabled[27]
 #else
 #ifdef DEBUG_GRAPHICS
 #define dprintf_graphics fprintf
@@ -856,8 +897,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_heap if(!debug_msg_enabled[27]) ; else fprintf
-#define debugging_heap debug_msg_enabled[27]
+#define dprintf_heap if(!debug_msg_enabled[28]) ; else fprintf
+#define debugging_heap debug_msg_enabled[28]
 #else
 #ifdef DEBUG_HEAP
 #define dprintf_heap fprintf
@@ -869,8 +910,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_icon if(!debug_msg_enabled[28]) ; else fprintf
-#define debugging_icon debug_msg_enabled[28]
+#define dprintf_icon if(!debug_msg_enabled[29]) ; else fprintf
+#define debugging_icon debug_msg_enabled[29]
 #else
 #ifdef DEBUG_ICON
 #define dprintf_icon fprintf
@@ -882,8 +923,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_int if(!debug_msg_enabled[29]) ; else fprintf
-#define debugging_int debug_msg_enabled[29]
+#define dprintf_int if(!debug_msg_enabled[30]) ; else fprintf
+#define debugging_int debug_msg_enabled[30]
 #else
 #ifdef DEBUG_INT
 #define dprintf_int fprintf
@@ -895,8 +936,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_key if(!debug_msg_enabled[30]) ; else fprintf
-#define debugging_key debug_msg_enabled[30]
+#define dprintf_key if(!debug_msg_enabled[31]) ; else fprintf
+#define debugging_key debug_msg_enabled[31]
 #else
 #ifdef DEBUG_KEY
 #define dprintf_key fprintf
@@ -908,8 +949,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_keyboard if(!debug_msg_enabled[31]) ; else fprintf
-#define debugging_keyboard debug_msg_enabled[31]
+#define dprintf_keyboard if(!debug_msg_enabled[32]) ; else fprintf
+#define debugging_keyboard debug_msg_enabled[32]
 #else
 #ifdef DEBUG_KEYBOARD
 #define dprintf_keyboard fprintf
@@ -921,8 +962,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_ldt if(!debug_msg_enabled[32]) ; else fprintf
-#define debugging_ldt debug_msg_enabled[32]
+#define dprintf_ldt if(!debug_msg_enabled[33]) ; else fprintf
+#define debugging_ldt debug_msg_enabled[33]
 #else
 #ifdef DEBUG_LDT
 #define dprintf_ldt fprintf
@@ -934,8 +975,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_listbox if(!debug_msg_enabled[33]) ; else fprintf
-#define debugging_listbox debug_msg_enabled[33]
+#define dprintf_listbox if(!debug_msg_enabled[34]) ; else fprintf
+#define debugging_listbox debug_msg_enabled[34]
 #else
 #ifdef DEBUG_LISTBOX
 #define dprintf_listbox fprintf
@@ -947,8 +988,21 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_malloc if(!debug_msg_enabled[34]) ; else fprintf
-#define debugging_malloc debug_msg_enabled[34]
+#define dprintf_local if(!debug_msg_enabled[35]) ; else fprintf
+#define debugging_local debug_msg_enabled[35]
+#else
+#ifdef DEBUG_LOCAL
+#define dprintf_local fprintf
+#define debugging_local 1
+#else
+#define dprintf_local while(0) fprintf
+#define debugging_local 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_malloc if(!debug_msg_enabled[36]) ; else fprintf
+#define debugging_malloc debug_msg_enabled[36]
 #else
 #ifdef DEBUG_MALLOC
 #define dprintf_malloc fprintf
@@ -960,8 +1014,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mci if(!debug_msg_enabled[35]) ; else fprintf
-#define debugging_mci debug_msg_enabled[35]
+#define dprintf_mci if(!debug_msg_enabled[37]) ; else fprintf
+#define debugging_mci debug_msg_enabled[37]
 #else
 #ifdef DEBUG_MCI
 #define dprintf_mci fprintf
@@ -973,8 +1027,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mcianim if(!debug_msg_enabled[36]) ; else fprintf
-#define debugging_mcianim debug_msg_enabled[36]
+#define dprintf_mcianim if(!debug_msg_enabled[38]) ; else fprintf
+#define debugging_mcianim debug_msg_enabled[38]
 #else
 #ifdef DEBUG_MCIANIM
 #define dprintf_mcianim fprintf
@@ -986,8 +1040,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mciwave if(!debug_msg_enabled[37]) ; else fprintf
-#define debugging_mciwave debug_msg_enabled[37]
+#define dprintf_mciwave if(!debug_msg_enabled[39]) ; else fprintf
+#define debugging_mciwave debug_msg_enabled[39]
 #else
 #ifdef DEBUG_MCIWAVE
 #define dprintf_mciwave fprintf
@@ -999,8 +1053,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mdi if(!debug_msg_enabled[38]) ; else fprintf
-#define debugging_mdi debug_msg_enabled[38]
+#define dprintf_mdi if(!debug_msg_enabled[40]) ; else fprintf
+#define debugging_mdi debug_msg_enabled[40]
 #else
 #ifdef DEBUG_MDI
 #define dprintf_mdi fprintf
@@ -1012,8 +1066,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_menu if(!debug_msg_enabled[39]) ; else fprintf
-#define debugging_menu debug_msg_enabled[39]
+#define dprintf_menu if(!debug_msg_enabled[41]) ; else fprintf
+#define debugging_menu debug_msg_enabled[41]
 #else
 #ifdef DEBUG_MENU
 #define dprintf_menu fprintf
@@ -1025,8 +1079,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_menucalc if(!debug_msg_enabled[40]) ; else fprintf
-#define debugging_menucalc debug_msg_enabled[40]
+#define dprintf_menucalc if(!debug_msg_enabled[42]) ; else fprintf
+#define debugging_menucalc debug_msg_enabled[42]
 #else
 #ifdef DEBUG_MENUCALC
 #define dprintf_menucalc fprintf
@@ -1038,8 +1092,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_message if(!debug_msg_enabled[41]) ; else fprintf
-#define debugging_message debug_msg_enabled[41]
+#define dprintf_message if(!debug_msg_enabled[43]) ; else fprintf
+#define debugging_message debug_msg_enabled[43]
 #else
 #ifdef DEBUG_MESSAGE
 #define dprintf_message fprintf
@@ -1051,8 +1105,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_metafile if(!debug_msg_enabled[42]) ; else fprintf
-#define debugging_metafile debug_msg_enabled[42]
+#define dprintf_metafile if(!debug_msg_enabled[44]) ; else fprintf
+#define debugging_metafile debug_msg_enabled[44]
 #else
 #ifdef DEBUG_METAFILE
 #define dprintf_metafile fprintf
@@ -1064,8 +1118,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_midi if(!debug_msg_enabled[43]) ; else fprintf
-#define debugging_midi debug_msg_enabled[43]
+#define dprintf_midi if(!debug_msg_enabled[45]) ; else fprintf
+#define debugging_midi debug_msg_enabled[45]
 #else
 #ifdef DEBUG_MIDI
 #define dprintf_midi fprintf
@@ -1077,8 +1131,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmio if(!debug_msg_enabled[44]) ; else fprintf
-#define debugging_mmio debug_msg_enabled[44]
+#define dprintf_mmio if(!debug_msg_enabled[46]) ; else fprintf
+#define debugging_mmio debug_msg_enabled[46]
 #else
 #ifdef DEBUG_MMIO
 #define dprintf_mmio fprintf
@@ -1090,8 +1144,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmtime if(!debug_msg_enabled[45]) ; else fprintf
-#define debugging_mmtime debug_msg_enabled[45]
+#define dprintf_mmtime if(!debug_msg_enabled[47]) ; else fprintf
+#define debugging_mmtime debug_msg_enabled[47]
 #else
 #ifdef DEBUG_MMTIME
 #define dprintf_mmtime fprintf
@@ -1103,8 +1157,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_module if(!debug_msg_enabled[46]) ; else fprintf
-#define debugging_module debug_msg_enabled[46]
+#define dprintf_module if(!debug_msg_enabled[48]) ; else fprintf
+#define debugging_module debug_msg_enabled[48]
 #else
 #ifdef DEBUG_MODULE
 #define dprintf_module fprintf
@@ -1116,8 +1170,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_msg if(!debug_msg_enabled[47]) ; else fprintf
-#define debugging_msg debug_msg_enabled[47]
+#define dprintf_msg if(!debug_msg_enabled[49]) ; else fprintf
+#define debugging_msg debug_msg_enabled[49]
 #else
 #ifdef DEBUG_MSG
 #define dprintf_msg fprintf
@@ -1129,8 +1183,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_msgbox if(!debug_msg_enabled[48]) ; else fprintf
-#define debugging_msgbox debug_msg_enabled[48]
+#define dprintf_msgbox if(!debug_msg_enabled[50]) ; else fprintf
+#define debugging_msgbox debug_msg_enabled[50]
 #else
 #ifdef DEBUG_MSGBOX
 #define dprintf_msgbox fprintf
@@ -1142,8 +1196,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_nonclient if(!debug_msg_enabled[49]) ; else fprintf
-#define debugging_nonclient debug_msg_enabled[49]
+#define dprintf_nonclient if(!debug_msg_enabled[51]) ; else fprintf
+#define debugging_nonclient debug_msg_enabled[51]
 #else
 #ifdef DEBUG_NONCLIENT
 #define dprintf_nonclient fprintf
@@ -1155,8 +1209,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_ole if(!debug_msg_enabled[50]) ; else fprintf
-#define debugging_ole debug_msg_enabled[50]
+#define dprintf_ole if(!debug_msg_enabled[52]) ; else fprintf
+#define debugging_ole debug_msg_enabled[52]
 #else
 #ifdef DEBUG_OLE
 #define dprintf_ole fprintf
@@ -1168,8 +1222,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_palette if(!debug_msg_enabled[51]) ; else fprintf
-#define debugging_palette debug_msg_enabled[51]
+#define dprintf_palette if(!debug_msg_enabled[53]) ; else fprintf
+#define debugging_palette debug_msg_enabled[53]
 #else
 #ifdef DEBUG_PALETTE
 #define dprintf_palette fprintf
@@ -1181,8 +1235,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_profile if(!debug_msg_enabled[52]) ; else fprintf
-#define debugging_profile debug_msg_enabled[52]
+#define dprintf_profile if(!debug_msg_enabled[54]) ; else fprintf
+#define debugging_profile debug_msg_enabled[54]
 #else
 #ifdef DEBUG_PROFILE
 #define dprintf_profile fprintf
@@ -1194,8 +1248,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_prop if(!debug_msg_enabled[53]) ; else fprintf
-#define debugging_prop debug_msg_enabled[53]
+#define dprintf_prop if(!debug_msg_enabled[55]) ; else fprintf
+#define debugging_prop debug_msg_enabled[55]
 #else
 #ifdef DEBUG_PROP
 #define dprintf_prop fprintf
@@ -1207,8 +1261,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_reg if(!debug_msg_enabled[54]) ; else fprintf
-#define debugging_reg debug_msg_enabled[54]
+#define dprintf_reg if(!debug_msg_enabled[56]) ; else fprintf
+#define debugging_reg debug_msg_enabled[56]
 #else
 #ifdef DEBUG_REG
 #define dprintf_reg fprintf
@@ -1220,8 +1274,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_region if(!debug_msg_enabled[55]) ; else fprintf
-#define debugging_region debug_msg_enabled[55]
+#define dprintf_region if(!debug_msg_enabled[57]) ; else fprintf
+#define debugging_region debug_msg_enabled[57]
 #else
 #ifdef DEBUG_REGION
 #define dprintf_region fprintf
@@ -1233,8 +1287,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_relay if(!debug_msg_enabled[56]) ; else fprintf
-#define debugging_relay debug_msg_enabled[56]
+#define dprintf_relay if(!debug_msg_enabled[58]) ; else fprintf
+#define debugging_relay debug_msg_enabled[58]
 #else
 #ifdef DEBUG_RELAY
 #define dprintf_relay fprintf
@@ -1246,8 +1300,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_resource if(!debug_msg_enabled[57]) ; else fprintf
-#define debugging_resource debug_msg_enabled[57]
+#define dprintf_resource if(!debug_msg_enabled[59]) ; else fprintf
+#define debugging_resource debug_msg_enabled[59]
 #else
 #ifdef DEBUG_RESOURCE
 #define dprintf_resource fprintf
@@ -1259,8 +1313,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_scroll if(!debug_msg_enabled[58]) ; else fprintf
-#define debugging_scroll debug_msg_enabled[58]
+#define dprintf_scroll if(!debug_msg_enabled[60]) ; else fprintf
+#define debugging_scroll debug_msg_enabled[60]
 #else
 #ifdef DEBUG_SCROLL
 #define dprintf_scroll fprintf
@@ -1272,8 +1326,21 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_selectors if(!debug_msg_enabled[59]) ; else fprintf
-#define debugging_selectors debug_msg_enabled[59]
+#define dprintf_selector if(!debug_msg_enabled[61]) ; else fprintf
+#define debugging_selector debug_msg_enabled[61]
+#else
+#ifdef DEBUG_SELECTOR
+#define dprintf_selector fprintf
+#define debugging_selector 1
+#else
+#define dprintf_selector while(0) fprintf
+#define debugging_selector 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_selectors if(!debug_msg_enabled[62]) ; else fprintf
+#define debugging_selectors debug_msg_enabled[62]
 #else
 #ifdef DEBUG_SELECTORS
 #define dprintf_selectors fprintf
@@ -1285,8 +1352,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_stack if(!debug_msg_enabled[60]) ; else fprintf
-#define debugging_stack debug_msg_enabled[60]
+#define dprintf_stack if(!debug_msg_enabled[63]) ; else fprintf
+#define debugging_stack debug_msg_enabled[63]
 #else
 #ifdef DEBUG_STACK
 #define dprintf_stack fprintf
@@ -1298,8 +1365,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_stress if(!debug_msg_enabled[61]) ; else fprintf
-#define debugging_stress debug_msg_enabled[61]
+#define dprintf_stress if(!debug_msg_enabled[64]) ; else fprintf
+#define debugging_stress debug_msg_enabled[64]
 #else
 #ifdef DEBUG_STRESS
 #define dprintf_stress fprintf
@@ -1311,8 +1378,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_syscolor if(!debug_msg_enabled[62]) ; else fprintf
-#define debugging_syscolor debug_msg_enabled[62]
+#define dprintf_syscolor if(!debug_msg_enabled[65]) ; else fprintf
+#define debugging_syscolor debug_msg_enabled[65]
 #else
 #ifdef DEBUG_SYSCOLOR
 #define dprintf_syscolor fprintf
@@ -1324,8 +1391,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_task if(!debug_msg_enabled[63]) ; else fprintf
-#define debugging_task debug_msg_enabled[63]
+#define dprintf_task if(!debug_msg_enabled[66]) ; else fprintf
+#define debugging_task debug_msg_enabled[66]
 #else
 #ifdef DEBUG_TASK
 #define dprintf_task fprintf
@@ -1337,8 +1404,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_text if(!debug_msg_enabled[64]) ; else fprintf
-#define debugging_text debug_msg_enabled[64]
+#define dprintf_text if(!debug_msg_enabled[67]) ; else fprintf
+#define debugging_text debug_msg_enabled[67]
 #else
 #ifdef DEBUG_TEXT
 #define dprintf_text fprintf
@@ -1350,8 +1417,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_timer if(!debug_msg_enabled[65]) ; else fprintf
-#define debugging_timer debug_msg_enabled[65]
+#define dprintf_timer if(!debug_msg_enabled[68]) ; else fprintf
+#define debugging_timer debug_msg_enabled[68]
 #else
 #ifdef DEBUG_TIMER
 #define dprintf_timer fprintf
@@ -1363,8 +1430,21 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_utility if(!debug_msg_enabled[66]) ; else fprintf
-#define debugging_utility debug_msg_enabled[66]
+#define dprintf_toolhelp if(!debug_msg_enabled[69]) ; else fprintf
+#define debugging_toolhelp debug_msg_enabled[69]
+#else
+#ifdef DEBUG_TOOLHELP
+#define dprintf_toolhelp fprintf
+#define debugging_toolhelp 1
+#else
+#define dprintf_toolhelp while(0) fprintf
+#define debugging_toolhelp 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_utility if(!debug_msg_enabled[70]) ; else fprintf
+#define debugging_utility debug_msg_enabled[70]
 #else
 #ifdef DEBUG_UTILITY
 #define dprintf_utility fprintf
@@ -1376,8 +1456,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_win if(!debug_msg_enabled[67]) ; else fprintf
-#define debugging_win debug_msg_enabled[67]
+#define dprintf_win if(!debug_msg_enabled[71]) ; else fprintf
+#define debugging_win debug_msg_enabled[71]
 #else
 #ifdef DEBUG_WIN
 #define dprintf_win fprintf
@@ -1389,8 +1469,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_winsock if(!debug_msg_enabled[68]) ; else fprintf
-#define debugging_winsock debug_msg_enabled[68]
+#define dprintf_winsock if(!debug_msg_enabled[72]) ; else fprintf
+#define debugging_winsock debug_msg_enabled[72]
 #else
 #ifdef DEBUG_WINSOCK
 #define dprintf_winsock fprintf
@@ -1431,6 +1511,7 @@
     "fixup",
     "font",
     "gdi",
+    "global",
     "graphics",
     "heap",
     "icon",
@@ -1439,6 +1520,7 @@
     "keyboard",
     "ldt",
     "listbox",
+    "local",
     "malloc",
     "mci",
     "mcianim",
@@ -1464,6 +1546,7 @@
     "relay",
     "resource",
     "scroll",
+    "selector",
     "selectors",
     "stack",
     "stress",
@@ -1471,6 +1554,7 @@
     "task",
     "text",
     "timer",
+    "toolhelp",
     "utility",
     "win",
     "winsock",
diff --git a/include/dlls.h b/include/dlls.h
index 0ad5c2f..cdceae5 100644
--- a/include/dlls.h
+++ b/include/dlls.h
@@ -20,7 +20,7 @@
 struct ne_data {
     struct ne_header_s *ne_header;
     struct ne_segment_table_entry_s *seg_table;
-    struct segment_descriptor_s *selector_table;
+    unsigned short *selector_table;
     char *lookup_table;
     char *nrname_table;
     char *rname_table;
@@ -61,7 +61,6 @@
 #define DLL_MAX_ARGS		16
 
 #define DLL_HANDLERTYPE_PASCAL	16
-#define DLL_HANDLERTYPE_C	17
 
 struct dll_table_entry_s
 {
@@ -76,7 +75,6 @@
      */
     char *export_name;
     void *handler;		/* Address of function to process request */
-    char handler_type;		/* C or PASCAL calling convention	  */
     char n_args;			/* Number of arguments passed to function */
     short conv_reference ; /* reference to Argument conversion data  */
 #ifdef WINESTAT
@@ -97,7 +95,6 @@
 extern struct dll_table_entry_s KERNEL_table[];
 extern struct dll_table_entry_s USER_table[];
 extern struct dll_table_entry_s GDI_table[];
-extern struct dll_table_entry_s UNIXLIB_table[];
 extern struct dll_table_entry_s WIN87EM_table[];
 extern struct dll_table_entry_s MMSYSTEM_table[];
 extern struct dll_table_entry_s SHELL_table[];
@@ -116,12 +113,13 @@
 extern struct dll_table_entry_s OLE2PROX_table[];
 extern struct dll_table_entry_s OLECLI_table[];
 extern struct dll_table_entry_s OLESVR_table[];
+extern struct dll_table_entry_s COMPOBJ_table[];
+extern struct dll_table_entry_s STORAGE_table[];
 
 
 extern unsigned short KERNEL_offsets[];
 extern unsigned short USER_offsets[];
 extern unsigned short GDI_offsets[];
-extern unsigned short UNIXLIB_offsets[];
 extern unsigned short WIN87EM_offsets[];
 extern unsigned short MMSYSTEM_offsets[];
 extern unsigned short SHELL_offsets[];
@@ -140,12 +138,13 @@
 extern unsigned short OLE2PROX_offsets[];
 extern unsigned short OLECLI_offsets[];
 extern unsigned short OLESVR_offsets[];
+extern unsigned short COMPOBJ_offsets[];
+extern unsigned short STORAGE_offsets[];
 
 
 extern unsigned char KERNEL_types[];
 extern unsigned char USER_types[];
 extern unsigned char GDI_types[];
-extern unsigned char UNIXLIB_types[];
 extern unsigned char WIN87EM_types[];
 extern unsigned char MMSYSTEM_types[];
 extern unsigned char SHELL_types[];
@@ -164,8 +163,10 @@
 extern unsigned char OLE2PROX_types[];
 extern unsigned char OLECLI_types[];
 extern unsigned char OLESVR_types[];
+extern unsigned char COMPOBJ_types[];
+extern unsigned char STORAGE_types[];
 
-#define N_BUILTINS	22
+#define N_BUILTINS	23
 
 #endif /* DLLS_H */
 
diff --git a/include/gdi.h b/include/gdi.h
index 476782f..561e882 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -11,8 +11,8 @@
 #include <X11/Xutil.h>
 
 #include "windows.h"
-#include "segmem.h"
-#include "heap.h"
+#include "ldt.h"
+#include "local.h"
 
   /* GDI objects magic numbers */
 #define PEN_MAGIC             0x4f47
@@ -245,18 +245,26 @@
 
 #ifdef WINELIB
 
-#define GDI_HEAP_ALLOC(f,size) LocalAlloc (f,size)
-#define GDI_HEAP_ADDR(handle)  LocalLock (handle)
-#define GDI_HEAP_FREE(handle)  LocalFree (handle)
+#define GDI_HEAP_ALLOC(f,size)     LocalAlloc (f,size)
+#define GDI_HEAP_LIN_ADDR(handle)  LocalLock (handle)
+#define GDI_HEAP_SEG_ADDR(handle)  LocalLock (handle)
+#define GDI_HEAP_FREE(handle)      LocalFree (handle)
 
 #else
 
-extern MDESC *GDI_Heap;
+extern LPSTR GDI_Heap;
+extern WORD GDI_HeapSel;
 
-#define GDI_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&GDI_Heap,f,size) & 0xffff)
-#define GDI_HEAP_FREE(handle) (HEAP_Free(&GDI_Heap,GDI_HEAP_ADDR(handle)))
-#define GDI_HEAP_ADDR(handle) \
-    ((void *)((handle) ? ((handle) | ((int)GDI_Heap & 0xffff0000)) : 0))
+#define GDI_HEAP_ALLOC(size) \
+            LOCAL_Alloc( GDI_HeapSel, LMEM_FIXED, (size) )
+#define GDI_HEAP_REALLOC(handle,size) \
+            LOCAL_ReAlloc( GDI_HeapSel, (handle), (size), LMEM_FIXED )
+#define GDI_HEAP_FREE(handle) \
+            LOCAL_Free( GDI_HeapSel, (handle) )
+#define GDI_HEAP_LIN_ADDR(handle)  \
+            ((handle) ? PTR_SEG_OFF_TO_LIN(GDI_HeapSel, (handle)) : NULL)
+#define GDI_HEAP_SEG_ADDR(handle)  \
+            ((handle) ? MAKELONG((handle), GDI_HeapSel) : 0)
 
 #endif
 
diff --git a/include/heap.h b/include/heap.h
deleted file mode 100644
index 043d013..0000000
--- a/include/heap.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $Id: heap.h,v 1.2 1993/07/04 04:04:21 root Exp root $
- */
-/*
- * Copyright  Robert J. Amstadt, 1993
- */
-#ifndef HEAP_H
-#define HEAP_H
-
-#include "segmem.h"
-#include "atom.h"
-#include "stackframe.h"
-
-/**********************************************************************
- * LOCAL HEAP STRUCTURES AND FUNCTIONS
- */
-typedef struct heap_mem_desc_s
-{
-    struct heap_mem_desc_s *prev, *next;
-    unsigned short length;
-    unsigned char  lock;
-    unsigned char  flags;
-} MDESC;
-
-typedef struct heap_local_heap_s
-{
-    struct heap_local_heap_s *next;
-    MDESC *free_list;
-    ATOMTABLE *local_table;
-    unsigned short selector;
-    unsigned short delta;		/* Number saved for Windows compat. */
-} LHEAP;
-
-extern void HEAP_Init(MDESC **free_list, void *start, int length);
-extern void *HEAP_Alloc(MDESC **free_list, int flags, int bytes);
-extern int  HEAP_Free(MDESC **free_list, void *block);
-extern void *HEAP_ReAlloc(MDESC **free_list, void *old_block, 
-			  int new_size, unsigned int flags);
-
-extern LHEAP *HEAP_LocalFindHeap(unsigned short owner);
-extern unsigned int HEAP_LocalSize(MDESC **free_list, unsigned int handle);
-extern void HEAP_LocalInit(unsigned short owner, void *start, int length);
-
-extern void *WIN16_LocalAlloc(int flags, int bytes);
-extern int WIN16_LocalCompact(int min_free);
-extern unsigned int WIN16_LocalFlags(unsigned int handle);
-extern unsigned int WIN16_LocalFree(unsigned int handle);
-extern void *WIN16_LocalLock(unsigned int handle);
-extern void *WIN16_LocalReAlloc(unsigned int handle, int flags, int bytes);
-extern unsigned int WIN16_LocalUnlock(unsigned int handle);
-
-/* Use ds instead of owner of cs */
-#define HEAP_OWNER	(pStack16Frame->ds)
-#define LOCALHEAP()	(&HEAP_LocalFindHeap(HEAP_OWNER)->free_list)
-#define LOCALATOMTABLE() (&HEAP_LocalFindHeap(HEAP_OWNER)->local_table)
-
-/**********************************************************************
- * GLOBAL HEAP STRUCTURES AND FUNCTIONS:
- *
- * Global memory pool descriptor.  Segments MUST be maintained in segment
- * ascending order.  If not the reallocation routine will die a horrible
- * death.
- *
- * handle  = 0, this descriptor contains the address of a free pool.
- *        != 0, this describes an allocated block.
- *
- * sequence = 0, this is not a huge block
- *          > 0, this is a portion of a huge block
- *          =-1, this is a free segment
- *
- * addr	      - address of this memory block.
- *
- * length     - used to maintain huge blocks.
- */
-typedef struct global_mem_desc_s
-{
-    struct global_mem_desc_s *next;	/* Next GDESC in list              */
-    struct global_mem_desc_s *prev;	/* Previous GDESC in list          */
-    unsigned short handle;		/* Handle of this block.	   */
-    short          sequence;		/* Block sequence # in huge block  */
-    void          *addr;		/* Address allocated with mmap()   */
-    int            length;		/* Length of block		   */
-    int            lock_count;		/* Block lock count		   */
-    unsigned short alias;		/* Offset-zero alias selector      */
-    unsigned int   alias_key;		/* Offset-zero alias sh. mem. key  */
-    void          *linear_addr;		/* Linear address of huge block    */
-    int            linear_key;		/* Linear shared memory key        */
-    int            linear_count;	/* Linear lock count               */
-} GDESC;
-
-extern GDESC *GlobalList;
-
-extern void *GlobalQuickAlloc(int size);
-extern unsigned int GlobalHandleFromPointer(void *block);
-extern GDESC *GlobalGetGDesc(unsigned int block);
-extern void *GlobalLinearLock(unsigned int block);
-extern unsigned int GlobalLinearUnlock(unsigned int block);
-
-#endif /* HEAP_H */
diff --git a/include/hook.h b/include/hook.h
index f70dce8..303fdd8 100644
--- a/include/hook.h
+++ b/include/hook.h
@@ -8,7 +8,7 @@
 #define HOOK_H
 
 #include "windows.h"
-#include "user.h"
+#include "ldt.h"
 
   /* Hook data (pointed to by a HHOOK) */
 typedef struct
@@ -26,7 +26,8 @@
 #define SYSTEM_HOOK(id)  (systemHooks[(id)-FIRST_HOOK])
 #define TASK_HOOK(id)    (taskHooks[(id)-FIRST_HOOK])
 #define INTERNAL_CALL_HOOK(hhook,code,wparam,lparam) \
-    ((hhook) ? CallHookProc(((HOOKDATA*)(hhook))->proc,code,wparam,lparam) : 0)
+    ((hhook) ? CallHookProc(((HOOKDATA*)PTR_SEG_TO_LIN(hhook))->proc,\
+                            code, wparam, lparam) : 0)
 
 #define CALL_SYSTEM_HOOK(id,code,wparam,lparam) \
     INTERNAL_CALL_HOOK(SYSTEM_HOOK(id),code,wparam,lparam)
diff --git a/include/if1632.h b/include/if1632.h
index 1cf7637..03621a6 100644
--- a/include/if1632.h
+++ b/include/if1632.h
@@ -8,7 +8,6 @@
 extern int CallTo16cx(unsigned long csip, unsigned long dscx);
 extern int CallToDllEntry(unsigned long csip, unsigned long dscx, unsigned short di);
 extern int CallBack16(void *func, int n_args, ...);
-extern void *CALLBACK_MakeProcInstance(void *func, int instance);
 extern void CallLineDDAProc(FARPROC func, short xPos, short yPos, long lParam);
 extern void winestat(void);
 extern int DLLRelay(unsigned int func_num, unsigned int seg_off);
diff --git a/include/instance.h b/include/instance.h
new file mode 100644
index 0000000..95dde0e
--- /dev/null
+++ b/include/instance.h
@@ -0,0 +1,26 @@
+/*
+ * Instance data declaration
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#ifndef __WINE_INSTANCE_H
+#define __WINE_INSTANCE_H
+
+#include "wintypes.h"
+
+  /* This structure is always located at offset 0 of the DGROUP segment */
+
+typedef struct
+{
+    WORD null;        /* Always 0 */
+    WORD old_sp;      /* Stack pointer; used by SwitchTaskTo() */
+    WORD old_ss;      /* Stack segment; used by SwitchTaskTo() */
+    WORD heap;        /* Pointer to the local heap information (if any) */
+    WORD atomtable;   /* Pointer to the local atom table (if any) */ 
+    WORD stacktop;    /* Top of the stack */
+    WORD stackmin;    /* Lowest stack address used so far */
+    WORD stackbottom; /* Bottom of the stack */
+} INSTANCEDATA;
+
+#endif /* __WINE_INSTANCE_H */
diff --git a/include/ldt.h b/include/ldt.h
new file mode 100644
index 0000000..6fa19aa
--- /dev/null
+++ b/include/ldt.h
@@ -0,0 +1,62 @@
+/*
+ * LDT copy
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#ifndef _WINE_LDT_H
+#define _WINE_LDT_H
+
+enum seg_type
+{
+    SEGMENT_DATA  = 0,
+    SEGMENT_STACK = 1,
+    SEGMENT_CODE  = 2
+};
+
+  /* This structure represents a real LDT entry.        */
+  /* It is used by get_ldt_entry() and set_ldt_entry(). */
+typedef struct
+{
+    unsigned long base;            /* base address */
+    unsigned long limit;           /* segment limit */
+    int           seg_32bit;       /* is segment 32-bit? */
+    int           read_only;       /* is segment read-only? */
+    int           limit_in_pages;  /* is the limit in pages or bytes? */
+    enum seg_type type;            /* segment type */
+} ldt_entry;
+
+extern int LDT_GetEntry( int entry, ldt_entry *content );
+extern int LDT_SetEntry( int entry, ldt_entry *content );
+extern void LDT_Print();
+
+
+  /* This structure is used to build the local copy of the LDT. */
+typedef struct
+{
+    unsigned long base;    /* base address or 0 if entry is free   */
+    unsigned long limit;   /* limit in bytes or 0 if entry is free */
+} ldt_copy_entry;
+
+#define LDT_SIZE  8192
+
+extern ldt_copy_entry ldt_copy[LDT_SIZE];
+
+#define __AHSHIFT  3
+#define __AHINCR   (1 << __AHSHIFT)
+
+#define SELECTOR_TO_ENTRY(sel)  ((int)(sel) >> __AHSHIFT)
+#define ENTRY_TO_SELECTOR(i)    ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0)
+#define IS_LDT_ENTRY_FREE(i)    (!(ldt_copy[(i)].base || ldt_copy[(i)].limit))
+#define IS_SELECTOR_FREE(sel)   (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel)))
+#define GET_SEL_BASE(sel)       (ldt_copy[SELECTOR_TO_ENTRY(sel)].base)
+#define GET_SEL_LIMIT(sel)      (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit)
+
+  /* Convert a segmented ptr (16:16) to a linear (32) pointer */
+#define PTR_SEG_TO_LIN(ptr) \
+           ((void*)(GET_SEL_BASE((int)(ptr) >> 16) + ((int)(ptr) & 0xffff)))
+
+#define PTR_SEG_OFF_TO_LIN(seg,off) \
+           ((void*)(GET_SEL_BASE(seg) + ((int)(off) & 0xffff)))
+
+#endif  /* _WINE_LDT_H */
diff --git a/include/listbox.h b/include/listbox.h
index 1e56b7f..c1b2278 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -30,7 +30,7 @@
 	HWND	hWndLogicParent;
 	HFONT	hFont;
 	BOOL	bRedrawFlag;
-	MDESC	*Heap;
+/*	MDESC	*Heap; */
 } HEADLIST;
 typedef HEADLIST FAR* LPHEADLIST;
 
diff --git a/include/local.h b/include/local.h
new file mode 100644
index 0000000..eb813e9
--- /dev/null
+++ b/include/local.h
@@ -0,0 +1,24 @@
+/*
+ * Local heap declarations
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#ifndef __WINE_HEAP_H
+#define __WINE_HEAP_H
+
+#include "wintypes.h"
+
+  /* These function are equivalent to the Local* API functions, */
+  /* excepted that they need DS as the first parameter. This    */
+  /* allows managing several heaps from the emulation library.  */
+
+extern HLOCAL LOCAL_Alloc( WORD ds, WORD flags, WORD size );
+extern HLOCAL LOCAL_ReAlloc( WORD ds, HLOCAL handle, WORD size, WORD flags );
+extern HLOCAL LOCAL_Free( WORD ds, HLOCAL handle );
+extern HLOCAL LOCAL_Handle( WORD ds, WORD addr );
+extern WORD LOCAL_Size( WORD ds, HLOCAL handle );
+extern WORD LOCAL_Flags( WORD ds, HLOCAL handle );
+extern WORD LOCAL_HeapSize( WORD ds );
+
+#endif  /* __WINE_HEAP_H */
diff --git a/include/message.h b/include/message.h
index b634227..c8a1429 100644
--- a/include/message.h
+++ b/include/message.h
@@ -54,7 +54,7 @@
 extern void hardware_event( WORD message, WORD wParam, LONG lParam,
 			    int xPos, int yPos, DWORD time, DWORD extraInfo );
 extern BOOL MSG_GetHardwareMessage( LPMSG msg );
-extern BOOL MSG_InternalGetMessage( LPMSG msg, HWND hwnd, HWND hwndOwner,
+extern BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner,
 				    short code, WORD flags, BOOL sendIdle );
 
 #endif  /* MESSAGE_H */
diff --git a/include/msdos.h b/include/msdos.h
index 31bf3fb..35b8d92 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -15,6 +15,7 @@
 	char search_attribute;
 	long filesize;
 	long filetime;
+        short entnum;           /* Directory entry number */
 };
 
 struct fcb {
@@ -29,16 +30,13 @@
 	BYTE dummy2[9];
 };
 
-#define DOSVERSION 0x0330;
+#define DOSVERSION 0x0500;      /* Might as well pretend we're DOS 5.0 */
 #define MAX_DOS_DRIVES	26
 
 extern WORD ExtendedError;
 extern struct DosDeviceStruct COM[MAX_PORTS];
 extern struct DosDeviceStruct LPT[MAX_PORTS];
 
-#define segment(a) 	((DWORD)(a) >> 16)
-#define offset(a)	((DWORD)(a) & 0xffff)
-
 #define setword(a,b)	*(BYTE*)(a)	  = (b) & 0xff; \
 			*((BYTE*)((a)+1)) = ((b)>>8) & 0xff;
 			
diff --git a/include/neexe.h b/include/neexe.h
index d31a0e3..ad26cbe 100644
--- a/include/neexe.h
+++ b/include/neexe.h
@@ -133,11 +133,7 @@
 #define NE_RELTYPE_ORDINAL	1
 #define NE_RELTYPE_NAME		2
 #define NE_RELTYPE_OSFIXUP	3
-/* Used by Windows 3.0 programs, like when getting selector to be
-   given to makeprocinst */
-#define NE_RELTYPE_INT1		4
-#define NE_RELTYPE_ORDINALADD	5
-#define NE_RELTYPE_NAMEADD	6
+#define NE_RELFLAG_ADDITIVE	4
 
 /*
  * DOS PSP
diff --git a/include/options.h b/include/options.h
index 317f9c1..095fa88 100644
--- a/include/options.h
+++ b/include/options.h
@@ -17,6 +17,8 @@
     int    backingstore;    /* Use backing store */
     short  cmdShow;
     int    debug;
+    int    allowReadOnly;   /* Opening a read only file will succeed even
+			       if write access is requested */
 };
 
 extern struct options Options;
diff --git a/include/prototypes.h b/include/prototypes.h
index d50a2db..9fa03da 100644
--- a/include/prototypes.h
+++ b/include/prototypes.h
@@ -9,22 +9,11 @@
 #include <sys/types.h>
 
 #include "neexe.h"
-#include "segmem.h"
-#include "heap.h"
 #include "msdos.h"
 #include "windows.h"
 
 #ifndef WINELIB
 
-/* loader/ldtlib.c */
-
-struct segment_descriptor *
-make_sd(unsigned base, unsigned limit, int contents, int read_exec_only, int seg32, int inpgs);
-int get_ldt(void *buffer);
-int set_ldt_entry(int entry, unsigned long base, unsigned int limit,
-	      int seg_32bit_flag, int contents, int read_only_flag,
-	      int limit_in_pages_flag);
-
 /* loader/resource.c */
 
 extern HBITMAP ConvertCoreBitmap( HDC hdc, BITMAPCOREHEADER * image );
@@ -44,11 +33,6 @@
 extern int _WinMain(int argc, char **argv);
 extern void InitializeLoadedDLLs();
 
-extern int KERNEL_LockSegment(int segment);
-extern int KERNEL_UnlockSegment(int segment);
-extern void KERNEL_InitTask(void);
-extern int KERNEL_WaitEvent(int task);
-
 /* misc/spy.c */
 
 extern void SpyInit(void);
@@ -57,9 +41,5 @@
 
 extern BOOL WIDGETS_Init(void);
 
-/* windows/dce.c */
-
-extern void DCE_Init(void);
-
 #endif /* WINELIB */
 #endif /* _WINE_PROTOTYPES_H */
diff --git a/include/regfunc.h b/include/regfunc.h
index 913ca86..fa91700 100644
--- a/include/regfunc.h
+++ b/include/regfunc.h
@@ -7,13 +7,11 @@
 #include "wine.h"
 #include "stackframe.h"
 
-#define _CONTEXT ((struct sigcontext_struct *) pStack16Frame->args)
+#define _CONTEXT ((struct sigcontext_struct *) CURRENT_STACK16->args)
 #define _AX	(_CONTEXT->sc_eax)
 #define _BX	(_CONTEXT->sc_ebx)
 #define _CX	(_CONTEXT->sc_ecx)
 #define _DX	(_CONTEXT->sc_edx)
-#define _SP	(_CONTEXT->sc_esp)
-#define _BP	(_CONTEXT->sc_ebp)
 #define _SI	(_CONTEXT->sc_esi)
 #define _DI	(_CONTEXT->sc_edi)
 #define _DS	(_CONTEXT->sc_ds)
diff --git a/include/segmem.h b/include/segmem.h
deleted file mode 100644
index 583adc9..0000000
--- a/include/segmem.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/* $Id: segmem.h,v 1.3 1993/07/04 04:04:21 root Exp root $
- */
-/*
- * Copyright  Robert J. Amstadt, 1993
- */
-#ifndef SEGMEM_H
-#define SEGMEM_H
-
-#include "wine.h"
-
-#ifdef __linux__
-#define HAVE_IPC
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#define HAVE_IPC
-#include <sys/types.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#define SHMSEG 32     /* XXX SEMMNI /usr/src/sys/conf/param.h */
-#define SHM_RANGE_START       0x40000000
-#endif
-
-/*
- * Array to track selector allocation.
- */
-#define SELECTOR_ISFREE		0x8000
-#define SELECTOR_IS32BIT        0x4000
-#define SELECTOR_INDEXMASK	0x0fff
-
-#define __AHSHIFT 3
-#define __AHINCR  (1 << __AHSHIFT)
-
-extern unsigned short* SelectorMap;
-
-#ifdef HAVE_IPC
-#define SAFEMAKEPTR(s, o) ((void *)(((int) (s) << 16) | ((o) & 0xffff)))
-#define FIXPTR(p)	  (p)
-#else
-#define SAFEMAKEPTR(s, o) \
-  ((void*)(((int)SelectorMap[SelectorMap[(s)>>__AHSHIFT] & SELECTOR_INDEXMASK]\
-	    << (16 + __AHSHIFT)) | 0x70000 | ((o) & 0xffff)))
-#define FIXPTR(p)	  SAFEMAKEPTR((unsigned long) (p) >> 16, (p))
-#endif
-
-#define MAKESELECTOR(fp) ((unsigned short) (fp >> (16 + __AHSHIFT)))
- 
-
-/*
- * Structure to hold info about each selector we create.
- */
-
-typedef struct segment_descriptor_s
-{
-    void          *base_addr;	/* Pointer to segment in flat memory	*/
-    unsigned int   length;	/* Length of segment			*/
-    unsigned int   flags;	/* Segment flags (see neexe.h and below)*/
-    unsigned short selector;	/* Selector used to access this segment */
-    unsigned short owner;	/* Handle of owner program		*/
-    unsigned char  type;	/* DATA or CODE				*/
-#ifdef HAVE_IPC
-    key_t	   shm_key;	/* Shared memory key or -1              */
-#endif
-} SEGDESC;
-
-extern int IPCCopySelector(int i_old, unsigned long new, int swap_type);
-
-/*
- * Additional flags
- */
-#define NE_SEGFLAGS_MALLOCED	0x00010000 /* Memory allocated with malloc() */
-
-/*
- * Global memory flags
- */
-#define GLOBAL_FLAGS_MOVEABLE		0x0002
-#define GLOBAL_FLAGS_ZEROINIT		0x0040
-#define GLOBAL_FLAGS_CODE		0x00010000
-#define GLOBAL_FLAGS_EXECUTEONLY	0x00020000
-#define GLOBAL_FLAGS_READONLY		0x00020000
-
-#ifdef __ELF__
-#define FIRST_SELECTOR 2
-#define IS_16_BIT_ADDRESS(addr)  \
-  (!(SelectorMap[(unsigned int)(addr) >> (16+__AHSHIFT)]& SELECTOR_IS32BIT))
-#else
-#define FIRST_SELECTOR	8
-#define IS_16_BIT_ADDRESS(addr)  \
-     ((unsigned int)(addr) >= (((FIRST_SELECTOR << __AHSHIFT) | 7) << 16))
-#endif
-
-
-extern SEGDESC* Segments;
-
-#endif /* SEGMEM_H */
diff --git a/include/selectors.h b/include/selectors.h
index 7724f5c..55715b9 100644
--- a/include/selectors.h
+++ b/include/selectors.h
@@ -1,25 +1,28 @@
+/*
+ * Selector definitions
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
 #ifndef __WINE_SELECTORS_H
 #define __WINE_SELECTORS_H
 
-#include "dlls.h"
-#include "segmem.h"
 #include "windows.h"
+#include "ldt.h"
 
-extern int FindUnusedSelectors(int n_selectors);
-extern int IPCCopySelector(int i_old, unsigned long new, int swap_type);
-extern WORD AllocSelector(WORD old_selector);
-extern unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector);
-extern WORD AllocDStoCSAlias(WORD ds_selector);
-extern SEGDESC *CreateSelectors(struct  w_files * wpnt);
-extern WORD FreeSelector(WORD sel);
+extern WORD SELECTOR_AllocBlock( void *base, DWORD size, enum seg_type type,
+                                 BOOL is32bit, BOOL readonly );
+extern WORD SELECTOR_ReallocBlock( WORD sel, void *base, DWORD size,
+                                   enum seg_type type, BOOL is32bit,
+                                   BOOL readonly );
 
-extern SEGDESC *CreateNewSegments(int code_flag, int read_only, int length, 
-					int n_segments);
-extern SEGDESC *GetNextSegment(unsigned int flags, unsigned int limit);
+#include "dlls.h"
 
-extern unsigned int GetEntryDLLName(char *dll_name, char *function, int *sel,
+extern WORD *CreateSelectors( struct w_files * wpnt );
+
+extern unsigned int GetEntryDLLName(char *dll_name, char *function, WORD *sel,
 					int *addr);
-extern unsigned int GetEntryDLLOrdinal(char *dll_name, int ordinal, int *sel,
+extern unsigned int GetEntryDLLOrdinal(char *dll_name, int ordinal, WORD *sel,
 					int *addr);
 extern unsigned int GetEntryPointFromOrdinal(struct w_files * wpnt, 
 					int ordinal);
diff --git a/include/stackframe.h b/include/stackframe.h
index 9c008d7..d029ec1 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -8,13 +8,13 @@
 #define WINE_STACKFRAME_H
 
 #include <windows.h>
+#include "ldt.h"
 
 typedef struct
 {
     WORD    saved_ss;
     WORD    saved_bp;
     WORD    saved_sp;
-    WORD    es;
     WORD    ds;
     WORD    bp;
     WORD    arg_length;
@@ -23,7 +23,13 @@
     WORD    args[1];
 } STACK16FRAME;
 
+extern WORD IF1632_Saved16_ss;
+extern WORD IF1632_Saved16_sp;
+extern WORD IF1632_Saved16_bp;
 
-extern STACK16FRAME *pStack16Frame;
+#define CURRENT_STACK16 \
+    ((STACK16FRAME *)PTR_SEG_OFF_TO_LIN(IF1632_Saved16_ss,IF1632_Saved16_sp))
+
+#define CURRENT_DS   (CURRENT_STACK16->ds)
 
 #endif /* WINE_STACKFRAME_H */
diff --git a/include/stddebug.h b/include/stddebug.h
index e9d74ce..4abb78e 100644
--- a/include/stddebug.h
+++ b/include/stddebug.h
@@ -102,6 +102,7 @@
 #undef DEBUG_FIXUP
 #undef DEBUG_FONT
 #undef DEBUG_GDI
+#undef DEBUG_GLOBAL
 #undef DEBUG_GRAPHICS
 #undef DEBUG_HEAP
 #undef DEBUG_ICON
@@ -110,6 +111,7 @@
 #undef DEBUG_KEYBOARD
 #undef DEBUG_LDT
 #undef DEBUG_LISTBOX
+#undef DEBUG_LOCAL
 #undef DEBUG_MALLOC
 #undef DEBUG_MCI
 #undef DEBUG_MCIANIM
@@ -135,6 +137,7 @@
 #undef DEBUG_RELAY
 #undef DEBUG_RESOURCE
 #undef DEBUG_SCROLL
+#undef DEBUG_SELECTOR
 #undef DEBUG_SELECTORS
 #undef DEBUG_STACK
 #undef DEBUG_STRESS
@@ -142,6 +145,7 @@
 #undef DEBUG_TASK
 #undef DEBUG_TEXT
 #undef DEBUG_TIMER
+#undef DEBUG_TOOLHELP
 #undef DEBUG_UTILITY
 #undef DEBUG_WIN
 #undef DEBUG_WINSOCK
@@ -174,6 +178,7 @@
 #define DEBUG_FIXUP
 #define DEBUG_FONT
 #define DEBUG_GDI
+#define DEBUG_GLOBAL
 #define DEBUG_GRAPHICS
 #define DEBUG_HEAP
 #define DEBUG_ICON
@@ -182,6 +187,7 @@
 #define DEBUG_KEYBOARD
 #define DEBUG_LDT
 #define DEBUG_LISTBOX
+#define DEBUG_LOCAL
 #define DEBUG_MALLOC
 #define DEBUG_MCI
 #define DEBUG_MCIANIM
@@ -207,6 +213,7 @@
 #define DEBUG_RELAY
 #define DEBUG_RESOURCE
 #define DEBUG_SCROLL
+#define DEBUG_SELECTOR
 #define DEBUG_SELECTORS
 #define DEBUG_STACK
 #define DEBUG_STRESS
@@ -214,6 +221,7 @@
 #define DEBUG_TASK
 #define DEBUG_TEXT
 #define DEBUG_TIMER
+#define DEBUG_TOOLHELP
 #define DEBUG_UTILITY
 #define DEBUG_WIN
 #define DEBUG_WINSOCK
diff --git a/include/toolhelp.h b/include/toolhelp.h
index 40d7d9b..85ab7b3 100644
--- a/include/toolhelp.h
+++ b/include/toolhelp.h
@@ -3,14 +3,93 @@
 
 #include "windows.h"
 
-DECLARE_HANDLE(HMODULE);
-DECLARE_HANDLE(HGLOBAL);
-
 #define MAX_DATA	11
 #define MAX_MODULE_NAME	9
 #define MAX_PATH	255
 #define MAX_CLASSNAME	255
 
+/* Global heap */
+
+WORD GlobalHandleToSel( HANDLE handle );
+
+
+/* Local heap */
+
+typedef struct
+{
+    DWORD   dwSize;
+    WORD    wcItems;
+} LOCALINFO;
+
+typedef struct
+{
+    DWORD   dwSize;
+    HLOCAL  hHandle;
+    WORD    wAddress;
+    WORD    wSize;
+    WORD    wFlags;
+    WORD    wcLock;
+    WORD    wType;
+    WORD    hHeap;
+    WORD    wHeapType;
+    WORD    wNext;
+} LOCALENTRY;
+
+/* wHeapType values */
+#define NORMAL_HEAP     0
+#define USER_HEAP       1
+#define GDI_HEAP        2
+
+/* wFlags values */
+#define LF_FIXED        1
+#define LF_FREE         2
+#define LF_MOVEABLE     4
+
+/* wType values */
+#define LT_NORMAL                   0
+#define LT_FREE                     0xff
+#define LT_GDI_PEN                  1   /* LT_GDI_* is for GDI's heap */
+#define LT_GDI_BRUSH                2
+#define LT_GDI_FONT                 3
+#define LT_GDI_PALETTE              4
+#define LT_GDI_BITMAP               5
+#define LT_GDI_RGN                  6
+#define LT_GDI_DC                   7
+#define LT_GDI_DISABLED_DC          8
+#define LT_GDI_METADC               9
+#define LT_GDI_METAFILE             10
+#define LT_GDI_MAX                  LT_GDI_METAFILE
+#define LT_USER_CLASS               1   /* LT_USER_* is for USER's heap */
+#define LT_USER_WND                 2
+#define LT_USER_STRING              3
+#define LT_USER_MENU                4
+#define LT_USER_CLIP                5
+#define LT_USER_CBOX                6
+#define LT_USER_PALETTE             7
+#define LT_USER_ED                  8
+#define LT_USER_BWL                 9
+#define LT_USER_OWNERDRAW           10
+#define LT_USER_SPB                 11
+#define LT_USER_CHECKPOINT          12
+#define LT_USER_DCE                 13
+#define LT_USER_MWP                 14
+#define LT_USER_PROP                15
+#define LT_USER_LBIV                16
+#define LT_USER_MISC                17
+#define LT_USER_ATOMS               18
+#define LT_USER_LOCKINPUTSTATE      19
+#define LT_USER_HOOKLIST            20
+#define LT_USER_USERSEEUSERDOALLOC  21
+#define LT_USER_HOTKEYLIST          22
+#define LT_USER_POPUPMENU           23
+#define LT_USER_HANDLETABLE         32
+#define LT_USER_MAX                 LT_USER_HANDLETABLE
+
+BOOL LocalInfo( LOCALINFO *pLocalInfo, HGLOBAL handle );
+BOOL LocalFirst( LOCALENTRY *pLocalEntry, HGLOBAL handle );
+BOOL LocalNext( LOCALENTRY *pLocalEntry );
+
+
 /* modules */
 
 typedef struct {
@@ -73,16 +152,37 @@
 } MEMMANINFO;
 typedef MEMMANINFO *LPMEMMANINFO;
 
-typedef struct tagSYSHEAPINFO {
-	DWORD dwSize;
-	WORD wUserFreePercent;
-	WORD wGDIFreePercent;
-	HGLOBAL hUserSegment;
-	HGLOBAL hGDISegment;
+typedef struct
+{
+    DWORD   dwSize;
+    WORD    wUserFreePercent;
+    WORD    wGDIFreePercent;
+    HGLOBAL hUserSegment;
+    HGLOBAL hGDISegment;
 } SYSHEAPINFO;
-typedef SYSHEAPINFO *LPSYSHEAPINFO;
 
 BOOL MemManInfo(LPMEMMANINFO lpEnhMode);
-BOOL SystemHeapInfo(LPSYSHEAPINFO lpSysHeap);
+BOOL SystemHeapInfo( SYSHEAPINFO *pHeapInfo );
+
+
+/* Window classes */
+
+typedef struct
+{
+    DWORD     dwSize;
+    HMODULE   hInst;              /* This is really an hModule */
+    char      szClassName[MAX_CLASSNAME + 1];
+    WORD      wNext;
+} CLASSENTRY;
+
+BOOL ClassFirst( CLASSENTRY *pClassEntry );
+BOOL ClassNext( CLASSENTRY *pClassEntry );
+
+
+/* Memory read/write */
+
+DWORD MemoryRead( WORD sel, DWORD offset, void *buffer, DWORD count );
+DWORD MemoryWrite( WORD sel, DWORD offset, void *buffer, DWORD count );
+
 
 #endif /* __TOOLHELP_H */
diff --git a/include/user.h b/include/user.h
index 990428c..af0ecdf 100644
--- a/include/user.h
+++ b/include/user.h
@@ -7,8 +7,8 @@
 #ifndef USER_H
 #define USER_H
 
-#include "segmem.h"
-#include "heap.h"
+#include "ldt.h"
+#include "local.h"
 
 /* USER local heap */
 
@@ -16,18 +16,24 @@
 
 #define USER_HEAP_ALLOC(f,size) LocalAlloc (f, size)
 #define USER_HEAP_REALLOC(handle,size,f) LocalReAlloc (handle,size,f)
-#define USER_HEAP_ADDR(handle) LocalLock (handle)
+#define USER_HEAP_LIN_ADDR(handle) LocalLock (handle)
+#define USER_HEAP_SEG_ADDR(handle) LocalLock (handle)
 #define USER_HEAP_FREE(handle) LocalFree (handle)
 #else
 
-extern MDESC *USER_Heap;
+extern LPSTR USER_Heap;
+extern WORD USER_HeapSel;
 
-#define USER_HEAP_ALLOC(f,size) ((int)HEAP_Alloc(&USER_Heap,f,size) & 0xffff)
-#define USER_HEAP_REALLOC(handle,size,f) ((int)HEAP_ReAlloc(&USER_Heap, \
-				       USER_HEAP_ADDR(handle),size,f) & 0xffff)
-#define USER_HEAP_FREE(handle) (HEAP_Free(&USER_Heap,USER_HEAP_ADDR(handle)))
-#define USER_HEAP_ADDR(handle) \
-    ((void *)((handle) ? ((handle) | ((int)USER_Heap & 0xffff0000)) : 0))
+#define USER_HEAP_ALLOC(size) \
+            LOCAL_Alloc( USER_HeapSel, LMEM_FIXED, (size) )
+#define USER_HEAP_REALLOC(handle,size) \
+            LOCAL_ReAlloc( USER_HeapSel, (handle), (size), LMEM_FIXED )
+#define USER_HEAP_FREE(handle) \
+            LOCAL_Free( USER_HeapSel, (handle) )
+#define USER_HEAP_LIN_ADDR(handle)  \
+            ((handle) ? PTR_SEG_OFF_TO_LIN(USER_HeapSel, (handle)) : NULL)
+#define USER_HEAP_SEG_ADDR(handle)  \
+            ((handle) ? MAKELONG((handle), USER_HeapSel) : 0)
 
 #endif  /* WINELIB */
 
diff --git a/include/win.h b/include/win.h
index c33e722..e9cbb90 100644
--- a/include/win.h
+++ b/include/win.h
@@ -9,6 +9,7 @@
 
 #include <X11/Xlib.h>
 
+#include "ldt.h"
 #include "class.h"
 
 #define WND_MAGIC     0x444e4957  /* 'WIND' */
diff --git a/include/windows.h b/include/windows.h
index 088d0fa..5ff1c25 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1211,6 +1211,12 @@
 #define SPIF_UPDATEINIFILE		1
 #define SPIF_SENDWININICHANGE		2
 
+/* GetFreeSystemResources() parameters */
+
+#define GFSR_SYSTEMRESOURCES   0x0000
+#define GFSR_GDIRESOURCES      0x0001
+#define GFSR_USERRESOURCES     0x0002
+
 /* GetWinFlags */
 
 #define WF_PMODE 	0x0001
@@ -1229,25 +1235,25 @@
 #define	WF_PAGING	0x0800
 #define	WF_WLO          0x8000
 
-#define MAKEINTRESOURCE(i) (LPSTR)((DWORD)((WORD)(i)))
+#define MAKEINTRESOURCE(i) (SEGPTR)((DWORD)((WORD)(i)))
 
-#define IDI_APPLICATION MAKEINTRESOURCE(32512)
-#define IDI_HAND MAKEINTRESOURCE(32513)
-#define IDI_QUESTION MAKEINTRESOURCE(32514)
-#define IDI_EXCLAMATION MAKEINTRESOURCE(32515)
-#define IDI_ASTERISK MAKEINTRESOURCE(32516)
+#define IDI_APPLICATION  MAKEINTRESOURCE(32512)
+#define IDI_HAND         MAKEINTRESOURCE(32513)
+#define IDI_QUESTION     MAKEINTRESOURCE(32514)
+#define IDI_EXCLAMATION  MAKEINTRESOURCE(32515)
+#define IDI_ASTERISK     MAKEINTRESOURCE(32516)
 
-#define IDC_ARROW MAKEINTRESOURCE(32512)
-#define IDC_IBEAM MAKEINTRESOURCE(32513)
-#define IDC_WAIT MAKEINTRESOURCE(32514)
-#define IDC_CROSS MAKEINTRESOURCE(32515)
-#define IDC_UPARROW MAKEINTRESOURCE(32516)
-#define IDC_SIZE MAKEINTRESOURCE(32540)
-#define IDC_ICON MAKEINTRESOURCE(32541)
-#define IDC_SIZENWSE MAKEINTRESOURCE(32542)
-#define IDC_SIZENESW MAKEINTRESOURCE(32543)
-#define IDC_SIZEWE MAKEINTRESOURCE(32544)
-#define IDC_SIZENS MAKEINTRESOURCE(32545)
+#define IDC_ARROW        MAKEINTRESOURCE(32512)
+#define IDC_IBEAM        MAKEINTRESOURCE(32513)
+#define IDC_WAIT         MAKEINTRESOURCE(32514)
+#define IDC_CROSS        MAKEINTRESOURCE(32515)
+#define IDC_UPARROW      MAKEINTRESOURCE(32516)
+#define IDC_SIZE         MAKEINTRESOURCE(32540)
+#define IDC_ICON         MAKEINTRESOURCE(32541)
+#define IDC_SIZENWSE     MAKEINTRESOURCE(32542)
+#define IDC_SIZENESW     MAKEINTRESOURCE(32543)
+#define IDC_SIZEWE       MAKEINTRESOURCE(32544)
+#define IDC_SIZENS       MAKEINTRESOURCE(32545)
 
 /* OEM Resource Ordinal Numbers */
 #define OBM_CLOSE           32754
@@ -2315,8 +2321,8 @@
 F(LONG,GetVersion)
 F(LONG,GetWinFlags)
 F(LPINT,GetThresholdEvent)
-F(LPSTR,GetDOSEnvironment)
 F(LPSTR,ValidateFreeSpaces)
+F(SEGPTR,GetDOSEnvironment)
 F(WORD,GetCaretBlinkTime)
 F(WORD,GetCurrentPDB)
 F(WORD,GetDoubleClickTime)
@@ -2361,7 +2367,9 @@
 Fa(BOOL,EndDeferWindowPos,HDWP,hWinPosInfo)
 Fa(BOOL,FreeModule,HANDLE,a)
 Fa(BOOL,FreeResource,HANDLE,a)
-Fa(BOOL,InitAtomTable,WORD,a)
+Fa(BOOL,GlobalUnWire,HGLOBAL,a)
+Fa(BOOL,GlobalUnlock,HGLOBAL,a)
+Fa(BOOL,IsBadCodePtr,SEGPTR,a)
 Fa(BOOL,IsCharAlpha,char,ch)
 Fa(BOOL,IsCharAlphaNumeric,char,ch)
 Fa(BOOL,IsCharLower,char,ch)
@@ -2395,10 +2403,15 @@
 Fa(DWORD,GetCurrentPosition,HDC,a)
 Fa(DWORD,GetDCOrg,HDC,a)
 Fa(DWORD,GetFreeSpace,WORD,a)
+Fa(DWORD,GetHeapSpaces,HMODULE,a)
 Fa(DWORD,GetViewportExt,HDC,a)
 Fa(DWORD,GetViewportOrg,HDC,a)
 Fa(DWORD,GetWindowExt,HDC,a)
 Fa(DWORD,GetWindowOrg,HDC,a)
+Fa(DWORD,GlobalCompact,DWORD,a)
+Fa(DWORD,GlobalDOSAlloc,DWORD,a)
+Fa(DWORD,GlobalHandle,WORD,a)
+Fa(DWORD,GlobalSize,HGLOBAL,a)
 Fa(DWORD,OemKeyScan,WORD,a)
 Fa(FARPROC,LocalNotify,FARPROC,a)
 Fa(HANDLE,CreateMetaFile,LPSTR,a)
@@ -2413,9 +2426,7 @@
 Fa(HANDLE,LoadLibrary,LPSTR,a)
 Fa(HANDLE,LocalFree,HANDLE,a)
 Fa(HANDLE,LocalHandle,WORD,a)
-Fa(HANDLE,LockSegment,WORD,a)
 Fa(HANDLE,SetMetaFileBits,HANDLE,a)
-Fa(HANDLE,UnlockSegment,WORD,a)
 Fa(HBITMAP,CreateBitmapIndirect,BITMAP FAR*,a)
 Fa(HBRUSH,CreateBrushIndirect,LOGBRUSH FAR*,a)
 Fa(HBRUSH,CreatePatternBrush,HBITMAP,a)
@@ -2427,6 +2438,10 @@
 Fa(HDC,GetWindowDC,HWND,a)
 Fa(HDWP,BeginDeferWindowPos,INT,nNumWindows)
 Fa(HFONT,CreateFontIndirect,LOGFONT FAR*,a)
+Fa(HGLOBAL,GlobalFree,HGLOBAL,a)
+Fa(HGLOBAL,GlobalLRUNewest,HGLOBAL,a)
+Fa(HGLOBAL,GlobalLRUOldest,HGLOBAL,a)
+Fa(HGLOBAL,LockSegment,HGLOBAL,a)
 Fa(HMENU,GetMenu,HWND,a)
 Fa(HMENU,LoadMenuIndirect,LPSTR,a)
 Fa(HMETAFILE,CloseMetaFile,HANDLE,a)
@@ -2451,13 +2466,17 @@
 Fa(LONG,DispatchMessage,LPMSG,msg)
 Fa(LONG,SetSwapAreaSize,WORD,a)
 Fa(LPSTR,AnsiLower,LPSTR,a)
-Fa(LPSTR,AnsiNext,LPSTR,a)
+Fa(SEGPTR,AnsiNext,SEGPTR,a)
 Fa(LPSTR,AnsiUpper,LPSTR,a)
+Fa(LPSTR,GlobalLock,HGLOBAL,a)
+Fa(LPSTR,GlobalWire,HGLOBAL,a)
 Fa(LPSTR,LockResource,HANDLE,a)
+Fa(SEGPTR,WIN16_GlobalLock,HGLOBAL,a)
 Fa(UINT,GDIRealizePalette,HDC,a)
 Fa(UINT,RealizePalette,HDC,a)
 Fa(WORD,AllocDStoCSAlias,WORD,a)
 Fa(WORD,AllocSelector,WORD,a)
+Fa(WORD,AllocSelectorArray,WORD,a)
 Fa(WORD,ArrangeIconicWindows,HWND,a)
 Fa(WORD,EnumClipboardFormats,WORD,a)
 Fa(WORD,FreeSelector,WORD,a)
@@ -2471,15 +2490,20 @@
 Fa(WORD,GetStretchBltMode,HDC,a)
 Fa(WORD,GetTaskQueue,HANDLE,a)
 Fa(WORD,GetTextAlign,HDC,a)
+Fa(WORD,GlobalDOSFree,WORD,a)
+Fa(WORD,GlobalFlags,HGLOBAL,a)
+Fa(WORD,GlobalPageLock,HGLOBAL,a)
+Fa(WORD,GlobalPageUnlock,HGLOBAL,a)
+Fa(WORD,InitAtomTable,WORD,a)
 Fa(WORD,LocalCompact,WORD,a)
-Fa(WORD,LocalFlags,HANDLE,a)
-Fa(WORD,LocalSize,HANDLE,a)
+Fa(WORD,LocalFlags,HLOCAL,a)
+Fa(WORD,LocalLock,HLOCAL,a)
+Fa(WORD,LocalSize,HLOCAL,a)
 Fa(WORD,RealizeDefaultPalette,HDC,a)
 Fa(WORD,RegisterClipboardFormat,LPCSTR,a)
 Fa(WORD,RegisterWindowMessage,LPCSTR,a)
 Fa(WORD,SetHandleCount,WORD,a)
 Fa(WORD,VkKeyScan,WORD,a)
-Fa(char NEAR*,LocalLock,HANDLE,a)
 Fa(int,AddFontResource,LPSTR,a)
 Fa(int,Catch,LPCATCHBUF,a)
 Fa(int,ClearCommBreak,int,a)
@@ -2509,6 +2533,9 @@
 Fa(void,GetCaretPos,LPPOINT,a)
 Fa(void,GetCursorPos,LPPOINT,a)
 Fa(void,GetKeyboardState,BYTE FAR*,a)
+Fa(void,GlobalFix,HGLOBAL,a)
+Fa(void,GlobalNotify,FARPROC,a)
+Fa(void,GlobalUnfix,HGLOBAL,a)
 Fa(void,HideCaret,HWND,a)
 Fa(void,LimitEmsPages,DWORD,a)
 Fa(void,MessageBeep,WORD,a)
@@ -2522,8 +2549,9 @@
 Fa(void,SetRectEmpty,LPRECT,a)
 Fa(void,ShowCaret,HWND,a)
 Fa(void,SwapRecording,WORD,a)
+Fa(void,UnlockSegment,HGLOBAL,a)
 Fa(void,UpdateWindow,HWND,a)
-Fb(BOOL,CallMsgFilter,LPMSG,a,short,b)
+Fb(BOOL,CallMsgFilter,SEGPTR,a,short,b)
 Fb(BOOL,ChangeClipboardChain,HWND,a,HWND,b)
 Fb(BOOL,EnableWindow,HWND,a,BOOL,b)
 Fb(BOOL,EnumWindows,FARPROC,a,LONG,b)
@@ -2541,6 +2569,11 @@
 Fb(BOOL,GetWindowOrgEx,HDC,a,LPPOINT,b)
 Fb(BOOL,GetWindowPlacement,HWND,a,LPWINDOWPLACEMENT,b)
 Fb(BOOL,InvertRgn,HDC,a,HRGN,b)
+Fb(BOOL,IsBadHugeReadPtr,SEGPTR,a,DWORD,b)
+Fb(BOOL,IsBadHugeWritePtr,SEGPTR,a,DWORD,b)
+Fb(BOOL,IsBadReadPtr,SEGPTR,a,WORD,b)
+Fb(BOOL,IsBadStringPtr,SEGPTR,a,WORD,b)
+Fb(BOOL,IsBadWritePtr,SEGPTR,a,WORD,b)
 Fb(BOOL,IsChild,HWND,a,HWND,b)
 Fb(BOOL,IsDialogMessage,HWND,a,LPMSG,b)
 Fb(BOOL,KillSystemTimer,HWND,a,WORD,b)
@@ -2568,23 +2601,24 @@
 Fb(FARPROC,MakeProcInstance,FARPROC,a,HANDLE,b)
 Fb(HANDLE,CopyMetaFile,HANDLE,a,LPSTR,b)
 Fb(HANDLE,GetProp,HWND,a,LPSTR,b)
-Fb(HANDLE,LoadAccelerators,HANDLE,a,LPSTR,b)
+Fb(HANDLE,LoadAccelerators,HANDLE,a,SEGPTR,b)
 Fb(HANDLE,LoadModule,LPSTR,a,LPVOID,b)
 Fb(HANDLE,LoadResource,HANDLE,a,HANDLE,b)
 Fb(HANDLE,LocalAlloc,WORD,a,WORD,b)
 Fb(HANDLE,RemoveProp,HWND,a,LPSTR,b)
 Fb(HANDLE,SelectObject,HDC,a,HANDLE,b)
 Fb(HANDLE,SetClipboardData,WORD,a,HANDLE,b)
-Fb(HBITMAP,LoadBitmap,HANDLE,a,LPSTR,b)
+Fb(HBITMAP,LoadBitmap,HANDLE,a,SEGPTR,b)
 Fb(HBRUSH,CreateDIBPatternBrush,HANDLE,a,WORD,b)
 Fb(HBRUSH,CreateHatchBrush,short,a,COLORREF,b)
-Fb(HCURSOR,LoadCursor,HANDLE,a,LPSTR,b)
+Fb(HCURSOR,LoadCursor,HANDLE,a,SEGPTR,b)
 Fb(HDC,BeginPaint,HWND,a,LPPAINTSTRUCT,b) 
+Fb(HGLOBAL,GlobalAlloc,WORD,a,DWORD,b)
 Fb(HHOOK,SetWindowsHook,short,a,HOOKPROC,b)
-Fb(HICON,LoadIcon,HANDLE,a,LPSTR,b)
+Fb(HICON,LoadIcon,HANDLE,a,SEGPTR,b)
 Fb(HMENU,GetSubMenu,HMENU,a,short,b)
 Fb(HMENU,GetSystemMenu,HWND,a,BOOL,b)
-Fb(HMENU,LoadMenu,HANDLE,a,LPSTR,b)
+Fb(HMENU,LoadMenu,HANDLE,a,SEGPTR,b)
 Fb(HMENU,LookupMenuHandle,HMENU,a,INT,b)
 Fb(HPALETTE,GDISelectPalette,HDC,a,HPALETTE,b)
 Fb(HWND,ChildWindowFromPoint,HWND,a,POINT,b)
@@ -2601,9 +2635,9 @@
 Fb(LONG,EscapeCommFunction,int,a,int,b)
 Fb(LONG,GetClassLong,HWND,a,short,b)
 Fb(LONG,GetWindowLong,HWND,a,short,b)
-Fb(LPSTR,AnsiPrev,LPSTR,a,LPSTR,b)
-Fb(LPSTR,lstrcat,LPSTR,a,LPCSTR,b )
-Fb(LPSTR,lstrcpy,LPSTR,a,LPCSTR,b )
+Fb(SEGPTR,AnsiPrev,SEGPTR,a,SEGPTR,b)
+Fb(SEGPTR,lstrcat,SEGPTR,a,SEGPTR,b)
+Fb(SEGPTR,lstrcpy,SEGPTR,a,SEGPTR,b)
 Fb(WORD FAR*,SetCommEventMask,int,a,WORD,b)
 Fb(WORD,AnsiLowerBuff,LPSTR,a,WORD,b)
 Fb(WORD,AnsiUpperBuff,LPSTR,a,WORD,b)
@@ -2619,6 +2653,7 @@
 Fb(WORD,IsDlgButtonChecked,HWND,a,WORD,b)
 Fb(WORD,LocalShrink,HANDLE,a,WORD,b)
 Fb(WORD,MapVirtualKey,WORD,a,WORD,b)
+Fb(WORD,PrestoChangoSelector,WORD,a,WORD,b)
 Fb(WORD,SetBkMode,HDC,a,WORD,b)
 Fb(WORD,SetMapMode,HDC,a,WORD,b)
 Fb(WORD,SetPolyFillMode,HDC,a,WORD,b)
@@ -2711,12 +2746,13 @@
 Fc(DWORD,SetWindowOrg,HDC,a,short,b,short,c)
 Fc(FARPROC,SetResourceHandler,HANDLE,a,LPSTR,b,FARPROC,c)
 Fc(HANDLE,AllocResource,HANDLE,a,HANDLE,b,DWORD,c)
-Fc(HANDLE,FindResource,HANDLE,a,LPSTR,b,LPSTR,c)
+Fc(HANDLE,FindResource,HANDLE,a,SEGPTR,b,SEGPTR,c)
 Fc(HANDLE,LocalReAlloc,HANDLE,a,WORD,b,WORD,c)
 Fc(HBITMAP,CreateCompatibleBitmap,HDC,a,short,b,short,c)
 Fc(HBITMAP,CreateDiscardableBitmap,HDC,a,short,b,short,c)
 Fc(HBRUSH,GetControlBrush,HWND,a,HDC,b,WORD,c)
 Fc(HDC,GetDCEx,HWND,a,HRGN,b,DWORD,c)
+Fc(HGLOBAL,GlobalReAlloc,HGLOBAL,a,DWORD,b,WORD,c)
 Fc(HPALETTE,SelectPalette,HDC,a,HPALETTE,b,BOOL,c)
 Fc(HPEN,CreatePen,short,a,short,b,COLORREF,c)
 Fc(HRGN,CreatePolygonRgn,LPPOINT,a,short,b,short,c)
@@ -2731,6 +2767,7 @@
 Fc(LONG,SetClassLong,HWND,a,short,b,LONG,c)
 Fc(LONG,SetWindowLong,HWND,a,short,b,LONG,c)
 Fc(LONG,_llseek,INT,a,LONG,b,INT,c)
+Fc(SEGPTR,lstrcpyn,SEGPTR,a,SEGPTR,b,WORD,c)
 Fc(WORD,GetAtomName,ATOM,a,LPSTR,b,short,c)
 Fc(WORD,GetInternalWindowPos,HWND,a,LPRECT,b,LPPOINT,c)
 Fc(WORD,GetMenuState,HMENU,a,WORD,b,WORD,c)
@@ -2769,7 +2806,7 @@
 Fc(void,InvalidateRgn,HWND,a,HRGN,b,BOOL,c)
 Fc(void,OemToAnsiBuff,LPSTR,a,LPSTR,b,INT,c)
 Fc(void,OffsetRect,LPRECT,a,short,b,short,c)
-Fc(void,SetDlgItemText,HWND,a,WORD,b,LPSTR,c)
+Fc(void,SetDlgItemText,HWND,a,WORD,b,SEGPTR,c)
 Fc(void,SetSysColors,int,a,LPINT,b,COLORREF*,c)
 Fc(void,ShowScrollBar,HWND,a,WORD,b,BOOL,c)
 Fc(void,SwitchStackTo,WORD,a,WORD,b,WORD,c)
@@ -2778,7 +2815,7 @@
 Fd(BOOL,EnumMetaFile,HDC,a,LOCALHANDLE,b,FARPROC,c,BYTE FAR*,d)
 Fd(BOOL,FloodFill,HDC,a,INT,b,INT,c,COLORREF,d)
 Fd(BOOL,GetCharWidth,HDC,a,WORD,b,WORD,c,LPINT,d)
-Fd(BOOL,GetMessage,LPMSG,msg,HWND,b,WORD,c,WORD,d)
+Fd(BOOL,GetMessage,SEGPTR,msg,HWND,b,WORD,c,WORD,d)
 Fd(BOOL,GetTextExtentPoint,HDC,a,LPSTR,b,short,c,LPSIZE,d)
 Fd(BOOL,HiliteMenuItem,HWND,a,HMENU,b,WORD,c,WORD,d)
 Fd(BOOL,MoveToEx,HDC,a,short,b,short,c,LPPOINT,d)
@@ -2804,7 +2841,7 @@
 Fd(HRGN,CreateEllipticRgn,short,a,short,b,short,c,short,d)
 Fd(HRGN,CreatePolyPolygonRgn,LPPOINT,a,LPINT,b,short,c,short,d)
 Fd(HRGN,CreateRectRgn,short,a,short,b,short,c,short,d)
-Fd(HWND,CreateDialog,HANDLE,a,LPCSTR,b,HWND,c,WNDPROC,d)
+Fd(HWND,CreateDialog,HANDLE,a,SEGPTR,b,HWND,c,WNDPROC,d)
 Fd(HWND,CreateDialogIndirect,HANDLE,a,LPCSTR,b,HWND,c,WNDPROC,d)
 Fd(INT,GetTempFileName,BYTE,a,LPCSTR,b,UINT,c,LPSTR,d)
 Fd(LONG,DefDlgProc,HWND,a,WORD,b,WORD,c,LONG,d)
@@ -2819,11 +2856,11 @@
 Fd(WORD,SetSystemTimer,HWND,a,WORD,d,WORD,b,FARPROC,c)
 Fd(WORD,SetTimer,HWND,a,WORD,d,WORD,b,FARPROC,c)
 Fd(int,CombineRgn,HRGN,a,HRGN,b,HRGN,c,short,d)
-Fd(int,DialogBox,HINSTANCE,a,LPCSTR,b,HWND,c,WNDPROC,d)
+Fd(int,DialogBox,HINSTANCE,a,SEGPTR,b,HWND,c,WNDPROC,d)
 Fd(int,DialogBoxIndirect,HANDLE,a,HANDLE,b,HWND,c,WNDPROC,d)
 Fd(int,EnumFonts,HDC,a,LPSTR,b,FARPROC,c,LPSTR,d)
 Fd(int,EnumObjects,HDC,a,int,b,FARPROC,c,LPSTR,d)
-Fd(int,GetDlgItemText,HWND,a,WORD,b,LPSTR,c,WORD,d)
+Fd(int,GetDlgItemText,HWND,a,WORD,b,SEGPTR,c,WORD,d)
 Fd(int,LoadString,HANDLE,a,WORD,b,LPSTR,c,int,d)
 Fd(int,MessageBox,HWND,a,LPSTR,b,LPSTR,c,WORD,d)
 Fd(int,SetScrollPos,HWND,a,int,b,int,c,BOOL,d)
@@ -2853,14 +2890,14 @@
 Fe(DWORD,ScaleWindowExt,HDC,a,short,b,short,c,short,d,short,e)
 Fe(HBITMAP,CreateBitmap,short,a,short,b,BYTE,c,BYTE,d,LPSTR,e)
 Fe(HWND,CreateDialogIndirectParam,HANDLE,a,LPCSTR,b,HWND,c,WNDPROC,d,LPARAM,e)
-Fe(HWND,CreateDialogParam,HANDLE,a,LPCSTR,b,HWND,c,WNDPROC,d,LPARAM,e)
+Fe(HWND,CreateDialogParam,HANDLE,a,SEGPTR,b,HWND,c,WNDPROC,d,LPARAM,e)
 Fe(LONG,CallWindowProc,WNDPROC,a,HWND,b,WORD,c,WORD,d,LONG,e)
 Fe(LONG,DefFrameProc,HWND,a,HWND,b,WORD,c,WORD,d,LONG,e)
 Fe(LONG,SendDlgItemMessage,HWND,a,WORD,b,WORD,c,WORD,d,LONG,e)
 Fe(int,DialogBoxIndirectParam,HANDLE,a,HANDLE,b,HWND,c,WNDPROC,d,LONG,e)
-Fe(int,DialogBoxParam,HANDLE,a,LPCSTR,b,HWND,c,WNDPROC,d,LONG,e)
+Fe(int,DialogBoxParam,HANDLE,a,SEGPTR,b,HWND,c,WNDPROC,d,LONG,e)
 Fe(int,DlgDirList,HWND,a,LPSTR,b,int,c,int,d,WORD,e)
-Fe(int,DlgDirListComboBox,HWND,a,LPSTR,b,int,c,int,d,WORD,e)
+Fe(int,DlgDirListComboBox,HWND,a,SEGPTR,b,int,c,int,d,WORD,e)
 Fe(int,DrawText,HDC,a,LPSTR,str,int,c,LPRECT,d,WORD,flag)
 Fe(int,Escape,HDC,a,int,b,int,c,LPSTR,d,LPSTR,e)
 Fe(int,ExcludeClipRect,HDC,a,short,b,short,c,short,d,short,e)
@@ -2902,33 +2939,12 @@
 Fi(BOOL,GrayString,HDC,a,HBRUSH,b,FARPROC,gsprc,LPARAM,lParam,INT,cch,INT,x,INT,y,INT,cx,INT,cy)
 Fi(BOOL,Pie,HDC,a,int,xLeft,int,yTop,int,xRight,int,yBottom,int,xStart,int,yStart,int,xEnd,int,yEnd)
 Fk(BOOL,StretchBlt,HDC,a,short,b,short,c,short,d,short,e,HDC,f,short,g,short,h,short,i,short,j,DWORD,k)
-Fk(HWND,CreateWindow,LPSTR,szAppName,LPSTR,Label,DWORD,ol,short,x,short,y,short,w,short,h,HWND,d,HMENU,e,,HANDLE i,LPSTR,g)
-Fl(HWND,CreateWindowEx,DWORD,a,LPSTR,b,LPSTR,c,DWORD,d,short,e,short,f,short,g,short,h,HWND,i,HMENU,j,HANDLE,k,LPSTR,l)
+Fk(HWND,CreateWindow,LPSTR,szAppName,LPSTR,Label,DWORD,ol,short,x,short,y,short,w,short,h,HWND,d,HMENU,e,,HANDLE i,SEGPTR,g)
+Fl(HWND,CreateWindowEx,DWORD,a,LPSTR,b,LPSTR,c,DWORD,d,short,e,short,f,short,g,short,h,HWND,i,HMENU,j,HANDLE,k,SEGPTR,l)
 Fl(int,SetDIBitsToDevice,HDC,a,short,b,short,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l)
 Fm(int,StretchDIBits,HDC,a,WORD,b,WORD,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l,DWORD,m)
 Fn(HFONT,CreateFont,int,a,int,b,int,c,int,d,int,e,BYTE,f,BYTE,g,BYTE,h,BYTE,i,BYTE,j,BYTE,k,BYTE,l,BYTE,m,LPSTR,n)
 
-#ifndef GLOBAL_SOURCE
-Fa(BOOL,GlobalUnWire,HANDLE,a)
-Fa(BOOL,GlobalUnfix,HANDLE,a)
-Fa(BOOL,GlobalUnlock,HANDLE,a)
-Fa(DWORD,GlobalCompact,DWORD,a)
-Fa(DWORD,GlobalHandle,WORD,a)
-Fa(DWORD,GlobalSize,HANDLE,a)
-Fa(HANDLE,GlobalFree,HANDLE,a)
-Fa(HANDLE,GlobalLRUNewest,HANDLE,a)
-Fa(HANDLE,GlobalLRUOldest,HANDLE,a)
-Fa(LPSTR,GlobalLock,HANDLE,a)
-Fa(LPSTR,GlobalWire,HANDLE,a)
-Fa(WORD,GlobalFlags,HANDLE,a)
-Fa(WORD,GlobalPageLock,HANDLE,a)
-Fa(WORD,GlobalPageUnlock,HANDLE,a)
-Fa(void,GlobalFix,HANDLE,a)
-Fa(void,GlobalNotify,FARPROC,a)
-Fb(HANDLE,GlobalAlloc,WORD,a,DWORD,b)
-Fc(HANDLE,GlobalReAlloc,HANDLE,a,DWORD,b,WORD,c)
-#endif
-
 #ifdef WINELIB
 #define WINELIB_UNIMP(x) fprintf (stderr, "WineLib: Unimplemented %s\n", x)
 #endif
diff --git a/include/wintypes.h b/include/wintypes.h
index a74457e..88c627f 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -13,6 +13,7 @@
 typedef LONG LRESULT;
 typedef WORD HANDLE;
 typedef DWORD HHOOK;
+typedef DWORD SEGPTR;
 typedef char *LPSTR;
 typedef const char *LPCSTR;
 typedef char *NPSTR;
@@ -30,25 +31,28 @@
 
 #define DECLARE_HANDLE(a) typedef HANDLE a;
 
-DECLARE_HANDLE(HTASK);
-DECLARE_HANDLE(HDRVR);
-DECLARE_HANDLE(HWND);
-DECLARE_HANDLE(HDC);
-DECLARE_HANDLE(HCLASS);
-DECLARE_HANDLE(HCURSOR);
-DECLARE_HANDLE(HFONT);
-DECLARE_HANDLE(HPEN);
-DECLARE_HANDLE(HRGN);
-DECLARE_HANDLE(HPALETTE);
-DECLARE_HANDLE(HICON);
-DECLARE_HANDLE(HINSTANCE);
-DECLARE_HANDLE(HMENU);
 DECLARE_HANDLE(HBITMAP);
 DECLARE_HANDLE(HBRUSH);
-DECLARE_HANDLE(LOCALHANDLE);
-DECLARE_HANDLE(HMETAFILE);
-DECLARE_HANDLE(HDWP);
+DECLARE_HANDLE(HCLASS);
+DECLARE_HANDLE(HCURSOR);
+DECLARE_HANDLE(HDC);
 DECLARE_HANDLE(HDROP);
+DECLARE_HANDLE(HDRVR);
+DECLARE_HANDLE(HDWP);
+DECLARE_HANDLE(HFONT);
+DECLARE_HANDLE(HGLOBAL);
+DECLARE_HANDLE(HICON);
+DECLARE_HANDLE(HINSTANCE);
+DECLARE_HANDLE(HLOCAL);
+DECLARE_HANDLE(HMENU);
+DECLARE_HANDLE(HMETAFILE);
+DECLARE_HANDLE(HMODULE);
+DECLARE_HANDLE(HPALETTE);
+DECLARE_HANDLE(HPEN);
+DECLARE_HANDLE(HRGN);
+DECLARE_HANDLE(HTASK);
+DECLARE_HANDLE(HWND);
+DECLARE_HANDLE(LOCALHANDLE);
 
 #define TRUE 1
 #define FALSE 0
@@ -70,15 +74,18 @@
 #define WINE_PACKED __attribute__ ((packed))
 #endif
 
-#define LOBYTE(w)           ((BYTE)(w))
+#define LOBYTE(w)           ((BYTE)(UINT)(w))
 #define HIBYTE(w)           ((BYTE)((UINT)(w) >> 8))
 
-#define LOWORD(l)           ((WORD)(l))
+#define LOWORD(l)           ((WORD)(DWORD)(l))
 #define HIWORD(l)           ((WORD)((DWORD)(l) >> 16))
 
 #define MAKELONG(low, high) ((LONG)(((WORD)(low)) | \
 				    (((DWORD)((WORD)(high))) << 16)))
 
+#define SELECTOROF(ptr)     (HIWORD(ptr))
+#define OFFSETOF(ptr)       (LOWORD(ptr))
+
 #ifndef max
 #define max(a,b) (((a) > (b)) ? (a) : (b))
 #endif
diff --git a/loader/Imakefile b/loader/Imakefile
index c8a7bed..69bf07a 100644
--- a/loader/Imakefile
+++ b/loader/Imakefile
@@ -5,7 +5,6 @@
 SRCS = \
 	dump.c \
 	ldt.c \
-	ldtlib.c \
 	main.c \
 	ne_image.c \
 	ne_resource.c \
diff --git a/loader/dump.c b/loader/dump.c
index c811e44..77a2a06 100644
--- a/loader/dump.c
+++ b/loader/dump.c
@@ -16,7 +16,6 @@
 #endif
 #include <errno.h>
 #include "neexe.h"
-#include "segmem.h"
 #include "prototypes.h"
 
 /**********************************************************************
diff --git a/loader/ldt.c b/loader/ldt.c
index 45b6ae4..3654f2e 100644
--- a/loader/ldt.c
+++ b/loader/ldt.c
@@ -1,91 +1,221 @@
-#ifndef WINELIB
 /*
-static char RCSId[] = "$Id: ldt.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-*/
+ * LDT manipulation functions
+ *
+ * Copyright 1993 Robert J. Amstadt
+ * Copyright 1995 Alexandre Julliard
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <strings.h>
 #include <errno.h>
-#include "prototypes.h"
+#include "ldt.h"
+#include "stddebug.h"
+#include "debug.h"
+
+#ifndef WINELIB
+
+#ifdef linux
+#include <linux/unistd.h>
+#include <linux/head.h>
+#include <linux/ldt.h>
+
+_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
+#endif  /* linux */
 
 #if defined(__NetBSD__) || defined(__FreeBSD__)
 #include <machine/segments.h>
-#endif
 
-/**********************************************************************
- *					print_ldt
+extern int i386_get_ldt(int, union descriptor *, int);
+extern int i386_set_ldt(int, union descriptor *, int);
+#endif  /* __NetBSD__ || __FreeBSD__ */
+
+#endif  /* ifndef WINELIB */
+
+        
+/***********************************************************************
+ *           LDT_BytesToEntry
+ *
+ * Convert the raw bytes of the descriptor to an ldt_entry structure.
  */
-/* XXX These are *real* 386 descriptors !! */
-void
-print_ldt()
+static void LDT_BytesToEntry( unsigned long *buffer, ldt_entry *content )
 {
-    char buffer[0x10000];
-    unsigned long *lp;
-    unsigned long base_addr, limit;
-    int type, dpl, i;
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-    struct segment_descriptor *sd;
-#endif
-    
-    if (get_ldt(buffer) < 0)
-	exit(1);
-    
-    lp = (unsigned long *) buffer;
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-    sd = (struct segment_descriptor *) buffer;
-#endif
-    
-    for (i = 0; i < 32; i++, lp++)
-    {
-	/* First 32 bits of descriptor */
-	base_addr = (*lp >> 16) & 0x0000FFFF;
-	limit = *lp & 0x0000FFFF;
-	lp++;
-	
-	/* First 32 bits of descriptor */
-	base_addr |= (*lp & 0xFF000000) | ((*lp << 16) & 0x00FF0000);
-	limit |= (*lp & 0x000F0000);
-#ifdef linux
-	type = (*lp >> 10) & 5;
-	dpl = (*lp >> 13) & 3;
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-        type = sd->sd_type;
-        dpl = sd->sd_dpl;
-	sd++;
-#endif
-	if (*lp & 1000)
-	{
-	    printf("Entry %2d: Base %08lx, Limit %05lx, DPL %d, Type %d\n",
-		   i, base_addr, limit, dpl, type);
-	    printf("          ");
-	    if (*lp & 0x100)
-		printf("Accessed, ");
-	    if (*lp & 8000)
-		printf("Present, ");
-	    if (*lp & 0x100000)
-		printf("User, ");
-	    if (*lp & 0x200000)
-		printf("X, ");
-	    if (*lp & 0x400000)
-		printf("32, ");
-	    else
-		printf("16, ");
-	    if (*lp & 0x800000)
-		printf("page limit, ");
-	    else
-		printf("byte limit, ");
-	    printf("\n");
-	    printf("          %08lx %08lx\n", *(lp), *(lp-1));
-	}
-	else
-	{
-	    printf("Entry %2d: Base %08lx, Limit %05lx, DPL %d, Type %d\n",
-		   i, base_addr, limit, dpl, type);
-	    printf("          SYSTEM: %08lx %08lx\n", *lp, *(lp-1));
-	}
-    }
+    content->base  = (*buffer >> 16) & 0x0000ffff;
+    content->limit = *buffer & 0x0000ffff;
+    buffer++;
+    content->base  |= (*buffer & 0xff000000) | ((*buffer << 16) & 0x00ff0000);
+    content->limit |= (*buffer & 0x000f0000);
+    content->type           = (*buffer >> 10) & 3;
+    content->seg_32bit      = (*buffer & 0x00400000) != 0;
+    content->read_only      = (*buffer & 0x00000200) == 0;
+    content->limit_in_pages = (*buffer & 0x00800000) != 0;
 }
 
-#endif /* ifndef WINELIB */
+
+/***********************************************************************
+ *           LDT_GetEntry
+ *
+ * Retrieve an LDT entry.
+ */
+int LDT_GetEntry( int entry, ldt_entry *content )
+{
+    int ret = 0;
+
+#ifdef WINELIB
+    content->base           = ldt_copy[entry].base;
+    content->limit          = ldt_copy[entry].limit;
+    content->type           = SEGMENT_DATA;
+    content->seg_32bit      = 0;
+    content->read_only      = 0;
+    content->limit_in_pages = 0;
+#else  /* WINELIB */
+
+#ifdef linux
+    int size = (entry + 1) * 2 * sizeof(long);
+    long *buffer = (long *) malloc( size );
+    ret = modify_ldt( 0, buffer, size );
+    LDT_BytesToEntry( &buffer[entry*2], content );
+    free( buffer );
+#endif  /* linux */
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+    long buffer[2];
+    ret = i386_get_ldt( entry, (union descriptor *)buffer, 1 );
+    LDT_BytesToEntry( buffer, content );
+#endif  /* __NetBSD__ || __FreeBSD__ */
+
+#endif  /* WINELIB */
+
+    return ret;
+}
+
+
+/***********************************************************************
+ *           LDT_SetEntry
+ *
+ * Set an LDT entry.
+ */
+int LDT_SetEntry( int entry, ldt_entry *content )
+{
+    int ret = 0;
+
+    dprintf_ldt(stddeb,
+	  "LDT_SetEntry: entry=%04x base=%08lx limit=%05lx %s %d-bit flags=%c%c%c\n",
+          entry, content->base, content->limit,
+          content->limit_in_pages ? "pages" : "bytes",
+          content->seg_32bit ? 32 : 16,
+          content->read_only && (content->type & SEGMENT_CODE) ? '-' : 'r',
+          content->read_only || (content->type & SEGMENT_CODE) ? '-' : 'w',
+          (content->type & SEGMENT_CODE) ? 'x' : '-' );
+
+#ifndef WINELIB
+#ifdef linux
+    {
+        struct modify_ldt_ldt_s ldt_info;
+
+        memset( &ldt_info, 0, sizeof(ldt_info) );
+        ldt_info.entry_number   = entry;
+        ldt_info.base_addr      = content->base;
+        ldt_info.limit          = content->limit;
+        ldt_info.seg_32bit      = content->seg_32bit != 0;
+        ldt_info.contents       = content->type;
+        ldt_info.read_exec_only = content->read_only != 0;
+        ldt_info.limit_in_pages = content->limit_in_pages != 0;
+        ret = modify_ldt(1, &ldt_info, sizeof(ldt_info));
+    }
+#endif  /* linux */
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+    {
+        long d[2];
+
+        d[0] = ((content->base & 0x0000ffff) << 16) |
+                (content->limit & 0x0ffff);
+        d[1] = (content->base & 0xff000000) |
+               ((content->base & 0x00ff0000)>>16) |
+               (content->limit & 0xf0000) |
+               (content->type << 10) |
+               ((content->read_only == 0) << 9) |
+               ((content->seg_32bit != 0) << 22) |
+               ((content->limit_in_pages != 0) << 23) |
+               0xf000;
+        ret = i386_set_ldt(entry, (union descriptor *)d, 1);
+        if (ret < 0)
+        {
+            perror("i386_set_ldt");
+            fprintf(stderr,
+		"Did you reconfigure the kernel with \"options USER_LDT\"?\n");
+    	    exit(1);
+        }
+    }
+#endif  /* __NetBSD__ || __FreeBSD__ */
+#endif  /* ifndef WINELIB */
+
+    if (ret < 0) return ret;
+    ldt_copy[entry].base = content->base;
+    if (!content->limit_in_pages) ldt_copy[entry].limit = content->limit;
+    else ldt_copy[entry].limit = (content->limit << 12) | 0x0fff;
+    return ret;
+}
+
+
+/***********************************************************************
+ *           LDT_Print
+ *
+ * Print the content of the LDT on stdout.
+ */
+void LDT_Print()
+{
+    int i;
+
+#ifdef WINELIB
+    for (i = 0; i < LDT_SIZE; i++)
+    {
+        if (ldt_copy[i].base || ldt_copy[i].limit)
+        {
+            fprintf( stderr, "%04x: sel=%04x base=%08x limit=%05x\n",
+                     i, ENTRY_TO_SELECTOR(i),
+                     ldt_copy[i].base, ldt_copy[i].limit );
+        }
+    }
+#else  /* WINELIB */
+
+#ifdef linux
+    long buffer[2*LDT_SIZE];
+    ldt_entry content;
+
+    modify_ldt( 0, buffer, sizeof(buffer) );
+    for (i = 0; i < LDT_SIZE; i++)
+    {
+        LDT_BytesToEntry( &buffer[2*i], &content );
+        if (content.base || content.limit)
+        {
+            fprintf( stderr, "%04x: sel=%04x base=%08lx limit=%05lx %s type=%d\n",
+                    i, ENTRY_TO_SELECTOR(i),
+                    content.base, content.limit,
+                    content.limit_in_pages ? "(pages)" : "(bytes)",
+                    content.type );
+        }
+    }
+#endif  /* linux */
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+    long buffer[2*LDT_SIZE];
+    ldt_entry content;
+
+    i386_get_ldt( 0, (union descriptor *)buffer, LDT_SIZE );
+    for (i = 0; i < LDT_SIZE; i++)
+    {
+        LDT_BytesToEntry( buffer[2*i], &content );
+        if (content.base || content.limit)
+        {
+            fprintf( stderr, "%04x: sel=%04x base=%08lx limit=%05lx %s type=%d\n",
+                    i, ENTRY_TO_SELECTOR(i),
+                    content.base, content.limit,
+                    content.limit_in_pages ? "(pages)" : "(bytes)",
+                    content.type );
+        }
+    }
+#endif  /* __NetBSD__ || __FreeBSD__ */
+#endif  /* WINELIB */
+}
diff --git a/loader/ldtlib.c b/loader/ldtlib.c
deleted file mode 100644
index eb13508..0000000
--- a/loader/ldtlib.c
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef WINELIB
-/*
-static char RCSId[] = "$Id: ldtlib.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "stddebug.h"
-#include "debug.h"
-
-#ifdef linux
-#include <linux/unistd.h>
-#include <linux/head.h>
-#include <linux/ldt.h>
-
-_syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#include <machine/segments.h>
-
-extern int i386_get_ldt(int, union descriptor *, int);
-extern int i386_set_ldt(int, union descriptor *, int);
-
-struct segment_descriptor *
-make_sd(unsigned base, unsigned limit, int contents, int read_exec_only, int seg32, int inpgs)
-{
-        static long d[2];
-
-        d[0] = ((base & 0x0000ffff) << 16) |
-                (limit & 0x0ffff);
-        d[1] = (base & 0xff000000) |
-                ((base & 0x00ff0000)>>16) |
-                        (limit & 0xf0000) |
-                                (contents << 10) |
-                                        ((read_exec_only ^ 1) << 9) |
-                                                (seg32 << 22) |
-                                                        (inpgs << 23) |
-                                                                0xf000;
-        
-        return ((struct segment_descriptor *)d);
-}
-#endif
-        
-int
-get_ldt(void *buffer)
-{
-#ifdef linux
-    return modify_ldt(0, buffer, 32 * sizeof(struct modify_ldt_ldt_s));
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-    return i386_get_ldt(0, (union descriptor *)buffer, 32);
-#endif
-}
-
-int
-set_ldt_entry(int entry, unsigned long base, unsigned int limit,
-	      int seg_32bit_flag, int contents, int read_only_flag,
-	      int limit_in_pages_flag)
-{
-#ifdef linux
-    struct modify_ldt_ldt_s ldt_info;
-
-    ldt_info.entry_number   = entry;
-    ldt_info.base_addr      = base;
-    ldt_info.limit          = limit;
-    ldt_info.seg_32bit      = seg_32bit_flag;
-    ldt_info.contents       = contents;
-    ldt_info.read_exec_only = read_only_flag;
-    ldt_info.limit_in_pages = limit_in_pages_flag;
-#ifdef NEW_LDT_STRUCT
-    ldt_info.seg_not_present = 0;
-#endif
-
-    return modify_ldt(1, &ldt_info, sizeof(ldt_info));
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-    struct segment_descriptor *sd;
-    int ret;
-    
-    dprintf_ldt(stddeb,
-	  "set_ldt_entry: entry=%x base=%x limit=%x%s %s-bit contents=%d %s\n",
-          entry, base, limit, limit_in_pages_flag?"-pages":"",
-          seg_32bit_flag?"32":"16",
-          contents, read_only_flag?"read-only":"");
-
-    sd = make_sd(base, limit, contents, read_only_flag, seg_32bit_flag, limit_in_pages_flag);
-    ret = i386_set_ldt(entry, (union descriptor *)sd, 1);
-    if (ret < 0) {
-            perror("i386_set_ldt");
-            fprintf(stderr,
-		"Did you reconfigure the kernel with \"options USER_LDT\"?\n");
-    	    exit(1);
-    }
-
-    return ret;
-    
-#endif
-}
-#endif /* ifndef WINELIB */
diff --git a/loader/library.c b/loader/library.c
index 4b33bdc..e610d3c 100644
--- a/loader/library.c
+++ b/loader/library.c
@@ -11,7 +11,6 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include "neexe.h"
-#include "segmem.h"
 #include "dlls.h"
 #include "if1632.h"
 #include "wineopts.h"
@@ -436,7 +435,8 @@
 #ifdef WINELIB
     WINELIB_UNIMP ("GetProcAddress");
 #else
-    int		sel, addr, ret;
+    int		addr, ret;
+    WORD        sel;
     register struct w_files *w = wine_files;
     int 	ordinal, len;
     char 	* cpnt;
diff --git a/loader/main.c b/loader/main.c
index 01136c8..6fa103e 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -11,12 +11,12 @@
 #include <string.h>
 #include <errno.h>
 #include "neexe.h"
-#include "segmem.h"
 #include "dos_fs.h"
 #include "dlls.h"
 #include "library.h"
 #include "windows.h"
 #include "wineopts.h"
+#include "wine.h"
 #include "task.h"
 #include "prototypes.h"
 #include "options.h"
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 14914b7..0c18f4d 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -12,7 +12,6 @@
 #include <string.h>
 #include <errno.h>
 #include "neexe.h"
-#include "segmem.h"
 #include "dlls.h"
 #include "windows.h"
 #include "arch.h"
@@ -82,20 +81,20 @@
  */
 int NE_FixupSegment(struct w_files *wpnt, int segment_num)
 {
-    struct segment_descriptor_s *selector_table = wpnt->ne->selector_table;
+    WORD *selector_table = wpnt->ne->selector_table;
+    WORD selector, sel, offset;
     struct relocation_entry_s *rep, *rep1;
     struct ne_segment_table_entry_s *seg;
-    struct segment_descriptor_s *sel;
     int status, ordinal, i, n_entries, additive;
     unsigned short *sp;
-    unsigned int selector, address, next_addr;
+    unsigned int address;
     unsigned char dll_name[257], func_name[257];
 
     seg = &wpnt->ne->seg_table[segment_num];
-    sel = &selector_table[segment_num];
+    sel = selector_table[segment_num];
 
-    dprintf_fixup(stddeb, "Segment fixups for %s, segment %d, selector %x\n", 
-                  wpnt->name, segment_num, (int) sel->base_addr >> 16);
+    dprintf_fixup(stddeb, "Segment fixups for %s, segment %d, selector %04x\n", 
+                  wpnt->name, segment_num, sel );
 
     if ((seg->seg_data_offset == 0) ||
 	!(seg->seg_flags & NE_SEGFLAGS_RELOC_DATA))
@@ -128,13 +127,14 @@
 	/*
 	 * Get the target address corresponding to this entry.
 	 */
-	additive = 0;
+
+	/* If additive, there is no target chain list. Instead, add source
+	   and target */
+	additive = rep->relocation_type & NE_RELFLAG_ADDITIVE;
+	rep->relocation_type &= 0x3;
 	
 	switch (rep->relocation_type)
 	{
-	  case NE_RELTYPE_ORDINALADD:
-	    additive = 1;
-	    
 	  case NE_RELTYPE_ORDINAL:
 	    if (NE_GetModuleName(wpnt, rep->target1,
 			      dll_name) == NULL)
@@ -160,9 +160,6 @@
 		   dll_name, ordinal, selector, address);
 	    break;
 	    
-	  case NE_RELTYPE_NAMEADD:
-	    additive = 1;
-	    
 	  case NE_RELTYPE_NAME:
 	    if (NE_GetModuleName(wpnt, rep->target1, dll_name) == NULL) {
 	        fprintf(stderr,"NE_RELTYPE_NAME failed");
@@ -189,7 +186,6 @@
 	    break;
 	    
 	  case NE_RELTYPE_INTERNAL:
-    	  case NE_RELTYPE_INT1:
 	    if (rep->target1 == 0x00ff)
 	    {
 		address  = GetEntryPointFromOrdinal(wpnt, rep->target2);
@@ -198,7 +194,7 @@
 	    }
 	    else
 	    {
-		selector = selector_table[rep->target1-1].selector;
+		selector = selector_table[rep->target1-1];
 		address  = rep->target2;
 	    }
 	    
@@ -206,7 +202,7 @@
 			  i + 1, selector, address);
 	    break;
 
-	  case 7:
+	  case NE_RELTYPE_OSFIXUP:
 	    /* Relocation type 7:
 	     *
 	     *    These appear to be used as fixups for the Windows
@@ -234,69 +230,70 @@
 	    return -1;
 	}
 
-	/*
-	 * Stuff the right size result in.
-	 */
-	sp = (unsigned short *) ((char *) sel->base_addr + rep->offset);
-	if (additive)
-	{
-	    if (FindDLLTable(dll_name) == NULL)
-		additive = 2;
-	    dprintf_fixup(stddeb,
-		   "%d: ADDR TYPE %d,  TYPE %d,  OFFSET %04x,  ",
-		   i + 1, rep->address_type, rep->relocation_type, 
-		   rep->offset);
-	    dprintf_fixup(stddeb,"TARGET %04x %04x\n", 
-		    rep->target1, rep->target2);
-	    dprintf_fixup(stddeb, "    Additive = %d\n", additive);
-	}
-	
+        /* I'm not sure why a DLL entry point fixup could be additive.
+           Old code used to ignore additive if the target is a built-in
+           DLL. This doesn't seem to work for __AHSHIFT */
+        if (additive && FindDLLTable(dll_name) != NULL)
+            dprintf_fixup(stddeb,"Additive for builtin???\n"
+                          "%d: ADDR TYPE %d, TYPE %d, OFFSET %04x, "
+                          "TARGET %04x %04x\n",
+                          i+1, rep->address_type, rep->relocation_type,
+                          rep->offset, rep->target1, rep->target2);
+
+	offset = rep->offset;
+
 	switch (rep->address_type)
 	{
 	  case NE_RADDR_LOWBYTE:
-	    dprintf_fixup(stddeb,"Unhandled address type NE_RADDR_LOWBYTE\n");
-	    return -1;
+            do {
+                sp = PTR_SEG_OFF_TO_LIN( sel, offset );
+                dprintf_fixup(stddeb,"    %04x:%04x:%04x BYTE%s\n",
+                              sel, offset, *sp, additive ? " additive":"");
+                offset = *sp;
+		if(additive)
+                    *(unsigned char*)sp = (unsigned char)(address & 0xFF);
+		else
+                    *(unsigned char*)sp = (unsigned char)((address+offset) & 0xFF);
+            }
+            while (offset != 0xffff && !additive);
+            break;
+
 	  case NE_RADDR_OFFSET16:
 	    do {
-		dprintf_fixup(stddeb,"    %04x:%04x:%04x OFFSET16\n",
-		       (unsigned int) sp >> 16, (int) sp & 0xFFFF, *sp);
-		next_addr = *sp;
+                sp = PTR_SEG_OFF_TO_LIN( sel, offset );
+		dprintf_fixup(stddeb,"    %04x:%04x:%04x OFFSET16%s\n",
+                              sel, offset, *sp, additive ? " additive" : "" );
+		offset = *sp;
 		*sp = (unsigned short) address;
-		if (additive == 2)
-		    *sp += next_addr;
-		sp = (unsigned short *) ((char *) sel->base_addr + next_addr);
+		if (additive) *sp += offset;
 	    } 
-	    while (next_addr != 0xffff && !additive);
-
+	    while (offset != 0xffff && !additive);
 	    break;
 	    
 	  case NE_RADDR_POINTER32:
 	    do {
-		dprintf_fixup(stddeb,"    %04x:%04x:%04x POINTER32\n",
-		       (unsigned int) sp >> 16, (int) sp & 0xFFFF, *sp);
-		next_addr = *sp;
-		*sp     = (unsigned short) address;
-		if (additive == 2)
-		    *sp += next_addr;
-		*(sp+1) = (unsigned short) selector;
-		sp = (unsigned short *) ((char *) sel->base_addr + next_addr);
+                sp = PTR_SEG_OFF_TO_LIN( sel, offset );
+		dprintf_fixup(stddeb,"    %04x:%04x:%04x POINTER32%s\n",
+                              sel, offset, *sp, additive ? " additive" : "" );
+		offset = *sp;
+		*sp    = (unsigned short) address;
+		if (additive) *sp += offset;
+		*(sp+1) = selector;
 	    } 
-	    while (next_addr != 0xffff && !additive);
-
+	    while (offset != 0xffff && !additive);
 	    break;
 	    
 	  case NE_RADDR_SELECTOR:
 	    do {
-		dprintf_fixup(stddeb,"    %04x:%04x:%04x SELECTOR\n",
-		       (unsigned int) sp >> 16, (int) sp & 0xFFFF, *sp);
-		next_addr = *sp;
-		*sp     = (unsigned short) selector;
-		sp = (unsigned short *) ((char *) sel->base_addr + next_addr);
-		if (rep->relocation_type == NE_RELTYPE_INT1) 
-		    break;
+                sp = PTR_SEG_OFF_TO_LIN( sel, offset );
+		dprintf_fixup(stddeb,"    %04x:%04x:%04x SELECTOR%s\n",
+                              sel, offset, *sp, additive ? " additive" : "" );
+		offset = *sp;
+		*sp    = (unsigned short) selector;
+		if(additive)
+                    fprintf(stderr,"Additive selector, please report\n");
 	    } 
-	    while (next_addr != 0xffff && !additive);
-
+	    while (offset != 0xffff && !additive);
 	    break;
 	    
 	  default:
@@ -331,10 +328,10 @@
     WIN_StackSize = wpnt->ne->ne_header->stack_length;
     WIN_HeapSize = wpnt->ne->ne_header->local_heap_length;
 
-    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;
 
     return CallToInit16(cs_reg << 16 | ip_reg, ss_reg << 16 | sp_reg, ds_reg);
@@ -358,15 +355,15 @@
   		exit(1);
 	    } else { /* DATA NONE DLL */
 		ds_reg = current_exe->ne->selector_table[
-		        current_exe->ne->ne_header->auto_data_seg-1].selector;
+		        current_exe->ne->ne_header->auto_data_seg-1];
 		cx_reg = 0;
 	    } else { /* DATA SINGLE DLL */
 		    ds_reg = wpnt->ne->selector_table[wpnt->ne->
-					  ne_header->auto_data_seg-1].selector;
+					  ne_header->auto_data_seg-1];
 		    cx_reg = wpnt->ne->ne_header->local_heap_length;
   	    }
   
-  	    cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1].selector;
+  	    cs_reg = wpnt->ne->selector_table[wpnt->ne->ne_header->cs-1];
   	    ip_reg = wpnt->ne->ne_header->ip;
   
             di_reg = wpnt->hinstance;
@@ -423,8 +420,7 @@
         wpnt->hinstance=current_nodata++;
     } else
     wpnt->hinstance = (wpnt->ne->
-		       selector_table[wpnt->ne->ne_header->auto_data_seg-1].
-		       selector);
+		       selector_table[wpnt->ne->ne_header->auto_data_seg-1]);
     if (wpnt->hinstance == 0)
     	wpnt->hinstance = 0xf000;
 #endif
diff --git a/loader/ne_resource.c b/loader/ne_resource.c
index 9a3e56d..6114d95 100644
--- a/loader/ne_resource.c
+++ b/loader/ne_resource.c
@@ -10,12 +10,12 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include "windows.h"
+#include "ldt.h"
 #include "neexe.h"
 #include "peexe.h"
 #include "arch.h"
 #include "dlls.h"
 #include "library.h"
-#include "heap.h"
 #include "resource.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -75,7 +75,7 @@
 		read(wpnt->fd, &len, sizeof(len));
 		while (len)
 		{
-		    new = (RESNAMTAB *) GlobalQuickAlloc(sizeof(*new));
+		    new = (RESNAMTAB *) GlobalLock(GlobalAlloc(GMEM_MOVEABLE,sizeof(*new)));
 		    new->next = top;
 		    top = new;
 
@@ -337,12 +337,13 @@
 /**********************************************************************
  *			NE_FindResource	[KERNEL.60]
  */
-int NE_FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name,
-		RESOURCE *r)
+int NE_FindResource(HANDLE instance, SEGPTR resource_name, SEGPTR type_name,
+                    RESOURCE *r)
 {
     int type, x;
+    char *type_name_ptr, *resource_name_ptr;
 
-    dprintf_resource(stddeb, "NE_FindResource hInst=%04X typename=%p resname=%p\n", 
+    dprintf_resource(stddeb, "NE_FindResource hInst=%04X typename=%08lx resname=%08lx\n", 
 			instance, type_name, resource_name);
 
     r->size = r->offset = 0;
@@ -351,30 +352,32 @@
     if (r->wpnt->ne->resnamtab == NULL)
 	NE_LoadNameTable(r->wpnt);
 
-    if (((int) type_name & 0xffff0000) == 0)
+    if (HIWORD(type_name) == 0)
 	type = (int) type_name;
     else {
-    	if (type_name[0] == '\0')
+        type_name_ptr = PTR_SEG_TO_LIN( type_name );
+    	if (type_name_ptr[0] == '\0')
 		type = -1;
-    	if (type_name[0] == '#')
-		type = atoi(type_name + 1);
+    	if (type_name_ptr[0] == '#')
+		type = atoi(type_name_ptr + 1);
 	    else
-    		type = (int) type_name;
+    		type = (int) type_name_ptr;
     }
 
-    if (((int) resource_name & 0xffff0000) == 0)
-	x = FindResourceByNumber(r, type, (int) resource_name | 0x8000);
+    if (HIWORD(resource_name) == 0)
+	x = FindResourceByNumber(r, type, LOWORD(resource_name) | 0x8000);
     else {
-	if (resource_name[0] == '\0')
+        resource_name_ptr = PTR_SEG_TO_LIN( resource_name );
+	if (resource_name_ptr[0] == '\0')
 		x = FindResourceByNumber(r, type, -1);
-	if (resource_name[0] == '#')
-		x = FindResourceByNumber(r, type, atoi(resource_name + 1));
+	if (resource_name_ptr[0] == '#')
+		x = FindResourceByNumber(r, type, atoi(resource_name_ptr + 1));
 	else
-		x = FindResourceByName(r, type, resource_name);
+		x = FindResourceByName(r, type, resource_name_ptr);
     }
     if (x == -1) {
-        printf("NE_FindResource hInst=%04X typename=%08X resname=%08X not found!\n", 
-		instance, (int) type_name, (int) resource_name);
+        printf("NE_FindResource hInst=%04x typename=%p resname=%p not found!\n", 
+		instance, type_name_ptr, resource_name_ptr);
 	return 0;
     }
     return 1;
diff --git a/loader/pe_resource.c b/loader/pe_resource.c
index 9efec34..181b90b 100644
--- a/loader/pe_resource.c
+++ b/loader/pe_resource.c
@@ -14,6 +14,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include "windows.h"
+#include "ldt.h"
 #include "neexe.h"
 #include "peexe.h"
 #include "dlls.h"
@@ -124,18 +125,26 @@
  *			PE_FindResource	[KERNEL.60]
  */
 int
-PE_FindResource(HANDLE instance, LPSTR resource_name, LPSTR type_name,
+PE_FindResource(HANDLE instance, SEGPTR resource_name, SEGPTR type_name,
 		RESOURCE *r)
 {
 	dprintf_resource(stddeb, "PE_FindResource hInst=%04X typename=%08X resname=%08X\n", 
 		instance, (int) type_name, (int) resource_name);
-	if (HIWORD((DWORD)resource_name)) 
-		if (resource_name[0] == '#')
-			resource_name = (LPSTR) atoi(resource_name + 1);
-
-	if (HIWORD((DWORD)type_name)) 
-		if (type_name[0] == '#')
-			type_name = (LPSTR) atoi(type_name + 1);
-
+	if (HIWORD(resource_name))
+        {
+                char *resource_name_ptr = PTR_SEG_TO_LIN( resource_name );
+		if (resource_name_ptr[0] == '#')
+			resource_name = (SEGPTR) atoi(resource_name_ptr + 1);
+                else
+                    resource_name = (SEGPTR)resource_name_ptr;
+        }
+	if (HIWORD(type_name)) 
+        {
+                char *type_name_ptr = PTR_SEG_TO_LIN( type_name );
+		if (type_name_ptr[0] == '#')
+			type_name = (SEGPTR) atoi(type_name_ptr + 1);
+                else
+                        type_name = (SEGPTR) type_name_ptr;
+        }
 	return find_type(r->wpnt->pe->pe_resource, resource_name, type_name,r);
 }
diff --git a/loader/resource.c b/loader/resource.c
index 1da3260..0446393 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -27,19 +27,19 @@
 
 RESOURCE *Top = NULL;
 
-extern int NE_FindResource(HANDLE, LPSTR, LPSTR, RESOURCE *);
-extern int PE_FindResource(HANDLE, LPSTR, LPSTR, RESOURCE *);
+extern int NE_FindResource(HANDLE, SEGPTR, SEGPTR, RESOURCE *);
+extern int PE_FindResource(HANDLE, SEGPTR, SEGPTR, RESOURCE *);
 
 #define PrintId(name) \
 	if (HIWORD((DWORD)name)) \
-		printf(", %s", name); \
-	else \
-		printf(", #%d", (int) name); 
+		printf(", '%s'", (char *)PTR_SEG_TO_LIN(name)); \
+  	else \
+		printf(", #%d", LOWORD(name)); 
 
 /**********************************************************************
  *			FindResource	[KERNEL.60]
  */
-HANDLE FindResource(HANDLE instance, LPSTR name, LPSTR type)
+HANDLE FindResource(HANDLE instance, SEGPTR name, SEGPTR type)
 {
 	int status;
 	RESOURCE *r;
@@ -64,14 +64,14 @@
 	r->rsc_mem = 0;
 	r->count = 0;
 	if (HIWORD((DWORD)name))
-		r->name = strdup(name);
+		r->name = strdup(PTR_SEG_TO_LIN(name));
 	else
-		r->name = name;
+		r->name = (LPSTR)name;
 
 	if (HIWORD((DWORD)type))
-		r->type = strdup(type);
+		r->type = strdup(PTR_SEG_TO_LIN(type));
 	else
-		r->type = type;
+		r->type = (LPSTR)type;
 
 	r->wpnt = GetFileInfo(instance);
 	r->fd = dup(r->wpnt->fd);
@@ -178,7 +178,7 @@
 	return 0;
     
     h = r->rsc_mem = AllocResource(instance, hResInfo, 0);
-    image = GlobalLinearLock(h);
+    image = GlobalLock(h);
     image_size = r->size;
     fd = AccessResource(instance, hResInfo);
 
@@ -189,7 +189,7 @@
     }
     r->count++;
     close(fd);
-    GlobalLinearUnlock(h);
+    GlobalUnlock(h);
     GlobalUnlock(hResInfo);
     return h;
 }
@@ -197,6 +197,14 @@
 /**********************************************************************
  *				LockResource	[KERNEL.62]
  */
+
+/* 16-bit version */
+SEGPTR WIN16_LockResource(HANDLE hResData)
+{
+    return WIN16_GlobalLock(hResData);
+}
+
+/* 32-bit version */
 LPSTR LockResource(HANDLE hResData)
 {
     return GlobalLock(hResData);
@@ -302,15 +310,15 @@
  *			RSC_LoadResource
  */
 HANDLE
-RSC_LoadResource(int instance, LPSTR rsc_name, LPSTR type, int *image_size_ret)
+RSC_LoadResource(int instance, SEGPTR rsc_name, SEGPTR type, int *image_size_ret)
 {
 	HANDLE hResInfo;
 	RESOURCE *r;
 
-	dprintf_resource(stddeb, "RSC_LoadResource: instance = %04x, name = %08x, type = %08x\n",
-	   instance, (int) rsc_name, (int) type);
+	dprintf_resource(stddeb, "RSC_LoadResource: instance = %04x, name = %08lx, type = %08lx\n",
+	   instance, rsc_name, type);
 
-	if ((hResInfo = FindResource(instance, rsc_name, (LPSTR) type)) == (HANDLE) NULL) {
+	if ((hResInfo = FindResource(instance, rsc_name, type)) == (HANDLE) NULL) {
 		return (HANDLE)NULL;
 	}
 	r = (RESOURCE *)GlobalLock(hResInfo);
@@ -324,7 +332,7 @@
 /**********************************************************************
  *			LoadIcon [USER.174]
  */
-HICON LoadIcon(HANDLE instance, LPSTR icon_name)
+HICON LoadIcon( HANDLE instance, SEGPTR icon_name )
 {
     HICON 	hIcon;
     HANDLE 	rsc_mem;
@@ -338,11 +346,12 @@
     HDC 	hdc;
     int 	image_size;
 
-    if(debugging_resource){
-	printf("LoadIcon(%04X", instance);
-	PrintId(icon_name);
-	printf(")\n");
-    }
+    if (HIWORD(icon_name))
+        dprintf_resource( stddeb, "LoadIcon: %04x '%s'\n",
+                          instance, (char *)PTR_SEG_TO_LIN( icon_name ) );
+    else
+        dprintf_resource( stddeb, "LoadIcon: %04x %04x\n",
+                          instance, LOWORD(icon_name) );
     
     if (!instance)
     {
@@ -351,10 +360,10 @@
     }
 
     if (!(hdc = GetDC(GetDesktopWindow()))) return 0;
-    rsc_mem = RSC_LoadResource(instance, icon_name, (LPSTR) NE_RSCTYPE_GROUP_ICON, 
-			       &image_size);
+    rsc_mem = RSC_LoadResource(instance, icon_name,
+                               (SEGPTR) NE_RSCTYPE_GROUP_ICON, &image_size);
     if (rsc_mem == (HANDLE)NULL) {
-	printf("LoadIcon / Icon %04X not Found !\n", (int) icon_name);
+	printf("LoadIcon / Icon %08x not Found !\n", (int) icon_name);
 	ReleaseDC(GetDesktopWindow(), hdc); 
 	return 0;
 	}
@@ -377,11 +386,11 @@
     height = lpicodesc->Height;
     GlobalUnlock(rsc_mem);
     GlobalFree(rsc_mem);
-    rsc_mem = RSC_LoadResource(instance, 
-    	MAKEINTRESOURCE(lpicodesc->icoDIBOffset), 
-    	(LPSTR) NE_RSCTYPE_ICON, &image_size);
+    rsc_mem = RSC_LoadResource( instance, 
+                                MAKEINTRESOURCE(lpicodesc->icoDIBOffset), 
+                                (SEGPTR) NE_RSCTYPE_ICON, &image_size );
     if (rsc_mem == (HANDLE)NULL) {
-	printf("LoadIcon / Icon %04X Bitmaps not Found !\n", (int) icon_name);
+	printf("LoadIcon / Icon %08lx Bitmaps not Found !\n", icon_name );
 	ReleaseDC(GetDesktopWindow(), hdc); 
 	return 0;
 	}
@@ -503,7 +512,7 @@
 /**********************************************************************
  *			LoadAccelerators	[USER.177]
  */
-HANDLE LoadAccelerators(HANDLE instance, LPSTR lpTableName)
+HANDLE LoadAccelerators(HANDLE instance, SEGPTR lpTableName)
 {
     HANDLE 	hAccel;
     HANDLE 	rsc_mem;
@@ -511,18 +520,17 @@
     ACCELHEADER	*lpAccelTbl;
     int 	i, image_size, n;
 
-    if(debugging_accel){
-	printf("LoadAccelerators(%04X", instance);
-	PrintId(lpTableName);
-	printf(")\n");
-    }
+    if (HIWORD(lpTableName))
+        dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n",
+                      instance, (char *)PTR_SEG_TO_LIN( lpTableName ) );
+    else
+        dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n",
+                       instance, LOWORD(lpTableName) );
 
-    rsc_mem = RSC_LoadResource(instance, lpTableName, (LPSTR) NE_RSCTYPE_ACCELERATOR, 
-			       &image_size);
+    rsc_mem = RSC_LoadResource( instance, lpTableName,
+                                (SEGPTR) NE_RSCTYPE_ACCELERATOR, &image_size );
     if (rsc_mem == (HANDLE)NULL) {
-	printf("LoadAccelerators(%04X", instance);
-	PrintId(lpTableName);
-	printf(") not found !\n");
+	printf("LoadAccelerators(%08lx) not found!\n", lpTableName );
 	return 0;
 	}
     lp = (BYTE *)GlobalLock(rsc_mem);
@@ -624,8 +632,8 @@
     dprintf_resource(stddeb, "LoadString: instance = %04x, id = %d, buffer = %08x, "
 	   "length = %d\n", instance, resource_id, (int) buffer, buflen);
 
-    hmem = RSC_LoadResource(instance, (char *) ((resource_id >> 4) + 1),
-			    (LPSTR) NE_RSCTYPE_STRING, &rsc_size);
+    hmem = RSC_LoadResource(instance, (SEGPTR)((resource_id >> 4) + 1),
+			    (SEGPTR) NE_RSCTYPE_STRING, &rsc_size );
     if (hmem == 0)
 	return 0;
     
@@ -656,33 +664,34 @@
 /**********************************************************************
  *			LoadMenu		[USER.150]
  */
-HMENU LoadMenu(HINSTANCE instance, char *menu_name)
+HMENU LoadMenu( HINSTANCE instance, SEGPTR menu_name )
 {
-	HMENU     		hMenu;
-	HANDLE		hMenu_desc;
-	MENU_HEADER 	*menu_desc;
+    HMENU     		hMenu;
+    HANDLE		hMenu_desc;
+    MENU_HEADER 	*menu_desc;
 
-	if(debugging_menu){
-	printf("LoadMenu(%04X", instance);
-	PrintId(menu_name);
-	printf(")\n");
-	}
-	if (menu_name == NULL)
-		return 0;
+    if (HIWORD(menu_name))
+        dprintf_resource( stddeb, "LoadMenu(%04x,'%s')\n",
+                          instance, (char *)PTR_SEG_TO_LIN( menu_name ) );
+    else
+        dprintf_resource( stddeb, "LoadMenu(%04x,%04x)\n",
+                          instance, LOWORD(menu_name) );
 
-	if ((hMenu_desc = RSC_LoadResource(instance, menu_name, (LPSTR) NE_RSCTYPE_MENU, NULL)) == (HANDLE) NULL)
-		return 0;
+    if (!menu_name) return 0;
+
+    if (!(hMenu_desc = RSC_LoadResource( instance, menu_name,
+                                         (SEGPTR) NE_RSCTYPE_MENU, NULL )))
+        return 0;
 	
-	menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc);
-	hMenu = LoadMenuIndirect((LPSTR)menu_desc);
-	return hMenu;
+    menu_desc = (MENU_HEADER *) GlobalLock(hMenu_desc);
+    hMenu = LoadMenuIndirect((LPSTR)menu_desc);
+    return hMenu;
 }
 
 /**********************************************************************
  *					LoadBitmap
  */
-HBITMAP 
-LoadBitmap(HANDLE instance, LPSTR bmp_name)
+HBITMAP LoadBitmap( HANDLE instance, SEGPTR bmp_name )
 {
     HBITMAP hbitmap;
     HANDLE rsc_mem;
@@ -691,11 +700,12 @@
     int image_size;
     int size;
     
-    if(debugging_resource){
-	printf("LoadBitmap(%04X", instance);
-	PrintId(bmp_name);
-	printf(")\n");
-    }
+    if (HIWORD(bmp_name))
+        dprintf_resource( stddeb, "LoadBitmap(%04x,'%s')\n",
+                          instance, (char *)PTR_SEG_TO_LIN( bmp_name ) );
+    else
+        dprintf_resource( stddeb, "LoadBitmap(%04x,%04x)\n",
+                          instance, LOWORD( bmp_name ) );
 
     if (!instance)
     {
@@ -703,20 +713,19 @@
         return OBM_LoadBitmap( LOWORD((int)bmp_name) );
     }
 
-    rsc_mem = RSC_LoadResource(instance, bmp_name, (LPSTR) NE_RSCTYPE_BITMAP, 
+    rsc_mem = RSC_LoadResource(instance, bmp_name, (SEGPTR) NE_RSCTYPE_BITMAP, 
 			       &image_size);
     if (rsc_mem == (HANDLE)NULL) {
-	printf("LoadBitmap(%04X", instance);
-	PrintId(bmp_name);
-	printf(") NOT found!\n");
+	printf("LoadBitmap(%04x,%08lx)\n", instance, bmp_name);
 	return 0;
 	}
-    lp = (long *) GlobalLinearLock(rsc_mem);
+    lp = (long *) GlobalLock(rsc_mem);
     if (lp == NULL)
     {
 	GlobalFree(rsc_mem);
 	return 0;
     }
+
     if (!(hdc = GetDC(0))) lp = NULL;
     size = CONV_LONG (*lp);
     if (size == sizeof(BITMAPCOREHEADER)){
diff --git a/loader/selector.c b/loader/selector.c
index 7447e07..a8e6871 100644
--- a/loader/selector.c
+++ b/loader/selector.c
@@ -1,8 +1,10 @@
-#ifndef WINELIB
 /*
-static char RCSId[] = "$Id: selector.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-*/
+ * Selector manipulation functions
+ *
+ * Copyright 1993 Robert J. Amstadt
+ * Copyright 1995 Alexandre Julliard
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -10,7 +12,9 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <errno.h>
+
+#ifndef WINELIB
+
 #ifdef __linux__
 #include <sys/mman.h>
 #include <linux/unistd.h>
@@ -23,54 +27,32 @@
 #include <sys/mman.h>
 #include <machine/segments.h>
 #endif
+
+#include "windows.h"
+#include "ldt.h"
+#include "wine.h"
+
 #include "dlls.h"
 #include "neexe.h"
-#include "segmem.h"
-#include "wine.h"
 #include "if1632.h"
-#include "windows.h"
 #include "prototypes.h"
 #include "stddebug.h"
 /* #define DEBUG_SELECTORS */
 #include "debug.h"
 
 
-#ifdef linux
-#define DEV_ZERO
-#ifdef __ELF__
-#define  UTEXTSEL 0x0f
-#else
-#define UTEXTSEL 0x23
-#endif
-#endif
+#define MAX_ENV_SIZE 16384  /* Max. environment size (ought to be dynamic) */
 
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#define PAGE_SIZE getpagesize()
-#define MODIFY_LDT_CONTENTS_DATA	0
-#define MODIFY_LDT_CONTENTS_STACK	1
-#define MODIFY_LDT_CONTENTS_CODE	2
-#define UTEXTSEL 0x1f
-#endif
-
-static SEGDESC * EnvironmentSelector =  NULL;
-static SEGDESC * PSP_Selector = NULL;
-SEGDESC * MakeProcThunks = NULL;
-unsigned short PSPSelector;
-unsigned char ran_out = 0;
-int LastUsedSelector = FIRST_SELECTOR - 1;
+static HANDLE EnvironmentHandle = 0;
+WORD PSPSelector = 0;
 
 #define MAX_SELECTORS (512 * 2)
 
 int max_selectors = 0;
-unsigned short* SelectorMap;
-SEGDESC* Segments;
 
-#ifdef DEV_ZERO
-    static FILE *zfile = NULL;
-#endif    
 
-extern void KERNEL_Ordinal_102();
-extern void UNIXLIB_Ordinal_0();
+extern void KERNEL_Ordinal_1();    /* FatalExit() */
+extern void KERNEL_Ordinal_102();  /* Dos3Call() */
 extern char WindowsPath[256];
 
 extern char **Argv;
@@ -80,6 +62,8 @@
 unsigned int 
 GetEntryPointFromOrdinal(struct w_files * wpnt, int ordinal);
 
+#if 0
+
 
 /**********************************************************************
  *					InitSelectors
@@ -113,526 +97,9 @@
 #endif
     }
 
-/**********************************************************************
- *					FindUnusedSelectors
- */
-int
-FindUnusedSelectors(int n_selectors)
-{
-    int i;
-    int n_found;
 
-    n_found = 0;
-    for (i = LastUsedSelector + 1; i != LastUsedSelector; i++)
-    {
-	if (i >= max_selectors)
-	{
-	    int j;
-	    max_selectors += MAX_SELECTORS;
-	    dprintf_selectors(stddeb, "Expanding no of segments to %d.\n", 
-			      max_selectors);
-            SelectorMap =
-	      realloc(SelectorMap, max_selectors * sizeof(unsigned short));
-            Segments = realloc(Segments, max_selectors * sizeof(SEGDESC));
-	    if (!SelectorMap || !Segments)
-	      {
-		fprintf(stderr,
-			"FindUnusedSelectors: Out of memory! Exiting\n");
-		exit (-1);
-	      }
-            for (j = max_selectors - MAX_SELECTORS; j < max_selectors; j++)
-	      SelectorMap[j] = 0;
-	}
+#endif /* 0 */
 
-	if (SelectorMap[i] && n_found) n_found=0;
-	
-	if (!SelectorMap[i] && ++n_found == n_selectors)
-	    break;
-    }
-    
-    if (i == LastUsedSelector)
-	return 0;
-
-    LastUsedSelector = i;
-    return i - n_selectors + 1;
-}
-
-#ifdef HAVE_IPC
-/**********************************************************************
- *					IPCCopySelector
- *
- * Created a shared memory copy of a segment:
- *
- *	- at a new selector location (if "new" is a 16-bit value)
- *	- at an arbitrary memory location (if "new" is a 32-bit value)
- */
-int
-IPCCopySelector(int i_old, unsigned long new, int swap_type)
-{
-    SEGDESC *s_new, *s_old;
-    int i_new;
-    void *base_addr;
-
-    s_old  = &Segments[i_old];
-
-    if (new & 0xffff0000)
-    {
-	/**************************************************************
-	 * Let's set the address parameter for no segment.
-	 */
-	i_new = -1;
-	s_new = NULL;
-	base_addr = (void *) new;
-    }
-    else
-    {
-	/***************************************************************
-	 * We need to fill in the segment descriptor for segment "new".
-	 */
-	i_new = new;
-	s_new = &Segments[i_new];
-
-	SelectorMap[i_new] = i_new;
-    
-	s_new->selector  = (i_new << __AHSHIFT) | 0x0007;
-	s_new->base_addr = (void *) ((long) s_new->selector << 16);
-	s_new->length    = s_old->length;
-	s_new->flags     = s_old->flags;
-	s_new->owner     = s_old->owner;
-	if (swap_type)
-	{
-	    if (s_old->type == MODIFY_LDT_CONTENTS_DATA)
-		s_new->type = MODIFY_LDT_CONTENTS_CODE;
-	    else
-		s_new->type = MODIFY_LDT_CONTENTS_DATA;
-	}
-	else
-	    s_new->type = s_old->type;
-
-	base_addr = s_new->base_addr;
-    }
-
-    /******************************************************************
-     * If we don't have a shared memory key for s_old, then we need
-     * to get one.  In this case, we'll also have to copy the data
-     * to protect it.
-     */
-    if (s_old->shm_key == -1)
-    {
-	s_old->shm_key = shmget(IPC_PRIVATE, s_old->length, IPC_CREAT | 0600);
-	if (s_old->shm_key == -1)
-	{
-	    if (s_new) {
-		memset(s_new, 0, sizeof(*s_new));
-		s_new->shm_key = -1;
-	    }
-	    return -1;
-	}
-	if (shmat(s_old->shm_key, base_addr, 0) == (char *) -1)
-	{
-	    if (s_new) {
-		memset(s_new, 0, sizeof(*s_new));
-		s_new->shm_key = -1;
-	    }
-	    shmctl(s_old->shm_key, IPC_RMID, NULL);
-	    return -1;
-	}
-	memcpy(base_addr, s_old->base_addr, s_old->length);
-	munmap(s_old->base_addr, 
-	       ((s_old->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)));
-	shmat(s_old->shm_key, s_old->base_addr, 0);
-    }
-    /******************************************************************
-     * If have shared memory key s_old, then just attach the new
-     * address.
-     */
-    else
-    {
-	if (shmat(s_old->shm_key, base_addr, 0) == (char *) -1)
-	{
-	    if (s_new) {
-		memset(s_new, 0, sizeof(*s_new));
-		s_new->shm_key = -1;
-	    }
-	    return -1;
-	}
-    }
-
-    /******************************************************************
-     * If we are creating a new segment, then we also need to update
-     * the LDT to include the new selector.  In this return the
-     * new selector.
-     */
-    if (s_new)
-    {
-	s_new->shm_key = s_old->shm_key;
-
-	if (set_ldt_entry(i_new, (unsigned long) base_addr, 
-			  s_old->length - 1, 0, s_new->type, 0, 0) < 0)
-	{
-	    return -1;
-	}
-
-	return s_new->selector;
-    }
-    /******************************************************************
-     * No new segment.  So, just return the shared memory key.
-     */
-    else
-	return s_old->shm_key;
-}
-#endif
-
-/**********************************************************************
- *					AllocSelector
- *
- * This is very bad!!!  This function is implemented for Windows
- * compatibility only.  Do not call this from the emulation library.
- */
-WORD AllocSelector(WORD old_selector)
-{
-    SEGDESC *s_new;
-    int i_new, i_old;
-    int selector;
-    
-    i_new = FindUnusedSelectors(1);
-    s_new = &Segments[i_new];
-    
-    if (old_selector)
-    {
-	i_old = (old_selector >> __AHSHIFT);
-#ifdef HAVE_IPC
-	selector = IPCCopySelector(i_old, i_new, 0);
-	if (selector < 0)
-	    return 0;
-	else
-	    return selector;
-#else
-	s_old = &Segments[i_old];
-	s_new->selector = (i_new << __AHSHIFT) | 0x0007;
-	*s_new = *s_old;
-	SelectorMap[i_new] = SelectorMap[i_old];
-
-	if (set_ldt_entry(i_new, s_new->base_addr, 
-			  s_new->length - 1, 0, 
-			  s_new->type, 0, 0) < 0)
-	{
-	    return 0;
-	}
-#endif
-    }
-    else
-    {
-	memset(s_new, 0, sizeof(*s_new));
-#ifdef HAVE_IPC
-	s_new->shm_key = -1;
-#endif
-	SelectorMap[i_new] = i_new;
-    }
-
-    return (i_new << __AHSHIFT) | 0x0007;
-}
-
-/**********************************************************************
- *					PrestoChangoSelector
- *
- * This is very bad!!!  This function is implemented for Windows
- * compatibility only.  Do not call this from the emulation library.
- */
-unsigned int PrestoChangoSelector(unsigned src_selector, unsigned dst_selector)
-{
-#ifdef HAVE_IPC
-    SEGDESC *src_s;
-    int src_idx, dst_idx;
-
-    src_idx = src_selector >> __AHSHIFT;
-    dst_idx = dst_selector >> __AHSHIFT;
-
-    if (src_idx == dst_idx)
-    {
-	src_s = &Segments[src_idx];
-	
-	if (src_s->type == MODIFY_LDT_CONTENTS_DATA)
-	    src_s->type = MODIFY_LDT_CONTENTS_CODE;
-	else
-	    src_s->type = MODIFY_LDT_CONTENTS_DATA;
-
-	if (set_ldt_entry(src_idx, (long) src_s->base_addr,
-			  src_s->length - 1, 0, src_s->type, 0, 0) < 0)
-	{
-	    return 0;
-	}
-
-	return src_s->selector;
-    }
-    else
-    {
-	return IPCCopySelector(src_idx, dst_idx, 1);
-    }
-#else /* HAVE_IPC */
-    SEGDESC *src_s, *dst_s;
-    char *p;
-    int src_idx, dst_idx;
-    int alias_count;
-    int i;
-
-    src_idx = (SelectorMap[src_selector >> __AHSHIFT]);
-    dst_idx = dst_selector >> __AHSHIFT;
-    src_s = &Segments[src_idx];
-    dst_s = &Segments[dst_idx];
-
-    alias_count = 0;
-    for (i = FIRST_SELECTOR; i < max_selectors; i++)
-	if (SelectorMap[i] == src_idx)
-	    alias_count++;
-    
-    if (src_s->type == MODIFY_LDT_CONTENTS_DATA 
-	|| alias_count > 1 || src_idx == dst_idx)
-    {
-	*dst_s = *src_s;
-	
-	if (src_s->type == MODIFY_LDT_CONTENTS_DATA)
-	    dst_s->type = MODIFY_LDT_CONTENTS_CODE;
-	else
-	    dst_s->type = MODIFY_LDT_CONTENTS_DATA;
-
-	SelectorMap[dst_idx] = SelectorMap[src_idx];
-	if (set_ldt_entry(dst_idx, (long) dst_s->base_addr,
-			  dst_s->length - 1, 0, dst_s->type, 0, 0) < 0)
-	{
-	    return 0;
-	}
-    }
-    else
-    {
-	/*
-	 * We're changing an unaliased code segment into a data
-	 * segment.  The SAFEST (but ugliest) way to deal with 
-	 * this is to map the new segment and copy all the contents.
-	 */
-	SelectorMap[dst_idx] = dst_idx;
-	*dst_s = *src_s;
-	dst_s->selector  = (dst_idx << __AHSHIFT) | 0x0007;
-	dst_s->base_addr = (void *) ((unsigned int) dst_s->selector << 16);
-	dst_s->type      = MODIFY_LDT_CONTENTS_DATA;
-#ifdef DEV_ZERO
-	if (zfile == NULL)
-	    zfile = fopen("/dev/zero","r");
-	p = (void *) mmap((char *) dst_s->base_addr,
-			  ((dst_s->length + PAGE_SIZE-1) 
-			   & ~(PAGE_SIZE - 1)),
-			  PROT_EXEC | PROT_READ | PROT_WRITE,
-			  MAP_FIXED | MAP_PRIVATE, fileno(zfile), 0);
-#else
-	p = (void *) mmap((char *) dst_s->base_addr,
-			  ((dst_s->length + PAGE_SIZE-1) 
-			   & ~(PAGE_SIZE - 1)),
-			  PROT_EXEC | PROT_READ | PROT_WRITE,
-			  MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0);
-#endif
-	if (p == NULL)
-	    return 0;
-	
-	memcpy((void *) dst_s->base_addr, (void *) src_s->base_addr, 
-	       dst_s->length);
-	if (set_ldt_entry(src_idx, dst_s->base_addr,
-			  dst_s->length - 1, 0, dst_s->type, 0, 0) < 0)
-	{
-	    return 0;
-	}
-	if (set_ldt_entry(dst_idx, dst_s->base_addr,
-			  dst_s->length - 1, 0, dst_s->type, 0, 0) < 0)
-	{
-	    return 0;
-	}
-
-	munmap(src_s->base_addr,
-	       (src_s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1));
-	SelectorMap[src_idx] = dst_idx;
-	src_s->base_addr = dst_s->base_addr;
-    }
-
-    return dst_s->selector;
-#endif /* HAVE_IPC */
-}
-
-/**********************************************************************
- *					AllocCStoDSAlias
- */
-WORD AllocDStoCSAlias(WORD ds_selector)
-{
-    unsigned int cs_selector;
-    
-    if (ds_selector == 0)
-	return 0;
-    
-    cs_selector = AllocSelector(0);
-    return PrestoChangoSelector(ds_selector, cs_selector);
-}
-
-/**********************************************************************
- *					CleanupSelectors
- */
-
-void CleanupSelectors(void)
-{
-    int sel_idx;
-
-    for (sel_idx = FIRST_SELECTOR; sel_idx < max_selectors; sel_idx++)
-	if (SelectorMap[sel_idx])
-	    FreeSelector((sel_idx << __AHSHIFT) | 7);
-}
-
-/**********************************************************************
- *					FreeSelector
- */
-WORD FreeSelector(WORD sel)
-{
-    SEGDESC *s;
-    int sel_idx;
-    int alias_count;
-    int i;
-
-#ifdef HAVE_IPC
-    sel_idx = sel >> __AHSHIFT;
-
-    if (sel_idx < FIRST_SELECTOR || sel_idx >= max_selectors)
-	return 0;
-    
-    s = &Segments[sel_idx];
-    if (s->shm_key == -1)
-    {
-	munmap(s->base_addr, ((s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)));
-	memset(s, 0, sizeof(*s));
-	s->shm_key = -1;
-	SelectorMap[sel_idx] = 0;
-    }
-    else
-    {
-	shmdt(s->base_addr);
-
-	alias_count = 0;
-	for (i = FIRST_SELECTOR; i < max_selectors; i++)
-	    if (SelectorMap[i] && Segments[i].shm_key == s->shm_key)
-		alias_count++;
-	
-	if (alias_count == 1)
-	    shmctl(s->shm_key, IPC_RMID, NULL);
-	    
-	memset(s, 0, sizeof(*s));
-	s->shm_key = -1;
-	SelectorMap[sel_idx] = 0;
-    }
-    
-#else /* HAVE_IPC */
-    sel_idx = SelectorMap[sel >> __AHSHIFT];
-
-    if (sel_idx < FIRST_SELECTOR || sel_idx >= max_selectors)
-	return 0;
-    
-    if (sel_idx != (sel >> __AHSHIFT))
-    {
-	SelectorMap[sel >> __AHSHIFT] = 0;
-	return 0;
-    }
-    
-    alias_count = 0;
-    for (i = FIRST_SELECTOR; i < max_selectors; i++)
-	if (SelectorMap[i] == sel_idx)
-	    alias_count++;
-
-    if (alias_count == 1)
-    {
-	s = &Segments[sel_idx];
-	munmap(s->base_addr, ((s->length + PAGE_SIZE) & ~(PAGE_SIZE - 1)));
-	memset(s, 0, sizeof(*s));
-	SelectorMap[sel >> __AHSHIFT] = 0;
-    }
-#endif /* HAVE_IPC */
-
-    return 0;
-}
-
-/**********************************************************************
- *					CreateNewSegments
- */
-SEGDESC *
-CreateNewSegments(int code_flag, int read_only, int length, int n_segments)
-{
-    SEGDESC *s, *first_segment;
-    int contents;
-    int i, last_i;
-    
-    i = FindUnusedSelectors(n_segments);
-
-    dprintf_selectors(stddeb, "Using %d segments starting at index %d.\n", 
-	n_segments, i);
-
-    /*
-     * Fill in selector info.
-     */
-    first_segment = s = &Segments[i];
-    for (last_i = i + n_segments; i < last_i; i++, s++)
-    {
-	if (code_flag)
-	{
-	    contents = MODIFY_LDT_CONTENTS_CODE;
-	    s->flags = 0;
-	}
-	else
-	{
-	    contents = MODIFY_LDT_CONTENTS_DATA;
-	    s->flags = NE_SEGFLAGS_DATA;
-	}
-	
-	s->selector = (i << __AHSHIFT) | 0x0007;
-	s->length = length;
-#ifdef DEV_ZERO
-	if (zfile == NULL)
-	    zfile = fopen("/dev/zero","r");
-	s->base_addr = (void *) mmap((char *) (s->selector << 16),
-				     ((s->length + PAGE_SIZE - 1) & 
-				      ~(PAGE_SIZE - 1)),
-				     PROT_EXEC | PROT_READ | PROT_WRITE,
-				     MAP_FIXED | MAP_PRIVATE, 
-				     fileno(zfile), 0);
-#else
-	s->base_addr = (void *) mmap((char *) (s->selector << 16),
-				     ((s->length + PAGE_SIZE - 1) & 
-				      ~(PAGE_SIZE - 1)),
-				     PROT_EXEC | PROT_READ | PROT_WRITE,
-				     MAP_FIXED | MAP_PRIVATE | MAP_ANON, 
-				     -1, 0);
-#endif
-#ifdef HAVE_IPC
-	s->shm_key = -1;
-#endif
-	if (set_ldt_entry(i, (unsigned long) s->base_addr, 
-			  (s->length - 1) & 0xffff, 0, 
-			  contents, read_only, 0) < 0)
-	{
-	    memset(s, 0, sizeof(*s));
-#ifdef HAVE_IPC
-	    s->shm_key = -1;
-#endif
-	    return NULL;
-	}
-
-	SelectorMap[i] = (unsigned short) i;
-	s->type = contents;
-    }
-
-    return first_segment;
-}
-
-/**********************************************************************
- *					GetNextSegment
- */
-SEGDESC *
-GetNextSegment(unsigned int flags, unsigned int limit)
-{
-    return CreateNewSegments(0, 0, limit, 1);
-}
 
 
 
@@ -643,7 +110,7 @@
  *         (e.g. reading from the Bios data segment (esp. clock!) )
  */
 
-unsigned int GetMemoryReference(char *dll_name, char *function, int *sel,
+unsigned int GetMemoryReference(char *dll_name, char *function, WORD *sel,
 				 int *addr)
 {
   static HANDLE memory_handles[ 10 ] = { 0,0,0,0,0,0,0,0,0,0 };
@@ -675,7 +142,17 @@
     else if( !strcasecmp( function, "__F000H" ) ) nr = 7;
     else if( !strcasecmp( function, "__C000H" ) ) nr = 8;
     else if( !strcasecmp( function, "__0040H" ) ) nr = 9;
-    else
+    else if( !strcasecmp( function, "__AHIncr" ) ) {
+      *sel = __AHINCR;   
+      *addr = MAKELONG(__AHINCR,__AHINCR);
+      return 1;      
+    }
+    else if( !strcasecmp( function, "__AHShift" ) ) {
+      *sel = __AHSHIFT;
+      *addr = MAKELONG(__AHSHIFT,__AHSHIFT);
+      return 1;
+    }
+     else
       return 0;
   }
   else {
@@ -690,6 +167,14 @@
     case 194: nr = 7; break;
     case 195: nr = 8; break;
     case 193: nr = 9; break;
+    case 114:
+      *sel = __AHINCR;  
+      *addr = MAKELONG(__AHINCR,__AHINCR);
+      return 1;
+    case 113:
+      *sel = __AHSHIFT;
+      *addr = MAKELONG(__AHSHIFT,__AHSHIFT);
+      return 1;
     default: return 0;
     }
   }
@@ -715,7 +200,7 @@
     char  * cpnt;
 };
 
-unsigned int GetEntryDLLName(char * dll_name, char * function, int * sel, 
+unsigned int GetEntryDLLName(char * dll_name, char * function, WORD* sel, 
 				int  * addr)
 {
 	struct dll_table_entry_s *dll_table;
@@ -730,6 +215,13 @@
 
 	if(dll_table) {
 		ordinal = FindOrdinalFromName(dll_table, function);
+		if(!ordinal){
+			dprintf_module(stddeb,"GetEntryDLLName: %s.%s not found\n",
+				dll_name, function);
+			*sel=0;
+			*addr=0;
+			return -1;
+		}
 		*sel = dll_table[ordinal].selector;
 		*addr  = (unsigned int) dll_table[ordinal].address;
 #ifdef WINESTAT
@@ -760,7 +252,7 @@
 	return 1;
 }
 
-unsigned int GetEntryDLLOrdinal(char * dll_name, int ordinal, int * sel, 
+unsigned int GetEntryDLLOrdinal(char * dll_name, int ordinal, WORD *sel, 
 				int  * addr)
 {
 	struct dll_table_entry_s *dll_table;
@@ -832,58 +324,53 @@
 	{
 	    if (eth->seg_number >= 0xfe)
 	    {
-		    etm = entry_tab_pointer.etm++;
-
+                etm = entry_tab_pointer.etm++;
 		if (current_ordinal == ordinal)
 		{
-		    return ((unsigned int) 
-			    (wpnt->ne->selector_table[etm->seg_number - 1].base_addr + 
-			     etm->offset));
+		    return MAKELONG(etm->offset,
+                                  wpnt->ne->selector_table[etm->seg_number-1]);
 		}
 	    }
 	    else
 	    {
-		    etf = entry_tab_pointer.etf++;
-
+                etf = entry_tab_pointer.etf++;
 		if (current_ordinal == ordinal)
 		{
-		    return ((unsigned int) 
-			    (wpnt->ne->selector_table[eth->seg_number - 1].base_addr + 
-			     (int) etf->offset[0] + 
-			     ((int) etf->offset[1] << 8)));
+		    return MAKELONG( etf->offset[0] + ((int)etf->offset[1]<<8),
+                                  wpnt->ne->selector_table[eth->seg_number-1]);
 		}
 	    }
 	}
     }
 }
-
-/**********************************************************************
- *					GetDOSEnvironment
+
+
+/***********************************************************************
+ *           GetDOSEnvironment   (KERNEL.131)
  */
-LPSTR GetDOSEnvironment(void)
+SEGPTR GetDOSEnvironment(void)
 {
-    return (LPSTR) EnvironmentSelector->base_addr;
+    return WIN16_GlobalLock( EnvironmentHandle );
 }
-
+
+
 /**********************************************************************
- *					CreateEnvironment
+ *           CreateEnvironment
  */
-static SEGDESC *
-CreateEnvironment(void)
+static HANDLE CreateEnvironment(void)
 {
+    HANDLE handle;
     char **e;
     char *p;
-    SEGDESC * s;
 
-    s = CreateNewSegments(0, 0, PAGE_SIZE, 1);
-    if (s == NULL)
-	return NULL;
+    handle = GlobalAlloc( GMEM_MOVEABLE, MAX_ENV_SIZE );
+    if (!handle) return 0;
+    p = (char *) GlobalLock( handle );
 
     /*
      * Fill environment with Windows path, the Unix environment,
      * and program name.
      */
-    p = (char *) s->base_addr;
     strcpy(p, "PATH=");
     strcat(p, WindowsPath);
     p += strlen(p) + 1;
@@ -902,51 +389,53 @@
     /*
      * Display environment
      */
-    dprintf_selectors(stddeb, "Environment at %p\n", s->base_addr);
-    for (p = s->base_addr; *p; p += strlen(p) + 1)
-	dprintf_selectors(stddeb, "    %s\n", p);
+    p = (char *) GlobalLock( handle );
+    dprintf_selectors(stddeb, "Environment at %p\n", p);
+    for (; *p; p += strlen(p) + 1) dprintf_selectors(stddeb, "    %s\n", p);
 
-    return  s;
+    return handle;
 }
-
+
+
 /**********************************************************************
+ *           GetCurrentPDB   (KERNEL.37)
  */
 WORD GetCurrentPDB()
 {
     return PSPSelector;
 }
-
+
+
 /**********************************************************************
- *					CreatePSP
+ *           CreatePSP
  */
-static SEGDESC *
-CreatePSP(void)
+static WORD CreatePSP(void)
 {
+    HANDLE handle;
     struct dos_psp_s *psp;
     unsigned short *usp;
-    SEGDESC * s;
     char *p1, *p2;
     int i;
 
-    s = CreateNewSegments(0, 0, PAGE_SIZE, 1);
+    handle = GlobalAlloc( GMEM_MOVEABLE, sizeof(*psp) );
+    if (!handle) return 0;
+    psp = (struct dos_psp_s *) GlobalLock( handle );
 
     /*
      * Fill PSP
      */
-    PSPSelector = s->selector;
-    psp = (struct dos_psp_s *) s->base_addr;
     psp->pspInt20 = 0x20cd;
     psp->pspDispatcher[0] = 0x9a;
     usp = (unsigned short *) &psp->pspDispatcher[1];
     *usp       = (unsigned short) KERNEL_Ordinal_102;
-    *(usp + 1) = UTEXTSEL;
-    psp->pspTerminateVector[0] = (unsigned short) UNIXLIB_Ordinal_0;
-    psp->pspTerminateVector[1] = UTEXTSEL;
-    psp->pspControlCVector[0] = (unsigned short) UNIXLIB_Ordinal_0;
-    psp->pspControlCVector[1] = UTEXTSEL;
-    psp->pspCritErrorVector[0] = (unsigned short) UNIXLIB_Ordinal_0;
-    psp->pspCritErrorVector[1] = UTEXTSEL;
-    psp->pspEnvironment = EnvironmentSelector->selector;
+    *(usp + 1) = WINE_CODE_SELECTOR;
+    psp->pspTerminateVector[0] = (unsigned short) KERNEL_Ordinal_1;
+    psp->pspTerminateVector[1] = WINE_CODE_SELECTOR;
+    psp->pspControlCVector[0] = (unsigned short) KERNEL_Ordinal_1;
+    psp->pspControlCVector[1] = WINE_CODE_SELECTOR;
+    psp->pspCritErrorVector[0] = (unsigned short) KERNEL_Ordinal_1;
+    psp->pspCritErrorVector[1] = WINE_CODE_SELECTOR;
+    psp->pspEnvironment = SELECTOROF( GetDOSEnvironment() );
 
     p1 = psp->pspCommandTail;
     for (i = 1; i < Argc; i++)
@@ -965,48 +454,41 @@
     *p1 = '\0';
     psp->pspCommandTailCount = strlen(psp->pspCommandTail);
 
-    return s;
+    return SELECTOROF( WIN16_GlobalLock( handle ) );
 }
-
+
+
 /**********************************************************************
  *					CreateSelectors
  */
-SEGDESC *
-CreateSelectors(struct  w_files * wpnt)
+unsigned short *CreateSelectors(struct w_files * wpnt)
 {
     int fd = wpnt->fd;
     struct ne_segment_table_entry_s *seg_table = wpnt->ne->seg_table;
     struct ne_header_s *ne_header = wpnt->ne->ne_header;
-    SEGDESC *selectors, *s;
     unsigned short auto_data_sel;
-    int contents, read_only;
-    int SelectorTableLength;
-    int i;
-    int status;
+
     int old_length, file_image_length = 0;
     int saved_old_length = 0;
+    int i, length;
+    void *base_addr;
+    WORD *selectors;
+    ldt_entry entry;
 
     auto_data_sel=0;
     /*
      * Allocate memory for the table to keep track of all selectors.
      */
-    SelectorTableLength = ne_header->n_segment_tab;
-    selectors = malloc(SelectorTableLength * sizeof(*selectors));
+    selectors = (WORD *) malloc( ne_header->n_segment_tab * sizeof(WORD) );
     if (selectors == NULL)
 	return NULL;
 
     /*
      * Step through the segment table in the exe header.
      */
-    s = selectors;
-    for (i = 0; i < ne_header->n_segment_tab; i++, s++)
+    for (i = 0; i < ne_header->n_segment_tab; i++)
     {
 	/*
-	 * Store the flags in our table.
-	 */
-	s->flags = seg_table[i].seg_flags;
-
-	/*
 	 * Is there an image for this segment in the file?
 	 */
 	if (seg_table[i].seg_data_offset == 0)
@@ -1014,21 +496,20 @@
 	    /*
 	     * No image in exe file, let's allocate some memory for it.
 	     */
-	    s->length = seg_table[i].min_alloc;
+	    length = seg_table[i].min_alloc;
 	}
 	else
 	{
 	    /*
 	     * Image in file, let's just point to the image in memory.
 	     */
-	    s->length         = seg_table[i].min_alloc;
+	    length            = seg_table[i].min_alloc;
 	    file_image_length = seg_table[i].seg_data_length;
 	    if (file_image_length == 0)	file_image_length = 0x10000;
 	}
 
-	if (s->length == 0)
-	    s->length = 0x10000;
-	old_length = s->length;
+	if (length == 0) length = 0x10000;
+	old_length = length;
 
 	/*
 	 * If this is the automatic data segment, its size must be adjusted.
@@ -1037,55 +518,54 @@
 	 */
 	if (i + 1 == ne_header->auto_data_seg || i + 1 == ne_header->ss)
 	{
-	    s->length = 0x10000;
-	    ne_header->sp = s->length - 2;
-	}
+	    length = 0x10000;
+	    ne_header->sp = length - 2;
+            dprintf_selectors(stddeb,"Auto data image length %x\n",file_image_length);
+ 	}
+
+        if (!(selectors[i] = AllocSelector( 0 )))
+        {
+            fprintf( stderr, "CreateSelectors: out of free LDT entries\n" );
+            exit( 1 );
+        }
+        if (!(base_addr = (void *) malloc( length )))
+        {
+            fprintf( stderr, "CreateSelectors: malloc() failed\n" );
+            exit( 1 );
+        }
+        entry.base           = (unsigned long) base_addr;
+        entry.limit          = length - 1;
+        entry.seg_32bit      = 0;
+        entry.limit_in_pages = 0;
 
 	/*
 	 * Is this a DATA or CODE segment?
 	 */
-	read_only = 0;
-	if (s->flags & NE_SEGFLAGS_DATA)
-	{
-	    contents = MODIFY_LDT_CONTENTS_DATA;
-	    if (s->flags & NE_SEGFLAGS_READONLY)
-		read_only = 1;
-	}
-	else
-	{
-	    contents = MODIFY_LDT_CONTENTS_CODE;
-	    if (s->flags & NE_SEGFLAGS_EXECUTEONLY)
-		read_only = 1;
-	}
+        if (seg_table[i].seg_flags & NE_SEGFLAGS_DATA)
+        {
+            entry.type = SEGMENT_DATA;
+            entry.read_only = seg_table[i].seg_flags & NE_SEGFLAGS_READONLY;
+            memset( base_addr, 0, length );
+        }
+        else
+        {
+            entry.type = SEGMENT_CODE;
+            entry.read_only = seg_table[i].seg_flags & NE_SEGFLAGS_EXECUTEONLY;
+        }
+        LDT_SetEntry( SELECTOR_TO_ENTRY(selectors[i]), &entry );
 
-#if 0
-	stmp = CreateNewSegments(!(s->flags & NE_SEGFLAGS_DATA), read_only,
-				s->length, 1);
-	s->base_addr = stmp->base_addr;
-	s->selector = stmp->selector;
-#endif
-	s->selector = GlobalAlloc(GMEM_FIXED, s->length);
-	if (s->selector == 0)
-	    myerror("CreateSelectors: GlobalAlloc() failed");
-
-	s->base_addr = (void *) ((LONG) s->selector << 16);
-#ifdef HAVE_IPC
-	s->shm_key = -1;
-#endif
-	if (!(s->flags & NE_SEGFLAGS_DATA))
-	    PrestoChangoSelector(s->selector, s->selector);
-	else
-	    memset(s->base_addr, 0, s->length);
-	
 	if (seg_table[i].seg_data_offset != 0)
 	{
 	    /*
 	     * Image in file.
 	     */
-	    status = lseek(fd, seg_table[i].seg_data_offset * 
-			   (1 << ne_header->align_shift_count), SEEK_SET);
-	    if(read(fd, s->base_addr, file_image_length) != file_image_length)
-		myerror("Unable to read segment from file");
+	    lseek( fd, seg_table[i].seg_data_offset * 
+                   (1 << ne_header->align_shift_count), SEEK_SET );
+	    if(read(fd, base_addr, file_image_length) != file_image_length)
+            {
+                fprintf( stderr, "Unable to read segment %d from file\n", i+1);
+                exit(1);
+            }
 	}
 
 	/*
@@ -1094,30 +574,37 @@
 	 */
 	if (i + 1 == ne_header->auto_data_seg)
 	{
-	    auto_data_sel = s->selector;
+	    auto_data_sel = selectors[i];
 	    saved_old_length = old_length;
 	}
     }
 
     if(!auto_data_sel)dprintf_selectors(stddeb,"Warning: No auto_data_sel\n");
-    s = selectors;
-    for (i = 0; i < ne_header->n_segment_tab; i++, s++)
+    for (i = 0; i < ne_header->n_segment_tab; i++)
     {
-	Segments[s->selector >> __AHSHIFT].owner = auto_data_sel;
-	if (s->selector == auto_data_sel)
-	    HEAP_LocalInit(auto_data_sel, s->base_addr + saved_old_length, 
+/*	Segments[s->selector >> __AHSHIFT].owner = auto_data_sel; */
+	if (selectors[i] == auto_data_sel)
+            LocalInit( auto_data_sel, saved_old_length,
+			   0x10000 - 2 - saved_old_length 
+			   - ne_header->stack_length );
+#if 0
+	    HEAP_LocalInit(auto_data_sel,
+                           (char *)GET_SEL_BASE(selectors[i]) + saved_old_length, 
 			   0x10000 - 2 - saved_old_length 
 			   - ne_header->stack_length);
+#endif
     }
 
-    if(!EnvironmentSelector) {
-	    EnvironmentSelector = CreateEnvironment();
-	    PSP_Selector = CreatePSP();
-	    MakeProcThunks = CreateNewSegments(1, 0, 0x10000, 1);
-    };
+    if(!EnvironmentHandle)
+    {
+        EnvironmentHandle = CreateEnvironment();
+        PSPSelector = CreatePSP();
+    }
 
     return selectors;
 }
+
+
 /**********************************************************************
  */
 void
@@ -1158,15 +645,14 @@
 	    if (eth->seg_number >= 0xfe)
 	    {
 		etm = entry_tab_pointer.etm++;
-		fixup_ptr = (wpnt->ne->selector_table[etm->seg_number-1].base_addr
-			     + etm->offset);
+		fixup_ptr = (char *)GET_SEL_BASE(wpnt->ne->selector_table[etm->seg_number-1]) + etm->offset;
 	    }
 	    else
 	    {
 		etf = entry_tab_pointer.etf++;
-		fixup_ptr = (wpnt->ne->selector_table[eth->seg_number-1].base_addr
+		fixup_ptr = (char *)GET_SEL_BASE(wpnt->ne->selector_table[eth->seg_number-1])
 			     + (int) etf->offset[0] 
-			     + ((int) etf->offset[1] << 8));
+			     + ((int) etf->offset[1] << 8);
 
 	    }
 
@@ -1183,41 +669,4 @@
     }
 }
 
-/***********************************************************************
- *	GetSelectorBase (KERNEL.186)
- */
-DWORD GetSelectorBase(WORD wSelector)
-{
-	fprintf(stdnimp, "GetSelectorBase(selector %4X) stub!\n", wSelector);
-        return 0;
-}
-
-/***********************************************************************
- *	SetSelectorBase (KERNEL.187)
- */
-void SetSelectorBase(WORD wSelector, DWORD dwBase)
-{
-	fprintf(stdnimp, "SetSelectorBase(selector %4X, base %8lX) stub!\n",
-			wSelector, dwBase);
-}
-
-/***********************************************************************
- *	GetSelectorLimit (KERNEL.188)
- */
-DWORD GetSelectorLimit(WORD wSelector)
-{
-	fprintf(stdnimp, "GetSelectorLimit(selector %4X) stub!\n", wSelector);
-
-	return 0xffff;
-}
-
-/***********************************************************************
- *	SetSelectorLimit (KERNEL.189)
- */
-void SetSelectorLimit(WORD wSelector, DWORD dwLimit)
-{
-	fprintf(stdnimp, "SetSelectorLimit(selector %4X, base %8lX) stub!\n", 
-			wSelector, dwLimit);
-}
-
 #endif /* ifndef WINELIB */
diff --git a/loader/signal.c b/loader/signal.c
index 344a777..5b34839 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -16,7 +16,6 @@
 
 #include "wine.h"
 #include "dos_fs.h"
-#include "segmem.h"
 #include "prototypes.h"
 #include "miscemu.h"
 #include "win.h"
@@ -72,11 +71,15 @@
 		scp->sc_edx = 0xdef0;
 		return 1;
 
-	      case 0x25: return do_int25(scp);
-	      case 0x26: return do_int26(scp);
+              case 0x25: return do_int25(scp);
+              case 0x26: return do_int26(scp);
               case 0x2a: return do_int2a(scp);
 	      case 0x2f: return do_int2f(scp);
 	      case 0x31: return do_int31(scp);
+
+              default:
+                printf("int%02x: Unimplemented!\n", intnum);
+                break;
 	}
 	return 0;
 }
@@ -98,6 +101,7 @@
 #ifdef linux
     if(signal != SIGSEGV 
        && signal != SIGILL 
+       && signal != SIGFPE 
 #ifdef SIGBUS
        && signal != SIGBUS 
 #endif
@@ -131,7 +135,7 @@
 
     /*  Now take a look at the actual instruction where the program
 	bombed */
-    instr = (unsigned char *) SAFEMAKEPTR(scp->sc_cs, scp->sc_eip);
+    instr = (unsigned char *) PTR_SEG_OFF_TO_LIN(scp->sc_cs, scp->sc_eip);
 
     switch(*instr)
     {
@@ -233,6 +237,7 @@
 		(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
 	wine_sigaction(SIGSEGV, &segv_act, NULL);
 	wine_sigaction(SIGILL, &segv_act, NULL);
+	wine_sigaction(SIGFPE, &segv_act, NULL);
 #ifdef SIGBUS
 	wine_sigaction(SIGBUS, &segv_act, NULL);
 #endif
diff --git a/memory/Imakefile b/memory/Imakefile
index 55448b0..3364fec 100644
--- a/memory/Imakefile
+++ b/memory/Imakefile
@@ -3,9 +3,9 @@
 MODULE = memory
 
 SRCS = \
+	selector.c \
 	global.c \
-	heap.c \
-	linear.c
+	local.c
 
 OBJS = $(SRCS:.c=.o)
 
diff --git a/memory/global.c b/memory/global.c
index a3e5eb7..f62f2fd 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -1,842 +1,270 @@
 /*
-static char RCSId[] = "$Id: global.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-*/
+ * Global heap functions
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
 
-#define GLOBAL_SOURCE
-
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "windows.h"
-#include "prototypes.h"
 #include "toolhelp.h"
-#include "heap.h"
-#include "segmem.h"
 #include "selectors.h"
+#include "stackframe.h"
 #include "stddebug.h"
-/* #define DEBUG_HEAP */
 #include "debug.h"
 
+#define GLOBAL_MAX_ALLOC_SIZE 0x00ff0000  /* Largest allocation is 16M - 64K */
 
-GDESC *GlobalList = NULL;
-static unsigned short next_unused_handle = 1;
+#define HGLOBAL_TO_SEL(handle) \
+     ((handle == (HGLOBAL)-1) ? CURRENT_DS : GlobalHandleToSel(handle))
 
-/**********************************************************************
- *					GlobalGetGDesc
+/***********************************************************************
+ *           GlobalAlloc   (KERNEL.15)
  */
-GDESC *GlobalGetGDesc(unsigned int block)
+HGLOBAL GlobalAlloc( WORD flags, DWORD size )
 {
-    GDESC *g;
+    WORD sel;
+    void *ptr;
 
-    if (block == 0)
-	return NULL;
+    dprintf_global( stddeb, "GlobalAlloc: %ld flags=%04x\n", size, flags );
 
-    /*
-     * Find GDESC for this block.
-     */
-    if (block & 0xffff0000)
+      /* Fixup the size */
+
+    if (size >= GLOBAL_MAX_ALLOC_SIZE - 0x0f) return 0;
+    if (size == 0) size = 0x10;
+    else size = (size + 0x0f) & ~0x0f;
+
+      /* Allocate the linear memory */
+
+    ptr = malloc( size );
+    if (!ptr) return 0;
+
+      /* Allocate the selector(s) */
+
+    sel = SELECTOR_AllocBlock( ptr, size, SEGMENT_DATA, 0, 0 );
+    if (!sel)
     {
-	for (g = GlobalList; g != NULL; g = g->next)
-	    if (g->handle > 0 && (unsigned int) g->addr == block)
-		break;
-    }
-    else
-    {
-	for (g = GlobalList; g != NULL; g = g->next)
-	    if (g->handle == block)
-		break;
+        free( ptr );
+        return 0;
     }
 
-    return g;
-}
-
-/**********************************************************************
- *					GlobalGetFreeSegments
- */
-GDESC *
-GlobalGetFreeSegments(unsigned int flags, int n_segments)
-{
-    struct segment_descriptor_s *s;
-    GDESC *g;
-    GDESC *g_start;
-    GDESC *g_prev;
-    int count, i;
+    if (flags & GMEM_ZEROINIT) memset( ptr, 0, size );
 
-    /*
-     * Try to find some empty segments in our list.
-     */
-    count = 0;
-    for (g = GlobalList; g != NULL && count != n_segments; g = g->next)
-    {
-	if ((int) g->sequence == -1)
-	{
-	    if (count > 0)
-	    {
-		if (g->prev->handle + 8 != g->handle)
-		    count = 0;
-		else
-		    count++;
-	    }
-	    else
-	    {
-		g_start = g;
-		count = 1;
-	    }
-	}
-	else if (count)
-	    count = 0;
-    }
-    
-    /*
-     * If we couldn't find enough segments, then we need to create some.
-     */
-    if (count != n_segments)
-    {
-	/*
-	 * Find list tail.
-	 */
-	g_prev = NULL;
-	for (g = GlobalList; g != NULL; g = g->next)
-	    g_prev = g;
-	    
-	/*
-	 * Allocate segments.
-	 */
-	s = CreateNewSegments(0, 0, 0x10000, n_segments);
-	if (s == NULL) 
-	{
-	    fprintf(stderr,"GlobalGetFreeSegments // bad CreateNewSegments !\n");
-	    return NULL;
-	}
-	for (count = 0; count < n_segments; count++, s++)
-	{
-	    g = (GDESC *) malloc(sizeof(*g));
-	    if (g == NULL) 
-	    {
-		fprintf(stderr,"GlobalGetFreeSegments // bad GDESC malloc !\n");
-		return NULL;
-	    }
-	    g->prev         = g_prev;
-	    g->next         = NULL;
-	    g->handle       = s->selector;
-	    g->sequence     = -1;
-	    g->addr         = s->base_addr;
-	    g->length       = s->length;
-	    g->alias        = 0;
-	    g->linear_addr  = NULL;
-	    g->linear_key   = 0;
-	    g->linear_count = 0;
-	    if (!(flags & GLOBAL_FLAGS_MOVEABLE))
-		g->lock_count = 1;
-	    else
-		g->lock_count = 0;
-	    
-	    if (count == 0) g_start = g;
-
-	    if (g_prev != NULL)
-	    {
-		g_prev->next = g;
-	    }
-	    else
-		GlobalList = g;
-	    g_prev = g;
-	}
-    }
-
-    /*
-     * We have all of the segments we need.  Let's adjust their contents.
-     */
-    g = g_start;
-    for (i = 0; i < n_segments; i++, g = g->next)
-    {
-	if (g == NULL) 
-	{
-	    fprintf(stderr,"GlobalGetFreeSegments // bad Segments chain !\n");
-	    return NULL;
-	}
-	g->sequence     = i + 1;
-	g->length       = n_segments;
-	g->alias        = 0;
-	g->linear_addr  = NULL; 
-	g->linear_key   = 0;
-	g->linear_count = 0;
-    }
-
-    return g_start;
-}
-
-/**********************************************************************
- *					GlobalAlloc
- */
-HANDLE
-GlobalAlloc(unsigned int flags, unsigned long size)
-{
-    GDESC *g;
-    GDESC *g_prev;
-    void *m;
-
-    dprintf_heap(stddeb,"GlobalAlloc flags %4X, size %ld\n", flags, size);
-
-    if (size == 0) size = 1;
-
-    /*
-     * If this block is fixed or very big we need to allocate entire
-     * segments.
-     */
-    if (size > 0x8000 || !(flags & GLOBAL_FLAGS_MOVEABLE))
-    {
-	int segments = ((size - 1) >> 16) + 1;
-
-	g = GlobalGetFreeSegments(flags, segments);
-	if (g == NULL)
-	  {
-	    dprintf_heap(stddeb, "==> NULL\n");
-	    return 0;
-	  }
-	else
-	  {
-	    dprintf_heap(stddeb, "==> %04x\n",g->handle);
-	    return g->handle;
-	  }
-    }
-    /*
-     * Otherwise we just need a little piece of a segment.
-     */
-    else
-    {
-	/*
-	 * Try to allocate from active free lists.
-	 */
-	for (g = GlobalList; g != NULL; g = g->next)
-	{
-	    if (g->handle == 0 && g->sequence == 0)
-	    {
-		m = HEAP_Alloc((MDESC **) g->addr, 0, size);
-		if (m != NULL)
-		    break;
-	    }
-	}
-
-	/*
-	 * If we couldn't get the memory there, then we need to create
-	 * a new free list.
-	 */
-	if (g == NULL)
-	{
-	    g = GlobalGetFreeSegments(0, 1);
-	    if (g == NULL)
-	      {
-		dprintf_heap(stddeb, "==> Null\n");
-		return 0;
-	      }
-
-	    g->handle = 0;
-	    g->sequence = 0;
-	    HEAP_Init((MDESC **) g->addr, (MDESC **) g->addr + 1, 
-		      0x10000 - sizeof(MDESC **));
-	    m = HEAP_Alloc((MDESC **) g->addr, flags & GLOBAL_FLAGS_ZEROINIT, 
-			   size);
-	    if (m == NULL)
-	      {
-		dprintf_heap(stddeb, "==> Null\n");
-		return 0;
-	      }
-	}
-
-	/*
-	 * Save position of heap descriptor.
-	 */
-	g_prev = g;
-
-	/*
-	 * We have a new block.  Let's create a GDESC entry for it.
-	 */
-	g = malloc(sizeof(*g));
-	dprintf_heap(stddeb,"New GDESC %08x\n", (unsigned int) g);
-	if (g == NULL)
-	    return 0;
-
-	g->handle       = next_unused_handle;
-	g->sequence     = 0;
-	g->addr         = m;
-	g->alias        = 0;
-	g->linear_addr  = NULL;
-	g->linear_key   = 0;
-	g->linear_count = 0;
-	g->length       = size;
-	g->next         = g_prev->next;
-	if (g->next) g->next->prev = g;
-	g->lock_count = 0;
-
-	g_prev->next = g;
-	g->prev = g_prev;
-
-	next_unused_handle++;
-	if ((next_unused_handle & 7) == 7)
-	    next_unused_handle++;
-	
-	dprintf_heap(stddeb,"GlobalAlloc: returning %04x\n", g->handle);
-	return g->handle;
-    }
+      /* Return the handle */
+      /* If allocating a GMEM_FIXED block, the handle is the selector. */
+      /* Otherwise, the handle is the selector-1 (don't ask me why :-) */
+    if (flags & GMEM_MOVEABLE) return sel - 1;
+    else return sel;
 }
 
-/**********************************************************************
- *					WIN16_GlobalAlloc
+
+/***********************************************************************
+ *           GlobalReAlloc   (KERNEL.16)
  */
-HANDLE
-WIN16_GlobalAlloc(unsigned int flags, unsigned long size)
+HGLOBAL GlobalReAlloc( HGLOBAL handle, DWORD size, WORD flags )
 {
-    return GlobalAlloc(flags & ~GLOBAL_FLAGS_MOVEABLE, size);
+    WORD sel;
+    DWORD oldsize;
+    void *ptr;
+
+    dprintf_global( stddeb, "GlobalReAlloc: %04x %ld flags=%04x\n",
+                    handle, size, flags );
+
+      /* Fixup the size */
+
+    if (size >= 0x00ff0000-0x0f) return 0;  /* No allocation > 16Mb-64Kb */
+    if (size == 0) size = 0x10;
+    else size = (size + 0x0f) & ~0x0f;
+
+      /* Reallocate the linear memory */
+
+    sel = GlobalHandleToSel( handle );
+    ptr = (void *)GET_SEL_BASE( sel );
+    oldsize = GlobalSize( handle );
+    if (size == oldsize) return handle;  /* Nothing to do */
+
+    ptr = realloc( ptr, size );
+    if (!ptr)
+    {
+        FreeSelector( sel );
+        return 0;
+    }
+
+      /* Reallocate the selector(s) */
+
+    sel = SELECTOR_ReallocBlock( sel, ptr, size, SEGMENT_DATA, 0, 0 );
+    if (!sel)
+    {
+        free( ptr );
+        return 0;
+    }
+
+    if ((oldsize < size) && (flags & GMEM_ZEROINIT))
+        memset( (char *)ptr + oldsize, 0, size - oldsize );
+
+    if (sel == GlobalHandleToSel( handle ))
+        return handle;  /* Selector didn't change */
+
+    if (flags & GMEM_MOVEABLE) return sel - 1;
+    else return sel;
 }
-
-/**********************************************************************
- *					GlobalFree
- *
- * Windows programs will pass a handle in the "block" parameter, but
- * this function will also accept a 32-bit address.
+
+
+/***********************************************************************
+ *           GlobalFree   (KERNEL.17)
  */
-HANDLE
-GlobalFree(unsigned int block)
+HGLOBAL GlobalFree( HGLOBAL handle )
 {
-    GDESC *g;
+    WORD sel;
+    void *ptr;
 
-    if (block == 0)
-	return 0;
-
-    /*
-     * Find GDESC for this block.
-     */
-    g = GlobalGetGDesc(block);
-    if (g == NULL)
-	return block;
-
-    /*
-     * If the sequence number is zero then use HEAP_Free to deallocate
-     * memory, and throw away this descriptor.
-     */
-    if (g->sequence == 0)
-    {
-	HEAP_Free((MDESC **) ((int) g->addr & 0xffff0000), (void *) g->addr);
-
-	g->prev->next = g->next;
-	
-	if (g->next != NULL)
-	    g->next->prev = g->prev;
-
-	free(g);
-    }
-    
-    /*
-     * Otherwise just mark these descriptors as free.
-     */
-    else
-    {
-	int i, limit;
-	
-	limit = g->length;
-	for (i = g->sequence - 1; i < limit && g != NULL; i++, g = g->next)
-	{
-	    g->sequence = -1;
-	    g->length = 0x10000;
-	}
-    }
-
+    dprintf_global( stddeb, "GlobalFree: %04x\n", handle );
+    sel = GlobalHandleToSel( handle );
+    ptr = (void *)GET_SEL_BASE(sel);
+    if (FreeSelector( sel )) return handle;  /* failed */
+    free( ptr );
     return 0;
 }
-
-/**********************************************************************
- *					GlobalLock
+
+
+/***********************************************************************
+ *           WIN16_GlobalLock   (KERNEL.18)
  *
+ * This is the GlobalLock() function used by 16-bit code.
  */
-void *
-GlobalLock(unsigned int block)
+SEGPTR WIN16_GlobalLock( HGLOBAL handle )
 {
-    GDESC *g;
-
-    if ((g = GlobalGetGDesc(block)) == NULL)
-	return 0;
-
-    g->lock_count++;
-
-    dprintf_heap(stddeb,"GlobalLock: returning %08x\n",(unsigned int)g->addr);
-    return g->addr;
+    dprintf_global( stddeb, "WIN16_GlobalLock: %04x\n", handle );
+    if (!handle) return 0;
+    return (SEGPTR)MAKELONG( 0, HGLOBAL_TO_SEL(handle) );
 }
-
-/**********************************************************************
- *					GlobalUnlock
+
+
+/***********************************************************************
+ *           GlobalLock   (KERNEL.18)
  *
+ * This is the GlobalLock() function used by 32-bit code.
  */
-int
-GlobalUnlock(unsigned int block)
+LPSTR GlobalLock( HGLOBAL handle )
 {
-    GDESC *g;
-
-    if (block == 0)
-	return 0;
-
-    /*
-     * Find GDESC for this block.
-     */
-    for (g = GlobalList; g != NULL; g = g->next)
-    {
-	if (g->handle == block && g->lock_count > 0)
-	{
-	    g->lock_count--;
-	    return 0;
-	}
-    }
-
-    return 1;
+    dprintf_global( stddeb, "GlobalLock: %04x\n", handle );
+    if (!handle) return 0;
+    return (LPSTR)GET_SEL_BASE( HGLOBAL_TO_SEL(handle) );
 }
-
-/**********************************************************************
- *					GlobalFlags
- *
+
+
+/***********************************************************************
+ *           GlobalUnlock   (KERNEL.19)
  */
-unsigned int
-GlobalFlags(unsigned int block)
+BOOL GlobalUnlock( HGLOBAL handle )
 {
-    GDESC *g;
-
-    if (block == 0)
-	return 0;
-
-    /*
-     * Find GDESC for this block.
-     */
-    for (g = GlobalList; g != NULL; g = g->next)
-    {
-	if (g->handle == block)
-	    return g->lock_count;
-    }
-
+    dprintf_global( stddeb, "GlobalUnlock: %04x\n", handle );
     return 0;
 }
-
-/**********************************************************************
- *					GlobalSize
- *
+
+
+/***********************************************************************
+ *           GlobalSize   (KERNEL.20)
  */
-unsigned int
-GlobalSize(unsigned int block)
+DWORD GlobalSize( HGLOBAL handle )
 {
-    GDESC *g = GlobalGetGDesc(block);
-    
-    if (g == NULL)
-	return 0;
-
-    if (g->sequence == 0)
-    {
-	MDESC *m = (MDESC *) g->addr - 1;
-	
-	return m->length;
-    }
-    else if (g->sequence >= 1)
-    {
-	return g->length * 0x10000;
-    }
-    
-    return g->length;
+    dprintf_global( stddeb, "GlobalSize: %04x\n", handle );
+    if (!handle) return 0;
+    return GET_SEL_LIMIT( HGLOBAL_TO_SEL(handle) ) + 1;
 }
-
-/**********************************************************************
- *					GlobalHandle
- *
- * This routine is not strictly correct.  MS Windows creates a selector
- * for every locked global block.  We do not.  If the allocation is small
- * enough, we only give out a little piece of a selector.  Thus this
- * function cannot be implemented.
+
+
+/***********************************************************************
+ *           GlobalHandle   (KERNEL.21)
  */
-unsigned int
-GlobalHandle(unsigned int selector)
+DWORD GlobalHandle( WORD sel )
 {
-    GDESC *g;
-
-    if (selector == 0)
-	return 0;
-
-    /*
-     * Find GDESC for this block.
-     */
-    for (g = GlobalList; g != NULL; g = g->next)
-    {
-	if (g->handle == selector)
-	{
-	    if (g->sequence > 0)
-		return MAKELONG(g->handle, selector);
-	    else
-	    {
-		fprintf(stderr, "Attempt to get a handle "
-			"from a selector to a far heap.\n");
-		return 0;
-	    }
-	}
-    }
-	dprintf_heap(stddeb, "GlobalHandle ==> Null\n");
-    return 0;
+      /* FIXME: what about GMEM_FIXED blocks? */
+    WORD handle = sel & ~1;
+    dprintf_global( stddeb, "GlobalHandle(%04x): returning %08lx\n",
+                    sel, MAKELONG( handle, sel ) );
+    return MAKELONG( handle, sel );
 }
-
-/**********************************************************************
- *					GlobalCompact
- *
+
+
+/***********************************************************************
+ *           GlobalFlags   (KERNEL.22)
  */
-unsigned int
-GlobalCompact(unsigned int desired)
+WORD GlobalFlags( HGLOBAL handle )
 {
-    GDESC *g;
-    unsigned char free_map[512];
-    unsigned int max_selector_used = 0;
-    unsigned int i;
-    unsigned int selector;
-    int current_free;
-    int max_free;
-
-    /*
-     * Initialize free list to all items not controlled by GlobalAlloc()
-     */
-    for (i = 0; i < 512; i++)
-	free_map[i] = -1;
-
-    /*
-     * Traverse table looking for used and free selectors.
-     */
-    for (g = GlobalList; g != NULL; g = g->next)
-    {
-	/*
-	 * Check for free segments.
-	 */
-	if (g->sequence == -1)
-	{
-	    free_map[g->handle >> __AHSHIFT] = 1;
-	    if (g->handle > max_selector_used)
-		max_selector_used = g->handle;
-	}
-
-	/*
-	 * Check for heap allocated segments.
-	 */
-	else if (g->handle == 0)
-	{
-	    selector = (unsigned int) g->addr >> 16;
-	    free_map[selector >> __AHSHIFT] = 0;
-	    if (selector > max_selector_used)
-		max_selector_used = selector;
-	}
-    }
-
-    /*
-     * All segments past the biggest selector used are free.
-     */
-    for (i = (max_selector_used >> __AHSHIFT) + 1; i < 512; i++)
-	free_map[i] = 1;
-
-    /*
-     * Find the largest free block of segments
-     */
-    current_free = 0;
-    max_free = 0;
-    for (i = 0; i < 512; i++)
-    {
-	if (free_map[i] == 1)
-	{
-	    current_free++;
-	}
-	else
-	{
-	    if (current_free > max_free)
-		max_free = current_free;
-	    current_free = 0;
-	}
-    }
-
-    /* One final check just in case the last block was also marked free, in
-     * which case the above test against max_free doesn't occur for the
-     * last run of free blocks.
-     */
-    if (current_free > max_free)
-        max_free = current_free;
-    
-    return max_free << 16;
+    dprintf_global( stddeb, "GlobalFlags: %04x\n", handle );
+    return 0;  /* lock count is always 0 */
 }
-
-/**********************************************************************
- *					GlobalReAlloc
- *
+
+
+/***********************************************************************
+ *           LockSegment   (KERNEL.23)
  */
-unsigned int
-GlobalReAlloc(unsigned int block, unsigned int new_size, unsigned int flags)
+HGLOBAL LockSegment( HGLOBAL handle )
 {
-    GDESC *g;
-    unsigned int n_segments;
-    int i;
-
-    if (block == 0)
-	return 0;
-
-    /*
-     * Find GDESC for this block.
-     */
-    g = GlobalGetGDesc(block);
-    if (g == NULL)
-	return 0;
-    
-    /*
-     * If this is a heap allocated block,  then use HEAP_ReAlloc() to
-     * reallocate the block.  If this fails, call GlobalAlloc() to get
-     * a new block.
-     */
-    if (g->sequence == 0)
-    {
-	MDESC **free_list;
-	void *p;
-	
-	free_list = (MDESC **) ((unsigned int) g->addr & 0xffff0000);
-	p = HEAP_ReAlloc(free_list, g->addr, new_size, flags) ;
-	if (p == NULL)
-	{
-	    unsigned int handle = GlobalAlloc(flags, new_size);
-	    if (handle == 0)
-		return 0;
-	    p = GlobalLock(handle);
-	    memcpy(p, g->addr, g->length);
-	    GlobalUnlock(handle);
-	    GlobalFree(g->handle);
-
-	    return handle;
-	}
-	else
-	{
-	    g->addr = p;
-	    g->length = new_size;
-	    return g->handle;
-	}
-    }
-    
-    /*
-     * Otherwise, we need to do the work ourselves.  First verify the
-     * handle.
-     */
-    else
-    {
-	if (g->sequence != 1)
-	    return 0;
-
-	/*
-	 * Do we need more memory?  Segments are in ascending order in 
-	 * the GDESC list.
-	 */
-	n_segments = (new_size >> 16) + 1;
-        if (n_segments > g->length)
-	{
-	    GDESC *g_new;
-	    GDESC *g_start = g;
-/*	    int old_segments = g_start->length;*/
-	    unsigned short next_handle = g_start->handle;
-	    
-	    for (i = 1; i <= n_segments; i++, g = g->next)
-	    {
-		/*
-		 * If we run into a block allocated to something else,
-		 * try GlobalGetFreeSegments() and memcpy(). (Yuk!)
-		 */
-		if (g->sequence != i || g->handle != next_handle)
-		{
-		    g = GlobalGetFreeSegments(flags, n_segments);
-		    if (g == NULL)
-			return 0;
-		    
-		    memcpy(g->addr, g_start->addr,
-			   g_start->length << 16);
-
-		    GlobalFree(block);
-		    return g->handle;
-		}
-
-		/*
-		 * Otherwise this block is used by us or free.  So,
-		 * snatch it.  If this block is new and we are supposed to
-		 * zero init, then do some erasing.
-		 */
-		if (g->sequence == -1 && (flags & GLOBAL_FLAGS_ZEROINIT))
-		    memset(g->addr, 0, 0x10000);
-		
-		g->sequence = i;
-		g->length = n_segments;
-		next_handle += 8;
-
-		/*
-		 * If the next descriptor is non-existant, then use
-		 * GlobalGetFreeSegments to create them.
-		 */
-		if (i != n_segments && g->next == NULL)
-		{
-		    g_new = GlobalGetFreeSegments(flags, n_segments - i);
-		    if (g_new == NULL)
-			return 0;
-		    GlobalFree(g_new->handle);
-		}
-	    }
-
-	    return g_start->handle;
-	}
-	
-	/*
-	 * Do we need less memory?
-	 */
-	else if (n_segments < g->length)
-	{
-	    GDESC *g_free;
-	    int old_length = g->length;
-	    
-	    g_free = g;
-	    for (i = 0; i < n_segments; i++)
-	    {
-		if (g_free->sequence != i + 1)
-		    return 0;
-		g_free->length = n_segments;
-		g_free = g_free->next;
-	    }
-
-	    for ( ; i < old_length; i++)
-	    {
-		g_free->length = 0x10000;
-		g_free->sequence = -1;
-		g_free = g_free->next;
-	    }
-
-	    return g->handle;
-	}
-	
-	/*
-	 * We already have exactly the right amount of memory.
-	 */
-	else
-	    return block;
-    }
-
-    /*
-     * If we fall through it must be an error.
-     */
-    return 0;
+    dprintf_global( stddeb, "LockSegment: %04x\n", handle );
+    if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
+    return handle;
 }
-
-/**********************************************************************
- *					GlobalQuickAlloc
+
+
+/***********************************************************************
+ *           UnlockSegment   (KERNEL.24)
  */
-void *
-GlobalQuickAlloc(int size)
+void UnlockSegment( HGLOBAL handle )
 {
-    unsigned int hmem;
-    
-    hmem = GlobalAlloc(GLOBAL_FLAGS_MOVEABLE, size);
-    if (hmem == 0)
-	return NULL;
-    else
-	return GlobalLock(hmem);
+    dprintf_global( stddeb, "UnlockSegment: %04x\n", handle );
+    /* FIXME: this ought to return the lock count in CX (go figure...) */
 }
-
-/**********************************************************************
- *					GlobalHandleFromPointer
 
+
+/***********************************************************************
+ *           GlobalCompact   (KERNEL.25)
  */
-unsigned int
-GlobalHandleFromPointer(void *block)
+DWORD GlobalCompact( DWORD desired )
 {
-    GDESC *g;
-
-    if (block == NULL)
-	return 0;
-
-    /*
-     * Find GDESC for this block.
-     */
-    for (g = GlobalList; g != NULL; g = g->next)
-	if (g->handle > 0 && g->addr == block)
-	    break;
-
-    if (g == NULL)
-	return 0;
-    else
-	return g->handle;
+    return GLOBAL_MAX_ALLOC_SIZE;
 }
-
-/**********************************************************************
- *                      GetFreeSpace (kernel.169)
 
+
+/***********************************************************************
+ *           GlobalWire   (KERNEL.111)
  */
-DWORD GetFreeSpace(UINT wFlags)
-/* windows 3.1 doesn't use the wFlags parameter !! 
-   (so I won't either)                            */
+LPSTR GlobalWire( HGLOBAL handle )
 {
-    GDESC *g;
-    unsigned char free_map[512];
-    unsigned int max_selector_used = 0;
-    unsigned int i;
-    unsigned int selector;
-    int total_free;
-
-    /*
-     * Initialize free list to all items not controlled by GlobalAlloc()
-     */
-    for (i = 0; i < 512; i++)
-	free_map[i] = -1;
-
-    /*
-     * Traverse table looking for used and free selectors.
-     */
-    for (g = GlobalList; g != NULL; g = g->next)
-    {
-	/*
-	 * Check for free segments.
-	 */
-	if (g->sequence == -1)
-	{
-	    free_map[g->handle >> __AHSHIFT] = 1;
-	    if (g->handle > max_selector_used)
-		max_selector_used = g->handle;
-	}
-
-	/*
-	 * Check for heap allocated segments.
-	 */
-	else if (g->handle == 0)
-	{
-	    selector = (unsigned int) g->addr >> 16;
-	    free_map[selector >> __AHSHIFT] = 0;
-	    if (selector > max_selector_used)
-		max_selector_used = selector;
-	}
-    }
-
-    /*
-     * All segments past the biggest selector used are free.
-     */
-    for (i = (max_selector_used >> __AHSHIFT) + 1; i < 512; i++)
-	free_map[i] = 1;
-
-    /*
-     * Add up the total free segments (obviously this amount of memory
-       may not be contiguous, use GlobalCompact to get largest contiguous
-       memory available).
-     */
-    total_free=0;
-    for (i = 0; i < 512; i++)
-	if (free_map[i] == 1)
-	    total_free++;
-
-    dprintf_heap(stddeb,"GetFreeSpace // return %ld !\n", (long) (total_free << 16));
-    return total_free << 16;
+    return GlobalLock( handle );
 }
-
-/**********************************************************************
- *                      MemManInfo (toolhelp.72)
+
+
+/***********************************************************************
+ *           GlobalUnWire   (KERNEL.112)
  */
-BOOL MemManInfo(LPMEMMANINFO lpmmi)
+BOOL GlobalUnWire( HGLOBAL handle )
 {
-	return 1;
+    return GlobalUnlock( handle );
 }
 
+
+/***********************************************************************
+ *           GlobalDOSAlloc   (KERNEL.184)
+ */
+DWORD GlobalDOSAlloc( DWORD size )
+{
+    WORD sel = GlobalAlloc( GMEM_FIXED, size );
+    if (!sel) return 0;
+    return MAKELONG( sel, sel /* this one ought to be a real-mode segment */ );
+}
+
+
+/***********************************************************************
+ *           GlobalDOSFree   (KERNEL.185)
+ */
+WORD GlobalDOSFree( WORD sel )
+{
+    return GlobalFree( GlobalHandle(sel) ) ? sel : 0;
+}
+
+
 /***********************************************************************
  *           SetSwapAreaSize   (KERNEL.106)
  */
@@ -846,61 +274,100 @@
     return MAKELONG( size, 0xffff );
 }
 
-/***********************************************************************
- *           IsBadCodePtr   (KERNEL.336)
- */
-BOOL IsBadCodePtr( FARPROC lpfn )
-{
-    printf( "STUB: IsBadCodePtr(%p)\n", lpfn );
-    return FALSE;
-}
 
 /***********************************************************************
- *           IsBadHugeWritePtr  (KERNEL.347)
+ *           GlobalLRUOldest   (KERNEL.163)
  */
-BOOL IsBadHugeWritePtr( const char *lp, DWORD cb )
+HGLOBAL GlobalLRUOldest( HGLOBAL handle )
 {
-    return !test_memory(&lp[cb-1], TRUE);
+    dprintf_global( stddeb, "GlobalLRUOldest: %04x\n", handle );
+    if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
+    return handle;
 }
 
-/***********************************************************************
- *           IsBadWritePtr   	(KERNEL.335)
- */
-BOOL IsBadWritePtr( const char *lp, DWORD cb )
-{
-    if ((0xffff & (unsigned int) lp) + cb > 0xffff)
-	return TRUE;
-    return !test_memory(&lp[cb-1], TRUE);
-}
 
 /***********************************************************************
- *           IsBadReadPtr      (KERNEL.334)
+ *           GlobalLRUNewest   (KERNEL.164)
  */
-BOOL IsBadReadPtr( const char *lp, DWORD cb )
+HGLOBAL GlobalLRUNewest( HGLOBAL handle )
 {
-    if ((0xffff & (unsigned int) lp) + cb > 0xffff)
-	return TRUE;
-    return !test_memory(&lp[cb-1], FALSE);
+    dprintf_global( stddeb, "GlobalLRUNewest: %04x\n", handle );
+    if (handle == (HGLOBAL)-1) handle = CURRENT_DS;
+    return handle;
 }
 
-/***********************************************************************
- *           IsBadHugeReadPtr  (KERNEL.346)
- */
-BOOL IsBadHugeReadPtr( const char *lp, DWORD cb )
-{
-    if ((0xffff & (unsigned int) lp) + cb > 0xffff)
-	return TRUE;
-    return !test_memory(&lp[cb-1], FALSE);
-}
 
 /***********************************************************************
- *           IsBadStringPtr   (KERNEL.337)
+ *           GetFreeSpace   (KERNEL.169)
  */
-BOOL IsBadStringPtr( const char *lp, UINT cb )
+DWORD GetFreeSpace( UINT wFlags )
 {
-    if (!IsBadReadPtr(lp, cb+1))
-	return FALSE;
-    if (lp[cb])
-	return FALSE;
-    return TRUE;
+    return GLOBAL_MAX_ALLOC_SIZE;
 }
+
+
+/***********************************************************************
+ *           GlobalPageLock   (KERNEL.191)
+ */
+WORD GlobalPageLock( HGLOBAL handle )
+{
+    dprintf_global( stddeb, "GlobalPageLock: %04x\n", handle );
+    /* Nothing to do, as we can't page-lock a block (and we don't want to) */
+    return 1;  /* lock count */
+}
+
+
+/***********************************************************************
+ *           GlobalPageUnlock   (KERNEL.192)
+ */
+WORD GlobalPageUnlock( HGLOBAL handle )
+{
+    dprintf_global( stddeb, "GlobalPageUnlock: %04x\n", handle );
+    return 0;  /* lock count */
+}
+
+
+/***********************************************************************
+ *           GlobalFix   (KERNEL.197)
+ */
+void GlobalFix( HGLOBAL handle )
+{
+    dprintf_global( stddeb, "GlobalFix: %04x\n", handle );
+    /* Nothing to do, as all the blocks are fixed in linear memory anyway */
+}
+
+
+/***********************************************************************
+ *           GlobalUnfix   (KERNEL.198)
+ */
+void GlobalUnfix( HGLOBAL handle )
+{
+    dprintf_global( stddeb, "GlobalUnfix: %04x\n", handle );
+    /* This one is even more complicated that GlobalFix() :-) */
+}
+
+
+/***********************************************************************
+ *           GlobalHandleToSel   (TOOLHELP.50)
+ */
+WORD GlobalHandleToSel( HGLOBAL handle )
+{
+    dprintf_toolhelp( stddeb, "GlobalHandleToSel: %04x\n", handle );
+    if (!(handle & 7))
+    {
+        fprintf( stderr, "Program attempted invalid selector conversion\n" );
+        return handle - 1;
+    }
+    return handle | 1;
+}
+
+
+/**********************************************************************
+ *                      MemManInfo (toolhelp.72)
+ */
+/*
+BOOL MemManInfo(LPMEMMANINFO lpmmi)
+{
+	return 1;
+}
+*/
diff --git a/memory/heap.c b/memory/heap.c
deleted file mode 100644
index 54157d0..0000000
--- a/memory/heap.c
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
-static char RCSId[] = "$Id: heap.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "prototypes.h"
-#include "segmem.h"
-#include "heap.h"
-#include "regfunc.h"
-#include "dlls.h"
-#include "stddebug.h"
-/* #define DEBUG_HEAP */
-#include "debug.h"
-
-
-LHEAP *LocalHeaps = NULL;
-
-void
-HEAP_CheckHeap(MDESC **free_list)
-{
-    MDESC *m;
-
-    for (m = *free_list; m != NULL; m = m->next)
-    {
-	if (((int) m & 0xffff0000) != ((int) *free_list & 0xffff0000))
-	{   dprintf_heap(stddeb,"Invalid block %p\n",m);
-	    *(char *)0 = 0;
-	}
-	if (m->prev && (((int) m->prev & 0xffff0000) != ((int) *free_list & 0xffff0000)))
-	{   dprintf_heap(stddeb,"Invalid prev %p from %p\n", m->prev, m);
-	    *(char *)0 = 0;
-	}
-    }
-}
-
-/**********************************************************************
- *					HEAP_Init
- */
-void
-HEAP_Init(MDESC **free_list, void *start, int length)
-{
-    if (length < 2 * sizeof(MDESC))
-	return;
-    
-    *free_list = (MDESC *) start;
-    (*free_list)->prev   = NULL;
-    (*free_list)->next   = NULL;
-    (*free_list)->length = length - sizeof(MDESC);
-}
-
-/**********************************************************************
- *					HEAP_Alloc
- */
-void *
-HEAP_Alloc(MDESC **free_list, int flags, int bytes)
-{
-    MDESC *m, *m_new;
-    
-    dprintf_heap(stddeb,"HeapAlloc: free_list %08x(%08x), flags %x, bytes %d\n", 
-	   (unsigned int) free_list, (unsigned int) *free_list, flags, bytes);
-    if(debugging_heap)HEAP_CheckHeap(free_list);
-
-    /*
-     * Find free block big enough.
-     */
-    for (m = *free_list; m != NULL; m = m->next)
-    {
-	if (m->length >= bytes && m->length < bytes + 4 * sizeof(MDESC))
-	{
-	    break;
-	}
-	else if (m->length > bytes)
-	{
-	    m_new = m + (bytes / sizeof(MDESC)) + 2;
-	    if (m->prev == NULL)
-		*free_list = m_new;
-	    else
-		m->prev->next = m_new;
-	    
-	    if (m->next != NULL)
-		m->next->prev = m_new;
-	    
-	    m_new->next = m->next;
-	    m_new->prev = m->prev;
-	    m_new->length = m->length - ((int) m_new - (int) m);
-	    m->length -= (m_new->length + sizeof(MDESC));
-
-	    m->prev = m;
-	    m->next = m;
-	    m->lock = 0;
-	    m->flags = 0;
-	    if (flags & GLOBAL_FLAGS_ZEROINIT)
-		memset(m + 1, 0, bytes);
-	    dprintf_heap(stddeb,"HeapAlloc: returning %08x\n", 
-	    	(unsigned int) (m + 1));
-	    if(debugging_heap)HEAP_CheckHeap(free_list);
-	    return (void *) (m + 1);
-	}
-    }
-
-    if (m != NULL)
-    {
-	if (m->prev == NULL)
-	    *free_list = m->next;
-	else
-	    m->prev->next = m->next;
-	
-	if (m->next != NULL)
-	    m->next->prev = m->prev;
-	
-	m->prev = m;
-	m->next = m;
-	m->lock = 0;
-	m->flags = 0;
-	if (flags & GLOBAL_FLAGS_ZEROINIT)
-	    memset(m + 1, 0, bytes);
-	dprintf_heap(stddeb,"HeapAlloc: returning %08x\n",
-	    	(unsigned int)  (m + 1));
-        if(debugging_heap)HEAP_CheckHeap(free_list);
-	return (void *) (m + 1);
-    }
-
-    dprintf_heap(stddeb,"HeapAlloc: returning %08x\n", 0);
-    if(debugging_heap)HEAP_CheckHeap(free_list);
-    return 0;
-}
-
-/**********************************************************************
- *					HEAP_ReAlloc
- */
-void *
-HEAP_ReAlloc(MDESC **free_list, void *old_block, 
-	     int new_size, unsigned int flags)
-{
-    MDESC *m_free;
-    MDESC *m;
-
-
-    if (!old_block)
-	return HEAP_Alloc(free_list, flags, new_size);
-    
-    /*
-     * Check validity of block
-     */
-    m = (MDESC *) old_block - 1;
-
-    dprintf_heap(stddeb,"HEAP_ReAlloc new_size=%d !\n", 
-	    	(unsigned int) new_size);
-    dprintf_heap(stddeb,"HEAP_ReAlloc old_block=%08X !\n",
-	    	(unsigned int)  old_block);
-    dprintf_heap(stddeb,"HEAP_ReAlloc m=%08X free_list=%08X !\n", 
-	    	(unsigned int) m, (unsigned int) free_list);
-    dprintf_heap(stddeb,"HEAP_ReAlloc m->prev=%08X !\n",
-    	 (unsigned int)  m->prev);
-    dprintf_heap(stddeb,"HEAP_ReAlloc m->next=%08X !\n",
-    	 (unsigned int)  m->next);
-    dprintf_heap(stddeb,"HEAP_ReAlloc *free_list=%08X !\n",
-    	 (unsigned int)  *free_list);
-    if(debugging_heap)HEAP_CheckHeap(free_list);
-
-    if (m->prev != m || m->next != m || 
-	((int) m & 0xffff0000) != ((int) *free_list & 0xffff0000))
-    {
-	fprintf(stderr,"Attempt to resize bad pointer, m = %p, *free_list = %p\n",
-	       m, free_list);
-	HEAP_CheckHeap(free_list);
-	return NULL;
-    }
-    
-    /*
-     * Check for grow block
-     */
-
-    dprintf_heap(stddeb,"HEAP_ReAlloc Check for grow block !\n");
-    if (new_size > m->length)
-    {
-	m_free = m + 1 + m->length / sizeof(MDESC);
-	if (m_free->next == m_free || 
-	    m_free->prev == m_free ||
-	    m_free->length + 2*sizeof(MDESC) < new_size - m->length)
-	{
-	    void *new_p = HEAP_Alloc(free_list, flags, new_size);
-	    if (new_p ==NULL)
-		return NULL;
-	    memcpy(new_p, old_block, m->length);
-	    HEAP_Free(free_list, old_block);
-	    if(debugging_heap)HEAP_CheckHeap(free_list);
-	    return new_p;
-	}
-
-	if (m_free->prev == NULL)
-	    *free_list = m_free->next;
-	else
-	    m_free->prev->next = m_free->next;
-	
-	if (m_free->next != NULL)
-	    m_free->next->prev = m_free->prev;
-	
-	m->length += sizeof(MDESC) + m_free->length;
-
-	dprintf_heap(stddeb,"HEAP_ReAlloc before GLOBAL_FLAGS_ZEROINIT !\n");
-	if (flags & GLOBAL_FLAGS_ZEROINIT)
-	    memset(m_free, '\0', sizeof(MDESC) + m_free->length);
-    }
-
-    /*
-     * Check for shrink block.
-     */
-    dprintf_heap(stddeb,"HEAP_ReAlloc Check for shrink block !\n");
-    if (new_size + 4*sizeof(MDESC) < m->length)
-    {
-	m_free = m + new_size / sizeof(MDESC) + 2;
-	m_free->next = m_free;
-	m_free->prev = m_free;
-	m_free->length = m->length - ((int) m_free - (int) m);
-	m->length = (int) m_free - (int) (m + 1);
-	HEAP_Free(free_list, m_free + 1);
-    }
-    
-    if(debugging_heap)HEAP_CheckHeap(free_list);
-    return old_block;
-}
-
-
-/**********************************************************************
- *					HEAP_Free
- */
-int
-HEAP_Free(MDESC **free_list, void *block)
-{
-    MDESC *m_free;
-    MDESC *m;
-    MDESC *m_prev;
-
-    dprintf_heap(stddeb,"HeapFree: free_list %p, block %p\n", 
-	   free_list, block);
-    if(debugging_heap)HEAP_CheckHeap(free_list);
-
-    /*
-     * Validate pointer.
-     */
-    m_free = (MDESC *) block - 1;
-    if (m_free->prev != m_free || m_free->next != m_free)
-    {
-	fprintf(stderr,"Attempt to free bad pointer,"
-	       "m_free = %p, *free_list = %p\n",
-	       m_free, free_list);
-	return -1;
-    }
-
-    if (*free_list == NULL)
-    {
-	*free_list = m_free;
-	(*free_list)->next = NULL;
-	(*free_list)->prev = NULL;
-	return 0;
-    }
-    else if (((int) m_free & 0xffff0000) != ((int) *free_list & 0xffff0000))
-    {
-	fprintf(stderr,"Attempt to free bad pointer,"
-	       "m_free = %p, *free_list = %p\n",
-	       m_free, free_list);
-	return -1;
-    }
-
-    /*
-     * Find location in free list.
-     */
-    m_prev = NULL;
-    for (m = *free_list; m != NULL && m < m_free; m = m->next)
-	m_prev = m;
-    
-    if (m_prev != NULL && (int) m_prev + m_prev->length > (int) m_free)
-    {
-	fprintf(stderr,"Attempt to free bad pointer,"
-	       "m_free = %p, m_prev = %p (length %x)\n",
-	       m_free, m_prev, m_prev->length);
-	return -1;
-    }
-	
-    if ((m != NULL && (int) m_free + m_free->length > (int) m) ||
-	(int) m_free + m_free->length > ((int) m_free | 0xffff))
-    {
-	fprintf(stderr,"Attempt to free bad pointer,"
-	       "m_free = %p (length %x), m = %p\n",
-	       m_free, m_free->length, m);
-	return -1;
-    }
-
-    /*
-     * Put block back in free list.
-     * Does it merge with the previos block?
-     */
-    if (m_prev != NULL)
-    {
-	if ((int) m_prev + m_prev->length == (int) m_free)
-	{
-	    m_prev->length += sizeof(MDESC) + m_free->length;
-	    m_free = m_prev;
-	}
-	else
-	{
-	    m_prev->next = m_free;
-	    m_free->prev = m_prev;
-	}
-    }
-    else
-    {
-	*free_list = m_free;
-	m_free->prev = NULL;
-    }
-    
-    /*
-     * Does it merge with the next block?
-     */
-    if (m != NULL)
-    {
-	if ((int) m_free + m_free->length == (int) m)
-	{
-	    m_free->length += sizeof(MDESC) + m->length;
-	    m_free->next = m->next;
-	}
-	else
-	{
-	    m->prev = m_free;
-	    m_free->next = m;
-	}
-    }
-    else
-    {
-	m_free->next = NULL;
-    }
-
-    if(debugging_heap)HEAP_CheckHeap(free_list);
-    return 0;
-}
-
-/**********************************************************************
- *					HEAP_CheckLocalHeaps
- */
-void
-HEAP_CheckLocalHeaps(char *file,int line)
-{
-    LHEAP *lh;
-    dprintf_heap(stddeb,"CheckLocalHeaps called from %s %d\n",file,line);
-    for(lh=LocalHeaps; lh!=NULL; lh = lh->next)
-    {	dprintf_heap(stddeb,"Checking heap %p, free_list %p\n",
-		lh,lh->free_list);
-	HEAP_CheckHeap(&lh->free_list);
-    }
-}
-
-
-/**********************************************************************
- *					HEAP_LocalFindHeap
- */
-LHEAP *
-HEAP_LocalFindHeap(unsigned short owner)
-{
-    LHEAP *lh;
-    
-    dprintf_heap(stddeb,"HEAP_LocalFindHeap: owner %04x\n", owner);
-
-    for (lh = LocalHeaps; lh != NULL; lh = lh->next)
-    {
-	if (lh->selector == owner)
-	    return lh;
-    }
-
-    dprintf_heap(stddeb,"Warning: Local heap not found\n");
-    return NULL;
-}
-
-/**********************************************************************
- *					HEAP_LocalInit
- */
-void
-HEAP_LocalInit(unsigned short owner, void *start, int length)
-{
-    LHEAP *lh;
-
-    dprintf_heap(stddeb,"HEAP_LocalInit: owner %04x, start %p, length %04x\n"
-	   ,owner, start, length);
-
-    if (length < 2 * sizeof(MDESC))
-	return;
-    
-    lh = (LHEAP *) malloc(sizeof(*lh));
-    if (lh == NULL)
-	return;
-    
-    lh->next        = LocalHeaps;
-    lh->selector    = owner;
-    lh->local_table = NULL;
-    lh->delta       = 0x20;
-    HEAP_Init(&lh->free_list, start, length);
-    dprintf_heap(stddeb,"HEAP_LocalInit: free_list %p, length %04x, prev %p, next %p\n",&lh->free_list,lh->free_list->length, lh->free_list->prev,lh->free_list->next);
-    LocalHeaps = lh;
-}
-
-/**********************************************************************
- *					HEAP_LocalSize
- */
-unsigned int
-HEAP_LocalSize(MDESC **free_list, unsigned int handle)
-{
-    MDESC *m;
-    
-    m = (MDESC *) (((int) *free_list & 0xffff0000) | 
-		   (handle & 0xffff)) - 1;
-    if (m->next != m || m->prev != m)
-	return 0;
-
-    return m->length;
-}
-
-/**********************************************************************
- *					WIN16_LocalAlloc
- */
-void *
-WIN16_LocalAlloc(int flags, int bytes)
-{
-    void *m;
-    
-    dprintf_heap(stddeb,"WIN16_LocalAlloc: flags %x, bytes %d\n", flags,bytes);
-    dprintf_heap(stddeb,"    called from segment %04x, ds=%04x\n", pStack16Frame->cs,pStack16Frame->ds);
-
-    m = HEAP_Alloc(LOCALHEAP(), flags, bytes);
-	
-    dprintf_heap(stddeb,"WIN16_LocalAlloc: returning %x\n", (int) m);
-    return m;
-}
-
-/**********************************************************************
- *					WIN16_LocalCompact
- */
-int
-WIN16_LocalCompact(int min_free)
-{
-    MDESC *m;
-    int max_block;
-    
-    max_block = 0;
-    for (m = *LOCALHEAP(); m != NULL; m = m->next)
-	if (m->length > max_block)
-	    max_block = m->length;
-    
-    return max_block;
-}
-
-/**********************************************************************
- *					WIN16_LocalFlags
- */
-unsigned int
-WIN16_LocalFlags(unsigned int handle)
-{
-    MDESC *m;
-
-    m = (MDESC *) (((int) *LOCALHEAP() & 0xffff0000) | 
-		   (handle & 0xffff)) - 1;
-    if (m->next != m || m->prev != m)
-	return 0;
-    
-    return m->lock;
-}
-
-/**********************************************************************
- *					WIN16_LocalFree
- */
-unsigned int 
-WIN16_LocalFree(unsigned int handle)
-{
-    unsigned int addr;
-    
-    addr = ((int) *LOCALHEAP() & 0xffff0000) | (handle & 0xffff);
-    if (HEAP_Free(LOCALHEAP(), (void *) addr) < 0)
-	return handle;
-    else
-	return 0;
-}
-
-/**********************************************************************
- *					WIN16_LocalInit
- */
-unsigned int
-WIN16_LocalInit(unsigned int segment, unsigned int start, unsigned int end)
-{
-    unsigned short owner = HEAP_OWNER;
-    LHEAP *lh = HEAP_LocalFindHeap(owner);
-    
-    if (segment == 0)
-    {
-	/* Get current DS */
-	segment = pStack16Frame->ds;
-    }
-
-    dprintf_heap(stddeb, "WIN16_LocalInit   segment=%04x  start=%04x  end=%04x\n", segment, start, end);
-
-    /* start=0 doesn't mean the first byte of the segment if the segment 
-       is an auto data segment. Instead it should start after the actual
-       data (and the stack if there is one). As we don't know the length
-       of the data and stack right now, we simply put the local heap at the
-       end of the segment */
-    if ((start==0)&&(Segments[segment>>__AHSHIFT].owner==segment))
-    {
-        return;
-        start = Segments[segment>>__AHSHIFT].length-end-2;
-        end   = Segments[segment>>__AHSHIFT].length-1;  
-        dprintf_heap(stddeb, "Changed to  start=%04x  end=%04x\n",start,end);
-    }
-
-    if (lh == NULL)
-    {
-	HEAP_LocalInit(owner, 
-		       (void *) ((segment << 16) | start), end - start + 1);
-    }
-    else
-    {
-	HEAP_Init(&lh->free_list,
-		  (void *) ((segment << 16) | start), end - start + 1);
-    }
-    dprintf_heap(stddeb,"WIN16_LocalInit // return segment=%04X !\n", segment);
-    return segment;
-}
-
-/**********************************************************************
- *					WIN16_LocalLock
- */
-void *
-WIN16_LocalLock(unsigned int handle)
-{
-    MDESC *m;
-
-    m = (MDESC *) (((int) *LOCALHEAP() & 0xffff0000) | 
-		   (handle & 0xffff)) - 1;
-    if (m->next != m || m->prev != m)
-	return 0;
-
-    m->lock++;
-    return (void *) (m + 1);
-}
-
-/**********************************************************************
- *					WIN16_LocalReAlloc
- */
-void *
-WIN16_LocalReAlloc(unsigned int handle, int bytes, int flags)
-{
-    void *m;
-    dprintf_heap(stddeb,"WIN16_LocalReAlloc(%04X, %d, %04X); !\n",	
-		 handle, bytes, flags);
-    dprintf_heap(stddeb,"WIN16_LocalReAlloc // LOCALHEAP()=%p !\n", 
-		 LOCALHEAP());
-    dprintf_heap(stddeb,"WIN16_LocalReAlloc // *LOCALHEAP()=%p !\n", 
-		 *LOCALHEAP());
-    m = HEAP_ReAlloc(LOCALHEAP(), (void *)
-		     (((int) *LOCALHEAP() & 0xffff0000) | (handle & 0xffff)),
-		     bytes, flags);
-	
-    return m;
-}
-
-/**********************************************************************
- *					WIN16_LocalSize
- */
-unsigned int
-WIN16_LocalSize(unsigned int handle)
-{
-    MDESC *m;
-
-    m = (MDESC *) (((int) *LOCALHEAP() & 0xffff0000) | 
-		   (handle & 0xffff)) - 1;
-    if (m->next != m || m->prev != m)
-	return 0;
-
-    return m->length;
-}
-
-/**********************************************************************
- *					WIN16_LocalUnlock
- */
-unsigned int
-WIN16_LocalUnlock(unsigned int handle)
-{
-    MDESC *m;
-    
-    m = (MDESC *) (((int) *LOCALHEAP() & 0xffff0000) | 
-		   (handle & 0xffff)) - 1;
-    if (m->next != m || m->prev != m)
-	return 1;
-
-    if (m->lock > 0)
-	m->lock--;
-
-    return 0;
-}
-
-/**********************************************************************
- *					WIN16_LocalHandleDelta
- */
-unsigned int
-WIN16_LocalHandleDelta(unsigned int new_delta)
-{
-    LHEAP *lh;
-    
-    lh = HEAP_LocalFindHeap(HEAP_OWNER);
-    if (lh == NULL)
-	return 0;
-    
-    if (new_delta)
-	lh->delta = new_delta;
-
-    return lh->delta;
-}
-
-/**********************************************************************
- *                      GetFreeSystemResources (user.284)
-
- */
-#define USERRESOURCES 2
-#define GDIRESOURCES 1
-#define SYSTEMRESOURCES 0
-#include <user.h>
-#include <gdi.h>
-
-WORD GetFreeSystemResources(WORD SystemResourceType)
-{
-  unsigned int GdiFree=0,GdiResult=0;
-  unsigned int UserFree=0,UserResult=0;
-  unsigned int result=0;
-  MDESC *m;
-  dprintf_heap(stddeb,"GetFreeSystemResources(%u)\n",SystemResourceType);
-  switch(SystemResourceType) {
-    case(USERRESOURCES):
-      for (m = USER_Heap; m != NULL; m = m->next) /* add up free area in heap */
-         UserFree += m->length;
-      result=(UserFree*100)/65516;  /* 65516 == 64K */
-      break;
-    case(GDIRESOURCES):
-      for (m = GDI_Heap; m != NULL; m = m->next)
-         GdiFree += m->length;
-      result=(GdiFree*100)/65516;
-      break;
-    case(SYSTEMRESOURCES):
-      for (m = USER_Heap; m != NULL; m = m->next)
-         UserFree += m->length;
-      UserResult=(UserFree*100)/65516;
-      for (m = GDI_Heap; m != NULL; m = m->next)
-         GdiFree += m->length;
-      GdiResult=(GdiFree*100)/65516;
-      result=(UserResult < GdiResult) ? UserResult:GdiResult; 
-      break;
-    default:
-      result=0;
-      break;
-  }
-  return(result);
-}
diff --git a/memory/linear.c b/memory/linear.c
deleted file mode 100644
index 1d09b14..0000000
--- a/memory/linear.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
-static char RCSId[] = "$Id$";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1994";
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "prototypes.h"
-#include "heap.h"
-#include "segmem.h"
-
-#ifdef HAVE_IPC
-static key_t MemoryKeys[SHMSEG];	/* Keep track of keys were using */
-static int   LinearInitialized = 0;
-#endif
-
-
-#ifdef HAVE_IPC
-/**********************************************************************
- *					LinearFindSpace
- */
-int 
-LinearFindSpace(int n_segments)
-{
-    int i, n;
-    
-    if (!LinearInitialized)
-    {
-	memset(MemoryKeys, -1, sizeof(MemoryKeys));
-	return 0;
-    }
-
-    for (i = 0, n = 0; i < SHMSEG, n != n_segments; i++)
-    {
-	if (MemoryKeys[i] < 0)
-	    n++;
-	else
-	    n = 0;
-    }
-    
-    if (n != n_segments)
-	return -1;
-    else
-	return i - n;
-}
-#endif /* HAVE_IPC */
-
-/**********************************************************************
- *					GlobalLinearLock
- *
- * OK, this is an evil beast.  We will do one of two things:
- *
- *	1. If the data item <= 64k, then just call GlobalLock().
- *	2. If the data item > 64k, then map memory.
- */
-void *
-GlobalLinearLock(unsigned int block)
-{
-    GDESC *g, *g_first;
-    int loc_idx;
-    unsigned long addr;
-    int i;
-    
-    /******************************************************************
-     * Get GDESC for this block.
-     */
-    g_first = GlobalGetGDesc(block);
-    if (g_first == NULL)
-	return 0;
-
-    /******************************************************************
-     * Is block less then 64k in length?
-     */
-    if (g_first->sequence != 1 || g_first->length == 1)
-    {
-	return (void *) GlobalLock(block);
-    }
-
-    /******************************************************************
-     * If there is already a linear lock on this memory, then
-     * just return a pointer to it.
-     */
-    if (g_first->linear_count)
-    {
-	g_first->linear_count++;
-	return g_first->linear_addr;
-    }
-    
-    /******************************************************************
-     * No luck.  We need to do the linear mapping right now.
-     */
-#ifdef HAVE_IPC
-    loc_idx = LinearFindSpace(g_first->length);
-    if (loc_idx < 0)
-	return NULL;
-    
-    addr = (unsigned long) SHM_RANGE_START + (0x10000 * loc_idx);
-    g = g_first;
-    for (i = loc_idx; 
-	 i < loc_idx + g_first->length; 
-	 i++, addr += 0x10000, g = g->next)
-    {
-	if ((MemoryKeys[i] = IPCCopySelector(g->handle >> __AHSHIFT,
-					     addr, 0)) < 0)
-	    return NULL;
-	g->linear_addr = (void *) addr;
-	g->linear_count = 1;
-    }
-#endif /* HAVE_IPC */
-
-    return g_first->linear_addr;
-}
-
-/**********************************************************************
- *					GlobalLinearUnlock
- *
- */
-unsigned int
-GlobalLinearUnlock(unsigned int block)
-{
-    GDESC *g, *g_first;
-    int loc_idx;
-    int i;
-    
-    /******************************************************************
-     * Get GDESC for this block.
-     */
-    g_first = GlobalGetGDesc(block);
-    if (g_first == NULL)
-	return block;
-
-    /******************************************************************
-     * Is block less then 64k in length?
-     */
-    if (g_first->sequence != 1 || g_first->length == 1)
-    {
-	return GlobalUnlock(block);
-    }
-
-    /******************************************************************
-     * Make sure we have a lock on this block.
-     */
-#ifdef HAVE_IPC
-    if (g_first->linear_count > 1)
-    {
-	g_first->linear_count--;
-    }
-    else if (g_first->linear_count == 1)
-    {
-	g = g_first;
-	loc_idx = (((unsigned int) g_first - (unsigned int) SHM_RANGE_START) 
-		   / 0x10000);
-	for (i = 0; i < g_first->length; i++, g = g->next)
-	{
-	    shmdt(g->linear_addr);
-	    g->linear_addr = NULL;
-	    MemoryKeys[i] = -1;
-	}
-	
-	g_first->linear_count = 0;
-	return 0;
-    }
-#endif /* HAVE_IPC */
-
-    return 0;
-}
-/**********************************************************************/
-
-void LinearTest()
-{
-#if 0
-    unsigned int handle;
-    int *seg_ptr;
-    int *lin_ptr;
-    int seg, i;
-    int *p;
-
-    handle = GlobalAlloc(0, 0x40000);
-    seg_ptr = GlobalLock(handle);
-    lin_ptr = GlobalLinearLock(handle);
-
-    for (seg = 0; seg < 4; seg++)
-    {
-	p = (int *) ((char *) seg_ptr + (0x80000 * seg));
-	for (i = 0; i < (0x10000 / sizeof(int)); i++, p++)
-	    *p = (seg * (0x10000 / sizeof(int))) + i;
-    }
-    
-    p = lin_ptr;
-    for (i = 0; i < (0x40000 / sizeof(int)); i++, p++)
-    {
-	if (*p != i)
-	    printf("lin_ptr[%x] = %x\n", i, *p);
-    }
-#endif
-}
diff --git a/memory/local.c b/memory/local.c
new file mode 100644
index 0000000..5adf693
--- /dev/null
+++ b/memory/local.c
@@ -0,0 +1,725 @@
+/*
+ * Local heap functions
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+/*
+ * Note:
+ * All local heap functions need the current DS as first parameter
+ * when called from the emulation library, so they take one more
+ * parameter than usual.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "windows.h"
+#include "ldt.h"
+#include "instance.h"
+#include "local.h"
+#include "stackframe.h"
+#include "toolhelp.h"
+#include "stddebug.h"
+#include "debug.h"
+
+
+#ifndef WINELIB
+#pragma pack(1)
+#endif
+
+typedef struct
+{
+/* Arena header */
+    WORD prev;          /* Previous arena | arena type */
+    WORD next;          /* Next arena */
+/* Start of the memory block or free-list info */
+    WORD size;          /* Size of the free block */
+    WORD free_prev;     /* Previous free block */
+    WORD free_next;     /* Next free block */
+} LOCALARENA;
+
+#define ARENA_HEADER_SIZE      4
+
+  /* Arena types (stored in 'prev' field of the arena) */
+#define LOCAL_ARENA_FREE       0
+#define LOCAL_ARENA_FIXED      1
+#define LOCAL_ARENA_MOVEABLE   3
+
+
+
+typedef struct
+{
+    WORD addr;                /* Address of the MOVEABLE block */
+    BYTE flags;               /* Flags for this block */
+    BYTE lock;                /* Lock count */
+} LOCALHANDLEENTRY;
+
+typedef struct
+{
+    WORD check;               /* Heap checking flag */
+    WORD freeze;              /* Heap frozen flag */
+    WORD items;               /* Count of items on the heap */
+    WORD first;               /* First item of the heap */
+    WORD pad1;                /* Always 0 */
+    WORD last;                /* Last item of the heap */
+    WORD pad2;                /* Always 0 */
+    BYTE ncompact;            /* Compactions counter */
+    BYTE dislevel;            /* Discard level */
+    DWORD distotal;           /* Total bytes discarded */
+    WORD htable;              /* Pointer to handle table */
+    WORD hfree;               /* Pointer to free handle table */
+    WORD hdelta;              /* Delta to expand the handle table */
+    WORD expand;              /* Pointer to expand function (unused) */
+    WORD pstat;               /* Pointer to status structure (unused) */
+    DWORD notify WINE_PACKED; /* Pointer to LocalNotify() function */
+    WORD lock;                /* Lock count for the heap */
+    WORD extra;               /* Extra bytes to allocate when expanding */
+    WORD minsize;             /* Minimum size of the heap */
+    WORD magic;               /* Magic number */
+} LOCALHEAPINFO;
+
+#ifndef WINELIB
+#pragma pack(4)
+#endif
+
+#define LOCAL_HEAP_MAGIC  0x484c  /* 'LH' */
+
+
+  /* All local heap allocations are aligned on 4-byte boundaries */
+#define LALIGN(word)          (((word) + 3) & ~3)
+
+#define ARENA_PTR(ptr,arena)       ((LOCALARENA *)((char*)(ptr)+(arena)))
+#define ARENA_PREV(ptr,arena)      (ARENA_PTR(ptr,arena)->prev & ~3)
+#define ARENA_NEXT(ptr,arena)      (ARENA_PTR(ptr,arena)->next)
+#define ARENA_FLAGS(ptr,arena)     (ARENA_PTR(ptr,arena)->prev & 3)
+
+
+/***********************************************************************
+ *           LOCAL_GetHeap
+ *
+ * Return a pointer to the local heap, making sure it exists.
+ */
+static LOCALHEAPINFO *LOCAL_GetHeap( WORD ds )
+{
+    LOCALHEAPINFO *pInfo;
+    INSTANCEDATA *ptr = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN( ds, 0 );
+    if (!ptr->heap) return 0;
+    pInfo = (LOCALHEAPINFO*)((char*)ptr + ptr->heap);
+    if (pInfo->magic != LOCAL_HEAP_MAGIC) return NULL;
+    return pInfo;
+}
+
+
+/***********************************************************************
+ *           LOCAL_AddFreeBlock
+ *
+ * Make a block free, inserting it in the free-list.
+ * 'block' is the handle of the block arena; 'baseptr' points to
+ * the beginning of the data segment containing the heap.
+ */
+static void LOCAL_AddFreeBlock( char *baseptr, WORD block )
+{
+    LOCALARENA *pArena, *pNext;
+    WORD next;
+
+      /* Mark the block as free */
+
+    pArena = ARENA_PTR( baseptr, block );
+    pArena->prev = (pArena->prev & ~3) | LOCAL_ARENA_FREE;
+    pArena->size = pArena->next - block;
+    
+      /* Find the next free block (last block is always free) */
+
+    next = pArena->next;
+    for (;;)
+    {
+        pNext = ARENA_PTR( baseptr, next );
+        if ((pNext->prev & 3) == LOCAL_ARENA_FREE) break;
+        next = pNext->next;
+    }
+
+      /* Insert the free block in the free-list */
+
+    pArena->free_prev = pNext->free_prev;
+    pArena->free_next = next;
+    ARENA_PTR(baseptr,pNext->free_prev)->free_next = block;
+    pNext->free_prev  = block;
+}
+
+
+/***********************************************************************
+ *           LOCAL_RemoveFreeBlock
+ *
+ * Remove a block from the free-list.
+ * 'block' is the handle of the block arena; 'baseptr' points to
+ * the beginning of the data segment containing the heap.
+ */
+static void LOCAL_RemoveFreeBlock( char *baseptr, WORD block )
+{
+      /* Mark the block as fixed */
+
+    LOCALARENA *pArena = ARENA_PTR( baseptr, block );
+    pArena->prev = (pArena->prev & ~3) | LOCAL_ARENA_FIXED;
+
+      /* Remove it from the list */
+
+    ARENA_PTR(baseptr,pArena->free_prev)->free_next = pArena->free_next;
+    ARENA_PTR(baseptr,pArena->free_next)->free_prev = pArena->free_prev;
+}
+
+
+/***********************************************************************
+ *           LOCAL_AddBlock
+ *
+ * Insert a new block in the heap.
+ * 'new' is the handle of the new block arena; 'baseptr' points to
+ * the beginning of the data segment containing the heap; 'prev' is
+ * the block before the new one.
+ */
+static void LOCAL_AddBlock( char *baseptr, WORD prev, WORD new )
+{
+    LOCALARENA *pPrev = ARENA_PTR( baseptr, prev );
+    LOCALARENA *pNew  = ARENA_PTR( baseptr, new );
+
+    pNew->prev = prev | LOCAL_ARENA_FIXED;
+    pNew->next = pPrev->next;
+    ARENA_PTR(baseptr,pPrev->next)->prev &= 3;
+    ARENA_PTR(baseptr,pPrev->next)->prev |= new;
+    pPrev->next = new;
+}
+
+
+/***********************************************************************
+ *           LOCAL_RemoveBlock
+ *
+ * Remove a block from the heap.
+ * 'block' is the handle of the block arena; 'baseptr' points to
+ * the beginning of the data segment containing the heap.
+ */
+static void LOCAL_RemoveBlock( char *baseptr, WORD block )
+{
+    LOCALARENA *pArena, *pTmp;
+
+      /* Remove the block from the free-list */
+
+    pArena = ARENA_PTR( baseptr, block );
+    if ((pArena->prev & 3) == LOCAL_ARENA_FREE)
+        LOCAL_RemoveFreeBlock( baseptr, block );
+
+      /* If the previous block is free, expand its size */
+
+    pTmp = ARENA_PTR( baseptr, pArena->prev & ~3 );
+    if ((pTmp->prev & 3) == LOCAL_ARENA_FREE)
+        pTmp->size += pArena->next - block;
+
+      /* Remove the block from the linked list */
+
+    pTmp->next = pArena->next;
+    pTmp = ARENA_PTR( baseptr, pArena->next );
+    pTmp->prev = (pTmp->prev & 3) | (pArena->prev & ~3);
+}
+
+
+/***********************************************************************
+ *           LOCAL_PrintHeap
+ */
+static void LOCAL_PrintHeap( WORD ds )
+{
+    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+    LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds );
+    WORD arena;
+
+    if (!pInfo)
+    {
+        printf( "Local Heap corrupted!  ds=%04x\n", ds );
+        return;
+    }
+    printf( "Local Heap  ds=%04x first=%04x last=%04x items=%d\n",
+            ds, pInfo->first, pInfo->last, pInfo->items );
+
+    arena = pInfo->first;
+    for (;;)
+    {
+        LOCALARENA *pArena = ARENA_PTR(ptr,arena);
+        printf( "  %04x: prev=%04x next=%04x type=%d\n", arena,
+                pArena->prev & ~3, pArena->next, pArena->prev & 3 );
+        if ((pArena->prev & 3) == LOCAL_ARENA_FREE)
+        {
+            printf( "        size=%d free_prev=%04x free_next=%04x\n",
+                    pArena->size, pArena->free_prev, pArena->free_next );
+            if (pArena->next == arena) break;  /* last one */
+            if (ARENA_PTR(ptr,pArena->free_next)->free_prev != arena)
+            {
+                printf( "*** arena->free_next->free_prev != arena\n" );
+                break;
+            }
+        }
+        if (pArena->next == arena)
+        {
+            printf( "*** last block is not marked free\n" );
+            break;
+        }
+        if ((ARENA_PTR(ptr,pArena->next)->prev & ~3) != arena)
+        {
+            printf( "*** arena->next->prev != arena\n" );
+            break;
+        }
+        arena = pArena->next;
+    }
+}
+
+
+/***********************************************************************
+ *           LocalInit   (KERNEL.4)
+ */
+HLOCAL LocalInit( WORD selector, WORD start, WORD end )
+{
+    char *ptr;
+    WORD heapInfoArena, freeArena, lastArena;
+    LOCALHEAPINFO *pHeapInfo;
+    LOCALARENA *pArena, *pFirstArena, *pLastArena;
+
+      /* The initial layout of the heap is: */
+      /* - first arena         (FIXED)      */
+      /* - heap info structure (FIXED)      */
+      /* - large free block    (FREE)       */
+      /* - last arena          (FREE)       */
+
+      /* FIXME: What should be done if there's already */
+      /* a local heap in this segment? */
+    dprintf_local(stddeb, "LocalInit: %04x %04x-%04x\n", selector, start, end);
+    if (!selector) selector = CURRENT_DS;
+    ptr = PTR_SEG_OFF_TO_LIN( selector, 0 );
+    start = LALIGN( max( start, sizeof(INSTANCEDATA) ) );
+    heapInfoArena = LALIGN(start + sizeof(LOCALARENA) );
+    freeArena = LALIGN( heapInfoArena + ARENA_HEADER_SIZE
+                        + sizeof(LOCALHEAPINFO) );
+    lastArena = (end - sizeof(LOCALARENA)) & ~3;
+
+      /* Make sure there's enough space.       */
+
+    if (freeArena + sizeof(LOCALARENA) >= lastArena) return FALSE;
+
+      /* Initialise the first arena */
+
+    pFirstArena = ARENA_PTR( ptr, start );
+    pFirstArena->prev      = start | LOCAL_ARENA_FIXED;
+    pFirstArena->next      = heapInfoArena;
+    pFirstArena->size      = LALIGN(sizeof(LOCALARENA));
+    pFirstArena->free_prev = start;  /* this one */
+    pFirstArena->free_next = freeArena;
+
+      /* Initialise the arena of the heap info structure */
+
+    pArena = ARENA_PTR( ptr, heapInfoArena );
+    pArena->prev = start | LOCAL_ARENA_FIXED;
+    pArena->next = freeArena;
+
+      /* Initialise the heap info structure */
+
+    pHeapInfo = (LOCALHEAPINFO *) (ptr + heapInfoArena + ARENA_HEADER_SIZE );
+    memset( pHeapInfo, 0, sizeof(LOCALHEAPINFO) );
+    pHeapInfo->items   = 4;
+    pHeapInfo->first   = start;
+    pHeapInfo->last    = lastArena;
+    pHeapInfo->hdelta  = 0x20;
+    pHeapInfo->extra   = 0x200;
+    pHeapInfo->minsize = lastArena - freeArena;
+    pHeapInfo->magic   = LOCAL_HEAP_MAGIC;
+
+      /* Initialise the large free block */
+
+    pArena = ARENA_PTR( ptr, freeArena );
+    pArena->prev      = heapInfoArena | LOCAL_ARENA_FREE;
+    pArena->next      = lastArena;
+    pArena->size      = lastArena - freeArena;
+    pArena->free_prev = start;
+    pArena->free_next = lastArena;
+
+      /* Initialise the last block */
+
+    pLastArena = ARENA_PTR( ptr, lastArena );
+    pLastArena->prev      = heapInfoArena | LOCAL_ARENA_FREE;
+    pLastArena->next      = lastArena;  /* this one */
+    pLastArena->size      = LALIGN(sizeof(LOCALARENA));
+    pLastArena->free_prev = freeArena;
+    pLastArena->free_next = lastArena;  /* this one */
+
+      /* Store the local heap address in the instance data */
+
+    ((INSTANCEDATA *)ptr)->heap = heapInfoArena + ARENA_HEADER_SIZE;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LOCAL_Alloc
+ *
+ * Implementation of LocalAlloc().
+ */
+HLOCAL LOCAL_Alloc( WORD ds, WORD flags, WORD size )
+{
+    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+    LOCALHEAPINFO *pInfo;
+    LOCALARENA *pArena;
+    WORD arena;
+
+    dprintf_local( stddeb, "LocalAlloc: %04x %d ds=%04x\n", flags, size, ds );
+
+      /* Find a suitable free block */
+
+    if (!(pInfo = LOCAL_GetHeap( ds ))) return 0;
+    size += ARENA_HEADER_SIZE;
+    size = LALIGN( max( size, sizeof(LOCALARENA) ) );
+    arena = pInfo->first;
+    pArena = ARENA_PTR( ptr, arena );
+    for (;;)
+    {
+        if (arena == pArena->free_next) return 0;  /* not found */
+        arena = pArena->free_next;
+        pArena = ARENA_PTR( ptr, arena );
+        if (pArena->size >= size) break;
+    }
+
+      /* Make a block out of the free arena */
+
+    if (pArena->size > size + LALIGN(sizeof(LOCALARENA)))
+    {
+        LOCAL_AddBlock( ptr, arena, arena+size );
+        LOCAL_AddFreeBlock( ptr, arena+size );
+        pInfo->items++;
+    }
+    LOCAL_RemoveFreeBlock( ptr, arena );
+
+    dprintf_local( stddeb, "LocalAlloc: returning %04x\n",
+                   arena + ARENA_HEADER_SIZE );
+    return arena + ARENA_HEADER_SIZE;
+}
+
+
+/***********************************************************************
+ *           LOCAL_ReAlloc
+ *
+ * Implementation of LocalReAlloc().
+ */
+HLOCAL LOCAL_ReAlloc( WORD ds, HLOCAL handle, WORD size, WORD flags )
+{
+    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+    LOCALHEAPINFO *pInfo;
+    LOCALARENA *pArena, *pNext;
+    WORD arena, newhandle;
+
+    dprintf_local( stddeb, "LocalReAlloc: %04x %d %04x ds=%04x\n",
+                   handle, size, flags, ds );
+    if (!(pInfo = LOCAL_GetHeap( ds ))) return 0;
+    arena = handle - ARENA_HEADER_SIZE;
+    pArena = ARENA_PTR( ptr, arena );
+    if (!size) size = 1;
+    size = LALIGN( size );
+
+      /* Check for size reduction */
+
+    if (size < pArena->next - handle)
+    {
+        if (handle + size < pArena->next - LALIGN(sizeof(LOCALARENA)))
+        {
+              /* It is worth making a new free block */
+            LOCAL_AddBlock( ptr, arena, handle + size );
+            LOCAL_AddFreeBlock( ptr, handle + size );
+            pInfo->items++;
+        }
+        dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
+        return handle;
+    }
+
+      /* Check if the next block is free */
+
+    pNext = ARENA_PTR( ptr, pArena->next );
+    if (((pNext->prev & 3) == LOCAL_ARENA_FREE) &&
+        (size <= pNext->next - handle))
+    {
+        LOCAL_RemoveBlock( ptr, pArena->next );
+        if (handle + size < pArena->next - LALIGN(sizeof(LOCALARENA)))
+        {
+              /* It is worth making a new free block */
+            LOCAL_AddBlock( ptr, arena, handle + size );
+            LOCAL_AddFreeBlock( ptr, handle + size );
+            pInfo->items++;
+        }
+        dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
+        return handle;
+    }
+
+      /* Now we have to allocate a new block */
+
+    newhandle = LOCAL_Alloc( ds, flags, size );
+    if (!newhandle) return 0;
+    memcpy( ptr + newhandle, ptr + handle, pArena->next - handle );
+    LOCAL_Free( ds, handle );
+    dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", newhandle );
+    return newhandle;
+}
+
+
+/***********************************************************************
+ *           LOCAL_Free
+ *
+ * Implementation of LocalFree().
+ */
+HLOCAL LOCAL_Free( WORD ds, HLOCAL handle )
+{
+    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+    LOCALHEAPINFO *pInfo;
+    LOCALARENA *pArena, *pPrev, *pNext;
+    WORD arena;
+
+    dprintf_local( stddeb, "LocalFree: %04x ds=%04x\n", handle, ds );
+    if (!(pInfo = LOCAL_GetHeap( ds ))) return handle;
+    arena = handle - ARENA_HEADER_SIZE;
+    pArena = ARENA_PTR( ptr, arena );
+    if ((pArena->prev & 3) == LOCAL_ARENA_FREE) return handle;
+
+      /* Check if we can merge with the previous block */
+
+    pPrev = ARENA_PTR( ptr, pArena->prev & ~3 );
+    pNext = ARENA_PTR( ptr, pArena->next );
+    if ((pPrev->prev & 3) == LOCAL_ARENA_FREE)
+    {
+        arena  = pArena->prev & ~3;
+        pArena = pPrev;
+        LOCAL_RemoveBlock( ptr, pPrev->next );
+        pInfo->items--;
+    }
+    else  /* Make a new free block */
+    {
+        LOCAL_AddFreeBlock( ptr, arena );
+    }
+
+      /* Check if we can merge with the next block */
+
+    if ((pArena->next == pArena->free_next) &&
+        (pArena->next != pInfo->last))
+    {
+        LOCAL_RemoveBlock( ptr, pArena->next );
+        pInfo->items--;
+    }
+    return 0;
+}
+
+
+/***********************************************************************
+ *           LOCAL_Size
+ *
+ * Implementation of LocalSize().
+ */
+WORD LOCAL_Size( WORD ds, HLOCAL handle )
+{
+    LOCALARENA *pArena = PTR_SEG_OFF_TO_LIN( ds, handle - ARENA_HEADER_SIZE );
+    return pArena->next - handle;
+}
+
+
+/***********************************************************************
+ *           LOCAL_HeapSize
+ *
+ * Implementation of LocalHeapSize().
+ */
+WORD LOCAL_HeapSize( WORD ds )
+{
+    LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds );
+    if (!pInfo) return 0;
+    return pInfo->last - pInfo->first;
+}
+
+
+/***********************************************************************
+ *           LocalAlloc   (KERNEL.5)
+ */
+HLOCAL LocalAlloc( WORD flags, WORD size )
+{
+    return LOCAL_Alloc( CURRENT_DS, flags, size );
+}
+
+
+/***********************************************************************
+ *           LocalReAlloc   (KERNEL.6)
+ */
+HLOCAL LocalReAlloc( HLOCAL handle, WORD flags, WORD size )
+{
+    return LOCAL_ReAlloc( CURRENT_DS, handle, flags, size );
+}
+
+
+/***********************************************************************
+ *           LocalFree   (KERNEL.7)
+ */
+HLOCAL LocalFree( HLOCAL handle )
+{
+    return LOCAL_Free( CURRENT_DS, handle );
+}
+
+
+/***********************************************************************
+ *           LocalLock   (KERNEL.8)
+ */
+WORD LocalLock( HLOCAL handle )
+{
+    return handle;
+}
+
+
+/***********************************************************************
+ *           LocalUnlock   (KERNEL.9)
+ */
+BOOL LocalUnlock( HLOCAL handle )
+{
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LocalSize   (KERNEL.10)
+ */
+WORD LocalSize( HLOCAL handle )
+{
+    return LOCAL_Size( CURRENT_DS, handle );
+}
+
+
+/***********************************************************************
+ *           LocalHandle   (KERNEL.11)
+ */
+HLOCAL LocalHandle( WORD addr )
+{
+    dprintf_local( stddeb, "LocalHandle: %04x\n", addr );
+    return addr;
+}
+
+
+/***********************************************************************
+ *           LocalFlags   (KERNEL.12)
+ */
+WORD LocalFlags( HLOCAL handle )
+{
+    dprintf_local( stddeb, "LocalFlags: %04x\n", handle );
+    return 0;
+}
+
+
+/***********************************************************************
+ *           LocalCompact   (KERNEL.13)
+ */
+WORD LocalCompact( WORD minfree )
+{
+}
+
+
+/***********************************************************************
+ *           LocalNotify   (KERNEL.14)
+ */
+FARPROC LocalNotify( FARPROC func )
+{
+}
+
+
+/***********************************************************************
+ *           LocalShrink   (KERNEL.121)
+ */
+WORD LocalShrink( HLOCAL handle, WORD newsize )
+{
+}
+
+
+/***********************************************************************
+ *           GetHeapSpaces   (KERNEL.138)
+ */
+DWORD GetHeapSpaces( HMODULE module )
+{
+}
+
+
+/***********************************************************************
+ *           LocalCountFree   (KERNEL.161)
+ */
+void LocalCountFree()
+{
+}
+
+
+/***********************************************************************
+ *           LocalHeapSize   (KERNEL.162)
+ */
+WORD LocalHeapSize()
+{
+    return LOCAL_HeapSize( CURRENT_DS );
+}
+
+
+/***********************************************************************
+ *           LocalHandleDelta   (KERNEL.310)
+ */
+WORD LocalHandleDelta( WORD delta )
+{
+}
+
+
+/***********************************************************************
+ *           LocalInfo   (TOOLHELP.56)
+ */
+BOOL LocalInfo( LOCALINFO *pLocalInfo, HGLOBAL handle )
+{
+    LOCALHEAPINFO *pInfo = LOCAL_GetHeap(SELECTOROF(WIN16_GlobalLock(handle)));
+    if (!pInfo) return FALSE;
+    pLocalInfo->wcItems = pInfo->items;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LocalFirst   (TOOLHELP.57)
+ */
+BOOL LocalFirst( LOCALENTRY *pLocalEntry, HGLOBAL handle )
+{
+    WORD ds = SELECTOROF( WIN16_GlobalLock( handle ) );
+    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+    LOCALHEAPINFO *pInfo = LOCAL_GetHeap( ds );
+    if (!pInfo) return FALSE;
+
+    pLocalEntry->hHandle   = pInfo->first + ARENA_HEADER_SIZE;
+    pLocalEntry->wAddress  = pLocalEntry->hHandle;
+    pLocalEntry->wFlags    = LF_FIXED;
+    pLocalEntry->wcLock    = 0;
+    pLocalEntry->wType     = LT_NORMAL;
+    pLocalEntry->hHeap     = handle;
+    pLocalEntry->wHeapType = NORMAL_HEAP;
+    pLocalEntry->wNext     = ARENA_PTR(ptr,pInfo->first)->next;
+    pLocalEntry->wSize     = pLocalEntry->wNext - pLocalEntry->hHandle;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           LocalNext   (TOOLHELP.58)
+ */
+BOOL LocalNext( LOCALENTRY *pLocalEntry )
+{
+    WORD ds = SELECTOROF( pLocalEntry->hHeap );
+    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+    LOCALARENA *pArena;
+
+    if (!LOCAL_GetHeap( ds )) return FALSE;
+    if (!pLocalEntry->wNext) return FALSE;
+    pArena = ARENA_PTR( ptr, pLocalEntry->wNext );
+
+    pLocalEntry->hHandle   = pLocalEntry->wNext + ARENA_HEADER_SIZE;
+    pLocalEntry->wAddress  = pLocalEntry->hHandle;
+    pLocalEntry->wFlags    = (pArena->prev & 3) + 1;
+    pLocalEntry->wcLock    = 0;
+    pLocalEntry->wType     = LT_NORMAL;
+    if (pArena->next != pLocalEntry->wNext)  /* last one? */
+        pLocalEntry->wNext = pArena->next;
+    else
+        pLocalEntry->wNext = 0;
+    pLocalEntry->wSize     = pLocalEntry->wNext - pLocalEntry->hHandle;
+    return TRUE;
+}
diff --git a/memory/selector.c b/memory/selector.c
new file mode 100644
index 0000000..c9dc5ae
--- /dev/null
+++ b/memory/selector.c
@@ -0,0 +1,438 @@
+/*
+ * Selector manipulation functions
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include "windows.h"
+#include "ldt.h"
+#include "stddebug.h"
+#include "debug.h"
+
+ldt_copy_entry ldt_copy[LDT_SIZE] = { {0,0}, };
+
+#define FIRST_LDT_ENTRY_TO_ALLOC  10
+
+
+/***********************************************************************
+ *           SELECTOR_Init
+ */
+void SELECTOR_Init()
+{
+}
+
+
+/***********************************************************************
+ *           AllocSelectorArray   (KERNEL.206)
+ */
+WORD AllocSelectorArray( WORD count )
+{
+    WORD i, size = 0;
+
+    if (!count) return 0;
+    for (i = FIRST_LDT_ENTRY_TO_ALLOC; i < LDT_SIZE; i++)
+    {
+        if (!IS_LDT_ENTRY_FREE(i)) size = 0;
+        else if (++size >= count) break;
+    }
+    if (i == LDT_SIZE) return 0;
+    return ENTRY_TO_SELECTOR( i - size + 1 );
+}
+
+
+/***********************************************************************
+ *           AllocSelector   (KERNEL.175)
+ */
+WORD AllocSelector( WORD sel )
+{
+    WORD newsel, count, i;
+
+    count = sel ? ((GET_SEL_LIMIT(sel) >> 16) + 1) : 1;
+    newsel = AllocSelectorArray( count );
+    dprintf_selector( stddeb, "AllocSelector(%04x): returning %04x\n",
+                      sel, newsel );
+    if (!newsel) return 0;
+    if (!sel) return newsel;  /* nothing to copy */
+    for (i = 0; i < count; i++)
+    {
+        ldt_entry entry;
+        LDT_GetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
+        LDT_SetEntry( SELECTOR_TO_ENTRY(newsel) + i, &entry );
+    }
+    return newsel;
+}
+
+
+/***********************************************************************
+ *           FreeSelector   (KERNEL.176)
+ */
+WORD FreeSelector( WORD sel )
+{
+    WORD i, count;
+    ldt_entry entry;
+
+    dprintf_selector( stddeb, "FreeSelector(%04x)\n", sel );
+    if (IS_SELECTOR_FREE(sel)) return sel;  /* error */
+    count = (GET_SEL_LIMIT(sel) >> 16) + 1;
+    entry.base = entry.limit = 0;  /* clear the LDT entries */
+    for (i = 0; i < count; i++)
+        LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
+    return 0;
+}
+
+
+/***********************************************************************
+ *           SELECTOR_SetEntries
+ *
+ * Set the LDT entries for an array of selectors.
+ */
+static void SELECTOR_SetEntries( WORD sel, void *base, DWORD size,
+                                 enum seg_type type, BOOL is32bit,
+                                 BOOL readonly )
+{
+    ldt_entry entry;
+    WORD i, count;
+
+      /* The limit for the first selector is the whole */
+      /* block. The next selectors get a 64k limit.    */
+    entry.base           = (unsigned long)base;
+    entry.type           = type;
+    entry.seg_32bit      = is32bit;
+    entry.read_only      = readonly;
+    entry.limit_in_pages = (size > 0x100000);
+    if (entry.limit_in_pages) entry.limit = ((size + 0xfff) >> 12) - 1;
+    else entry.limit = size - 1;
+    count = (size + 0xffff) / 0x10000;
+    for (i = 0; i < count; i++)
+    {
+        LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
+        entry.base += 0x10000;
+        size -= 0x10000;
+        entry.limit = (size > 0x10000) ? 0xffff : size-1;
+        entry.limit_in_pages = 0;
+    }
+}
+
+
+/***********************************************************************
+ *           SELECTOR_ReallocArray
+ *
+ * Change the size of an allocated selector array.
+ */
+static WORD SELECTOR_ReallocArray( WORD sel, WORD newcount )
+{
+    WORD i, oldcount;
+    ldt_entry entry;
+
+    oldcount = (GET_SEL_LIMIT(sel) >> 16) + 1;
+    if (oldcount < newcount)  /* We need to add selectors */
+    {
+          /* Check if the next selectors are free */
+        for (i = oldcount; i < newcount; i++)
+            if (!IS_SELECTOR_FREE(sel)) break;
+        if (i < newcount)
+        {
+            FreeSelector( sel );
+            sel = AllocSelectorArray( newcount );
+        }
+    }
+    else if (oldcount > newcount) /* We need to remove selectors */
+    {
+        entry.base = entry.limit = 0;  /* clear the LDT entries */
+        for (i = oldcount; i < newcount; i++)
+            LDT_SetEntry( SELECTOR_TO_ENTRY(sel) + i, &entry );
+    }
+    return sel;
+}
+
+
+/***********************************************************************
+ *           SELECTOR_AllocBlock
+ *
+ * Allocate selectors for a block of linear memory.
+ */
+WORD SELECTOR_AllocBlock( void *base, DWORD size, enum seg_type type,
+                          BOOL is32bit, BOOL readonly )
+{
+    WORD sel, count;
+
+    if (!size) return 0;
+    count = (size + 0xffff) / 0x10000;
+    sel = AllocSelectorArray( count );
+    if (sel) SELECTOR_SetEntries( sel, base, size, type, is32bit, readonly );
+    return sel;
+}
+
+
+/***********************************************************************
+ *           SELECTOR_ReallocBlock
+ *
+ * Change the size of a block of selectors.
+ */
+WORD SELECTOR_ReallocBlock( WORD sel, void *base, DWORD size,
+                            enum seg_type type, BOOL is32bit, BOOL readonly )
+{
+    WORD count;
+
+    if (!size)
+    {
+        FreeSelector( sel );
+        return 0;
+    }
+    count = (size + 0xffff) / 0x10000;
+    sel = SELECTOR_ReallocArray( sel, count );
+    if (sel) SELECTOR_SetEntries( sel, base, size, type, is32bit, readonly );
+    return sel;
+}
+
+
+/***********************************************************************
+ *           PrestoChangoSelector   (KERNEL.177)
+ */
+WORD PrestoChangoSelector( WORD selSrc, WORD selDst )
+{
+    ldt_entry entry;
+    LDT_GetEntry( SELECTOR_TO_ENTRY( selSrc ), &entry );
+    entry.type ^= SEGMENT_CODE;  /* toggle the executable bit */
+    LDT_SetEntry( SELECTOR_TO_ENTRY( selDst ), &entry );
+    return selDst;
+}
+
+
+/***********************************************************************
+ *           AllocCStoDSAlias   (KERNEL.170)
+ */
+WORD AllocCStoDSAlias( WORD sel )
+{
+    WORD newsel;
+    ldt_entry entry;
+
+    newsel = AllocSelectorArray( 1 );
+    dprintf_selector( stddeb, "AllocCStoDSAlias(%04x): returning %04x\n",
+                      sel, newsel );
+    if (!newsel) return 0;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    entry.type = SEGMENT_DATA;
+    LDT_SetEntry( SELECTOR_TO_ENTRY(newsel), &entry );
+    return newsel;
+}
+
+
+/***********************************************************************
+ *           AllocDStoCSAlias   (KERNEL.171)
+ */
+WORD AllocDStoCSAlias( WORD sel )
+{
+    WORD newsel;
+    ldt_entry entry;
+
+    newsel = AllocSelectorArray( 1 );
+    dprintf_selector( stddeb, "AllocDStoCSAlias(%04x): returning %04x\n",
+                      sel, newsel );
+    if (!newsel) return 0;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    entry.type = SEGMENT_CODE;
+    LDT_SetEntry( SELECTOR_TO_ENTRY(newsel), &entry );
+    return newsel;
+}
+
+
+/***********************************************************************
+ *           LongPtrAdd   (KERNEL.180)
+ */
+void LongPtrAdd( DWORD ptr, DWORD add )
+{
+    ldt_entry entry;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(SELECTOROF(ptr)), &entry );
+    entry.base += add;
+    LDT_SetEntry( SELECTOR_TO_ENTRY(SELECTOROF(ptr)), &entry );
+}
+
+
+/***********************************************************************
+ *           GetSelectorBase   (KERNEL.186)
+ */
+DWORD GetSelectorBase( WORD sel )
+{
+    return GET_SEL_BASE(sel);
+}
+
+
+/***********************************************************************
+ *           SetSelectorBase   (KERNEL.187)
+ */
+WORD SetSelectorBase( WORD sel, DWORD base )
+{
+    ldt_entry entry;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    entry.base = base;
+    LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    return sel;
+}
+
+
+/***********************************************************************
+ *           GetSelectorLimit   (KERNEL.188)
+ */
+DWORD GetSelectorLimit( WORD sel )
+{
+    return GET_SEL_LIMIT(sel);
+}
+
+
+/***********************************************************************
+ *           SetSelectorLimit   (KERNEL.189)
+ */
+WORD SetSelectorLimit( WORD sel, DWORD limit )
+{
+    ldt_entry entry;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    entry.limit = limit;
+    LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    return sel;
+}
+
+
+/***********************************************************************
+ *           SelectorAccessRights   (KERNEL.196)
+ */
+WORD SelectorAccessRights( WORD sel, WORD op, WORD val )
+{
+    ldt_entry entry;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    if (op == 0)  /* get */
+    {
+        return 1 /* accessed */ |
+               (entry.read_only << 1) |
+               (entry.type << 2) |
+               (entry.seg_32bit << 14) |
+               (entry.limit_in_pages << 15);
+    }
+    else  /* set */
+    {
+        entry.read_only = val & 2;
+        entry.type = (val >> 2) & 3;
+        entry.seg_32bit = val & 0x4000;
+        entry.limit_in_pages = val & 0x8000;
+        LDT_SetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+        return 0;
+    }
+}
+
+
+/***********************************************************************
+ *           IsBadCodePtr   (KERNEL.336)
+ */
+BOOL IsBadCodePtr( SEGPTR lpfn )
+{
+    WORD sel;
+    ldt_entry entry;
+
+    sel = SELECTOROF(lpfn);
+    if (!sel) return FALSE;
+    if (IS_SELECTOR_FREE(sel)) return FALSE;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    if (entry.type != SEGMENT_CODE) return FALSE;
+    if (OFFSETOF(lpfn) > entry.limit) return FALSE;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           IsBadStringPtr   (KERNEL.337)
+ */
+BOOL IsBadStringPtr( SEGPTR ptr, WORD size )
+{
+    WORD sel;
+    ldt_entry entry;
+
+    sel = SELECTOROF(ptr);
+    if (!sel) return FALSE;
+    if (IS_SELECTOR_FREE(sel)) return FALSE;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    if ((entry.type == SEGMENT_CODE) && entry.read_only) return FALSE;
+    if (strlen(PTR_SEG_TO_LIN(ptr)) < size) size = strlen(PTR_SEG_TO_LIN(ptr));
+    if (OFFSETOF(ptr) + size > entry.limit) return FALSE;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           IsBadHugeReadPtr   (KERNEL.346)
+ */
+BOOL IsBadHugeReadPtr( SEGPTR ptr, DWORD size )
+{
+    WORD sel;
+    ldt_entry entry;
+
+    sel = SELECTOROF(ptr);
+    if (!sel) return FALSE;
+    if (IS_SELECTOR_FREE(sel)) return FALSE;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    if ((entry.type == SEGMENT_CODE) && entry.read_only) return FALSE;
+    if (OFFSETOF(ptr) + size > entry.limit) return FALSE;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           IsBadHugeWritePtr   (KERNEL.347)
+ */
+BOOL IsBadHugeWritePtr( SEGPTR ptr, DWORD size )
+{
+    WORD sel;
+    ldt_entry entry;
+
+    sel = SELECTOROF(ptr);
+    if (!sel) return FALSE;
+    if (IS_SELECTOR_FREE(sel)) return FALSE;
+    LDT_GetEntry( SELECTOR_TO_ENTRY(sel), &entry );
+    if ((entry.type == SEGMENT_CODE) || entry.read_only) return FALSE;
+    if (OFFSETOF(ptr) + size > entry.limit) return FALSE;
+    return TRUE;
+}
+
+/***********************************************************************
+ *           IsBadReadPtr   (KERNEL.334)
+ */
+BOOL IsBadReadPtr( SEGPTR ptr, WORD size )
+{
+    return IsBadHugeReadPtr( ptr, size );
+}
+
+
+/***********************************************************************
+ *           IsBadWritePtr   (KERNEL.335)
+ */
+BOOL IsBadWritePtr( SEGPTR ptr, WORD size )
+{
+    return IsBadHugeWritePtr( ptr, size );
+}
+
+
+/***********************************************************************
+ *           MemoryRead   (TOOLHELP.78)
+ */
+DWORD MemoryRead( WORD sel, DWORD offset, void *buffer, DWORD count )
+{
+    if (IS_SELECTOR_FREE(sel)) return 0;
+    if (offset > GET_SEL_LIMIT(sel)) return 0;
+    if (offset + count > GET_SEL_LIMIT(sel) + 1)
+        count = GET_SEL_LIMIT(sel) + 1 - offset;
+    memcpy( buffer, ((char *)GET_SEL_BASE(sel)) + offset, count );
+    return count;
+}
+
+
+/***********************************************************************
+ *           MemoryWrite   (TOOLHELP.79)
+ */
+DWORD MemoryWrite( WORD sel, DWORD offset, void *buffer, DWORD count )
+{
+    if (IS_SELECTOR_FREE(sel)) return 0;
+    if (offset > GET_SEL_LIMIT(sel)) return 0;
+    if (offset + count > GET_SEL_LIMIT(sel) + 1)
+        count = GET_SEL_LIMIT(sel) + 1 - offset;
+    memcpy( ((char *)GET_SEL_BASE(sel)) + offset, buffer, count );
+    return count;
+}
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 */
diff --git a/miscemu/int10.c b/miscemu/int10.c
index 8bd9545..501b183 100644
--- a/miscemu/int10.c
+++ b/miscemu/int10.c
@@ -9,14 +9,18 @@
 
 void IntBarf(int i, struct sigcontext_struct *context)
 {
-	fprintf(stdnimp, "int%x: unknown/not implemented parameters:\n", i);
-	fprintf(stdnimp, "int%x: AX %04x, BX %04x, CX %04x, DX %04x, "
+	dprintf_int(stddeb, "int%x: unknown/not implemented parameters:\n", i);
+	dprintf_int(stddeb, "int%x: AX %04x, BX %04x, CX %04x, DX %04x, "
 	       "SI %04x, DI %04x, DS %04x, ES %04x\n",
 	       i, AX, BX, CX, DX, SI, DI, DS, ES);
 }
 
 int do_int10(struct sigcontext_struct *context)
 {
+        dprintf_int(stddeb,"int10: AX %04x, BX %04x, CX %04x, DX %04x, "
+               "SI %04x, DI %04x, DS %04x, ES %04x\n",
+               AX, BX, CX, DX, SI, DI, DS, ES);
+
 	switch(AH) {
 	case 0x0f:
 		AL = 0x5b;
diff --git a/miscemu/int13.c b/miscemu/int13.c
index 294f48d..e0e62f5 100644
--- a/miscemu/int13.c
+++ b/miscemu/int13.c
@@ -9,6 +9,10 @@
 
 int do_int13(struct sigcontext_struct *context)
 {
+        dprintf_int(stddeb,"int13: AX %04x, BX %04x, CX %04x, DX %04x, "
+               "SI %04x, DI %04x, DS %04x, ES %04x\n",
+               AX, BX, CX, DX, SI, DI, DS, ES);
+
 	switch(AH) {
 	case 0x00:                            /* RESET DISK SYSTEM     */
 	case 0x04:                            /* VERIFY DISK SECTOR(S) */
diff --git a/miscemu/int1a.c b/miscemu/int1a.c
index 9cb0db0..60a29ab 100644
--- a/miscemu/int1a.c
+++ b/miscemu/int1a.c
@@ -1,4 +1,5 @@
 #include <time.h>
+#include <sys/time.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include "registers.h"
@@ -16,21 +17,27 @@
 	time_t ltime;
         DWORD ticks;
 	struct tm *bdtime;
+        struct timeval tvs;
 
-    if (debugging_relay) {
-	fprintf(stddeb,"int1A: AX %04x, BX %04x, CX %04x, DX %04x, "
+	dprintf_int(stddeb,"int1A: AX %04x, BX %04x, CX %04x, DX %04x, "
 	       "SI %04x, DI %04x, DS %04x, ES %04x\n",
 	       AX, BX, CX, DX, SI, DI, DS, ES);
-    }
 
 	switch(AH) {
 	case 0:
-                ticks = GetTickCount();
+                /* This should give us the (approximately) correct
+                 * 18.206 clock ticks per second since midnight
+                 * expected from this interrupt
+                 */
+                gettimeofday(&tvs, NULL);
+                bdtime = localtime(&tvs.tv_sec);
+                ticks = (((bdtime->tm_hour * 3600 + bdtime->tm_min * 60 +
+                        bdtime->tm_sec) * 18206) / 1000) +
+                        (tvs.tv_usec / 54927);
 		CX = ticks >> 16;
 		DX = ticks & 0x0000FFFF;
 		AX = 0;  /* No midnight rollover */
-		dprintf_int(stddeb,"int1a_00 // ltime=%ld ticks=%ld\n",
-			ltime, ticks);
+		dprintf_int(stddeb,"int1a_00 // ticks=%ld\n", ticks);
 		break;
 		
 	case 2: 
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 62330ff..03afeef 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -18,25 +18,58 @@
 #include "dos_fs.h"
 #include "regfunc.h"
 #include "windows.h"
-#include "heap.h"
 #include "msdos.h"
 #include "registers.h"
+#include "ldt.h"
 #include "options.h"
 #include "miscemu.h"
 #include "stddebug.h"
 /* #define DEBUG_INT */
 #include "debug.h"
 
+/* Define the drive parameter block, as used by int21/1F
+ * and int21/32.  This table can be accessed through the
+ * global 'dpb' pointer, which points into the local dos
+ * heap.
+ */
+struct DPB
+{
+    BYTE drive_num;         /* 0=A, etc. */
+    BYTE unit_num;          /* Drive's unit number (?) */
+    WORD sector_size;       /* Sector size in bytes */
+    BYTE high_sector;       /* Highest sector in a cluster */
+    BYTE shift;             /* Shift count (?) */
+    WORD reserved;          /* Number of reserved sectors at start */
+    BYTE num_FAT;           /* Number of FATs */
+    WORD dir_entries;       /* Number of root dir entries */
+    WORD first_data;        /* First data sector */
+    WORD high_cluster;      /* Highest cluster number */
+    WORD sectors_in_FAT;    /* Number of sectors per FAT */
+    WORD start_dir;         /* Starting sector of first dir */
+    DWORD driver_head;      /* Address of device driver header (?) */
+    BYTE media_ID;          /* Media ID */
+    BYTE access_flag;       /* Prev. accessed flag (0=yes,0xFF=no) */
+    DWORD next;             /* Pointer to next DPB in list */
+    WORD free_search;       /* Free cluster search start */
+    WORD free_clusters;     /* Number of free clusters (0xFFFF=unknown) */
+};
+
 WORD ExtendedError, CodePage = 437;
 BYTE ErrorClass, Action, ErrorLocus;
 BYTE *dta;
+DWORD dtasegptr;
+struct DPB *dpb;
+DWORD dpbsegptr;
 
 struct DosHeap {
 	BYTE dta[256];
 	BYTE InDosFlag;
+        BYTE mediaID;
 	BYTE biosdate[8];
+        struct DPB dpb;
 };
 static struct DosHeap *heap;
+static WORD DosHeapHandle;
 
 WORD sharing_retries = 3;      /* number of retries at sharing violation */
 WORD sharing_pause = 1;        /* pause between retries */
@@ -87,22 +120,12 @@
 			Error (FileExists, EC_Exists, EL_Disk);
 			break;				
 		default:
-			fprintf(stderr, "int21: unknown errno %d!\n", errno);
+			dprintf_int(stddeb, "int21: unknown errno %d!\n", errno);
 			Error (GeneralFailure, EC_SystemFailure, EL_Unknown);
 			break;
 	}
 }
 
-/*
-static void Barf(struct sigcontext_struct *context)
-{
-	fprintf(stdnimp, "int21: unknown/not implemented parameters:\n");
-	fprintf(stdnimp, "int21: AX %04x, BX %04x, CX %04x, DX %04x, "
-	       "SI %04x, DI %04x, DS %04x, ES %04x\n",
-	       AX, BX, CX, DX, SI, DI, DS, ES);
-}
-*/
-
 void ChopOffWhiteSpace(char *string)
 {
 	int length;
@@ -180,7 +203,6 @@
 static void GetDriveAllocInfo(struct sigcontext_struct *context)
 {
 	long size, available;
-	BYTE mediaID;
 	
 	if (!DOS_ValidDrive(DL)) {
 		AX = 4;
@@ -200,10 +222,10 @@
 	ECX = 512;
 	EDX = (size / (CX * AX));
 
-	mediaID = 0xf0;
+	heap->mediaID = 0xf0;
 
-	DS = segment(mediaID);
-	BX = offset(mediaID);	
+	DS = DosHeapHandle;
+	BX = (int)&heap->mediaID - (int)heap;
 	Error (0,0,0);
 }
 
@@ -213,11 +235,46 @@
 	GetDriveAllocInfo(context);
 }
 
-static void GetDrivePB(struct sigcontext_struct *context)
+static void GetDrivePB(struct sigcontext_struct *context, int drive)
 {
-	Error (InvalidDrive, EC_MediaError, EL_Disk);
-	AX = 0x00ff;
-		/* I'm sorry but I only got networked drives :-) */
+        if(!DOS_ValidDrive(drive))
+        {
+	        Error (InvalidDrive, EC_MediaError, EL_Disk);
+                AX = 0x00ff;
+        }
+        else
+        {
+                dprintf_int(stddeb, "int21: GetDrivePB not fully implemented.\n");
+
+                /* FIXME: I have no idea what a lot of this information should
+                 * say or whether it even really matters since we're not allowing
+                 * direct block access.  However, some programs seem to depend on
+                 * getting at least _something_ back from here.  The 'next' pointer
+                 * does worry me, though.  Should we have a complete table of
+                 * separate DPBs per drive?  Probably, but I'm lazy. :-)  -CH
+                 */
+                dpb->drive_num = dpb->unit_num = drive;    /* The same? */
+                dpb->sector_size = 512;
+                dpb->high_sector = 1;
+                dpb->shift = 0;
+                dpb->reserved = 0;
+                dpb->num_FAT = 1;
+                dpb->dir_entries = 2;
+                dpb->first_data = 2;
+                dpb->high_cluster = 1023;
+                dpb->sectors_in_FAT = 1;
+                dpb->start_dir = 1;
+                dpb->driver_head = 0;
+                dpb->media_ID = (drive > 1) ? 0xF8 : 0xF0;
+                dpb->access_flag = 0;
+                dpb->next = 0;
+                dpb->free_search = 0;
+                dpb->free_clusters = 0xFFFF;    /* unknown */
+
+                AL = 0x00;
+                DS = SELECTOROF(dpbsegptr);
+                BX = OFFSETOF(dpbsegptr);
+        }
 }
 
 static void ReadFile(struct sigcontext_struct *context)
@@ -233,7 +290,7 @@
 		return;
 	}
 
-	ptr = SAFEMAKEPTR (DS,DX);
+	ptr = PTR_SEG_OFF_TO_LIN (DS,DX);
 	if (BX == 0) {
 		*ptr = EOF;
 		Error (0,0,0);
@@ -259,7 +316,7 @@
 	char *ptr;
 	int x,size;
 	
-	ptr = SAFEMAKEPTR (DS,DX);
+	ptr = PTR_SEG_OFF_TO_LIN (DS,DX);
 	
 	if (BX == 0) {
 		Error (InvalidHandle, EC_Unknown, EL_Unknown);
@@ -329,7 +386,8 @@
 		case 0:
 		case 1:
 		case 2:
-			DX = 0x80d3;
+			DX = 0x80d0 + (1 << BX);
+                        ResetCflag;
 			break;
 
 		default:
@@ -353,7 +411,7 @@
 
 static void ioctlGenericBlkDevReq(struct sigcontext_struct *context)
 {
-	BYTE *dataptr = SAFEMAKEPTR(DS, DX);
+	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
 	int drive;
 
 	if (BL == 0)
@@ -434,7 +492,7 @@
 {
 	int handle;
 
-	if ((handle = open(DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX)), 
+	if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)), 
            O_CREAT | O_TRUNC | O_RDWR )) == -1) {
 		errno_to_doserr();
 		AL = ExtendedError;
@@ -467,11 +525,19 @@
 	    break;
 	}
 
-	if ((handle = open(DOS_GetUnixFileName(SAFEMAKEPTR(DS,DX)), mode)) == -1) {
-		errno_to_doserr();
-		AL = ExtendedError;
-		SetCflag;
-		return;
+	if ((handle = open(DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)),
+                           mode)) == -1)
+        {
+            if( Options.allowReadOnly )
+                handle = open( DOS_GetUnixFileName(PTR_SEG_OFF_TO_LIN(DS,DX)),
+                               O_RDONLY );
+            if( handle == -1 )
+            {
+                errno_to_doserr();
+                AL = ExtendedError;
+                SetCflag;
+                return;
+            }
 	}		
 
         switch (AX & 0x0070)
@@ -482,9 +548,9 @@
 	    break;
 
 	  case 0x30:    /* DENYREAD */
-	    dprintf_int(stdnimp,
+	    dprintf_int(stddeb,
 	      "OpenExistingFile (%s): DENYREAD changed to DENYALL\n",
-	      (char *)SAFEMAKEPTR(DS,DX));
+	      (char *)PTR_SEG_OFF_TO_LIN(DS,DX));
 	  case 0x10:    /* DENYALL */  
 	    lock = LOCK_EX;
 	    break;
@@ -548,10 +614,10 @@
 	char *newname, *oldname;
 
 	dprintf_int(stddeb,"int21: renaming %s to %s\n",
-			(char *)SAFEMAKEPTR(DS,DX), (char *)SAFEMAKEPTR(ES,DI) );
+			(char *)PTR_SEG_OFF_TO_LIN(DS,DX), (char *)PTR_SEG_OFF_TO_LIN(ES,DI) );
 	
-	oldname = DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX) );
-	newname = DOS_GetUnixFileName( SAFEMAKEPTR(ES,DI) );
+	oldname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) );
+	newname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(ES,DI) );
 
 	rename( oldname, newname);
 	ResetCflag;
@@ -562,9 +628,9 @@
 {
 	char *dirname;
 
-	dprintf_int(stddeb,"int21: makedir %s\n", (char *)SAFEMAKEPTR(DS,DX) );
+	dprintf_int(stddeb,"int21: makedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS,DX) );
 	
-	if ((dirname = DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX) ))== NULL) {
+	if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ))== NULL) {
 		AL = CanNotMakeDir;
 		SetCflag;
 		return;
@@ -581,7 +647,7 @@
 static void ChangeDir(struct sigcontext_struct *context)
 {
 	int drive;
-	char *dirname = SAFEMAKEPTR(DS,DX);
+	char *dirname = PTR_SEG_OFF_TO_LIN(DS,DX);
 	drive = DOS_GetDefaultDrive();
 	dprintf_int(stddeb,"int21: changedir %s\n", dirname);
 	if (dirname != NULL && dirname[1] == ':') {
@@ -599,9 +665,9 @@
 {
 	char *dirname;
 
-	dprintf_int(stddeb,"int21: removedir %s\n", (char *)SAFEMAKEPTR(DS,DX) );
+	dprintf_int(stddeb,"int21: removedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS,DX) );
 
-	if ((dirname = DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX) ))== NULL) {
+	if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ))== NULL) {
 		AL = CanNotMakeDir;
 		SetCflag;
 		return;
@@ -622,14 +688,15 @@
 
 static void ExecProgram(struct sigcontext_struct *context)
 {
-	execl("wine", DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX)) );
+	execl("wine", DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)) );
 }
 
 static void FindNext(struct sigcontext_struct *context)
 {
 	struct dosdirent *dp;
+        struct tm *t;
 	
-        memcpy(&dp, dta+0x0d, sizeof(dp));
+        memcpy(&dp, dta+0x11, sizeof(dp));
 
 	do {
 		if ((dp = DOS_readdir(dp)) == NULL) {
@@ -639,24 +706,33 @@
 			return;
 		}
 	} /* while (*(dta + 0x0c) != dp->attribute);*/
-       while ( ( dp->search_attribute & dp->attribute) != dp->attribute);
+        while ( ( dp->search_attribute & dp->attribute) != dp->attribute);
 	
   	*(dta + 0x15) = dp->attribute;
-	setword(&dta[0x16], 0x1234); /* time */
-	setword(&dta[0x18], 0x1234); /* date */
+        setword(&dta[0x0d], dp->entnum);
+
+        t = localtime(&(dp->filetime));
+	setword(&dta[0x16], (t->tm_hour << 11) + (t->tm_min << 5) +
+                (t->tm_sec / 2)); /* time */
+	setword(&dta[0x18], ((t->tm_year - 80) << 9) + (t->tm_mon << 5) +
+                (t->tm_mday)); /* date */
 	setdword(&dta[0x1a], dp->filesize);
 	strncpy(dta + 0x1e, dp->filename, 13);
 
 	AL = 0;
 	ResetCflag;
+
+        dprintf_int(stddeb, "int21: FindNext -- (%s) index=%d size=%ld\n", dp->filename, dp->entnum, dp->filesize);
 	return;
 }
 
 static void FindFirst(struct sigcontext_struct *context)
 {
-	BYTE drive, *path = SAFEMAKEPTR(DS, DX);
+	BYTE drive, *path = PTR_SEG_OFF_TO_LIN(DS, DX);
 	struct dosdirent *dp;
 
+        dprintf_int(stddeb, "int21: FindFirst path = %s\n", path);
+
 	if ((*path)&&(path[1] == ':')) {
 		drive = (islower(*path) ? toupper(*path) : *path) - 'A';
 
@@ -692,23 +768,16 @@
 	}
 
 	dp->search_attribute = ECX & (FA_LABEL | FA_DIREC);
-	memcpy(dta + 0x0d, &dp, sizeof(dp));
+	memcpy(dta + 0x11, &dp, sizeof(dp));
 	FindNext(context);
 }
 
 static void GetFileDateTime(struct sigcontext_struct *context)
 {
-	char *filename;
 	struct stat filestat;
 	struct tm *now;
 
-	if ((filename = DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX) ))== NULL) {
-		AL = FileNotFound;
-		SetCflag;
-		return;
-	}
-	stat(filename, &filestat);
-	 	
+        fstat( BX, &filestat );	
 	now = localtime (&filestat.st_mtime);
 	
 	CX = ((now->tm_hour * 0x2000) + (now->tm_min * 0x20) + now->tm_sec/2);
@@ -722,7 +791,9 @@
 	char *filename;
 	struct utimbuf filetime;
 	
-	filename = DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX) );
+        /* FIXME: Argument isn't the name of the file in DS:DX,
+           but the file handle in BX */
+	filename = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) );
 
 	filetime.actime = 0L;
 	filetime.modtime = filetime.actime;
@@ -748,7 +819,7 @@
 		return;
 	}
 
-	strcpy(SAFEMAKEPTR(DS,DX), temp);
+	strcpy(PTR_SEG_OFF_TO_LIN(DS,DX), temp);
 	
 	AX = handle;
 	ResetCflag;
@@ -758,7 +829,7 @@
 {
 	int handle;
 	
-	if ((handle = open(DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX) ), O_CREAT | O_EXCL | O_RDWR)) == -1) {
+	if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ), O_CREAT | O_EXCL | O_RDWR)) == -1) {
 		AL = WriteProtected;
 		SetCflag;
 		return;
@@ -783,14 +854,14 @@
 		return;
 	}
 
-	strcpy(SAFEMAKEPTR(DS,SI), DOS_GetCurrentDir(drive) );
+	strcpy(PTR_SEG_OFF_TO_LIN(DS,SI), DOS_GetCurrentDir(drive) );
 	ResetCflag;
 }
 
 static void GetDiskSerialNumber(struct sigcontext_struct *context)
 {
 	int drive;
-	BYTE *dataptr = SAFEMAKEPTR(DS, DX);
+	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
 	DWORD serialnumber;
 	
 	if (BL == 0)
@@ -818,7 +889,7 @@
 static void SetDiskSerialNumber(struct sigcontext_struct *context)
 {
 	int drive;
-	BYTE *dataptr = SAFEMAKEPTR(DS, DX);
+	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, DX);
 	DWORD serialnumber;
 
 	if (BL == 0)
@@ -858,7 +929,7 @@
 
 static void FindFirstFCB(struct sigcontext_struct *context)
 {
-	BYTE *fcb = SAFEMAKEPTR(DS, DX);
+	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
 	struct fcb *standard_fcb;
 	struct fcb *output_fcb;
 	int drive;
@@ -925,7 +996,7 @@
 
 static void DeleteFileFCB(struct sigcontext_struct *context)
 {
-	BYTE *fcb = SAFEMAKEPTR(DS, DX);
+	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
 	int drive;
 	struct dosdirent *dp;
 	char temp[256], *ptr;
@@ -967,7 +1038,7 @@
 
 static void RenameFileFCB(struct sigcontext_struct *context)
 {
-	BYTE *fcb = SAFEMAKEPTR(DS, DX);
+	BYTE *fcb = PTR_SEG_OFF_TO_LIN(DS, DX);
 	int drive;
 	struct dosdirent *dp;
 	char temp[256], oldname[256], newname[256], *oldnameptr, *newnameptr;
@@ -1067,7 +1138,7 @@
 
 static void GetFileAttribute (struct sigcontext_struct * context)
 {
-  char *filename = SAFEMAKEPTR (DS,DX);
+  char *filename = PTR_SEG_OFF_TO_LIN (DS,DX);
   struct stat s;
   int res,cx; 
 
@@ -1097,12 +1168,9 @@
 
 int do_int21(struct sigcontext_struct * context)
 {
-    if (debugging_relay)
-    {
-	fprintf(stddeb,"int21: AX %04x, BX %04x, CX %04x, DX %04x, "
-	       "SI %04x, DI %04x, DS %04x, ES %04x\n",
-	       AX, BX, CX, DX, SI, DI, DS, ES);
-    }
+    dprintf_int(stddeb,"int21: AX %04x, BX %04x, CX %04x, DX %04x, "
+           "SI %04x, DI %04x, DS %04x, ES %04x\n",
+           AX, BX, CX, DX, SI, DI, DS, ES);
 
     if (AH == 0x59) 
     {
@@ -1199,7 +1267,8 @@
 	    break;
 
 	  case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
-            dta = SAFEMAKEPTR(DS, DX);
+            dtasegptr = MAKELONG( DX, DS );
+            dta = PTR_SEG_TO_LIN(dtasegptr);
             break;
 
 	  case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
@@ -1211,12 +1280,12 @@
 	    break;
 
 	  case 0x1f: /* GET DRIVE PARAMETER BLOCK FOR DEFAULT DRIVE */
-	    GetDrivePB(context);
+	    GetDrivePB(context, DOS_GetDefaultDrive());
 	    break;
 		
 	  case 0x25: /* SET INTERRUPT VECTOR */
 	    /* Ignore any attempt to set a segment vector */
- 		dprintf_int(stdnimp,
+ 		dprintf_int(stddeb,
 			"int21: set interrupt vector %2x (%04x:%04x)\n",
 			AL, DS, DX);
             break;
@@ -1230,8 +1299,8 @@
 	    break;
 
 	  case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
-            ES = segment(dta);
-            BX = offset(dta);
+            ES = SELECTOROF(dtasegptr);
+            BX = OFFSETOF(dtasegptr);
             break;
             
 	  case 0x30: /* GET DOS VERSION */
@@ -1245,7 +1314,7 @@
 	    break;
 
 	  case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
-	    GetDrivePB(context);
+	    GetDrivePB(context, (DL == 0) ? (DOS_GetDefaultDrive()) : (DL-1));
 	    break;
 
 	  case 0x33: /* MULTIPLEXED */
@@ -1279,14 +1348,14 @@
 	    break;	
 	    
 	  case 0x34: /* GET ADDRESS OF INDOS FLAG */
-		ES = segment(heap->InDosFlag);
-		BX = offset(heap->InDosFlag);
+		ES = DosHeapHandle;
+		BX = (int)&heap->InDosFlag - (int)heap;
 	    break;
 
 	  case 0x35: /* GET INTERRUPT VECTOR */
 	    /* Return a NULL segment selector - this will bomb, 
 	    		if anyone ever tries to use it */
-	    dprintf_int(stdnimp, "int21: get interrupt vector %2x\n",
+	    dprintf_int(stddeb, "int21: get interrupt vector %2x\n",
 		AX & 0xff);
 	    ES = 0;
 	    BX = 0;
@@ -1334,7 +1403,7 @@
 	    break;
 	
 	  case 0x41: /* "UNLINK" - DELETE FILE */
-		if (unlink( DOS_GetUnixFileName( SAFEMAKEPTR(DS,DX)) ) == -1) {
+		if (unlink( DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX)) ) == -1) {
 			errno_to_doserr();
 			AL = ExtendedError;
 			SetCflag;
@@ -1366,6 +1435,11 @@
               case 0x00:
                 ioctlGetDeviceInfo(context);
 		break;
+
+              case 0x08:   /* Check if drive is removable. */
+                EAX = (EAX & 0xFFFF0000) | 0x0001;   /* Nope, not removable. */
+                ResetCflag;
+                break;
 		   
 	      case 0x09:   /* CHECK IF BLOCK DEVICE REMOTE */
 		EDX = (EDX & 0xffff0000) | (1<<9) | (1<<12) | (1<<15);
@@ -1388,6 +1462,13 @@
               case 0x0d:
                 ioctlGenericBlkDevReq(context);
                 break;
+
+              case 0x0F:   /* Set logical drive mapping */
+                /* FIXME: Not implemented at the moment, always returns error
+                 */
+                EAX = (EAX & 0xFFFF0000) | 0x0001; /* invalid function */
+                SetCflag;
+                break;
                 
 	      default:
                 IntBarf(0x21, context);
@@ -1524,7 +1605,7 @@
 	    break;
 
 	  case 0x60: /* "TRUENAME" - CANONICALIZE FILENAME OR PATH */
-		strncpy(SAFEMAKEPTR(ES,DI), SAFEMAKEPTR(DS,SI), strlen(SAFEMAKEPTR(DS,SI)) & 0x7f);
+		strncpy(PTR_SEG_OFF_TO_LIN(ES,DI), PTR_SEG_OFF_TO_LIN(DS,SI), strlen(PTR_SEG_OFF_TO_LIN(DS,SI)) & 0x7f);
 		ResetCflag;
 	    break;
 
@@ -1596,19 +1677,17 @@
 
 void INT21_Init(void)
 {
-	int handle;
-	MDESC *DosHeapDesc;
+    if ((DosHeapHandle = GlobalAlloc(GMEM_FIXED,sizeof(struct DosHeap))) == 0)
+    {
+        fprintf( stderr, "INT21_Init: Out of memory\n");
+        exit(1);
+    }
+    heap = (struct DosHeap *) GlobalLock(DosHeapHandle);
 
-	if ((handle = GlobalAlloc(GMEM_FIXED,sizeof(struct DosHeap))) == 0)
-        {
-            fprintf( stderr, "INT21_Init: Out of memory\n");
-            exit(1);
-        }
-
-	heap = (struct DosHeap *) GlobalLock(handle);
-	HEAP_Init(&DosHeapDesc, heap, sizeof(struct DosHeap));
-
-	dta = heap->dta;
-	heap->InDosFlag = 0;
-	strcpy(heap->biosdate, "01/01/80");
+    dta = heap->dta;
+    dpb = &heap->dpb;
+    dtasegptr = MAKELONG( 0, DosHeapHandle );
+    dpbsegptr = MAKELONG( (int)&heap->dpb - (int)heap, DosHeapHandle );
+    heap->InDosFlag = 0;
+    strcpy(heap->biosdate, "01/01/80");
 }
diff --git a/miscemu/int25.c b/miscemu/int25.c
index 38c306d..2f5eaaf 100644
--- a/miscemu/int25.c
+++ b/miscemu/int25.c
@@ -3,7 +3,7 @@
 #include <string.h>
 #include "registers.h"
 #include "msdos.h"
-#include "segmem.h"
+#include "ldt.h"
 #include "wine.h"
 #include "miscemu.h"
 #include "stddebug.h"
@@ -12,13 +12,13 @@
 
 int do_int25(struct sigcontext_struct *context)
 {
-	BYTE *dataptr = SAFEMAKEPTR(DS, BX);
+	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
 	DWORD begin, length;
 
 	if (CX == 0xffff) {
 		begin = getdword(dataptr);
 		length = getword(&dataptr[4]);
-		dataptr = (BYTE *) getdword(&dataptr[6]);
+		dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
 			
 	} else {
 		begin = DX;
@@ -39,7 +39,7 @@
 
 	/* push flags on stack */
 	SP -= sizeof(WORD);
-	setword(SAFEMAKEPTR(SS,SP), (WORD) EFL);
+	setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
 
 	return 1;
 }
diff --git a/miscemu/int26.c b/miscemu/int26.c
index c642f4c..051a4de 100644
--- a/miscemu/int26.c
+++ b/miscemu/int26.c
@@ -2,7 +2,7 @@
 #include <stdlib.h>
 #include "registers.h"
 #include "msdos.h"
-#include "segmem.h"
+#include "ldt.h"
 #include "wine.h"
 #include "miscemu.h"
 #include "stddebug.h"
@@ -11,13 +11,13 @@
 
 int do_int26(struct sigcontext_struct *context)
 {
-	BYTE *dataptr = SAFEMAKEPTR(DS, BX);
+	BYTE *dataptr = PTR_SEG_OFF_TO_LIN(DS, BX);
 	DWORD begin, length;
 
 	if (CX == 0xffff) {
 		begin = getdword(dataptr);
 		length = getword(&dataptr[4]);
-		dataptr = (BYTE *) getdword(&dataptr[6]);
+		dataptr = (BYTE *) PTR_SEG_TO_LIN(getdword(&dataptr[6]));
 			
 	} else {
 		begin = DX;
@@ -31,7 +31,7 @@
 
 	/* push flags on stack */
 	SP -= sizeof(WORD);
-	setword(SAFEMAKEPTR(SS,SP), (WORD) EFL);
+	setword(PTR_SEG_OFF_TO_LIN(SS,SP), (WORD) EFL);
 
 	return 1;
 }
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
index 25d9acd..106d110 100644
--- a/miscemu/int2f.c
+++ b/miscemu/int2f.c
@@ -11,6 +11,10 @@
 
 int do_int2f(struct sigcontext_struct *context)
 {
+        dprintf_int(stddeb,"int2f: AX %04x, BX %04x, CX %04x, DX %04x, "
+               "SI %04x, DI %04x, DS %04x, ES %04x\n",
+               AX, BX, CX, DX, SI, DI, DS, ES);
+
 	switch((context->sc_eax >> 8) & 0xff)
 	{
 	case 0x10: /* share is installed */
diff --git a/miscemu/kernel.c b/miscemu/kernel.c
index 70b3283..8f24c72 100644
--- a/miscemu/kernel.c
+++ b/miscemu/kernel.c
@@ -14,36 +14,6 @@
 extern unsigned short WIN_StackSize;
 
 /**********************************************************************
- *					KERNEL_LockSegment
- */
-int
-KERNEL_LockSegment(int segment)
-{
-    if (segment == -1)
-	segment = pStack16Frame->ds;
-
-    if (debugging_relay)
-	fprintf(stddeb,"LockSegment: segment %x\n", segment);
-
-    return segment;
-}
-
-/**********************************************************************
- *					KERNEL_UnlockSegment
- */
-int
-KERNEL_UnlockSegment(int segment)
-{
-    if (segment == -1)
-	segment = pStack16Frame->ds;
-
-    if (debugging_relay)
-    	fprintf(stddeb,"UnlockSegment: segment %x\n", segment);
-
-    return segment;
-}
-
-/**********************************************************************
  *					KERNEL_InitTask
  */
 void KERNEL_InitTask(void)
diff --git a/multimedia/audio.c b/multimedia/audio.c
index 84b8fb3..de3c8ad 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -22,6 +22,7 @@
 #include "user.h"
 #include "driver.h"
 #include "mmsystem.h"
+#include "ldt.h"
 
 #ifdef linux
 #include <linux/soundcard.h>
@@ -154,28 +155,28 @@
 			return (LRESULT)DRVCNF_RESTART;
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
-			return WAVE_mciOpen(dwParam1, (LPMCI_WAVE_OPEN_PARMS)dwParam2);
+			return WAVE_mciOpen(dwParam1, (LPMCI_WAVE_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_CLOSE_DRIVER:
 		case MCI_CLOSE:
-			return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return WAVE_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_PLAY:
-			return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
+			return WAVE_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_RECORD:
-			return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)dwParam2);
+			return WAVE_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STOP:
-			return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return WAVE_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_SET:
-			return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
+			return WAVE_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_PAUSE:
-			return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return WAVE_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_RESUME:
-			return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return WAVE_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STATUS:
-			return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
+			return WAVE_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_GETDEVCAPS:
-			return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
+			return WAVE_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_INFO:
-			return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)dwParam2);
+			return WAVE_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		default:
 			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 		}
@@ -856,6 +857,8 @@
 	int			smplrate;
 	int			samplesize;
 	int			dsp_stereo;
+        LPWAVEFORMAT lpFormat;
+
 	dprintf_mciwave(stddeb,
 		     "wodOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
 	if (lpDesc == NULL) {
@@ -903,12 +906,13 @@
 	WOutDev[wDevID].dwTotalPlayed = 0;
 	WOutDev[wDevID].bufsize = abuf_size;
 	memcpy(&WOutDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
-	if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
+        lpFormat = (LPWAVEFORMAT)PTR_SEG_TO_LIN(lpDesc->lpFormat);
+	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
 	        fprintf(stderr,"Linux 'wodOpen' // Bad format %04X !\n",
-						lpDesc->lpFormat->wFormatTag);
+						lpFormat->wFormatTag);
 		return WAVERR_BADFORMAT;
 		}
-	memcpy(&WOutDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
+	memcpy(&WOutDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
 	if (WOutDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
 	if (WOutDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
 	if (WOutDev[wDevID].Format.wBitsPerSample == 0) {
@@ -1204,23 +1208,23 @@
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
 		case WODM_OPEN:
-			return wodOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
+			return wodOpen(wDevID, (LPWAVEOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WODM_CLOSE:
 			return wodClose(wDevID);
 		case WODM_WRITE:
-			return wodWrite(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+			return wodWrite(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WODM_PAUSE:
 			return 0L;
 		case WODM_GETPOS:
-			return wodGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
+			return wodGetPosition(wDevID, (LPMMTIME)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WODM_BREAKLOOP:
 			return 0L;
 		case WODM_PREPARE:
-			return wodPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+			return wodPrepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WODM_UNPREPARE:
-			return wodUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+			return wodUnprepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WODM_GETDEVCAPS:
-			return wodGetDevCaps(wDevID, (LPWAVEOUTCAPS)dwParam1, dwParam2);
+			return wodGetDevCaps(wDevID, (LPWAVEOUTCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WODM_GETNUMDEVS:
 			return 1L;
 		case WODM_GETPITCH:
@@ -1232,7 +1236,7 @@
 		case WODM_SETPLAYBACKRATE:
 			return 0L;
 		case WODM_GETVOLUME:
-			return wodGetVolume(wDevID, (LPDWORD)dwParam1);
+			return wodGetVolume(wDevID, (LPDWORD)PTR_SEG_TO_LIN(dwParam1));
 		case WODM_SETVOLUME:
 			return wodSetVolume(wDevID, dwParam1);
 		case WODM_RESTART:
@@ -1322,6 +1326,7 @@
 	int			smplrate;
 	int			samplesize;
 	int			dsp_stereo;
+        LPWAVEFORMAT  lpFormat;
 	dprintf_mciwave(stddeb,
 		 "widOpen(%u, %p, %08lX);\n", wDevID, lpDesc, dwFlags);
 	if (lpDesc == NULL) {
@@ -1370,12 +1375,13 @@
 	WInDev[wDevID].bufsize = abuf_size;
 	WInDev[wDevID].dwTotalRecorded = 0;
 	memcpy(&WInDev[wDevID].waveDesc, lpDesc, sizeof(WAVEOPENDESC));
-	if (lpDesc->lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
+        lpFormat = (LPWAVEFORMAT)PTR_SEG_TO_LIN(lpDesc->lpFormat);
+	if (lpFormat->wFormatTag != WAVE_FORMAT_PCM) {
 	        fprintf(stderr,"Linux 'widOpen' // Bad format %04X !\n",
-						lpDesc->lpFormat->wFormatTag);
+						lpFormat->wFormatTag);
 		return WAVERR_BADFORMAT;
 		}
-	memcpy(&WInDev[wDevID].Format, lpDesc->lpFormat, sizeof(PCMWAVEFORMAT));
+	memcpy(&WInDev[wDevID].Format, lpFormat, sizeof(PCMWAVEFORMAT));
 	WInDev[wDevID].Format.wBitsPerSample = 8; /* <-------------- */
 	if (WInDev[wDevID].Format.wf.nChannels == 0) return WAVERR_BADFORMAT;
 	if (WInDev[wDevID].Format.wf.nSamplesPerSec == 0) return WAVERR_BADFORMAT;
@@ -1700,21 +1706,21 @@
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
 		case WIDM_OPEN:
-			return widOpen(wDevID, (LPWAVEOPENDESC)dwParam1, dwParam2);
+			return widOpen(wDevID, (LPWAVEOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WIDM_CLOSE:
 			return widClose(wDevID);
 		case WIDM_ADDBUFFER:
-			return widAddBuffer(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+			return widAddBuffer(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WIDM_PREPARE:
-			return widPrepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+			return widPrepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WIDM_UNPREPARE:
-			return widUnprepare(wDevID, (LPWAVEHDR)dwParam1, dwParam2);
+			return widUnprepare(wDevID, (LPWAVEHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WIDM_GETDEVCAPS:
-			return widGetDevCaps(wDevID, (LPWAVEINCAPS)dwParam1, dwParam2);
+			return widGetDevCaps(wDevID, (LPWAVEINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WIDM_GETNUMDEVS:
 			return 1L;
 		case WIDM_GETPOS:
-			return widGetPosition(wDevID, (LPMMTIME)dwParam1, dwParam2);
+			return widGetPosition(wDevID, (LPMMTIME)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case WIDM_RESET:
 			return widReset(wDevID);
 		case WIDM_START:
diff --git a/multimedia/midi.c b/multimedia/midi.c
index 6f4507a..01ef172 100644
--- a/multimedia/midi.c
+++ b/multimedia/midi.c
@@ -17,7 +17,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include "windows.h"
-#include "user.h"
+#include "ldt.h"
 #include "driver.h"
 #include "mmsystem.h"
 
@@ -160,28 +160,28 @@
 			return (LRESULT)DRVCNF_RESTART;
 		case MCI_OPEN_DRIVER:
 		case MCI_OPEN:
-			return MIDI_mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
+			return MIDI_mciOpen(dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_CLOSE_DRIVER:
 		case MCI_CLOSE:
-			return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return MIDI_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_PLAY:
-			return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
+			return MIDI_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_RECORD:
-			return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)dwParam2);
+			return MIDI_mciRecord(dwDevID, dwParam1, (LPMCI_RECORD_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STOP:
-			return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return MIDI_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_SET:
-			return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
+			return MIDI_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_PAUSE:
-			return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return MIDI_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_RESUME:
-			return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return MIDI_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_STATUS:
-			return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
+			return MIDI_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_GETDEVCAPS:
-			return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
+			return MIDI_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_INFO:
-			return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)dwParam2);
+			return MIDI_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		default:
 			return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
 		}
@@ -1083,17 +1083,17 @@
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
 		case MIDM_OPEN:
-			return midOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
+			return midOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MIDM_CLOSE:
 			return midClose(wDevID);
 		case MIDM_ADDBUFFER:
-			return midAddBuffer(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+			return midAddBuffer(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MIDM_PREPARE:
-			return midPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+			return midPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MIDM_UNPREPARE:
-			return midUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+			return midUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MIDM_GETDEVCAPS:
-			return midGetDevCaps(wDevID, (LPMIDIINCAPS)dwParam1, dwParam2);
+			return midGetDevCaps(wDevID, (LPMIDIINCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MIDM_GETNUMDEVS:
 			return 1L;
 		case MIDM_RESET:
@@ -1353,19 +1353,19 @@
 			wDevID, wMsg, dwUser, dwParam1, dwParam2);
 	switch(wMsg) {
 		case MODM_OPEN:
-			return modOpen(wDevID, (LPMIDIOPENDESC)dwParam1, dwParam2);
+			return modOpen(wDevID, (LPMIDIOPENDESC)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MODM_CLOSE:
 			return modClose(wDevID);
 		case MODM_DATA:
 			return modData(wDevID, dwParam1);
 		case MODM_LONGDATA:
-			return modLongData(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+			return modLongData(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MODM_PREPARE:
-			return modPrepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+			return modPrepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MODM_UNPREPARE:
-			return modUnprepare(wDevID, (LPMIDIHDR)dwParam1, dwParam2);
+			return modUnprepare(wDevID, (LPMIDIHDR)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MODM_GETDEVCAPS:
-			return modGetDevCaps(wDevID, (LPMIDIOUTCAPS)dwParam1, dwParam2);
+			return modGetDevCaps(wDevID, (LPMIDIOUTCAPS)PTR_SEG_TO_LIN(dwParam1), dwParam2);
 		case MODM_GETNUMDEVS:
 			return 1L;
 		case MODM_GETVOLUME:
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index bb25771..27a2b3c 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -13,6 +13,7 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include "windows.h"
+#include "ldt.h"
 #include "callback.h"
 #include "user.h"
 #include "driver.h"
@@ -640,8 +641,9 @@
 			dwDevTyp = (DWORD)lpParms->lpstrDeviceType;
 			}
 		else {
-			printf("MCI_OPEN // Dev='%s' !\n", lpParms->lpstrDeviceType);
-			strcpy(str, lpParms->lpstrDeviceType);
+			printf("MCI_OPEN // Dev='%s' !\n",
+                              (char*)PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
+			strcpy(str, PTR_SEG_TO_LIN(lpParms->lpstrDeviceType));
 			AnsiUpper(str);
 			if (strcmp(str, "CDAUDIO") == 0) {
 				dwDevTyp = MCI_DEVTYPE_CD_AUDIO;
@@ -750,9 +752,9 @@
 					wDevID, wMsg, dwParam1, dwParam2);
 	switch(wMsg) {
 		case MCI_OPEN:
-			return mciOpen(dwParam1, (LPMCI_OPEN_PARMS)dwParam2);
+			return mciOpen(dwParam1, (LPMCI_OPEN_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		case MCI_CLOSE:
-			return mciClose(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
+			return mciClose(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)PTR_SEG_TO_LIN(dwParam2));
 		default:
 			switch(mciDrv[wDevID].wType) {
 				case MCI_DEVTYPE_CD_AUDIO:
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 8191585..40cb61d 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -122,7 +122,7 @@
       /* Create the BITMAPOBJ */
     hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
     if (!hbitmap) return 0;
-    bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_ADDR( hbitmap );
+    bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
 
     bmpObjPtr->size.cx = 0;
     bmpObjPtr->size.cy = 0;
diff --git a/objects/brush.c b/objects/brush.c
index 9d185af..de64274 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -145,7 +145,7 @@
     BRUSHOBJ * brushPtr;
     HBRUSH hbrush = GDI_AllocObject( sizeof(BRUSHOBJ), BRUSH_MAGIC );
     if (!hbrush) return 0;
-    brushPtr = (BRUSHOBJ *) GDI_HEAP_ADDR( hbrush );
+    brushPtr = (BRUSHOBJ *) GDI_HEAP_LIN_ADDR( hbrush );
     memcpy( &brushPtr->logbrush, brush, sizeof(LOGBRUSH) );
     return hbrush;
 }
diff --git a/objects/color.c b/objects/color.c
index 07acaf3..b455e49 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -107,14 +107,12 @@
     COLOR_ColormapSize = size;
     if (screenDepth <= 8)
     {
-        if (!(hSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
-                                            sizeof(WORD)*NB_RESERVED_COLORS )))
+        if (!(hSysColorTranslation = GDI_HEAP_ALLOC(sizeof(WORD)*NB_RESERVED_COLORS )))
             return FALSE;
-        if (!(hRevSysColorTranslation = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
-                                                        sizeof(WORD)*size )))
+        if (!(hRevSysColorTranslation = GDI_HEAP_ALLOC( sizeof(WORD)*size )))
             return FALSE;
-        colorTranslation = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
-        revTranslation   = (WORD *) GDI_HEAP_ADDR( hRevSysColorTranslation );
+        colorTranslation = (WORD *) GDI_HEAP_LIN_ADDR( hSysColorTranslation );
+        revTranslation   = (WORD *) GDI_HEAP_LIN_ADDR( hRevSysColorTranslation );
     }
     else colorTranslation = revTranslation = NULL;
 
@@ -284,12 +282,12 @@
     if (dc)
     {
         if (index >= dc->u.x.pal.mappingSize) return 0;
-        mapping = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping );
+        mapping = (WORD *) GDI_HEAP_LIN_ADDR( dc->u.x.pal.hMapping );
     }
     else
     {
         if (index >= NB_RESERVED_COLORS) return 0;
-        mapping = (WORD *) GDI_HEAP_ADDR( hSysColorTranslation );
+        mapping = (WORD *) GDI_HEAP_LIN_ADDR( hSysColorTranslation );
     }
     if (mapping) return mapping[index];
     else return index;  /* Identity mapping */
@@ -314,14 +312,13 @@
     if (map && (map != hSysColorTranslation))
     {
 	  /* Copy mapping table */
-	dc->u.x.pal.hMapping = GDI_HEAP_ALLOC(GMEM_MOVEABLE,sizeof(WORD)*size);
-	pmap = (WORD *) GDI_HEAP_ADDR( map );
-	pnewmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hMapping );
+	dc->u.x.pal.hMapping = GDI_HEAP_ALLOC( sizeof(WORD) * size );
+	pmap = (WORD *) GDI_HEAP_LIN_ADDR( map );
+	pnewmap = (WORD *) GDI_HEAP_LIN_ADDR( dc->u.x.pal.hMapping );
 	memcpy( pnewmap, pmap, sizeof(WORD)*size );
           /* Build reverse table */
-        dc->u.x.pal.hRevMapping = GDI_HEAP_ALLOC( GMEM_MOVEABLE,
-                                             sizeof(WORD)*COLOR_ColormapSize );
-        pmap = (WORD *) GDI_HEAP_ADDR( dc->u.x.pal.hRevMapping );
+        dc->u.x.pal.hRevMapping = GDI_HEAP_ALLOC(sizeof(WORD)*COLOR_ColormapSize);
+        pmap = (WORD *) GDI_HEAP_LIN_ADDR( dc->u.x.pal.hRevMapping );
         for (i = 0; i < size; i++) pmap[pnewmap[i]] = i;
     }
     else
diff --git a/objects/dc.c b/objects/dc.c
index 312f87f..243aae9 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -319,7 +319,7 @@
     
     if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
     if (!(handle = GDI_AllocObject( sizeof(DC), DC_MAGIC ))) return 0;
-    newdc = (DC *) GDI_HEAP_ADDR( handle );
+    newdc = (DC *) GDI_HEAP_LIN_ADDR( handle );
 
     dprintf_dc(stddeb, "GetDCState(%d): returning %d\n", hdc, handle );
 
@@ -394,7 +394,7 @@
 	return 1;  /* ?? */
     }
     if (!(hdcs = GetDCState( hdc ))) return 0;
-    dcs = (DC *) GDI_HEAP_ADDR( hdcs );
+    dcs = (DC *) GDI_HEAP_LIN_ADDR( hdcs );
     dcs->header.hNext = dc->header.hNext;
     dc->header.hNext = hdcs;
     dprintf_dc(stddeb, "SaveDC(%d): returning %d\n", hdc, dc->saveLevel+1 );
@@ -444,7 +444,7 @@
     
     handle = GDI_AllocObject( sizeof(DC), DC_MAGIC );
     if (!handle) return 0;
-    dc = (DC *) GDI_HEAP_ADDR( handle );
+    dc = (DC *) GDI_HEAP_LIN_ADDR( handle );
 
     dprintf_dc(stddeb, "CreateDC(%s %s %s): returning %d\n", 
 	    driver, device, output, handle );
@@ -500,7 +500,7 @@
 
     handle = GDI_AllocObject( sizeof(DC), DC_MAGIC );
     if (!handle) return 0;
-    dc = (DC *) GDI_HEAP_ADDR( handle );
+    dc = (DC *) GDI_HEAP_LIN_ADDR( handle );
 
     dprintf_dc(stddeb, "CreateCompatibleDC(%d): returning %d\n", hdc, handle );
 
diff --git a/objects/font.c b/objects/font.c
index 36d0ce4..15d1785 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -12,6 +12,7 @@
 #include <X11/Xatom.h>
 #include "font.h"
 #include "metafile.h"
+#include "wine.h"
 #include "callback.h"
 #include "stddebug.h"
 /* #define DEBUG_FONT */
@@ -249,7 +250,7 @@
     FONTOBJ * fontPtr;
     HFONT hfont = GDI_AllocObject( sizeof(FONTOBJ), FONT_MAGIC );
     if (!hfont) return 0;
-    fontPtr = (FONTOBJ *) GDI_HEAP_ADDR( hfont );
+    fontPtr = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hfont );
     memcpy( &fontPtr->logfont, font, sizeof(LOGFONT) );
     AnsiLower( fontPtr->logfont.lfFaceName );
     dprintf_font(stddeb,"CreateFontIndirect(%p); return %04x\n",font,hfont);
@@ -303,7 +304,7 @@
 	hnewfont = CreateFont(10, 7, 0, 0, FW_DONTCARE,
 			      FALSE, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
 			      DEFAULT_QUALITY, FF_DONTCARE, "*" );
-	font = (FONTOBJ *) GDI_HEAP_ADDR( hnewfont );
+	font = (FONTOBJ *) GDI_HEAP_LIN_ADDR( hnewfont );
     }
 
     if (dc->header.wMagic == METAFILE_DC_MAGIC)
@@ -688,14 +689,14 @@
 	dprintf_font(stddeb,"EnumFonts(%04X, %p='%s', %p, %p)\n", 
 		hDC, lpFaceName, lpFaceName, lpEnumFunc, lpData);
 	if (lpEnumFunc == NULL) return 0;
-	hLog = GDI_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LOGFONT) + LF_FACESIZE);
-	lpLogFont = (LPLOGFONT) GDI_HEAP_ADDR(hLog);
+	hLog = GDI_HEAP_ALLOC( sizeof(LOGFONT) + LF_FACESIZE );
+	lpLogFont = (LPLOGFONT) GDI_HEAP_LIN_ADDR(hLog);
 	if (lpLogFont == NULL) {
 		dprintf_font(stddeb,"EnumFonts // can't alloc LOGFONT struct !\n");
 		return 0;
 		}
-	hMet = GDI_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(TEXTMETRIC));
-	lptm = (LPTEXTMETRIC) GDI_HEAP_ADDR(hMet);
+	hMet = GDI_HEAP_ALLOC( sizeof(TEXTMETRIC) );
+	lptm = (LPTEXTMETRIC) GDI_HEAP_LIN_ADDR(hMet);
 	if (lptm == NULL) {
 		GDI_HEAP_FREE(hLog);
 		dprintf_font(stddeb, "EnumFonts // can't alloc TEXTMETRIC struct !\n");
@@ -739,8 +740,9 @@
 #ifdef WINELIB
 		nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData);
 #else
-		nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLogFont,
-					2, (int)lptm, 0, (int)0, 2, (int)lpData);
+		nRet = CallBack16(lpEnumFunc, 4, 2, GDI_HEAP_SEG_ADDR(hLog),
+					2, GDI_HEAP_SEG_ADDR(hMet),
+                                        0, (int)0, 2, (int)lpData);
 #endif
 		if (nRet == 0) {
 			dprintf_font(stddeb,"EnumFonts // EnumEnd requested by application !\n");
@@ -772,14 +774,14 @@
 	dprintf_font(stddeb,"EnumFontFamilies(%04X, %p, %p, %p)\n", 
 					hDC, lpszFamily, lpEnumFunc, lpData);
 	if (lpEnumFunc == NULL) return 0;
-	hLog = GDI_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LOGFONT) + LF_FACESIZE);
-	lpLogFont = (LPLOGFONT) GDI_HEAP_ADDR(hLog);
+	hLog = GDI_HEAP_ALLOC( sizeof(LOGFONT) + LF_FACESIZE );
+	lpLogFont = (LPLOGFONT) GDI_HEAP_LIN_ADDR(hLog);
 	if (lpLogFont == NULL) {
 		dprintf_font(stddeb,"EnumFontFamilies // can't alloc LOGFONT struct !\n");
 		return 0;
 		}
-	hMet = GDI_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(TEXTMETRIC));
-	lptm = (LPTEXTMETRIC) GDI_HEAP_ADDR(hMet);
+	hMet = GDI_HEAP_ALLOC( sizeof(TEXTMETRIC) );
+	lptm = (LPTEXTMETRIC) GDI_HEAP_LIN_ADDR(hMet);
 	if (lptm == NULL) {
 		GDI_HEAP_FREE(hLog);
 		dprintf_font(stddeb,"EnumFontFamilies // can't alloc TEXTMETRIC struct !\n");
@@ -824,8 +826,9 @@
 #ifdef WINELIB
 		nRet = (*lpEnumFunc)(lpLogFont, lptm, 0, lpData);
 #else
-		nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLogFont,
-					2, (int)lptm, 0, (int)0, 2, (int)lpData);
+		nRet = CallBack16(lpEnumFunc, 4, 2, GDI_HEAP_SEG_ADDR(hLog),
+					2, GDI_HEAP_SEG_ADDR(hMet),
+                                        0, (int)0, 2, (int)lpData);
 #endif
 		if (nRet == 0) {
 			dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 340c95d..fff10ce 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -8,7 +8,6 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include "selectors.h"
 #include "gdi.h"
 #include "color.h"
 #include "bitmap.h"
@@ -21,7 +20,8 @@
 /* #define DEBUG_GDI */
 #include "debug.h"
 
-MDESC *GDI_Heap = NULL;
+LPSTR GDI_Heap = NULL;
+WORD GDI_HeapSel = 0;
 
 /* Object types for EnumObjects() */
 #define OBJ_PEN             1
@@ -162,20 +162,19 @@
 BOOL GDI_Init(void)
 {
     HPALETTE hpalette;
-    struct segment_descriptor_s * s;
 
 #ifndef WINELIB
-    /* Create GDI heap */
+      /* Create GDI heap */
 
-    s = (struct segment_descriptor_s *)GetNextSegment( 0, 0x10000 );
-    if (s == NULL) return FALSE;
-    HEAP_Init( &GDI_Heap, s->base_addr, GDI_HEAP_SIZE );
+    if (!(GDI_HeapSel = GlobalAlloc(GMEM_FIXED, GDI_HEAP_SIZE))) return FALSE;
+    GDI_Heap = GlobalLock( GDI_HeapSel );
+    LocalInit( GDI_HeapSel, 0, GDI_HEAP_SIZE-1 );
 #endif
     
       /* Create default palette */
 
     if (!(hpalette = COLOR_Init())) return FALSE;
-    StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *) GDI_HEAP_ADDR( hpalette );
+    StockObjects[DEFAULT_PALETTE] = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( hpalette );
 
       /* Create default bitmap */
 
@@ -230,7 +229,7 @@
         
     for (handle = first; handle && (handle != obj); )
     {
-	GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+	GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
 	handle = header->hNext;
     }
     return handle;
@@ -244,9 +243,9 @@
 {
     static DWORD count = 0;
     GDIOBJHDR * obj;
-    HANDLE handle = GDI_HEAP_ALLOC( GMEM_MOVEABLE, size );
+    HANDLE handle = GDI_HEAP_ALLOC( size );
     if (!handle) return 0;
-    obj = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    obj = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
     obj->hNext   = 0;
     obj->wMagic  = magic;
     obj->dwCount = ++count;
@@ -267,7 +266,7 @@
       /* Can't free stock objects */
     if (handle >= FIRST_STOCK_HANDLE) return TRUE;
     
-    object = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    object = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
     if (!object) return FALSE;
     object->wMagic = 0;  /* Mark it as invalid */
 
@@ -292,7 +291,7 @@
 	if (handle < FIRST_STOCK_HANDLE + NB_STOCK_OBJECTS)
 	    ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
     }
-    else ptr = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    else ptr = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
     if (!ptr) return NULL;
     if (ptr->wMagic != magic) return NULL;
     return ptr;
@@ -306,7 +305,7 @@
 {
       /* Check if object is valid */
 
-    GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_ADDR( obj );
+    GDIOBJHDR * header = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( obj );
     if (!header) return FALSE;
 
     dprintf_gdi(stddeb, "DeleteObject: %d\n", obj );
@@ -353,7 +352,7 @@
 	if (handle < FIRST_STOCK_HANDLE + NB_STOCK_OBJECTS)
 	    ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
     }
-    else ptr = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    else ptr = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
     if (!ptr) return 0;
     
     switch(ptr->wMagic)
@@ -387,7 +386,7 @@
 	if (handle < FIRST_STOCK_HANDLE + NB_STOCK_OBJECTS)
 	    ptr = StockObjects[handle - FIRST_STOCK_HANDLE];
     }
-    else ptr = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+    else ptr = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
     if (!ptr) return 0;
     
     dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
@@ -446,8 +445,8 @@
 			wMagic = PEN_MAGIC;
 			dprintf_gdi(stddeb,"EnumObjects(%04X, OBJ_PEN, %p, %p);\n", 
 									hDC, lpEnumFunc, lpData);
-			hLog = GDI_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LOGPEN));
-			lpLog = (LPSTR) GDI_HEAP_ADDR(hLog);
+			hLog = GDI_HEAP_ALLOC( sizeof(LOGPEN) );
+			lpLog = (LPSTR) GDI_HEAP_LIN_ADDR(hLog);
 			if (lpLog == NULL) {
 				fprintf(stderr,"EnumObjects // Unable to alloc LOGPEN struct !\n");
 				return 0;
@@ -457,8 +456,8 @@
 			wMagic = BRUSH_MAGIC;
 			dprintf_gdi(stddeb,"EnumObjects(%04X, OBJ_BRUSH, %p, %p);\n", 
 									hDC, lpEnumFunc, lpData);
-			hLog = GDI_HEAP_ALLOC(GMEM_MOVEABLE, sizeof(LOGBRUSH));
-			lpLog = (LPSTR) GDI_HEAP_ADDR(hLog);
+			hLog = GDI_HEAP_ALLOC( sizeof(LOGBRUSH) );
+			lpLog = (LPSTR) GDI_HEAP_LIN_ADDR(hLog);
 			if (lpLog == NULL) {
 				fprintf(stderr,"EnumObjects // Unable to alloc LOGBRUSH struct !\n");
 				return 0;
@@ -469,6 +468,7 @@
 						hDC, nObjType, lpEnumFunc, lpData);
 			return 0;
 		}
+#ifdef notdef  /* FIXME: stock object ptr won't work in callback */
 	dprintf_gdi(stddeb,"EnumObjects // Stock Objects first !\n");
 	for (i = 0; i < NB_STOCK_OBJECTS; i++) {
 		header = StockObjects[i];
@@ -491,7 +491,8 @@
 #ifdef WINELIB
 			nRet = (*lpEnumFunc)(lpLog, lpData);
 #else
-			nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLog,	2, (int)lpData);
+			nRet = CallBack16(lpEnumFunc, 4, 2,
+                                      GDI_HEAP_SEG_ADDR(hLog), 2, (int)lpData);
 #endif
 */
 			dprintf_gdi(stddeb,"EnumObjects // after CallBack16 !\n");
@@ -502,11 +503,13 @@
 				}
 			}
 		}
+#endif  /* notdef */
+
 	if (lpPenBrushList == NULL) return 0;
 	dprintf_gdi(stddeb,"EnumObjects // Now DC owned objects %p !\n", header);
 	for (lphObj = lpPenBrushList; *lphObj != 0; ) {
 		dprintf_gdi(stddeb,"EnumObjects // *lphObj=%04X\n", *lphObj);
-		header = (GDIOBJHDR *) GDI_HEAP_ADDR(*lphObj++);
+		header = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR(*lphObj++);
 		if (header->wMagic == wMagic) {
 			dprintf_gdi(stddeb,"EnumObjects // DC_Obj lpLog=%p lpData=%p\n", lpLog, lpData);
 			if (header->wMagic == BRUSH_MAGIC) {
@@ -525,7 +528,8 @@
 #ifdef WINELIB
 			nRet = (*lpEnumFunc)(lpLog, lpData);
 #else
-			nRet = CallBack16(lpEnumFunc, 4, 2, (int)lpLog,	2, (int)lpData);
+			nRet = CallBack16(lpEnumFunc, 4, 2,
+                                      GDI_HEAP_SEG_ADDR(hLog), 2, (int)lpData);
 #endif
 */
 			nRet = 1;
@@ -549,7 +553,7 @@
 {
 	GDIOBJHDR *object;
 
-	object = (GDIOBJHDR *) GDI_HEAP_ADDR( handle );
+	object = (GDIOBJHDR *) GDI_HEAP_LIN_ADDR( handle );
 	if (object)
 		return TRUE;
 	else
diff --git a/objects/metafile.c b/objects/metafile.c
index 1ad135e..9a8208a 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -84,7 +84,7 @@
 
     handle = GDI_AllocObject(sizeof(DC), METAFILE_DC_MAGIC);
     if (!handle) return 0;
-    dc = (DC *)GDI_HEAP_ADDR(handle);
+    dc = (DC *)GDI_HEAP_LIN_ADDR(handle);
 
     if (!(dc->w.hMetaFile = GlobalAlloc(GMEM_MOVEABLE, sizeof(METAFILE))))
 	return 0;
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index a0abcbc..381bec6 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -193,7 +193,7 @@
     hbitmap = GDI_AllocObject( sizeof(BITMAPOBJ), BITMAP_MAGIC );
     if (!hbitmap) return 0;
 
-    bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_ADDR( hbitmap );
+    bmpObjPtr = (BITMAPOBJ *) GDI_HEAP_LIN_ADDR( hbitmap );
     bmpObjPtr->size.cx = 0;
     bmpObjPtr->size.cy = 0;
     bmpObjPtr->pixmap  = pixmap;
diff --git a/objects/palette.c b/objects/palette.c
index 050f7a2..bee05d5 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -33,7 +33,7 @@
     size = sizeof(LOGPALETTE) + (palette->palNumEntries - 1) * sizeof(PALETTEENTRY);
     hpalette = GDI_AllocObject( sizeof(GDIOBJHDR) + size, PALETTE_MAGIC );
     if (!hpalette) return 0;
-    palettePtr = (PALETTEOBJ *) GDI_HEAP_ADDR( hpalette );
+    palettePtr = (PALETTEOBJ *) GDI_HEAP_LIN_ADDR( hpalette );
     memcpy( &palettePtr->logpalette, palette, size );
     return hpalette;
 }
diff --git a/objects/pen.c b/objects/pen.c
index 0896fda..131667a 100644
--- a/objects/pen.c
+++ b/objects/pen.c
@@ -32,7 +32,7 @@
     if (pen->lopnStyle > PS_INSIDEFRAME) return 0;
     hpen = GDI_AllocObject( sizeof(PENOBJ), PEN_MAGIC );
     if (!hpen) return 0;
-    penPtr = (PENOBJ *) GDI_HEAP_ADDR( hpen );    
+    penPtr = (PENOBJ *) GDI_HEAP_LIN_ADDR( hpen );    
     memcpy( &penPtr->logpen, pen, sizeof(LOGPEN) );
     return hpen;
 }
diff --git a/objects/region.c b/objects/region.c
index 288d70f..41df11b 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -72,7 +72,7 @@
     RGNOBJ *obj;
 
     if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
-    obj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
+    obj = (RGNOBJ *) GDI_HEAP_LIN_ADDR( hrgn );
     if ((right > left) && (bottom > top))
     {
 	XRectangle rect = { left, top, right - left, bottom - top };
@@ -141,7 +141,7 @@
       /* Create region */
 
     if (!(hrgn = GDI_AllocObject( sizeof(RGNOBJ), REGION_MAGIC ))) return 0;
-    obj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
+    obj = (RGNOBJ *) GDI_HEAP_LIN_ADDR( hrgn );
     obj->xrgn = XCreateRegion();
     dprintf_region(stddeb,"CreateRoundRectRgn(%d,%d-%d,%d %dx%d): return=%x\n",
                left, top, right, bottom, ellipse_width, ellipse_height, hrgn );
@@ -274,7 +274,7 @@
 	free( xpoints );
 	return 0;
     }
-    obj = (RGNOBJ *) GDI_HEAP_ADDR( hrgn );
+    obj = (RGNOBJ *) GDI_HEAP_LIN_ADDR( hrgn );
     obj->xrgn = 0;
     dprintf_region(stddeb, "CreatePolyPolygonRgn: %d polygons, returning %x\n",
                    nbpolygons, hrgn );
diff --git a/objects/text.c b/objects/text.c
index 186b729..9e3347c 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -66,6 +66,7 @@
 		    i++;
 		i++;
 		*len = j;
+		(*count)--;
 		return (&str[i]);
 	    }
 	    dest[j++] = str[i++];
@@ -195,7 +196,7 @@
 
     dprintf_text(stddeb,"DrawText: '%s', %d , [(%d,%d),(%d,%d)]\n", str, count,
 	   rect->left, rect->top, rect->right, rect->bottom);
-
+    
     if (count == -1) count = strlen(str);
     strPtr = str;
 
diff --git a/rc/Imakefile b/rc/Imakefile
index 479cf27..424addb 100644
--- a/rc/Imakefile
+++ b/rc/Imakefile
@@ -50,13 +50,13 @@
 LOCAL_LIBRARIES = -lfl
 #endif
 
-depend:: y.tab.c y.tab.h lex.yy.c
+NormalProgramTarget(winerc,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
+
+DependTarget()
 
 clean::
 	$(RM) lex.yy.c y.tab.*
 
-ComplexProgramTarget(winerc)
-
 y.tab.c y.tab.h: parser.y
 	$(YACC) -d -t parser.y
 
diff --git a/toolkit/heap.c b/toolkit/heap.c
index cc4e2d7..d20be76 100644
--- a/toolkit/heap.c
+++ b/toolkit/heap.c
@@ -186,16 +186,6 @@
 	return LocalReAlloc (hMem, new_size, flags);
 }
 
-char *GlobalLinearLock (HANDLE hMem)
-{
-    return GlobalLock (hMem);
-}
-
-HANDLE GlobalLinearUnlock (HANDLE hMem)
-{
-    return GlobalUnlock (hMem);
-}
-
 int HEAP_LocalSize ()
 {
     return 0;
@@ -207,16 +197,9 @@
 }
 
 #ifdef UNIMPLEMENTED
-void *GlobalQuickAlloc(int size)
-{
-}
 
 DWORD int GlobalHandle(WORD selector)
 {
 }
 
-unsigned int GlobalHandleFromPointer(void *block)
-{
-}
-
 #endif
diff --git a/tools/Imakefile b/tools/Imakefile
index f3bac38..2c6613b 100644
--- a/tools/Imakefile
+++ b/tools/Imakefile
@@ -1,9 +1,19 @@
 #include "../Wine.tmpl"
 
-MODULE = tools
+SRCS = build.c
+
+OBJS = $(SRCS:.c=.o)
+
+AllTarget(build)
 
 #ifndef NewBuild
-SimpleProgramTarget(build)
+NormalProgramTarget(build,build.o,$(DEPLIBS),,)
 #else
-SimpleProgramTarget(newbuild)
+NormalProgramTarget(newbuild,$(OBJS),$(DEPLIBS),,)
 #endif
+
+DependTarget()
+
+includes::
+
+install::
diff --git a/tools/build.c b/tools/build.c
index 9549673..c4e8125 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -30,12 +30,11 @@
 #define VARTYPE_LONG	2
 #define VARTYPE_FARPTR	3
 
-#define FUNCTYPE_PASCAL_16	15
-#define FUNCTYPE_PASCAL		16
-#define FUNCTYPE_C		17
-#define FUNCTYPE_REG		19
+#define FUNCTYPE_PASCAL_16	16
+#define FUNCTYPE_PASCAL		17
+#define FUNCTYPE_REG		18
 
-#define EQUATETYPE_ABS	18
+#define EQUATETYPE_ABS	19
 #define TYPE_RETURN	20
 
 /*#define MAX_ORDINALS	1024*/
@@ -102,8 +101,6 @@
     int arg_16_offsets[16];
     int arg_16_size;
     char internal_name[80];
-    int n_args_32;
-    int arg_indices_32[16];
 } ORDFUNCDEF;
 
 typedef struct ordinal_return_definition_s
@@ -361,7 +358,7 @@
 	    fdp->arg_16_size += 2;
 	    fdp->arg_16_offsets[i] = 2;
 	}
-	else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
+	else if (stricmp(token, "long") == 0 || stricmp(token, "segptr") == 0)
 	{
 	    fdp->arg_types_16[i] = VARTYPE_LONG;
 	    fdp->arg_16_size += 4;
@@ -381,52 +378,15 @@
     }
     fdp->n_args_16 = i;
 
-    if (type == FUNCTYPE_PASCAL_16 || type == FUNCTYPE_PASCAL ||
-	type == FUNCTYPE_REG )
+    current_offset = 0;
+    for (i--; i >= 0; i--)
     {
-	current_offset = 0;
-	for (i--; i >= 0; i--)
-	{
-	    arg_size = fdp->arg_16_offsets[i];
-	    fdp->arg_16_offsets[i] = current_offset;
-	    current_offset += arg_size;
-	}
-    }
-    else
-    {
-	current_offset = 0;
-	for (i = 0; i < fdp->n_args_16; i++)
-	{
-	    arg_size = fdp->arg_16_offsets[i];
-	    fdp->arg_16_offsets[i] = current_offset;
-	    current_offset += arg_size;
-	}
+        arg_size = fdp->arg_16_offsets[i];
+        fdp->arg_16_offsets[i] = current_offset;
+        current_offset += arg_size;
     }
 
     strcpy(fdp->internal_name, GetToken());
-    token = GetToken();
-    if (*token != '(')
-    {
-	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
-	exit(1);
-    }
-    for (i = 0; i < 16; i++)
-    {
-	token = GetToken();
-	if (*token == ')')
-	    break;
-
-	fdp->arg_indices_32[i] = atoi(token);
-	if (fdp->arg_indices_32[i] < 1 || 
-	    fdp->arg_indices_32[i] > fdp->n_args_16)
-	{
-	    fprintf(stderr, "%d: Bad argument index %d\n", Line,
-		    fdp->arg_indices_32[i]);
-	    exit(1);
-	}
-    }
-    fdp->n_args_32 = i;
-
     return 0;
 }
 
@@ -524,8 +484,6 @@
 	return ParseVariable(ordinal, VARTYPE_WORD);
     else if (stricmp(token, "long") == 0)
 	return ParseVariable(ordinal, VARTYPE_LONG);
-    else if (stricmp(token, "c") == 0)
-	return ParseExportFunction(ordinal, FUNCTYPE_C);
     else if (stricmp(token, "p") == 0)
 	return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
     else if (stricmp(token, "pascal") == 0)
@@ -705,7 +663,7 @@
     ORDRETDEF *rdp;
     FILE *fp;
     char filename[80];
-    int i, ci, add_count;
+    int i, ci, add_count, argnum;
     int prev_index;      /* Index to previous #define (-1 if none) */
 
     /* the difference between last #define and the current */
@@ -765,27 +723,6 @@
     fprintf (fp, "#define __ASSEMBLY__\n");
     fprintf (fp, "#include <asm/segment.h>\n");
 #endif
-#if 0
-    fprintf(fp, "\t.globl " PREFIX "%s_Dispatch\n", UpperDLLName);
-    fprintf(fp, PREFIX "%s_Dispatch:\n", UpperDLLName);
-    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-#ifdef __ELF__
-    fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32\n\n");
-#else
-    fprintf(fp, "\tjmp\t_CallTo32\n\n");
-#endif
-
-    fprintf(fp, "\t.globl " PREFIX "%s_Dispatch_16\n", UpperDLLName);
-    fprintf(fp, PREFIX "%s_Dispatch_16:\n", UpperDLLName);
-    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-#ifdef __ELF__
-    fprintf(fp, "\tljmp\t$USER_CS, $" PREFIX "CallTo32_16\n\n");
-#else
-    fprintf(fp, "\tjmp\t_CallTo32_16\n\n");
-#endif
-#endif
 
     odp = OrdinalDefinitions;
     for (i = 0; i <= Limit; i++, odp++)
@@ -887,7 +824,6 @@
 #endif
 		break;
 		
-	      case FUNCTYPE_C:
 	      default:
 		fprintf(fp, PREFIX "%s_Ordinal_%d:\n", UpperDLLName, i);
                 fprintf(fp, "\tmovl\t$0x%08x,%%eax\n", (DLLId << 16) | i);
@@ -925,7 +861,7 @@
     {
 	if (odp->valid && 
 	    (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_PASCAL_16 ||
-	     odp->type == FUNCTYPE_REG || odp->type == FUNCTYPE_C ))
+	     odp->type == FUNCTYPE_REG))
 	{
 	    fdp = odp->additional_data;
 	    fprintf(fp, "extern int %s();\n", fdp->internal_name);
@@ -941,7 +877,6 @@
     odp = OrdinalDefinitions;
     for (i = 0; i <= Limit; i++, odp++)
     {
-	int argnum;
 	fdp = odp->additional_data;
 
 	switch (odp->type)
@@ -949,21 +884,19 @@
 	  case FUNCTYPE_PASCAL:
 	  case FUNCTYPE_PASCAL_16:
 	  case FUNCTYPE_REG:
-	    if (!odp->valid || fdp->n_args_32 <=0 )
-	       continue;
-	    if (prev_index<0) 
-		fprintf(fp,"#\tdefine %s_ref_%d   0\n\t", UpperDLLName, i);
-	    else
-		fprintf(fp,"#\tdefine %s_ref_%d   %s_ref_%d+%d\n\t",
-			UpperDLLName,i, UpperDLLName,prev_index ,prev_n_args);
-	    for (argnum = 0; argnum < fdp->n_args_32; argnum++)
-		 fprintf(fp, "%d, ",
-		         fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1]);
-	    fprintf(fp,"\n");
+            if (!odp->valid || fdp->n_args_16 <= 0) continue;
+            if (prev_index<0) 
+                fprintf(fp,"#\tdefine %s_ref_%d   0\n\t", UpperDLLName, i);
+            else
+                fprintf(fp,"#\tdefine %s_ref_%d   %s_ref_%d+%d\n\t",
+                        UpperDLLName,i, UpperDLLName,prev_index ,prev_n_args);
+            for (argnum = 0; argnum < fdp->n_args_16; argnum++)
+                fprintf(fp, "%d, ", fdp->arg_16_offsets[argnum]);
+            fprintf(fp,"\n");
 	    
-	    prev_n_args=fdp->n_args_32;
-	    prev_index=i;
-	}
+            prev_n_args=fdp->n_args_16;
+            prev_index=i;
+        }
     }    
     fprintf(fp,"};\n");
 
@@ -982,15 +915,14 @@
 	  case FUNCTYPE_PASCAL:
 	  case FUNCTYPE_PASCAL_16:
 	  case FUNCTYPE_REG:
-	    if (!odp->valid || fdp->n_args_32 <=0 )
-	       continue;
+            if (!odp->valid || fdp->n_args_16 <= 0) continue;
 	    
-	    fprintf(fp,"/* %s_%d */\n\t", UpperDLLName, i);
+            fprintf(fp,"/* %s_%d */\n\t", UpperDLLName, i);
 	    
-	    for (argnum = 0; argnum < fdp->n_args_32; argnum++)
-		fprintf(fp, "%d, ", fdp->arg_types_16[argnum]);
-	    fprintf(fp,"\n");
-	}
+            for (argnum = 0; argnum < fdp->n_args_16; argnum++)
+                fprintf(fp, "%d, ", fdp->arg_types_16[argnum]);
+            fprintf(fp,"\n");
+        }
     }    
     fprintf(fp,"};\n");
 
@@ -1014,9 +946,9 @@
 	  case FUNCTYPE_REG:
 	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
 	    fprintf(fp, "\042%s\042, ", odp->export_name);
-	    fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
-	    fprintf(fp, "%d, ", fdp->n_args_32);
-	    if (fdp->n_args_32 > 0)
+	    fprintf(fp, "%s, ", fdp->internal_name);
+	    fprintf(fp, "%d, ", fdp->n_args_16);
+	    if (fdp->n_args_16 > 0)
 	       fprintf(fp,"%s_ref_%d", UpperDLLName, i);
 	    else
 	       fprintf(fp,"      0    ");
@@ -1027,30 +959,6 @@
 	    fprintf(fp, "}, \n");
 	    break;
 		
-	  case FUNCTYPE_C:
-	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
-	    fprintf(fp, "\042%s\042, ", odp->export_name);
-	    fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
-#ifdef WINESTAT
-	    fprintf(fp, "0, ");
-#endif	    
-	    fprintf(fp, "%d, ", fdp->n_args_32);
-	    if (fdp->n_args_32 > 0)
-	    {
-		int argnum;
-		
-		fprintf(fp, "\n      {\n");
-		for (argnum = 0; argnum < fdp->n_args_32; argnum++)
-		{
-		    fprintf(fp, "        { %d, %d },\n",
-			    fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
-			    fdp->arg_types_16[argnum]);
-		}
-		fprintf(fp, "      }\n    ");
-	    }
-	    fprintf(fp, "}, \n");
-	    break;
-	    
 	  default:
 	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", 
 		    UTEXTSEL, UpperDLLName, i);
diff --git a/tools/build.c.save b/tools/build.c.save
deleted file mode 100644
index 9b0eada..0000000
--- a/tools/build.c.save
+++ /dev/null
@@ -1,847 +0,0 @@
-static char RCSId[] = "$Id: build.c,v 1.3 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#ifdef linux
-#define UTEXTSEL 0x23
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#define UTEXTSEL 0x1f
-#endif
-
-#define VARTYPE_BYTE	0
-#define VARTYPE_SIGNEDWORD	0
-#define VARTYPE_WORD	1
-#define VARTYPE_LONG	2
-#define VARTYPE_FARPTR	3
-
-#define FUNCTYPE_PASCAL	16
-#define FUNCTYPE_C	17
-#define FUNCTYPE_REG	19
-
-#define EQUATETYPE_ABS	18
-#define TYPE_RETURN	20
-
-#define MAX_ORDINALS	1024
-
-typedef struct ordinal_definition_s
-{
-    int valid;
-    int type;
-    char export_name[80];
-    void *additional_data;
-} ORDDEF;
-
-typedef struct ordinal_variable_definition_s
-{
-    int n_values;
-    int *values;
-} ORDVARDEF;
-
-typedef struct ordinal_function_definition_s
-{
-    int n_args_16;
-    int arg_types_16[16];
-    int arg_16_offsets[16];
-    int arg_16_size;
-    char internal_name[80];
-    int n_args_32;
-    int arg_indices_32[16];
-} ORDFUNCDEF;
-
-typedef struct ordinal_return_definition_s
-{
-    int arg_size;
-    int ret_value;
-} ORDRETDEF;
-
-ORDDEF OrdinalDefinitions[MAX_ORDINALS];
-
-char LowerDLLName[80];
-char UpperDLLName[80];
-int Limit;
-int DLLId;
-FILE *SpecFp;
-
-char *ParseBuffer = NULL;
-char *ParseNext;
-char ParseSaveChar;
-int Line;
-
-int IsNumberString(char *s)
-{
-    while (*s != '\0')
-	if (!isdigit(*s++))
-	    return 0;
-
-    return 1;
-}
-
-char *strlower(char *s)
-{
-    char *p;
-    
-    for(p = s; *p != '\0'; p++)
-	*p = tolower(*p);
-
-    return s;
-}
-
-char *strupper(char *s)
-{
-    char *p;
-    
-    for(p = s; *p != '\0'; p++)
-	*p = toupper(*p);
-
-    return s;
-}
-
-int stricmp(char *s1, char *s2)
-{
-    if (strlen(s1) != strlen(s2))
-	return -1;
-    
-    while (*s1 != '\0')
-	if (*s1++ != *s2++)
-	    return -1;
-    
-    return 0;
-}
-
-char *
-GetTokenInLine(void)
-{
-    char *p;
-    char *token;
-
-    if (ParseNext != ParseBuffer)
-    {
-	if (ParseSaveChar == '\0')
-	    return NULL;
-	*ParseNext = ParseSaveChar;
-    }
-    
-    /*
-     * Remove initial white space.
-     */
-    for (p = ParseNext; isspace(*p); p++)
-	;
-    
-    if (*p == '\0')
-	return NULL;
-    
-    /*
-     * Find end of token.
-     */
-    token = p++;
-    if (*token != '(' && *token != ')')
-	while (*p != '\0' && *p != '(' && *p != ')' && !isspace(*p))
-	    p++;
-    
-    ParseSaveChar = *p;
-    ParseNext = p;
-    *p = '\0';
-
-    return token;
-}
-
-char *
-GetToken(void)
-{
-    char *token;
-
-    if (ParseBuffer == NULL)
-    {
-	ParseBuffer = malloc(512);
-	ParseNext = ParseBuffer;
-	Line++;
-	while (1)
-	{
-	    if (fgets(ParseBuffer, 511, SpecFp) == NULL)
-		return NULL;
-	    if (ParseBuffer[0] != '#')
-		break;
-	}
-    }
-
-    while ((token = GetTokenInLine()) == NULL)
-    {
-	ParseNext = ParseBuffer;
-	Line++;
-	while (1)
-	{
-	    if (fgets(ParseBuffer, 511, SpecFp) == NULL)
-		return NULL;
-	    if (ParseBuffer[0] != '#')
-		break;
-	}
-    }
-
-    return token;
-}
-
-int
-ParseVariable(int ordinal, int type)
-{
-    ORDDEF *odp;
-    ORDVARDEF *vdp;
-    char export_name[80];
-    char *token;
-    char *endptr;
-    int *value_array;
-    int n_values;
-    int value_array_size;
-    
-    strcpy(export_name, GetToken());
-
-    token = GetToken();
-    if (*token != '(')
-    {
-	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
-	exit(1);
-    }
-
-    n_values = 0;
-    value_array_size = 25;
-    value_array = malloc(sizeof(*value_array) * value_array_size);
-    
-    while ((token = GetToken()) != NULL)
-    {
-	if (*token == ')')
-	    break;
-
-	value_array[n_values++] = strtol(token, &endptr, 0);
-	if (n_values == value_array_size)
-	{
-	    value_array_size += 25;
-	    value_array = realloc(value_array, 
-				  sizeof(*value_array) * value_array_size);
-	}
-	
-	if (endptr == NULL || *endptr != '\0')
-	{
-	    fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
-		    token);
-	    exit(1);
-	}
-    }
-    
-    if (token == NULL)
-    {
-	fprintf(stderr, "%d: End of file in variable declaration\n", Line);
-	exit(1);
-    }
-
-    if (ordinal >= MAX_ORDINALS)
-    {
-	fprintf(stderr, "%d: Ordinal number too large\n", Line);
-	exit(1);
-    }
-    
-    odp = &OrdinalDefinitions[ordinal];
-    odp->valid = 1;
-    odp->type = type;
-    strcpy(odp->export_name, export_name);
-    
-    vdp = malloc(sizeof(*vdp));
-    odp->additional_data = vdp;
-    
-    vdp->n_values = n_values;
-    vdp->values = realloc(value_array, sizeof(*value_array) * n_values);
-
-    return 0;
-}
-
-int
-ParseExportFunction(int ordinal, int type)
-{
-    char *token;
-    ORDDEF *odp;
-    ORDFUNCDEF *fdp;
-    int arg_types[16];
-    int i;
-    int arg_num;
-    int current_offset;
-    int arg_size;
-	
-    
-    if (ordinal >= MAX_ORDINALS)
-    {
-	fprintf(stderr, "%d: Ordinal number too large\n", Line);
-	exit(1);
-    }
-    
-    odp = &OrdinalDefinitions[ordinal];
-    strcpy(odp->export_name, GetToken());
-    odp->valid = 1;
-    odp->type = type;
-    fdp = malloc(sizeof(*fdp));
-    odp->additional_data = fdp;
-
-    token = GetToken();
-    if (*token != '(')
-    {
-	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
-	exit(1);
-    }
-
-    fdp->arg_16_size = 0;
-    for (i = 0; i < 16; i++)
-    {
-	token = GetToken();
-	if (*token == ')')
-	    break;
-
-	if (stricmp(token, "byte") == 0 || stricmp(token, "word") == 0)
-	{
-	    fdp->arg_types_16[i] = VARTYPE_WORD;
-	    fdp->arg_16_size += 2;
-	    fdp->arg_16_offsets[i] = 2;
-	}
-	else if (stricmp(token, "s_byte") == 0 || 
-		 stricmp(token, "s_word") == 0)
-	{
-	    fdp->arg_types_16[i] = VARTYPE_SIGNEDWORD;
-	    fdp->arg_16_size += 2;
-	    fdp->arg_16_offsets[i] = 2;
-	}
-	else if (stricmp(token, "long") == 0 || stricmp(token, "s_long") == 0)
-	{
-	    fdp->arg_types_16[i] = VARTYPE_LONG;
-	    fdp->arg_16_size += 4;
-	    fdp->arg_16_offsets[i] = 4;
-	}
-	else if (stricmp(token, "ptr") == 0)
-	{
-	    fdp->arg_types_16[i] = VARTYPE_FARPTR;
-	    fdp->arg_16_size += 4;
-	    fdp->arg_16_offsets[i] = 4;
-	}
-	else
-	{
-	    fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
-	    exit(1);
-	}
-    }
-    fdp->n_args_16 = i;
-
-    if (type == FUNCTYPE_PASCAL || type == FUNCTYPE_REG)
-    {
-	current_offset = 0;
-	for (i--; i >= 0; i--)
-	{
-	    arg_size = fdp->arg_16_offsets[i];
-	    fdp->arg_16_offsets[i] = current_offset;
-	    current_offset += arg_size;
-	}
-    }
-    else
-    {
-	current_offset = 0;
-	for (i = 0; i < fdp->n_args_16; i++)
-	{
-	    arg_size = fdp->arg_16_offsets[i];
-	    fdp->arg_16_offsets[i] = current_offset;
-	    current_offset += arg_size;
-	}
-    }
-
-    strcpy(fdp->internal_name, GetToken());
-    token = GetToken();
-    if (*token != '(')
-    {
-	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
-	exit(1);
-    }
-    for (i = 0; i < 16; i++)
-    {
-	token = GetToken();
-	if (*token == ')')
-	    break;
-
-	fdp->arg_indices_32[i] = atoi(token);
-	if (fdp->arg_indices_32[i] < 1 || 
-	    fdp->arg_indices_32[i] > fdp->n_args_16)
-	{
-	    fprintf(stderr, "%d: Bad argument index %d\n", Line,
-		    fdp->arg_indices_32[i]);
-	    exit(1);
-	}
-    }
-    fdp->n_args_32 = i;
-
-    return 0;
-}
-
-int
-ParseEquate(int ordinal)
-{
-    ORDDEF *odp;
-    char *token;
-    char *endptr;
-    int value;
-    
-    if (ordinal >= MAX_ORDINALS)
-    {
-	fprintf(stderr, "%d: Ordinal number too large\n", Line);
-	exit(1);
-    }
-    
-    odp = &OrdinalDefinitions[ordinal];
-    strcpy(odp->export_name, GetToken());
-
-    token = GetToken();
-    value = strtol(token, &endptr, 0);
-    if (endptr == NULL || *endptr != '\0')
-    {
-	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
-		token);
-	exit(1);
-    }
-
-    odp->valid = 1;
-    odp->type = EQUATETYPE_ABS;
-    odp->additional_data = (void *) value;
-
-    return 0;
-}
-
-int
-ParseReturn(int ordinal)
-{
-    ORDDEF *odp;
-    ORDRETDEF *rdp;
-    char *token;
-    char *endptr;
-    int value;
-    
-    if (ordinal >= MAX_ORDINALS)
-    {
-	fprintf(stderr, "%d: Ordinal number too large\n", Line);
-	exit(1);
-    }
-
-    rdp = malloc(sizeof(*rdp));
-    
-    odp = &OrdinalDefinitions[ordinal];
-    strcpy(odp->export_name, GetToken());
-    odp->valid = 1;
-    odp->type = TYPE_RETURN;
-    odp->additional_data = rdp;
-
-    token = GetToken();
-    rdp->arg_size = strtol(token, &endptr, 0);
-    if (endptr == NULL || *endptr != '\0')
-    {
-	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
-		token);
-	exit(1);
-    }
-
-    token = GetToken();
-    rdp->ret_value = strtol(token, &endptr, 0);
-    if (endptr == NULL || *endptr != '\0')
-    {
-	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
-		token);
-	exit(1);
-    }
-
-    return 0;
-}
-
-int
-ParseOrdinal(int ordinal)
-{
-    char *token;
-    
-    token = GetToken();
-    if (token == NULL)
-    {
-	fprintf(stderr, "%d: Expected type after ordinal\n", Line);
-	exit(1);
-    }
-
-    if (stricmp(token, "byte") == 0)
-	return ParseVariable(ordinal, VARTYPE_BYTE);
-    else if (stricmp(token, "word") == 0)
-	return ParseVariable(ordinal, VARTYPE_WORD);
-    else if (stricmp(token, "long") == 0)
-	return ParseVariable(ordinal, VARTYPE_LONG);
-    else if (stricmp(token, "c") == 0)
-	return ParseExportFunction(ordinal, FUNCTYPE_C);
-    else if (stricmp(token, "p") == 0)
-	return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
-    else if (stricmp(token, "pascal") == 0)
-	return ParseExportFunction(ordinal, FUNCTYPE_PASCAL);
-    else if (stricmp(token, "register") == 0)
-	return ParseExportFunction(ordinal, FUNCTYPE_REG);
-    else if (stricmp(token, "equate") == 0)
-	return ParseEquate(ordinal);
-    else if (stricmp(token, "return") == 0)
-	return ParseReturn(ordinal);
-    else
-    {
-	fprintf(stderr, 
-		"%d: Expected type after ordinal, found '%s' instead\n",
-		Line, token);
-	exit(1);
-    }
-}
-
-int
-ParseTopLevel(void)
-{
-    char *token;
-    
-    while ((token = GetToken()) != NULL)
-    {
-	if (stricmp(token, "name") == 0)
-	{
-	    strcpy(LowerDLLName, GetToken());
-	    strlower(LowerDLLName);
-
-	    strcpy(UpperDLLName, LowerDLLName);
-	    strupper(UpperDLLName);
-	}
-	else if (stricmp(token, "id") == 0)
-	{
-	    token = GetToken();
-	    if (!IsNumberString(token))
-	    {
-		fprintf(stderr, "%d: Expected number after id\n", Line);
-		exit(1);
-	    }
-	    
-	    DLLId = atoi(token);
-	}
-	else if (stricmp(token, "length") == 0)
-	{
-	    token = GetToken();
-	    if (!IsNumberString(token))
-	    {
-		fprintf(stderr, "%d: Expected number after length\n", Line);
-		exit(1);
-	    }
-
-	    Limit = atoi(token);
-	}
-	else if (IsNumberString(token))
-	{
-	    int ordinal;
-	    int rv;
-	    
-	    ordinal = atoi(token);
-	    if ((rv = ParseOrdinal(ordinal)) < 0)
-		return rv;
-	}
-	else
-	{
-	    fprintf(stderr, 
-		    "%d: Expected name, id, length or ordinal\n", Line);
-	    exit(1);
-	}
-    }
-
-    return 0;
-}
-
-void
-OutputVariableCode(FILE *fp, char *storage, ORDDEF *odp)
-{
-    ORDVARDEF *vdp;
-    int i;
-
-    fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-
-    vdp = odp->additional_data;
-    for (i = 0; i < vdp->n_values; i++)
-    {
-	if ((i & 7) == 0)
-	    fprintf(fp, "\t%s\t", storage);
-	    
-	fprintf(fp, "%d", vdp->values[i]);
-	
-	if ((i & 7) == 7 || i == vdp->n_values - 1)
-	    fprintf(fp, "\n");
-	else
-	    fprintf(fp, ", ");
-    }
-    fprintf(fp, "\n");
-}
-
-main(int argc, char **argv)
-{
-    ORDDEF *odp;
-    ORDFUNCDEF *fdp;
-    ORDRETDEF *rdp;
-    FILE *fp;
-    char filename[80];
-    char buffer[80];
-    char *p;
-    int i;
-    
-    if (argc < 2)
-    {
-	fprintf(stderr, "usage: build SPECNAME\n");
-	exit(1);
-    }
-
-    SpecFp = fopen(argv[1], "r");
-    if (SpecFp == NULL)
-    {
-	fprintf(stderr, "Could not open specification file, '%s'\n", argv[1]);
-	exit(1);
-    }
-
-    ParseTopLevel();
-
-    sprintf(filename, "dll_%s.S", LowerDLLName);
-    fp = fopen(filename, "w");
-
-    fprintf(fp, "\t.globl _%s_Dispatch\n", UpperDLLName);
-    fprintf(fp, "_%s_Dispatch:\n", UpperDLLName);
-    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-    fprintf(fp, "\torl\t$0x%08x,%%eax\n", DLLId << 16);
-    fprintf(fp, "\tjmp\t_CallTo32\n\n");
-
-    odp = OrdinalDefinitions;
-    for (i = 0; i <= Limit; i++, odp++)
-    {
-	fprintf(fp, "\t.globl _%s_Ordinal_%d\n", UpperDLLName, i);
-
-	if (!odp->valid)
-	{
-	    fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-#ifdef BOB_SAYS_NO
-	    fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-	    fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-#endif
-	    fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
-	    fprintf(fp, "\tpushw\t$0\n");
-	    fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
-	}
-	else
-	{
-	    fdp = odp->additional_data;
-	    rdp = odp->additional_data;
-	    
-	    switch (odp->type)
-	    {
-	      case EQUATETYPE_ABS:
-		fprintf(fp, "_%s_Ordinal_%d = %d\n\n", 
-			UpperDLLName, i, (int) odp->additional_data);
-		break;
-
-	      case VARTYPE_BYTE:
-		OutputVariableCode(fp, ".byte", odp);
-		break;
-
-	      case VARTYPE_WORD:
-		OutputVariableCode(fp, ".word", odp);
-		break;
-
-	      case VARTYPE_LONG:
-		OutputVariableCode(fp, ".long", odp);
-		break;
-
-	      case TYPE_RETURN:
-		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-		fprintf(fp, "\tmovw\t$%d,%%ax\n", rdp->ret_value & 0xffff);
-		fprintf(fp, "\tmovw\t$%d,%%dx\n", 
-			(rdp->ret_value >> 16) & 0xffff);
-		fprintf(fp, "\t.byte\t0x66\n");
-		if (rdp->arg_size != 0)
-		    fprintf(fp, "\tlret\t$%d\n", rdp->arg_size);
-		else
-		    fprintf(fp, "\tlret\n");
-		break;
-
-	      case FUNCTYPE_REG:
-		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-		fprintf(fp, "\tpushl\t$0\n");			/* cr2     */
-		fprintf(fp, "\tpushl\t$0\n");			/* oldmask */
-		fprintf(fp, "\tpushl\t$0\n");			/* i387    */
-		fprintf(fp, "\tpushw\t$0\n");			/* __ssh   */
-		fprintf(fp, "\tpushw\t%%ss\n");			/* ss      */
-		fprintf(fp, "\tpushl\t%%esp\n");		/* esp     */
-		fprintf(fp, "\tpushfl\n");			/* eflags  */
-		fprintf(fp, "\tpushw\t$0\n");			/* __csh   */
-		fprintf(fp, "\tpushw\t%%cs\n");			/* cs      */
-		fprintf(fp, "\tpushl\t$0\n");			/* eip     */
-		fprintf(fp, "\tpushl\t$0\n");			/* err     */
-		fprintf(fp, "\tpushl\t$0\n");			/* trapno  */
-		fprintf(fp, "\tpushal\n");			/* AX, ... */
-		fprintf(fp, "\tpushw\t$0\n");			/* __dsh   */
-		fprintf(fp, "\tpushw\t%%ds\n");			/* ds      */
-		fprintf(fp, "\tpushw\t$0\n");			/* __esh   */
-		fprintf(fp, "\tpushw\t%%es\n");			/* es      */
-		fprintf(fp, "\tpushw\t$0\n");			/* __fsh   */
-		fprintf(fp, "\tpushw\t%%fs\n");			/* fs      */
-		fprintf(fp, "\tpushw\t$0\n");			/* __gsh   */
-		fprintf(fp, "\tpushw\t%%gs\n");			/* gs      */
-		fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
-		fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
-		fprintf(fp, "\tpushl\t88(%%ebp)\n");
-		fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
-		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
-		fprintf(fp, "\tpushw\t$92\n");
-		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
-#if 0
-		fprintf(fp, "\tpushw\t%%ax\n");
-		fprintf(fp, "\tpushw\t%%cx\n");
-		fprintf(fp, "\tpushw\t%%dx\n");
-		fprintf(fp, "\tpushw\t%%bx\n");
-		fprintf(fp, "\tpushw\t%%sp\n");
-		fprintf(fp, "\tpushw\t%%bp\n");
-		fprintf(fp, "\tpushw\t%%si\n");
-		fprintf(fp, "\tpushw\t%%di\n");
-		fprintf(fp, "\tpushw\t%%ds\n");
-		fprintf(fp, "\tpushw\t%%es\n");
-		fprintf(fp, "\tmovl\t%%ebp,%%eax\n");
-		fprintf(fp, "\tmovw\t%%esp,%%ebp\n");
-		fprintf(fp, "\tpushl\t20(%%ebp)\n");
-		fprintf(fp, "\tmovl\t%%eax,%%ebp\n");
-		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
-		fprintf(fp, "\tpushw\t$24\n");
-		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
-#endif
-		break;
-
-	      case FUNCTYPE_PASCAL:
-		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-#ifdef BOB_SAYS_NO
-		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-#endif
-		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
-		fprintf(fp, "\tpushw\t$%d\n", fdp->arg_16_size);
-		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
-		break;
-		
-	      case FUNCTYPE_C:
-	      default:
-		fprintf(fp, "_%s_Ordinal_%d:\n", UpperDLLName, i);
-#ifdef BOB_SAYS_NO
-		fprintf(fp, "\tandl\t$0x0000ffff,%%esp\n");
-		fprintf(fp, "\tandl\t$0x0000ffff,%%ebp\n");
-#endif
-		fprintf(fp, "\tmovl\t$%d,%%eax\n", i);
-		fprintf(fp, "\tpushw\t$0\n");
-		fprintf(fp, "\tjmp\t_%s_Dispatch\n\n", UpperDLLName);
-		break;
-	    }
-	}
-    }
-
-    fclose(fp);
-
-#ifndef SHORTNAMES
-    sprintf(filename, "dll_%s_tab.c", LowerDLLName);
-#else
-    sprintf(filename, "dtb_%s.c", LowerDLLName);
-#endif
-    fp = fopen(filename, "w");
-
-    fprintf(fp, "#include <stdio.h>\n");
-    fprintf(fp, "#include <stdlib.h>\n");
-    fprintf(fp, "#include \042dlls.h\042\n\n");
-
-    for (i = 0; i <= Limit; i++)
-    {
-	fprintf(fp, "extern void %s_Ordinal_%d();\n", UpperDLLName, i);
-    }
-    
-    odp = OrdinalDefinitions;
-    for (i = 0; i <= Limit; i++, odp++)
-    {
-	if (odp->valid && 
-	    (odp->type == FUNCTYPE_PASCAL || odp->type == FUNCTYPE_C ||
-	     odp->type == FUNCTYPE_REG))
-	{
-	    fdp = odp->additional_data;
-	    fprintf(fp, "extern int %s();\n", fdp->internal_name);
-	}
-    }
-    
-    fprintf(fp, "\nstruct dll_table_entry_s %s_table[%d] =\n", 
-	    UpperDLLName, Limit + 1);
-    fprintf(fp, "{\n");
-    odp = OrdinalDefinitions;
-    for (i = 0; i <= Limit; i++, odp++)
-    {
-	fdp = odp->additional_data;
-
-	if (!odp->valid)
-	    odp->type = -1;
-	
-	switch (odp->type)
-	{
-	  case FUNCTYPE_PASCAL:
-	  case FUNCTYPE_REG:
-	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
-	    fprintf(fp, "\042%s\042, ", odp->export_name);
-	    fprintf(fp, "%s, DLL_HANDLERTYPE_PASCAL, ", fdp->internal_name);
-#ifdef WINESTAT
-	    fprintf(fp, "0, ");
-#endif	    
-	    fprintf(fp, "%d, ", fdp->n_args_32);
-	    if (fdp->n_args_32 > 0)
-	    {
-		int argnum;
-		
-		fprintf(fp, "\n      {\n");
-		for (argnum = 0; argnum < fdp->n_args_32; argnum++)
-		{
-		    fprintf(fp, "        { %d, %d },\n",
-			    fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
-			    fdp->arg_types_16[argnum]);
-		}
-		fprintf(fp, "      }\n    ");
-	    }
-	    fprintf(fp, "}, \n");
-	    break;
-		
-	  case FUNCTYPE_C:
-	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, ", UTEXTSEL, UpperDLLName, i);
-	    fprintf(fp, "\042%s\042, ", odp->export_name);
-	    fprintf(fp, "%s, DLL_HANDLERTYPE_C, ", fdp->internal_name);
-#ifdef WINESTAT
-	    fprintf(fp, "0, ");
-#endif	    
-	    fprintf(fp, "%d, ", fdp->n_args_32);
-	    if (fdp->n_args_32 > 0)
-	    {
-		int argnum;
-		
-		fprintf(fp, "\n      {\n");
-		for (argnum = 0; argnum < fdp->n_args_32; argnum++)
-		{
-		    fprintf(fp, "        { %d, %d },\n",
-			    fdp->arg_16_offsets[fdp->arg_indices_32[argnum]-1],
-			    fdp->arg_types_16[argnum]);
-		}
-		fprintf(fp, "      }\n    ");
-	    }
-	    fprintf(fp, "}, \n");
-	    break;
-	    
-	  default:
-	    fprintf(fp, "    { 0x%x, %s_Ordinal_%d, \042\042, NULL },\n", 
-		    UTEXTSEL, UpperDLLName, i);
-	    break;
-	}
-    }
-    fprintf(fp, "};\n");
-
-    fclose(fp);
-}
-
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 )