Release 980503

Thu Apr 30 16:28:12 1998  James Juran <jrj120@psu.edu>

	* [scheduler/process.c]
	Implemented GetExitCodeProcess.  The code is a direct translation
	of GetExitCodeThread.

Mon Apr 27 22:20:25 1998  Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>

	* [loader/pe_image.c]
	Unload dummy module when PE_LoadLibraryEx32A fails with
	PE_LoadImage (makes Encarta 98 installer proceed).

	* [files/drive.c]
	Make GetDriveType16 return DRIVE_REMOVABLE for TYPE_CDROM.
	Make GetCurrentDirectory32 behave like the code does and not
	like the help describes.

	* [files/profile.c]
	Revoke recent change in PROFILE_GetSection and try better 
	handling of special case.

	* [include/windows.h]
	Change definition of ACCEL32.

	* [misc/commdlg.c]
	Replace the GetXXXFilename32 macros by normal code.
	Fix two reported bugs in my changes to commdlg.

	* [windows/win.c]
	Add a hook to catch bogus WM_SIZE messages by emitting a warning
	in the appropriate case.

	* [objects/bitmap.c]
	Reject unreasonbable large size arguments in
	CreateCompatibleBitmap32 and add an fixme for that situation.

Sun Apr 26 18:30:07 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [include/ldt.h] [debugger/*.c] [miscemu/instr.c]
	Added IS_SELECTOR_SYSTEM and IS_SELECTOR_32BIT macros.
	Make instruction emulation support system selectors.

	* [loader/*.c]
	Started moving NE specific functions to the new loader/ne
	directory.

	* [memory/environ.c]
	Enforce the 127 chars limit only when creating the environment of
	a Win16 process.

Sun Apr 26 12:22:23 1998  Andreas Mohr <100.30936@germany.net>

	* [files/file.c]
	Fixed an incredible typo in CopyFile32A that made it unusable
	since a rewrite in 970112 (!!).

	* [files/directory.c]
	Fixed GetTempPath32A/W to include trailing backslash.

	* [misc/ver.c]
	Make find_pe_resource "work" with corrupt files.

	* [misc/wsprintf.c]
	Altered WPRINTF_ParseFormatA/W to treat invalid format chars
	as normal output, too.

	* [msdos/dpmi.c]
	Implemented "Allocate/Free real mode callback" (0x0303/0x0304).
	Cross your fingers if you need to use it ;) (completely untested)
	Implemented "Call real mode proc with far return" (0x0301, tested).

	* [msdos/int21.c]
	Fixed ioctlGenericBlkDevReq/0x60.

	* [relay32/dplayx.spec] [relay32/builtin32.c] [relay32/Makefile.in]
	Added built-in DPLAYX.DLL. 

	* [windows/win.c]
	Fixed GetWindowWord()/GWW_HWNDPARENT to return the window's owner
	if it has no parent (SDK).

Sat Apr 25 15:09:53 1998  M.T.Fortescue  <mark@mtfhpc.demon.co.uk>

	* [debugger/db_disasm.c]
	Fixed disassemble bug for no-display option and 'lock',
	'repne' and 'repe' prefixes.

	* [debugger/registers.c]
	Added textual flag description output on 'info regs'.

Sat Apr 25 14:18:26 1998  Matthew Becker <mbecker@glasscity.net>

	* [*/*.c]
	Added stubs and/or documentation for the following functions: 
	LookupPrivilegeValue, OpenService, ControlService, RegGetKeySecurity, 
	StartService, SetComputerName, DeleteService, CloseServiceHandle, 
	OpenProcessToken, OpenSCManager, DeregisterEventSource, 
	WaitForDebugEvent, WaitForInputIdle, RegisterEventSource,
	SetDebugErrorLevel, SetConsoleCursorPosition, ChoosePixelFormat,
	SetPixelFormat, GetPixelFormat, DescribePixelFormat, SwapBuffers,
	PolyBezier, AbortPath, DestroyAcceleratorTable, HeapWalk,
	DdeInitialize, DdeUninitialize, DdeConnectList, DdeDisconnectList,
	DdeCreateStringHandle, DdePostAdvise, DdeGetData, DdeNameService,
	DdeGetLastError, WNetGetDirectoryType, EnumPrinters, RegFlushKey,
	RegGetKeySecurity, DllGetClassObject, DllCanUnloadNow, CreateBitmap,
	CreateCompatibleBitmap, CreateBitmapIndirect, GetBitmapBits,
	SetBitmapBits, LoadImage, CopyImage, LoadBitmap, DrawIcon,
	CreateDiscardableBitmap, SetDIBits, GetCharABCWidths, LoadTypeLib,
	SetConsoleCtrlHandler, CreateConsoleScreenBuffer, ReadConsoleInput,
	GetConsoleCursorInfo, SetConsoleCursorInfo, SetConsoleWindowInfo,
	SetConsoleTextAttribute, SetConsoleScreenBufferSize,
	FillConsoleOutputCharacter, FillConsoleOutputAttribute,
	CreateMailslot, GetMailslotInfo, GetCompressedFileSize,
	GetProcessWindowStation, GetThreadDesktop, SetDebugErrorLevel,
	WaitForDebugEvent, SetComputerName, CreateMDIWindow.

