Migrate most int21 ioctl routines to winedos.

Migrate int21 set drive routine to winedos.
This commit is contained in:
Jukka Heinonen 2003-06-04 20:17:52 +00:00 committed by Alexandre Julliard
parent 370db5b47c
commit f07dfff17b
4 changed files with 220 additions and 201 deletions

View File

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

View File

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

View File

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

View File

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