Migrate most int21 ioctl routines to winedos.
Migrate int21 set drive routine to winedos.
This commit is contained in:
parent
370db5b47c
commit
f07dfff17b
|
@ -153,6 +153,22 @@ static BYTE INT21_MapDrive( BYTE drive )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* INT21_SetCurrentDrive
|
||||
*
|
||||
* Set current drive. Uses scheme (0=A:, 1=B:, 2=C:, ...).
|
||||
*/
|
||||
static void INT21_SetCurrentDrive( BYTE drive )
|
||||
{
|
||||
WCHAR drivespec[3] = {'A', ':', 0};
|
||||
|
||||
drivespec[0] += drive;
|
||||
|
||||
if (!SetCurrentDirectoryW( drivespec ))
|
||||
TRACE( "Failed to set current drive.\n" );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* INT21_ReadChar
|
||||
*
|
||||
|
@ -1584,7 +1600,139 @@ static void INT21_GetPSP( CONTEXT86 *context )
|
|||
*/
|
||||
static void INT21_Ioctl_Block( CONTEXT86 *context )
|
||||
{
|
||||
BYTE *dataptr;
|
||||
BYTE drive = INT21_MapDrive( BL_reg(context) );
|
||||
WCHAR drivespec[4] = {'A', ':', '\\', 0};
|
||||
UINT drivetype;
|
||||
|
||||
drivespec[0] += drive;
|
||||
drivetype = GetDriveTypeW( drivespec );
|
||||
|
||||
if (drivetype == DRIVE_UNKNOWN || drivetype == DRIVE_NO_ROOT_DIR)
|
||||
{
|
||||
TRACE( "IOCTL - SUBFUNCTION %d - INVALID DRIVE %c:\n",
|
||||
AL_reg(context), 'A' + drive );
|
||||
SetLastError( ERROR_INVALID_DRIVE );
|
||||
SET_AX( context, ERROR_INVALID_DRIVE );
|
||||
SET_CFLAG( context );
|
||||
return;
|
||||
}
|
||||
|
||||
switch (AL_reg(context))
|
||||
{
|
||||
case 0x04: /* READ FROM BLOCK DEVICE CONTROL CHANNEL */
|
||||
case 0x05: /* WRITE TO BLOCK DEVICE CONTROL CHANNEL */
|
||||
INT_BARF( context, 0x21 );
|
||||
break;
|
||||
|
||||
case 0x08: /* CHECK IF BLOCK DEVICE REMOVABLE */
|
||||
TRACE( "IOCTL - CHECK IF BLOCK DEVICE REMOVABLE - %c:\n",
|
||||
'A' + drive );
|
||||
|
||||
if (drivetype == DRIVE_REMOVABLE)
|
||||
SET_AX( context, 0 ); /* removable */
|
||||
else
|
||||
SET_AX( context, 1 ); /* not removable */
|
||||
break;
|
||||
|
||||
case 0x09: /* CHECK IF BLOCK DEVICE REMOTE */
|
||||
TRACE( "IOCTL - CHECK IF BLOCK DEVICE REMOTE - %c:\n",
|
||||
'A' + drive );
|
||||
|
||||
if (drivetype == DRIVE_REMOTE)
|
||||
SET_DX( context, (1<<9) | (1<<12) ); /* remote + no direct IO */
|
||||
else
|
||||
SET_DX( context, 0 ); /* FIXME: use driver attr here */
|
||||
break;
|
||||
|
||||
case 0x0d: /* GENERIC BLOCK DEVICE REQUEST */
|
||||
/* Get pointer to IOCTL parameter block. */
|
||||
dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
|
||||
|
||||
switch (CX_reg(context))
|
||||
{
|
||||
case 0x0841: /* write logical device track */
|
||||
TRACE( "GENERIC IOCTL - Write logical device track - %c:\n",
|
||||
'A' + drive);
|
||||
{
|
||||
WORD head = *(WORD *)dataptr+1;
|
||||
WORD cyl = *(WORD *)dataptr+3;
|
||||
WORD sect = *(WORD *)dataptr+5;
|
||||
WORD nrsect = *(WORD *)dataptr+7;
|
||||
BYTE *data = (BYTE *)dataptr+9; /* FIXME: is this correct? */
|
||||
|
||||
if (!DOSVM_RawWrite(drive, head*cyl*sect, nrsect, data, FALSE))
|
||||
{
|
||||
SET_AX( context, ERROR_WRITE_FAULT );
|
||||
SET_CFLAG(context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x084a: /* lock logical volume */
|
||||
TRACE( "GENERIC IOCTL - Lock logical volume, level %d mode %d - %c:\n",
|
||||
BH_reg(context), DX_reg(context), 'A' + drive );
|
||||
break;
|
||||
|
||||
case 0x0860: /* get device parameters */
|
||||
INT_Int21Handler( context );
|
||||
break;
|
||||
|
||||
case 0x0861: /* read logical device track */
|
||||
TRACE( "GENERIC IOCTL - Read logical device track - %c:\n",
|
||||
'A' + drive);
|
||||
{
|
||||
WORD head = *(WORD *)dataptr+1;
|
||||
WORD cyl = *(WORD *)dataptr+3;
|
||||
WORD sect = *(WORD *)dataptr+5;
|
||||
WORD nrsect = *(WORD *)dataptr+7;
|
||||
BYTE *data = (BYTE *)dataptr+9; /* FIXME: is this correct? */
|
||||
|
||||
if (!DOSVM_RawRead(drive, head*cyl*sect, nrsect, data, FALSE))
|
||||
{
|
||||
SET_AX( context, ERROR_READ_FAULT );
|
||||
SET_CFLAG(context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0866: /* get volume serial number */
|
||||
INT_Int21Handler( context );
|
||||
break;
|
||||
|
||||
case 0x086a: /* unlock logical volume */
|
||||
TRACE( "GENERIC IOCTL - Logical volume unlocked - %c:\n",
|
||||
'A' + drive );
|
||||
break;
|
||||
|
||||
case 0x086f: /* get drive map information */
|
||||
INT_Int21Handler( context );
|
||||
break;
|
||||
|
||||
case 0x0872:
|
||||
INT_Int21Handler( context );
|
||||
break;
|
||||
|
||||
default:
|
||||
INT_BARF( context, 0x21 );
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0e: /* GET LOGICAL DRIVE MAP */
|
||||
TRACE( "IOCTL - GET LOGICAL DRIVE MAP - %c:\n",
|
||||
'A' + drive );
|
||||
/* FIXME: this is not correct if drive has mappings */
|
||||
SET_AL( context, 0 ); /* drive has no mapping */
|
||||
break;
|
||||
|
||||
case 0x0f: /* SET LOGICAL DRIVE MAP */
|
||||
INT_Int21Handler( context );
|
||||
break;
|
||||
|
||||
case 0x11: /* QUERY GENERIC IOCTL CAPABILITY */
|
||||
default:
|
||||
INT_BARF( context, 0x21 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1613,7 +1761,74 @@ static void INT21_Ioctl_Char( CONTEXT86 *context )
|
|||
return;
|
||||
}
|
||||
|
||||
INT_Int21Handler( context );
|
||||
switch (AL_reg(context))
|
||||
{
|
||||
case 0x00: /* GET DEVICE INFORMATION */
|
||||
TRACE( "IOCTL - GET DEVICE INFORMATION - %d\n", BX_reg(context) );
|
||||
if (dev)
|
||||
{
|
||||
/*
|
||||
* Returns attribute word in DX:
|
||||
* Bit 14 - Device driver can process IOCTL requests.
|
||||
* Bit 13 - Output until busy supported.
|
||||
* Bit 11 - Driver supports OPEN/CLOSE calls.
|
||||
* Bit 8 - Unknown.
|
||||
* Bit 7 - Set (indicates device).
|
||||
* Bit 6 - EOF on input.
|
||||
* Bit 5 - Raw (binary) mode.
|
||||
* Bit 4 - Device is special (uses int29).
|
||||
* Bit 3 - Clock device.
|
||||
* Bit 2 - NUL device.
|
||||
* Bit 1 - Standard output.
|
||||
* Bit 0 - Standard input.
|
||||
*/
|
||||
SET_DX( context, dev->flags );
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Returns attribute word in DX:
|
||||
* Bit 15 - File is remote.
|
||||
* Bit 14 - Don't set file date/time on closing.
|
||||
* Bit 11 - Media not removable.
|
||||
* Bit 8 - Generate int24 if no disk space on write
|
||||
* or read past end of file
|
||||
* Bit 7 - Clear (indicates file).
|
||||
* Bit 6 - File has not been written.
|
||||
* Bit 5..0 - Drive number (0=A:,...)
|
||||
*
|
||||
* FIXME: Should check if file is on remote or removable drive.
|
||||
* FIXME: Should use drive file is located on (and not current).
|
||||
*/
|
||||
SET_DX( context, 0x0140 + INT21_GetCurrentDrive() );
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x01: /* SET DEVICE INFORMATION */
|
||||
case 0x02: /* READ FROM CHARACTER DEVICE CONTROL CHANNEL */
|
||||
case 0x03: /* WRITE TO CHARACTER DEVICE CONTROL CHANNEL */
|
||||
case 0x06: /* GET INPUT STATUS */
|
||||
case 0x07: /* GET OUTPUT STATUS */
|
||||
INT_BARF( context, 0x21 );
|
||||
break;
|
||||
|
||||
case 0x0a: /* CHECK IF HANDLE IS REMOTE */
|
||||
TRACE( "IOCTL - CHECK IF HANDLE IS REMOTE - %d\n", BX_reg(context) );
|
||||
/*
|
||||
* Returns attribute word in DX:
|
||||
* Bit 15 - Set if remote.
|
||||
* Bit 14 - Set if date/time not set on close.
|
||||
*
|
||||
* FIXME: Should check if file is on remote drive.
|
||||
*/
|
||||
SET_DX( context, 0 );
|
||||
break;
|
||||
|
||||
case 0x0c: /* GENERIC CHARACTER DEVICE REQUEST */
|
||||
case 0x10: /* QUERY GENERIC IOCTL CAPABILITY */
|
||||
default:
|
||||
INT_BARF( context, 0x21 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2211,7 +2426,9 @@ void WINAPI DOSVM_Int21Handler( CONTEXT86 *context )
|
|||
break;
|
||||
|
||||
case 0x0e: /* SELECT DEFAULT DRIVE */
|
||||
INT_Int21Handler( context );
|
||||
TRACE( "SELECT DEFAULT DRIVE - %c:\n", 'A' + DL_reg(context) );
|
||||
INT21_SetCurrentDrive( DL_reg(context) );
|
||||
SET_AL( context, MAX_DOS_DRIVES );
|
||||
break;
|
||||
|
||||
case 0x0f: /* OPEN FILE USING FCB */
|
||||
|
|
|
@ -1294,61 +1294,6 @@ int DRIVE_OpenDevice( int drive, int flags )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DRIVE_RawRead
|
||||
*
|
||||
* Read raw sectors from a device
|
||||
*/
|
||||
int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL fake_success)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1)
|
||||
{
|
||||
lseek( fd, begin * 512, SEEK_SET );
|
||||
/* FIXME: check errors */
|
||||
read( fd, dataptr, nr_sect * 512 );
|
||||
close( fd );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(dataptr, 0, nr_sect * 512);
|
||||
if (fake_success)
|
||||
{
|
||||
if (begin == 0 && nr_sect > 1) *(dataptr + 512) = 0xf8;
|
||||
if (begin == 1) *dataptr = 0xf8;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DRIVE_RawWrite
|
||||
*
|
||||
* Write raw sectors to a device
|
||||
*/
|
||||
int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL fake_success)
|
||||
{
|
||||
int fd;
|
||||
|
||||
if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1)
|
||||
{
|
||||
lseek( fd, begin * 512, SEEK_SET );
|
||||
/* FIXME: check errors */
|
||||
write( fd, dataptr, nr_sect * 512 );
|
||||
close( fd );
|
||||
}
|
||||
else
|
||||
if (!(fake_success))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* DRIVE_GetFreeSpace
|
||||
*/
|
||||
|
|
|
@ -54,8 +54,6 @@ extern int DRIVE_Disable( int drive );
|
|||
extern int DRIVE_Enable( int drive );
|
||||
extern int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive );
|
||||
extern int DRIVE_OpenDevice( int drive, int flags );
|
||||
extern int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL fake_success );
|
||||
extern int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL fake_success );
|
||||
extern char *DRIVE_BuildEnv(void);
|
||||
|
||||
#endif /* __WINE_DRIVE_H */
|
||||
|
|
141
msdos/int21.c
141
msdos/int21.c
|
@ -275,35 +275,6 @@ static void GetDrivePB( CONTEXT86 *context, int drive )
|
|||
}
|
||||
|
||||
|
||||
static void ioctlGetDeviceInfo( CONTEXT86 *context )
|
||||
{
|
||||
int curr_drive;
|
||||
const DOS_DEVICE *dev;
|
||||
|
||||
TRACE("(%d)\n", BX_reg(context));
|
||||
|
||||
RESET_CFLAG(context);
|
||||
|
||||
/* DOS device ? */
|
||||
if ((dev = DOSFS_GetDeviceByHandle( DosFileHandleToWin32Handle(BX_reg(context)) )))
|
||||
{
|
||||
SET_DX( context, dev->flags );
|
||||
return;
|
||||
}
|
||||
|
||||
/* it seems to be a file */
|
||||
curr_drive = DRIVE_GetCurrentDrive();
|
||||
SET_DX( context, 0x0140 + curr_drive + ((curr_drive > 1) ? 0x0800 : 0) );
|
||||
/* no floppy */
|
||||
/* bits 0-5 are current drive
|
||||
* 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
|
||||
*/
|
||||
}
|
||||
|
||||
static BOOL ioctlGenericBlkDevReq( CONTEXT86 *context )
|
||||
{
|
||||
BYTE *dataptr = CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
|
||||
|
@ -323,10 +294,6 @@ static BOOL ioctlGenericBlkDevReq( CONTEXT86 *context )
|
|||
|
||||
switch (CL_reg(context))
|
||||
{
|
||||
case 0x4a: /* lock logical volume */
|
||||
TRACE("lock logical volume (%d) level %d mode %d\n",drive,BH_reg(context),DX_reg(context));
|
||||
break;
|
||||
|
||||
case 0x60: /* get device parameters */
|
||||
/* used by w4wgrp's winfile */
|
||||
memset(dataptr, 0, 0x20); /* DOS 6.22 uses 0x20 bytes */
|
||||
|
@ -348,30 +315,6 @@ static BOOL ioctlGenericBlkDevReq( CONTEXT86 *context )
|
|||
RESET_CFLAG(context);
|
||||
break;
|
||||
|
||||
case 0x41: /* write logical device track */
|
||||
case 0x61: /* read logical device track */
|
||||
{
|
||||
BYTE drive = BL_reg(context) ?
|
||||
BL_reg(context) : DRIVE_GetCurrentDrive();
|
||||
WORD head = *(WORD *)dataptr+1;
|
||||
WORD cyl = *(WORD *)dataptr+3;
|
||||
WORD sect = *(WORD *)dataptr+5;
|
||||
WORD nrsect = *(WORD *)dataptr+7;
|
||||
BYTE *data = (BYTE *)dataptr+9;
|
||||
int (*raw_func)(BYTE, DWORD, DWORD, BYTE *, BOOL);
|
||||
|
||||
raw_func = (CL_reg(context) == 0x41) ?
|
||||
DRIVE_RawWrite : DRIVE_RawRead;
|
||||
|
||||
if (raw_func(drive, head*cyl*sect, nrsect, data, FALSE))
|
||||
RESET_CFLAG(context);
|
||||
else
|
||||
{
|
||||
SET_AX( context, 0x1e ); /* read fault */
|
||||
SET_CFLAG(context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x66:/* get disk serial number */
|
||||
{
|
||||
char label[12],fsname[9],path[4];
|
||||
|
@ -388,10 +331,6 @@ static BOOL ioctlGenericBlkDevReq( CONTEXT86 *context )
|
|||
}
|
||||
break;
|
||||
|
||||
case 0x6a:
|
||||
TRACE("logical volume %d unlocked.\n",drive);
|
||||
break;
|
||||
|
||||
case 0x6f:
|
||||
memset(dataptr+1, '\0', dataptr[0]-1);
|
||||
dataptr[1] = dataptr[0];
|
||||
|
@ -911,12 +850,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
|||
|
||||
switch(AH_reg(context))
|
||||
{
|
||||
case 0x0e: /* SELECT DEFAULT DRIVE */
|
||||
TRACE("SELECT DEFAULT DRIVE %d\n", DL_reg(context));
|
||||
DRIVE_SetCurrentDrive( DL_reg(context) );
|
||||
SET_AL( context, MAX_DOS_DRIVES );
|
||||
break;
|
||||
|
||||
case 0x11: /* FIND FIRST MATCHING FILE USING FCB */
|
||||
TRACE("FIND FIRST MATCHING FILE USING FCB %p\n",
|
||||
CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx));
|
||||
|
@ -981,82 +914,12 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
|||
case 0x44: /* IOCTL */
|
||||
switch (AL_reg(context))
|
||||
{
|
||||
case 0x00:
|
||||
ioctlGetDeviceInfo(context);
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
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));
|
||||
|
||||
FIXME("program tried to write to block device control channel of drive %d:\n",drive);
|
||||
/* for (i=0;i<CX_reg(context);i++)
|
||||
fprintf(stdnimp,"%02x ",dataptr[i]);
|
||||
fprintf(stdnimp,"\n");*/
|
||||
SET_AX( context, context->Ecx );
|
||||
break;
|
||||
}
|
||||
case 0x08: /* Check if drive is removable. */
|
||||
TRACE("IOCTL - CHECK IF BLOCK DEVICE REMOVABLE for drive %s\n",
|
||||
INT21_DriveName( BL_reg(context)));
|
||||
switch(GetDriveType16( DOS_GET_DRIVE( BL_reg(context) )))
|
||||
{
|
||||
case DRIVE_UNKNOWN:
|
||||
SetLastError( ERROR_INVALID_DRIVE );
|
||||
SET_AX( context, ERROR_INVALID_DRIVE );
|
||||
SET_CFLAG(context);
|
||||
break;
|
||||
case DRIVE_REMOVABLE:
|
||||
SET_AX( context, 0 ); /* removable */
|
||||
break;
|
||||
default:
|
||||
SET_AX( context, 1 ); /* not removable */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x09: /* CHECK IF BLOCK DEVICE REMOTE */
|
||||
TRACE("IOCTL - CHECK IF BLOCK DEVICE REMOTE for drive %s\n",
|
||||
INT21_DriveName( BL_reg(context)));
|
||||
switch(GetDriveType16( DOS_GET_DRIVE( BL_reg(context) )))
|
||||
{
|
||||
case DRIVE_UNKNOWN:
|
||||
SetLastError( ERROR_INVALID_DRIVE );
|
||||
SET_AX( context, ERROR_INVALID_DRIVE );
|
||||
SET_CFLAG(context);
|
||||
break;
|
||||
case DRIVE_REMOTE:
|
||||
SET_DX( context, (1<<9) | (1<<12) ); /* remote */
|
||||
break;
|
||||
default:
|
||||
SET_DX( context, 0 ); /* FIXME: use driver attr here */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0a: /* check if handle (BX) is remote */
|
||||
TRACE("IOCTL - CHECK IF HANDLE %d IS REMOTE\n",BX_reg(context));
|
||||
/* returns DX, bit 15 set if remote, bit 14 set if date/time
|
||||
* not set on close
|
||||
*/
|
||||
SET_DX( context, 0 );
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
TRACE("IOCTL - GENERIC BLOCK DEVICE REQUEST %s\n",
|
||||
INT21_DriveName( BL_reg(context)));
|
||||
bSetDOSExtendedError = ioctlGenericBlkDevReq(context);
|
||||
break;
|
||||
|
||||
case 0x0e: /* get logical drive mapping */
|
||||
TRACE("IOCTL - GET LOGICAL DRIVE MAP for drive %s\n",
|
||||
INT21_DriveName( BL_reg(context)));
|
||||
SET_AL( context, 0 ); /* drive has no mapping - FIXME: may be wrong*/
|
||||
break;
|
||||
|
||||
case 0x0F: /* Set logical drive mapping */
|
||||
{
|
||||
int drive;
|
||||
|
@ -1070,10 +933,6 @@ void WINAPI INT_Int21Handler( CONTEXT86 *context )
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
INT_BARF( context, 0x21 );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in New Issue