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/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));
+}