Thu Apr 23 23:54:04 1998  Douglas Ridgway  <ridgway@winehq.com>

	* [include/windows.h] [objects/enhmetafile.c] [relay32/gdi32.spec]
	Implement CopyEnhMetaFile, Get/SetEnhMetaFileBits, other fixes.

	* [include/windows.h] [objects/metafile.c] [relay32/gdi32.spec]
	32-bit metafile fixes, implement EnumMetaFile32, GetMetaFileBitsEx.

	* [objects/font.c] [graphics/x11drv/xfont.c] [graphics/x11drv/text.c]
	Some rotated text support for X11R6 displays.

	* [win32/newfns.c] [ole/ole2nls.c]
	Moved GetNumberFormat32A.

Wed Apr 22 17:38:20 1998  David Lee Lambert <lamber45@egr.msu.edu>

	* [ole/ole2nls.c] [misc/network.c]
	Changed some function documentation to the new style.

	* [misc/network.c] [include/windows.h] [if1632/user.spec]
	  [relay32/mpr.spec] [misc/mpr.c]
	Added stubs for some Win32 network functions;  renamed some 
	16-bit ones with 32-bit counterparts,  as well as
	WNetGetDirectoryType;  moved the stubs in misc/mpr.c (three of
	them!) to misc/network.c.

	* [ole/compobj.c] [ole/storage.c] [ole/ole2disp.c] 
	  [ole/ole2nls.c] [ole/folders.c] [ole/moniker.c] [ole/ole2.c]
	  [graphics/fontengine.c] [graphics/ddraw.c] [graphics/env.c]
	  [graphics/driver.c] [graphics/escape.c]
	Changed fprintf's to proper debug-macros.

	* [include/winnls.h]
	Added some flags (for internal use).

	* [ole/ole2nls.c] 
	Added the Unicode core function, and worked out a way to hide
	the commonality of the core.

	* [relay32/kernel32.spec]
	Added support for GetDate/Time32A/W.

Wed Apr 22 09:16:03 1998  Gordon Chaffee  <chaffee@cs.berkeley.edu>

	* [win32/code_page.c]
	Fixed problem with MultiByteToWideChar that was introduced in
	last release.  Made MultiByteToWideChar more compatible with Win32.

	* [graphics/x11drv/graphics.c]
	Fixed problem with drawing arcs.

Tue Apr 21 11:24:58 1998  Constantine Sapuntzakis  <csapuntz@tma-1.lcs.mit.edu>

	*  [ole/ole2nls.c]
	Move stuff from 0x409 case to Lang_En. 

	*  [relay32/user32.spec] [windows/winpos.c]
	Added stubs for GetWindowRgn32 and SetWindowRgn32. Makes Office
	Paperclip happy.

