Reorganize IOCTL handling.
Move ASPI hooking to winedos.
Move some miscellaneous functions to winedos.
Remove unnecessary exports from winedos dll.
diff --git a/dlls/winedos/dosexe.h b/dlls/winedos/dosexe.h
index c8cbad4..19ee6ca 100644
--- a/dlls/winedos/dosexe.h
+++ b/dlls/winedos/dosexe.h
@@ -111,6 +111,9 @@
extern void DMA_ioport_out( WORD port, BYTE val );
extern BYTE DMA_ioport_in( WORD port );
+/* dosaspi.c */
+void WINAPI DOSVM_ASPIHandler(CONTEXT86*);
+
/* fpu.c */
extern void WINAPI DOSVM_Int34Handler(CONTEXT86*);
extern void WINAPI DOSVM_Int35Handler(CONTEXT86*);
diff --git a/dlls/winedos/int21.c b/dlls/winedos/int21.c
index 525a40f..7aedb46 100644
--- a/dlls/winedos/int21.c
+++ b/dlls/winedos/int21.c
@@ -32,6 +32,7 @@
#include "miscemu.h"
#include "msdos.h"
#include "file.h"
+#include "task.h"
#include "winerror.h"
#include "winuser.h"
#include "wine/unicode.h"
@@ -598,40 +599,135 @@
/***********************************************************************
+ * INT21_Ioctl_Block
+ *
+ * Handler for block device IOCTLs.
+ */
+static void INT21_Ioctl_Block( CONTEXT86 *context )
+{
+ INT_Int21Handler( context );
+}
+
+
+/***********************************************************************
+ * INT21_Ioctl_Char
+ *
+ * Handler for character device IOCTLs.
+ */
+static void INT21_Ioctl_Char( CONTEXT86 *context )
+{
+ static const WCHAR emmxxxx0W[] = {'E','M','M','X','X','X','X','0',0};
+ static const WCHAR scsimgrW[] = {'S','C','S','I','M','G','R','$',0};
+
+ HANDLE handle = DosFileHandleToWin32Handle(BX_reg(context));
+ const DOS_DEVICE *dev = DOSFS_GetDeviceByHandle(handle);
+
+ if (dev && !strcmpiW( dev->name, emmxxxx0W ))
+ {
+ EMS_Ioctl_Handler(context);
+ return;
+ }
+
+ if (dev && !strcmpiW( dev->name, scsimgrW ) && AL_reg(context) == 2)
+ {
+ DOSVM_ASPIHandler(context);
+ return;
+ }
+
+ INT_Int21Handler( context );
+}
+
+
+/***********************************************************************
* INT21_Ioctl
*
* Handler for function 0x44.
*/
static void INT21_Ioctl( CONTEXT86 *context )
{
- static const WCHAR emmxxxx0W[] = {'E','M','M','X','X','X','X','0',0};
- const DOS_DEVICE *dev = DOSFS_GetDeviceByHandle(
- DosFileHandleToWin32Handle(BX_reg(context)) );
+ switch (AL_reg(context))
+ {
+ case 0x00:
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ INT21_Ioctl_Char( context );
+ break;
- if (dev && !strcmpiW( dev->name, emmxxxx0W )) {
- EMS_Ioctl_Handler(context);
- return;
- }
+ case 0x04:
+ case 0x05:
+ INT21_Ioctl_Block( context );
+ break;
- switch (AL_reg(context))
- {
- case 0x0b: /* SET SHARING RETRY COUNT */
- TRACE("IOCTL - SET SHARING RETRY COUNT pause %d retries %d\n",
- CX_reg(context), DX_reg(context));
- if (!CX_reg(context))
- {
- SET_AX( context, 1 );
- SET_CFLAG(context);
- break;
- }
- DOSMEM_LOL()->sharing_retry_delay = CX_reg(context);
- if (!DX_reg(context))
- DOSMEM_LOL()->sharing_retry_count = DX_reg(context);
- RESET_CFLAG(context);
- break;
- default:
- INT_Int21Handler( context );
- }
+ case 0x06:
+ case 0x07:
+ INT21_Ioctl_Char( context );
+ break;
+
+ case 0x08:
+ case 0x09:
+ INT21_Ioctl_Block( context );
+ break;
+
+ case 0x0a:
+ INT21_Ioctl_Char( context );
+ break;
+
+ case 0x0b: /* SET SHARING RETRY COUNT */
+ TRACE( "SET SHARING RETRY COUNT: Pause %d, retries %d.\n",
+ CX_reg(context), DX_reg(context) );
+ if (!CX_reg(context))
+ {
+ SET_AX( context, 1 );
+ SET_CFLAG( context );
+ }
+ else
+ {
+ DOSMEM_LOL()->sharing_retry_delay = CX_reg(context);
+ if (DX_reg(context))
+ DOSMEM_LOL()->sharing_retry_count = DX_reg(context);
+ RESET_CFLAG( context );
+ }
+ break;
+
+ case 0x0c:
+ INT21_Ioctl_Char( context );
+ break;
+
+ case 0x0d:
+ case 0x0e:
+ case 0x0f:
+ INT21_Ioctl_Block( context );
+ break;
+
+ case 0x10:
+ INT21_Ioctl_Char( context );
+ break;
+
+ case 0x11:
+ INT21_Ioctl_Block( context );
+ break;
+
+ case 0x12: /* DR DOS - DETERMINE DOS TYPE (OBSOLETE FUNCTION) */
+ TRACE( "DR DOS - DETERMINE DOS TYPE (OBSOLETE FUNCTION)\n" );
+ SET_CFLAG(context); /* Error / This is not DR DOS. */
+ SET_AX( context, 0x0001 ); /* Invalid function */
+ break;
+
+ case 0x52: /* DR DOS - DETERMINE DOS TYPE */
+ TRACE( "DR DOS - DETERMINE DOS TYPE\n" );
+ SET_CFLAG(context); /* Error / This is not DR DOS. */
+ SET_AX( context, 0x0001 ); /* Invalid function */
+ break;
+
+ case 0xe0: /* Sun PC-NFS API */
+ TRACE( "Sun PC-NFS API\n" );
+ /* not installed */
+ break;
+
+ default:
+ INT_BARF( context, 0x21 );
+ }
}
@@ -862,7 +958,29 @@
break;
case 0x09: /* WRITE STRING TO STANDARD OUTPUT */
- INT_Int21Handler( context );
+ TRACE("WRITE '$'-terminated string from %04lX:%04X to stdout\n",
+ context->SegDs, DX_reg(context) );
+ {
+ LPSTR data = CTX_SEG_OFF_TO_LIN( context,
+ context->SegDs, context->Edx );
+ LPSTR p = data;
+
+ /*
+ * Do NOT use strchr() to calculate the string length,
+ * as '\0' is valid string content, too!
+ * Maybe we should check for non-'$' strings, but DOS doesn't.
+ */
+ while (*p != '$') p++;
+
+ if (DOSVM_IsWin16())
+ WriteFile( DosFileHandleToWin32Handle(1),
+ data, p - data, 0, 0 );
+ else
+ for(; data != p; data++)
+ DOSVM_PutChar( *data );
+
+ SET_AL( context, '$' ); /* yes, '$' (0x24) gets returned in AL */
+ }
break;
case 0x0a: /* BUFFERED INPUT */
@@ -930,8 +1048,19 @@
break;
case 0x19: /* GET CURRENT DEFAULT DRIVE */
+ INT_Int21Handler( context );
+ break;
+
case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
- case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
+ TRACE( "SET DISK TRANSFER AREA ADDRESS %04lX:%04X\n",
+ context->SegDs, DX_reg(context) );
+ {
+ TDB *task = GlobalLock16( GetCurrentTask() );
+ task->dta = MAKESEGPTR( context->SegDs, DX_reg(context) );
+ }
+ break;
+
+ case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
case 0x1c: /* GET ALLOCATION INFORMATION FOR SPECIFIC DRIVE */
INT_Int21Handler( context );
break;
@@ -1019,8 +1148,13 @@
/* we cannot change the behaviour anyway, so just ignore it */
break;
- case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
- INT_Int21Handler( context );
+ case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
+ TRACE( "GET DISK TRANSFER AREA ADDRESS\n" );
+ {
+ TDB *task = GlobalLock16( GetCurrentTask() );
+ context->SegEs = SELECTOROF( task->dta );
+ SET_BX( context, OFFSETOF( task->dta ) );
+ }
break;
case 0x30: /* GET DOS VERSION */
@@ -1068,10 +1202,30 @@
break;
case 0x36: /* GET FREE DISK SPACE */
- case 0x37: /* SWITCHAR */
INT_Int21Handler( context );
break;
+ case 0x37: /* SWITCHAR */
+ {
+ switch (AL_reg(context))
+ {
+ case 0x00: /* "SWITCHAR" - GET SWITCH CHARACTER */
+ TRACE( "SWITCHAR - GET SWITCH CHARACTER\n" );
+ SET_AL( context, 0x00 ); /* success*/
+ SET_DL( context, '/' );
+ break;
+ case 0x01: /*"SWITCHAR" - SET SWITCH CHARACTER*/
+ FIXME( "SWITCHAR - SET SWITCH CHARACTER: %c\n",
+ DL_reg( context ));
+ SET_AL( context, 0x00 ); /* success*/
+ break;
+ default:
+ INT_BARF( context, 0x21 );
+ break;
+ }
+ }
+ break;
+
case 0x38: /* GET COUNTRY-SPECIFIC INFORMATION */
TRACE( "GET COUNTRY-SPECIFIC INFORMATION\n" );
if (AL_reg(context))
diff --git a/dlls/winedos/module.c b/dlls/winedos/module.c
index 46a8738..9fdf0d2 100644
--- a/dlls/winedos/module.c
+++ b/dlls/winedos/module.c
@@ -136,8 +136,13 @@
/* command.com does not skip over multiple spaces */
if(length > 126) {
- ERR("Command line truncated! (length %d > maximum length 126)\n",
- length);
+ /*
+ * FIXME: If length > 126 we should put truncated command line to
+ * PSP and store the entire command line in the environment
+ * variable CMDLINE.
+ */
+ FIXME("Command line truncated! (length %d > maximum length 126)\n",
+ length);
length = 126;
}
@@ -385,6 +390,12 @@
LPBYTE envblock = PTR_REAL_TO_LIN(psp->environment, 0);
BYTE cmdLength = cmdline[0];
+ /*
+ * FIXME: If cmdLength == 126, PSP may contain truncated version
+ * of the full command line. In this case environment
+ * variable CMDLINE contains the entire command line.
+ */
+
fullCmdLength = (strlen(filename) + 1) + cmdLength + 1; /* filename + space + cmdline + terminating null character */
fullCmdLine = HeapAlloc(GetProcessHeap(), 0, fullCmdLength);
@@ -557,6 +568,9 @@
MZ_FillPSP(psp_start, cmdline, cmdline ? strlen(cmdline) : 0);
pTask->flags |= TDBF_WINOLDAP;
+ /* DTA is set to PSP:0080h when a program is started. */
+ pTask->dta = MAKESEGPTR( DOSVM_psp, 0x80 );
+
GetpWin16Lock( &lock );
_LeaveSysLevel( lock );
diff --git a/dlls/winedos/winedos.spec b/dlls/winedos/winedos.spec
index d8644a5..4c2426b 100644
--- a/dlls/winedos/winedos.spec
+++ b/dlls/winedos/winedos.spec
@@ -2,16 +2,8 @@
@ stdcall EmulateInterruptPM(ptr long) DOSVM_EmulateInterruptPM
@ stdcall CallBuiltinHandler(ptr long) DOSVM_CallBuiltinHandler
-# DPMI functions
-@ stdcall CallRMInt(ptr) DOSVM_CallRMInt
-@ stdcall CallRMProc(ptr long) DOSVM_CallRMProc
-@ stdcall AllocRMCB(ptr) DOSVM_AllocRMCB
-@ stdcall FreeRMCB(ptr) DOSVM_FreeRMCB
-@ stdcall RawModeSwitch(ptr) DOSVM_RawModeSwitch
-
# I/O functions
@ stdcall SetTimer(long) DOSVM_SetTimer
@ stdcall GetTimer() DOSVM_GetTimer
@ stdcall inport(long long ptr) DOSVM_inport
@ stdcall outport(long long long) DOSVM_outport
-@ stdcall ASPIHandler(ptr) DOSVM_ASPIHandler
diff --git a/include/callback.h b/include/callback.h
index 8764eac..903c402 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -34,7 +34,6 @@
unsigned (WINAPI *GetTimer)( void );
BOOL (WINAPI *inport)( int port, int size, DWORD *res );
BOOL (WINAPI *outport)( int port, int size, DWORD val );
- void (WINAPI *ASPIHandler)( CONTEXT86 *context );
} DOSVM_TABLE;
extern DOSVM_TABLE Dosvm;
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index 4ae4fa5..ca0cdf6 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -50,7 +50,6 @@
GET_ADDR(GetTimer);
GET_ADDR(inport);
GET_ADDR(outport);
- GET_ADDR(ASPIHandler);
GET_ADDR(EmulateInterruptPM);
GET_ADDR(CallBuiltinHandler);
#undef GET_ADDR
diff --git a/msdos/int21.c b/msdos/int21.c
index 3c016cb..98d1672 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -908,17 +908,6 @@
}
-static void ASPI_DOS_HandleInt( CONTEXT86 *context )
-{
- if (!Dosvm.ASPIHandler && !DPMI_LoadDosSystem())
- {
- ERR("could not setup ASPI handler\n");
- return;
- }
- Dosvm.ASPIHandler( context );
-}
-
-
/***********************************************************************
* INT_Int21Handler
*/
@@ -928,21 +917,6 @@
switch(AH_reg(context))
{
- case 0x09: /* WRITE STRING TO STANDARD OUTPUT */
- TRACE("WRITE '$'-terminated string from %04lX:%04X to stdout\n",
- context->SegDs,DX_reg(context) );
- {
- LPSTR data = CTX_SEG_OFF_TO_LIN(context,context->SegDs,context->Edx);
- LPSTR p = data;
- /* do NOT use strchr() to calculate the string length,
- as '\0' is valid string content, too !
- Maybe we should check for non-'$' strings, but DOS doesn't. */
- while (*p != '$') p++;
- _hwrite16( 1, data, (int)p - (int)data);
- SET_AL( context, '$' ); /* yes, '$' (0x24) gets returned in AL */
- }
- break;
-
case 0x0e: /* SELECT DEFAULT DRIVE */
TRACE("SELECT DEFAULT DRIVE %d\n", DL_reg(context));
DRIVE_SetCurrentDrive( DL_reg(context) );
@@ -967,14 +941,6 @@
SET_AL( context, DRIVE_GetCurrentDrive() );
break;
- case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
- {
- TDB *pTask = TASK_GetCurrent();
- pTask->dta = MAKESEGPTR(context->SegDs,DX_reg(context));
- TRACE("Set DTA: %08lx\n", pTask->dta);
- }
- break;
-
case 0x1b: /* GET ALLOCATION INFORMATION FOR DEFAULT DRIVE */
SET_DL( context, 0 );
if (!INT21_GetDriveAllocInfo(context)) SET_AX( context, 0xffff );
@@ -992,15 +958,6 @@
INT21_ParseFileNameIntoFCB(context);
break;
- case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
- TRACE("GET DISK TRANSFER AREA ADDRESS\n");
- {
- TDB *pTask = TASK_GetCurrent();
- context->SegEs = SELECTOROF( pTask->dta );
- SET_BX( context, OFFSETOF( pTask->dta ) );
- }
- break;
-
case 0x32: /* GET DOS DRIVE PARAMETER BLOCK FOR SPECIFIC DRIVE */
TRACE("GET DOS DRIVE PARAMETER BLOCK FOR DRIVE %s\n",
INT21_DriveName( DL_reg(context)));
@@ -1062,28 +1019,6 @@
if (!INT21_GetFreeDiskSpace(context)) SET_AX( context, 0xffff );
break;
- case 0x37:
- {
- unsigned char switchchar='/';
- switch (AL_reg(context))
- {
- case 0x00: /* "SWITCHAR" - GET SWITCH CHARACTER */
- TRACE("SWITCHAR - GET SWITCH CHARACTER\n");
- SET_AL( context, 0x00 ); /* success*/
- SET_DL( context, switchchar );
- break;
- case 0x01: /*"SWITCHAR" - SET SWITCH CHARACTER*/
- TRACE("SWITCHAR - SET SWITCH CHARACTER\n");
- switchchar = DL_reg(context);
- SET_AL( context, 0x00 ); /* success*/
- break;
- default: /*"AVAILDEV" - SPECIFY \DEV\ PREFIX USE*/
- INT_BARF( context, 0x21 );
- break;
- }
- break;
- }
-
case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
TRACE("MKDIR %s\n",
(LPCSTR)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
@@ -1216,16 +1151,7 @@
case 0x01:
break;
- case 0x02:{
- const DOS_DEVICE *dev;
- static const WCHAR scsimgrW[] = {'S','C','S','I','M','G','R','$',0};
- if ((dev = DOSFS_GetDeviceByHandle( DosFileHandleToWin32Handle(BX_reg(context)) )) &&
- !strcmpiW( dev->name, scsimgrW ))
- {
- ASPI_DOS_HandleInt(context);
- }
- break;
- }
+
case 0x05:{ /* IOCTL - WRITE TO BLOCK DEVICE CONTROL CHANNEL */
/*BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx);*/
int drive = DOS_GET_DRIVE(BL_reg(context));
@@ -1309,20 +1235,6 @@
break;
}
- case 0xe0: /* Sun PC-NFS API */
- /* not installed */
- break;
-
- case 0x52: /* DR-DOS version */
- /* This is not DR-DOS */
-
- TRACE("GET DR-DOS VERSION requested\n");
-
- SET_AX( context, 0x0001 ); /* Invalid function */
- SET_CFLAG(context); /* Error */
- SetLastError( ERROR_INVALID_FUNCTION );
- break;
-
default:
INT_BARF( context, 0x21 );
break;