diff --git a/dlls/winedos/int21.c b/dlls/winedos/int21.c index e8e5b08fb5b..c1c4198b354 100644 --- a/dlls/winedos/int21.c +++ b/dlls/winedos/int21.c @@ -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 ) { - INT_Int21Handler( 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 */ diff --git a/files/drive.c b/files/drive.c index c8a9f884947..00d0c67cb12 100644 --- a/files/drive.c +++ b/files/drive.c @@ -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 */ diff --git a/include/drive.h b/include/drive.h index 70fe95c5567..ec9fba165b1 100644 --- a/include/drive.h +++ b/include/drive.h @@ -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 */ diff --git a/msdos/int21.c b/msdos/int21.c index fb2bfd8ca24..4f3c94fee60 100644 --- a/msdos/int21.c +++ b/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;iEcx ); - 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;