Tue Apr 21 11:16:16 1998  Constantine Sapuntzakis  <csapuntz@tma-1.lcs.mit.edu>

	*  [loader/pe_image.c]
	If image is relocated, TLS addresses need to be adjusted.

	* [debugger/*.c]
	Generalized tests for 32-bit segments.

Tue Apr 21 02:04:59 1998  James Juran  <jrj120@psu.edu>
	
	* [misc/*.c] [miscemu/*.c] [msdos/*.c] [if1632/*.c] 
	  [include/*.h] [loader/*.c] [memory/*.c] [multimedia/*.c] 
	  [objects/*.c]
	Almost all fprintf statements converted to appropriate 
	debug messages.

	* [README]
	Updated "GETTING MORE INFORMATION" section to include WineHQ.

	* [documentation/debugger]
	Fixed typo.

	* [windows/defwnd.c]
	Added function documentation.

Sun Apr 19 16:30:58 1998  Marcus Meissner <marcus@mud.de>

	* [Make.rules.in]
	Added lint target (using lclint).

	* [relay32/oleaut32.spec][relay32/Makefile.in][ole/typelib.c]
	  [ole/ole2disp.c]
	Added oleaut32 spec, added some SysString functions.

	* [if1632/signal.c]
	Added printing of faultaddress in Linux (using CR2 debug register).

	* [configure.in]
	Added <sys/types.h> for statfs checks.

	* [loader/*.c][debugger/break.c][debugger/hash.c]
	Started to split win32/win16 module handling, preparing support
	for other binary formats (like ELF).

Sat Apr 18 10:07:41 1998  Rein Klazes <rklazes@casema.net>

	* [misc/registry.c]
	Fixed a bug that made RegQueryValuexxx returning
	incorrect registry values.

Fri Apr 17 22:59:22 1998  Alexander V. Lukyanov <lav@long.yar.ru>

	* [misc/lstr.c]
	FormatMessage32*: remove linefeed when nolinefeed set;
	check for target underflow.

Fri Apr 17 00:38:14 1998  Alexander V. Lukyanov <lav@long.yar.ru>

	* [misc/crtdll.c]
	Implement xlat_file_ptr for CRT stdin/stdout/stderr address
	translation.

Wed Apr 15 20:43:56 1998  Jim Peterson <jspeter@birch.ee.vt.edu>

	* [controls/menu.c]
	Added 'odaction' parameter to MENU_DrawMenuItem() and redirected
	WM_DRAWITEM messages to GetWindow(hwnd,GW_OWNER).

Tue Apr 14 16:17:55 1998  Berend Reitsma <berend@united-info.com>

	* [graphics/metafiledrv/init.c]	[graphics/painting.c] 
	  [graphics/win16drv/init.c] [graphics/x11drv/graphics.c]
	  [graphics/x11drv/init.c] [include/gdi.h] [include/x11drv.h]
	  [relay32/gdi32.spec]
	Added PolyPolyline routine.

	* [windows/winproc.c]
	Changed WINPROC_GetProc() to return proc instead of &(jmp proc).
diff --git a/msdos/dosmem.c b/msdos/dosmem.c
index 4482cf9..6048ec5 100644
--- a/msdos/dosmem.c
+++ b/msdos/dosmem.c
@@ -208,7 +208,7 @@
                                   PAGE_EXECUTE_READWRITE );
     if (!DOSMEM_dosmem)
     {
-        fprintf( stderr, "Could not allocate DOS memory.\n" );
+        WARN(dosmem, "Could not allocate DOS memory.\n" );
         return FALSE;
     }
     DOSMEM_BiosSeg = GLOBAL_CreateBlock(GMEM_FIXED,DOSMEM_dosmem+0x400,0x100,
@@ -219,26 +219,6 @@
     return TRUE;
 }
 
-void DOSMEM_InitExports(HMODULE16 hKernel)
-{
-#define SET_ENTRY_POINT(num,addr) \
-    MODULE_SetEntryPoint( hKernel, (num), GLOBAL_CreateBlock( GMEM_FIXED, \
-                                  DOSMEM_dosmem+(addr), 0x10000, hKernel, \
-                                  FALSE, FALSE, FALSE, NULL ))
-
-    SET_ENTRY_POINT( 183, 0x00000 );  /* KERNEL.183: __0000H */
-    SET_ENTRY_POINT( 174, 0xa0000 );  /* KERNEL.174: __A000H */
-    SET_ENTRY_POINT( 181, 0xb0000 );  /* KERNEL.181: __B000H */
-    SET_ENTRY_POINT( 182, 0xb8000 );  /* KERNEL.182: __B800H */
-    SET_ENTRY_POINT( 195, 0xc0000 );  /* KERNEL.195: __C000H */
-    SET_ENTRY_POINT( 179, 0xd0000 );  /* KERNEL.179: __D000H */
-    SET_ENTRY_POINT( 190, 0xe0000 );  /* KERNEL.190: __E000H */
-    SET_ENTRY_POINT( 173, 0xf0000 );  /* KERNEL.173: __ROMBIOS */
-    SET_ENTRY_POINT( 194, 0xf0000 );  /* KERNEL.194: __F000H */
-    MODULE_SetEntryPoint(hKernel, 193,DOSMEM_BiosSeg); /* KERNEL.193: __0040H */
-
-#undef SET_ENTRY_POINT
-}
 
 /***********************************************************************
  *           DOSMEM_Tick
@@ -272,7 +252,7 @@
 #ifdef __DOSMEM_DEBUG__
        if( (dm->size & DM_BLOCK_DEBUG) != DM_BLOCK_DEBUG )
        {
-	    fprintf(stderr,"DOSMEM_GetBlock: MCB overrun! [prev = 0x%08x]\n", 4 + (UINT32)prev);
+	    WARN(dosmem,"MCB overrun! [prev = 0x%08x]\n", 4 + (UINT32)prev);
 	    return NULL;
        }
        prev = dm;
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index 5aea153..a452592 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -16,10 +16,14 @@
 #include "msdos.h"
 #include "toolhelp.h"
 #include "debug.h"
+#include "selectors.h"
+#include "thread.h"
+#include "stackframe.h"
+#include "callback.h"
 
 #define DOS_GET_DRIVE(reg) ((reg) ? (reg) - 1 : DRIVE_GetCurrentDrive())
 
-void CreateBPB(int drive, BYTE *data);  /* defined in int21.c */
+void CreateBPB(int drive, BYTE *data, BOOL16 limited);  /* defined in int21.c */
 
 
 /* Structure for real-mode callbacks */
