Reorganize IOCTL handling.

Move ASPI hooking to winedos.
Move some miscellaneous functions to winedos.
Remove unnecessary exports from winedos dll.
This commit is contained in:
Jukka Heinonen 2003-02-11 22:22:50 +00:00 committed by Alexandre Julliard
parent 33be954e62
commit 101f91d9df
7 changed files with 205 additions and 132 deletions

View File

@ -111,6 +111,9 @@ extern int DMA_Transfer(int channel,int reqlength,void* buffer);
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*);

View File

@ -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"
@ -597,6 +598,46 @@ static void INT21_GetPSP( CONTEXT86 *context )
}
/***********************************************************************
* 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
*
@ -604,33 +645,88 @@ static void INT21_GetPSP( CONTEXT86 *context )
*/
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)) );
if (dev && !strcmpiW( dev->name, emmxxxx0W )) {
EMS_Ioctl_Handler(context);
return;
}
switch (AL_reg(context))
{
case 0x00:
case 0x01:
case 0x02:
case 0x03:
INT21_Ioctl_Char( context );
break;
case 0x04:
case 0x05:
INT21_Ioctl_Block( context );
break;
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("IOCTL - SET SHARING RETRY COUNT pause %d retries %d\n",
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 );
break;
}
else
{
DOSMEM_LOL()->sharing_retry_delay = CX_reg(context);
if (!DX_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_Int21Handler( context );
INT_BARF( context, 0x21 );
}
}
@ -862,7 +958,29 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
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,7 +1048,18 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
break;
case 0x19: /* GET CURRENT DEFAULT DRIVE */
INT_Int21Handler( context );
break;
case 0x1a: /* SET DISK TRANSFER AREA ADDRESS */
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 );
@ -1020,7 +1149,12 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
break;
case 0x2f: /* GET DISK TRANSFER AREA ADDRESS */
INT_Int21Handler( context );
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 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
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))

View File

@ -136,7 +136,12 @@ static void MZ_FillPSP( LPVOID lpPSP, LPBYTE cmdline, int length )
/* command.com does not skip over multiple spaces */
if(length > 126) {
ERR("Command line truncated! (length %d > maximum length 126)\n",
/*
* 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 @@ BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID para
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 @@ static void MZ_Launch(void)
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 );

View File

@ -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

View File

@ -34,7 +34,6 @@ typedef struct {
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;

View File

@ -50,7 +50,6 @@ BOOL DPMI_LoadDosSystem(void)
GET_ADDR(GetTimer);
GET_ADDR(inport);
GET_ADDR(outport);
GET_ADDR(ASPIHandler);
GET_ADDR(EmulateInterruptPM);
GET_ADDR(CallBuiltinHandler);
#undef GET_ADDR

View File

@ -908,17 +908,6 @@ INT21_networkfunc (CONTEXT86 *context)
}
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 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
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 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
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 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
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 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
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 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
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 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
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;