@@ -46,6 +50,14 @@
 
 
 
+typedef struct tagRMCB {
+    DWORD address;
+    struct tagRMCB *next;
+
+} RMCB;
+
+static RMCB *FirstRMCB = NULL;
+
 /**********************************************************************
  *	    INT_GetRealModeContext
  */
@@ -189,7 +201,7 @@
                             setword(&dataptr[2], 0x02); /* removable */
                             setword(&dataptr[4], 80); /* # of cylinders */
                         }
-                        CreateBPB(drive, &dataptr[7]);
+                        CreateBPB(drive, &dataptr[7], FALSE);
                         break;
                     default:
                         SET_CFLAG(context);
@@ -223,6 +235,130 @@
 }
 
 
+static void CallRMProcFar( CONTEXT *context )
+{
+    REALMODECALL *p = (REALMODECALL *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
+    CONTEXT context16;
+    THDB *thdb = THREAD_Current();
+    WORD argsize, sel;
+    LPVOID addr;
+    SEGPTR seg_addr;
+
+    TRACE(int31, "RealModeCall: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n",
+	p->eax, p->ebx, p->ecx, p->edx);
+    TRACE(int31, "              ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x, %d WORD arguments\n",
+	p->esi, p->edi, p->es, p->ds, p->cs, p->ip, CX_reg(context) );
+
+    if (!(p->cs) && !(p->ip)) { /* remove this check
+                                   if Int21/6501 case map function
+                                   has been implemented */
+	SET_CFLAG(context);
+	return;
+    }
+    INT_GetRealModeContext(p, &context16);
+
+    addr = DOSMEM_MapRealToLinear(MAKELONG(p->ip, p->cs));
+    sel = SELECTOR_AllocBlock( addr, 0x10000, SEGMENT_CODE, FALSE, FALSE );
+    seg_addr = PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
+
+    CS_reg(&context16) = HIWORD(seg_addr);
+    IP_reg(&context16) = LOWORD(seg_addr);
+    EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
+                               + (WORD)&((STACK16FRAME*)0)->bp;
+
+    argsize = CX_reg(context)*sizeof(WORD);
+    memcpy( ((LPBYTE)THREAD_STACK16(thdb))-argsize,
+    (LPBYTE)PTR_SEG_OFF_TO_LIN(SS_reg(context), SP_reg(context))+6, argsize );
+
+    Callbacks->CallRegisterShortProc(&context16, argsize);
+
+    UnMapLS(seg_addr);
+    INT_SetRealModeContext(p, &context16);
+}
+
+
+void WINAPI RMCallbackProc( FARPROC16 pmProc, REALMODECALL *rmc )
+{
+    CONTEXT ctx;
+    INT_GetRealModeContext(rmc, &ctx);
+    Callbacks->CallRegisterShortProc(&ctx, 0);
+}
+
+
+static void AllocRMCB( CONTEXT *context )
+{
+    RMCB *NewRMCB = HeapAlloc(GetProcessHeap(), 0, sizeof(RMCB));
+    REALMODECALL *p = (REALMODECALL *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
+    UINT16 uParagraph;
+
+    FIXME(int31, "EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n", p->eax, p->ebx, p->ecx, p->edx);
+    FIXME(int31, "           ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x\n", p->esi, p->edi, p->es, p->ds, p->cs, p->ip);
+    FIXME(int31, "           Function to call: %04x:%04x\n",
+         (WORD)DS_reg(context), SI_reg(context) );
+
+    if (NewRMCB)
+    {
+	LPVOID RMCBmem = DOSMEM_GetBlock(20, &uParagraph);
+	LPBYTE p = RMCBmem;
+
+	*p++ = 0x68; /* pushl */
+	*(FARPROC16 *)p =
+	PTR_SEG_OFF_TO_LIN(ES_reg(context), SI_reg(context)); /* pmode proc to call */
+	p+=4;
+	*p++ = 0x68; /* pushl */
+	*(LPVOID *)p =
+	PTR_SEG_OFF_TO_LIN(ES_reg(context), DI_reg(context));
+	p+=4;
+	*p++ = 0x9a; /* lcall */
+	*(FARPROC16 *)p = (FARPROC16)RMCallbackProc; /* FIXME ? */
+	p+=4;
+	GET_CS(*(WORD *)p);
+	p+=2;
+	*p++=0xc3; /* retf */
+	NewRMCB->address = MAKELONG(0, uParagraph);
+	NewRMCB->next = FirstRMCB;
+	FirstRMCB = NewRMCB;
+	CX_reg(context) = uParagraph;
+	DX_reg(context) = 0;
+    }
+    else
+    {
+	AX_reg(context) = 0x8015; /* callback unavailable */
+	SET_CFLAG(context);
+    }
+}
+
+
+static void FreeRMCB( CONTEXT *context )
+{
+    RMCB *CurrRMCB = FirstRMCB;
+    RMCB *PrevRMCB = NULL;
+
+    FIXME(int31, "callback address: %04x:%04x\n",
+          CX_reg(context), DX_reg(context));
+
+    while (CurrRMCB && (CurrRMCB->address != MAKELONG(DX_reg(context), CX_reg(context))))
+    {
+	PrevRMCB = CurrRMCB;
+	CurrRMCB = CurrRMCB->next;
+    }
+    if (CurrRMCB)
+    {
+	if (PrevRMCB)
+	PrevRMCB->next = CurrRMCB->next;
+	    else
+	FirstRMCB = CurrRMCB->next;
+	DOSMEM_FreeBlock(DOSMEM_MapRealToLinear(CurrRMCB->address));
+	HeapFree(GetProcessHeap(), 0, CurrRMCB);
+    }
+    else
+    {
+	AX_reg(context) = 0x8024; /* invalid callback address */
+	SET_CFLAG(context);
+    }
+}
+
+
 /**********************************************************************
  *	    INT_Int31Handler
  *
@@ -280,7 +416,7 @@
                 break;
             }
             if (entryPoint) 
-                AX_reg(context) = LOWORD(MODULE_GetEntryPoint( 
+                AX_reg(context) = LOWORD(NE_GetEntryPoint( 
                                                  GetModuleHandle16( "KERNEL" ),
                                                  entryPoint ));
         }
@@ -382,15 +518,8 @@
         break;
 
     case 0x0301:  /* Call real mode procedure with far return */
-        {
-            REALMODECALL *p = (REALMODECALL *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
-            FIXME(int31, "RealModeCall: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n",
-		p->eax, p->ebx, p->ecx, p->edx);
-            FIXME(int31, "              ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x\n",
-		p->esi, p->edi, p->es, p->ds, p->cs, p->ip );
-            SET_CFLAG(context);
-        }
-        break;
+	CallRMProcFar( context );
+	break;
 
     case 0x0302:  /* Call real mode procedure with interrupt return */
         {
@@ -402,22 +531,11 @@
         break;
 
     case 0x0303:  /* Allocate Real Mode Callback Address */
-        {
-            REALMODECALL *p = (REALMODECALL *)PTR_SEG_OFF_TO_LIN( ES_reg(context), DI_reg(context) );
-            FIXME(int31, "AllocRMCB: EAX=%08lx EBX=%08lx ECX=%08lx EDX=%08lx\n", p->eax, p->ebx, p->ecx, p->edx);
-	    FIXME(int31, "           ESI=%08lx EDI=%08lx ES=%04x DS=%04x CS:IP=%04x:%04x\n", p->esi, p->edi, p->es, p->ds, p->cs, p->ip);
-	    FIXME(int31, "           Function to call: %04x:%04x\n",
-		(WORD)DS_reg(context), SI_reg(context) );
-            SET_CFLAG(context);
-        }
-        break;
+	AllocRMCB( context );
+	break;
 
     case 0x0304:  /* Free Real Mode Callback Address */
-	{
-	    FIXME(int31, "FreeRMCB: callback address: %04x:%04x\n",
-		  CX_reg(context), DX_reg(context));
-	    SET_CFLAG(context);
-	}
+	FreeRMCB( context );
 	break;
 
     case 0x0400:  /* Get DPMI version */
diff --git a/msdos/int13.c b/msdos/int13.c
index 761b2ad..68719d2 100644
--- a/msdos/int13.c
+++ b/msdos/int13.c
@@ -67,7 +67,7 @@
 
                         if ( (floppy_fd = DRIVE_OpenDevice( drive_nr, O_NONBLOCK)) == -1)
                         {
-                                fprintf(stderr, "INT 0x13 (GET DRIVE PARAMETERS): can't determine floppy geometry !\n");
+                                WARN(int, "(GET DRIVE PARAMETERS): Can't determine floppy geometry !\n");
                                 BX_reg(context) = 0;
                                 CX_reg(context) = 0;
                                 DH_reg(context) = 0;
diff --git a/msdos/int21.c b/msdos/int21.c
index 8a7c0a2..5ccf18f 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -83,7 +83,7 @@
 {
     if (!(DosHeapHandle = GlobalAlloc16(GMEM_FIXED,sizeof(struct DosHeap))))
     {
-        fprintf( stderr, "INT21_Init: Out of memory\n");
+        WARN(int21, "Out of memory\n");
         return FALSE;
     }
     heap = (struct DosHeap *) GlobalLock16(DosHeapHandle);
@@ -100,7 +100,8 @@
 }
 
 
-void CreateBPB(int drive, BYTE *data)
+void CreateBPB(int drive, BYTE *data, BOOL16 limited)
+/* limited == TRUE is used with INT 0x21/0x440d */
 {
 	if (drive > 1) {
 		setword(data, 512);
@@ -114,9 +115,11 @@
 		setword(&data[0x0d], 56);
 		setword(&data[0x0f], 2);
 		setword(&data[0x11], 0);
-		setword(&data[0x1f], 800);
-		data[0x21] = 5;
-		setword(&data[0x22], 1);
+		if (!limited) {
+		    setword(&data[0x1f], 800);
+		    data[0x21] = 5;
+		    setword(&data[0x22], 1);
+		}
 	} else { /* 1.44mb */
 		setword(data, 512);
 		data[2] = 2;
@@ -129,9 +132,11 @@
 		setword(&data[0x0d], 18);
 		setword(&data[0x0f], 2);
 		setword(&data[0x11], 0);
-		setword(&data[0x1f], 80);
-		data[0x21] = 7;
-		setword(&data[0x22], 2);
+		if (!limited) {
+		    setword(&data[0x1f], 80);
+		    data[0x21] = 7;
+		    setword(&data[0x22], 2);
+		}
 	}	
 }
 
@@ -215,6 +220,8 @@
      * bit 6 - file has NOT been written..FIXME: correct?
      * bit 8 - generate int24 if no diskspace on write/ read past end of file
      * bit 11 - media not removable
+     * bit 14 - don't set file date/time on closing
+     * bit 15 - file is remote
      */
     RESET_CFLAG(context);
 }
@@ -244,7 +251,7 @@
 
 		case 0x60: /* get device parameters */
 			   /* used by w4wgrp's winfile */
-			memset(dataptr, 0, 0x26);
+			memset(dataptr, 0, 0x20); /* DOS 6.22 uses 0x20 bytes */
 			dataptr[0] = 0x04;
 			dataptr[6] = 0; /* media type */
 			if (drive > 1) 
@@ -259,7 +266,7 @@
 				setword(&dataptr[2], 0x02); /* removable */
 				setword(&dataptr[4], 80); /* # of cylinders */
 			}
-			CreateBPB(drive, &dataptr[7]);			
+			CreateBPB(drive, &dataptr[7], TRUE);
 			RESET_CFLAG(context);
 			break;
 
@@ -589,7 +596,7 @@
     }
     if ((int)dta->count + count > 0xffff)
     {
-        fprintf( stderr, "Too many directory entries in %s\n", dta->unixPath );
+        WARN(int21, "Too many directory entries in %s\n", dta->unixPath );
         HeapFree( GetProcessHeap(), 0, dta->unixPath );
         dta->unixPath = NULL;
         return 0;
@@ -1632,6 +1639,7 @@
 	    *(WORD*)(dataptr+1) = 41;
 	    *(WORD*)(dataptr+3) = WINE_LanguageId;
 	    *(WORD*)(dataptr+5) = CodePage;
+	    *(DWORD*)(dataptr+0x19) = NULL; /* FIXME: ptr to case map routine */
 	    break;
 	case 0x06:
 	    TRACE(int21,"\tget pointer to collating sequence table\n");
diff --git a/msdos/int2f.c b/msdos/int2f.c
index c2d2564..fb8cf67 100644
--- a/msdos/int2f.c
+++ b/msdos/int2f.c
@@ -133,14 +133,14 @@
 	break;
 
     case 0x84:  /* Get device API entry point */
-        addr = (DWORD)MODULE_GetEntryPoint( GetModuleHandle16("WPROCS"),
-                                            VXD_BASE + BX_reg(context) );
+        addr = (DWORD)NE_GetEntryPoint( GetModuleHandle16("WPROCS"),
+                                        VXD_BASE + BX_reg(context) );
         if (!addr)  /* not supported */
         {
-	    fprintf( stderr,"Application attempted to access VxD %04x\n",
+	    WARN(int,"Application attempted to access VxD %04x\n",
                      BX_reg(context) );
-	    fprintf( stderr,"This device is not known to Wine.");
-	    fprintf( stderr,"Expect a failure now\n");
+	    WARN(int,"This device is not known to Wine.");
+	    WARN(int,"Expect a failure now\n");
         }
 	ES_reg(context) = SELECTOROF(addr);
 	DI_reg(context) = OFFSETOF(addr);
@@ -217,7 +217,7 @@
             break;
 
         default:
-            fprintf(stderr, "Unimplemented MSCDEX function 0x%02.2X.\n", AL_reg(context));
+            FIXME(int, "Unimplemented MSCDEX function 0x%02.2X.\n", AL_reg(context));
             break;
     }
 }
diff --git a/msdos/ioports.c b/msdos/ioports.c
index b4924bd..4233fff 100644
--- a/msdos/ioports.c
+++ b/msdos/ioports.c
@@ -236,7 +236,7 @@
             b = cmosimage[cmosaddress & 0x3f];
             break;
         default:
-            fprintf( stderr, "Direct I/O read attempted from port %x\n", port);
+            WARN( int, "Direct I/O read attempted from port %x\n", port);
             b = 0xff;
             break;
         }
@@ -274,7 +274,7 @@
                 case 2: outw( LOWORD(value), port ); break;
                 case 4: outl( value, port ); break;
                 default:
-                    fprintf( stderr, "IO_outport: invalid count %d\n", count);
+                    WARN(int, "Invalid count %d\n", count);
             }
             iopl(0);
             return;
@@ -295,8 +295,7 @@
             cmosimage[cmosaddress & 0x3f] = b;
             break;
         default:
-            fprintf( stderr, "Direct I/O write attempted "
-                     "to port %x\n", port );
+            WARN(int, "Direct I/O write attempted to port %x\n", port );
             break;
         }
 	port++;
diff --git a/msdos/vxd.c b/msdos/vxd.c
index bc922e3..60a120d 100644
--- a/msdos/vxd.c
+++ b/msdos/vxd.c
@@ -12,7 +12,7 @@
 
 
 #define VXD_BARF(context,name) \
-    fprintf( stderr, "vxd %s: unknown/not implemented parameters:\n" \
+    DUMP( "vxd %s: unknown/not implemented parameters:\n" \
                      "vxd %s: AX %04x, BX %04x, CX %04x, DX %04x, " \
                      "SI %04x, DI %04x, DS %04x, ES %04x\n", \
              (name), (name), AX_reg(context), BX_reg(context), \