Mail Archives: djgpp-workers/1997/09/14/14:54:18
A patch for statfs that makes it work better with CD-ROM drives.
diff -c src/libc/compat/sys/vfs/statfs.c~0 src/libc/compat/sys/vfs/statfs.c
*** src/libc/compat/sys/vfs/statfs.c~0 Sun Aug 31 21:19:12 1997
--- src/libc/compat/sys/vfs/statfs.c Sat Mar 29 11:48:10 1997
***************
*** 1,12 ****
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
- #include <libc/stubs.h>
#include <dpmi.h>
#include <go32.h>
! #include <sys/farptr.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/vfs.h>
#include <libc/dosio.h>
int
--- 1,14 ----
+ /* Copyright (C) 1997 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <dpmi.h>
#include <go32.h>
! #include <sys/movedata.h>
#include <errno.h>
+ #include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/vfs.h>
+ #include <libc/farptrgs.h>
#include <libc/dosio.h>
int
***************
*** 28,119 ****
}
/* For a CD-ROM drive, 213600 gives incorrect info.
! Use CD-ROM-specific calls if they are available. */
regs.x.ax = 0x150b; /* is this drive supported by CD-ROM driver? */
regs.x.cx = drive_number;
__dpmi_int(0x2f, ®s);
if ((regs.x.flags & 1) == 0 && regs.x.bx == 0xadad && regs.x.ax != 0)
{
! int drv_pos;
!
! /* Find this drive's position in the list of CD-ROM drives
! on this system (there might be more than one CD drive!) */
! regs.x.ax = 0x150d;
! regs.x.es = __tb_segment;
! regs.x.bx = 0;
! __dpmi_int (0x2f, ®s);
! _farsetsel (_dos_ds);
! for (drv_pos = 0; drv_pos <= drive_number; drv_pos++)
! if (_farnspeekb (__tb + drv_pos) == drive_number)
! break;
! if (drv_pos <= drive_number)
! {
! char dev_name[9], *p = dev_name + 7;
! int drv_off, drv_seg, drv_addr;
! /* 2F1501 will return an array of pointers to device driver
! headers for each supported drive. Each array element
! occupies 5 bytes: 1 byte for subunit number and 4 bytes
! for a DWORD address of the device drive header for this drive. */
! regs.x.ax = 0x1501;
regs.x.es = __tb_segment;
! regs.x.bx = 0;
__dpmi_int (0x2f, ®s);
! drv_off = _farpeekw (_dos_ds, __tb + drv_pos*5 + 1);
! drv_seg = _farpeekw (_dos_ds, __tb + drv_pos*5 + 3);
! drv_addr = drv_seg * 16 + drv_off;
!
! /* The device name is at offset 0Ah in the device driver header. */
! dosmemget (drv_addr + 0x0a, 8, dev_name);
! while (p > dev_name && p[-1] == ' ')
! p--;
! *p = '\0';
! if (dev_name[0])
{
! /* Open the device name and call 214402 to read the info. */
! int fd = open (dev_name, O_RDONLY | O_BINARY);
!
! if (fd >= 0)
! {
! int i = 2, bsize = 0;
!
! /* First time after the door is closed the IOCTL call
! might fail. Therefore try twice before giving up. */
! do
! {
! regs.x.ax = 0x4402;
! regs.x.bx = fd & 0xffff;
! regs.x.cx = 2;
! _farpokeb (_dos_ds, __tb, 7);
! _farpokeb (_dos_ds, __tb + 1, 0);
! regs.x.ds = __tb_segment;
! regs.x.dx = 0;
! __dpmi_int (0x21, ®s);
! if ((regs.x.flags & 1) == 0 && regs.x.ax == 2)
! {
! bsize = _farpeekw (_dos_ds, __tb + 2);
!
! regs.x.ax = 0x4402;
! regs.x.bx = fd & 0xffff;
! regs.x.cx = 4;
! _farpokeb (_dos_ds, __tb, 8);
! __dpmi_int (0x21, ®s);
! }
! } while (--i && (regs.x.flags & 1));
!
! if ((regs.x.flags & 1) == 0 && regs.x.ax == 4)
! {
! regs.x.ax = 1;
! regs.x.cx = bsize;
! regs.x.bx = 0; /* no free space: cannot add data */
! blocks = _farpeekl (_dos_ds, __tb + 1);
! cdrom_calls_used = 1;
! }
!
! close (fd);
! }
}
}
}
--- 30,98 ----
}
/* For a CD-ROM drive, 213600 gives incorrect info.
! Use CD-ROM-specific calls if they are available.
!
! Int 2Fh/AX=1510h gives us a way of doing IOCTL with the
! CD-ROM device driver without knowing the name of the
! device (which is defined by the CONFIG.SYS line that
! installs the driver and can therefore be arbitrary). */
regs.x.ax = 0x150b; /* is this drive supported by CD-ROM driver? */
regs.x.cx = drive_number;
__dpmi_int(0x2f, ®s);
if ((regs.x.flags & 1) == 0 && regs.x.bx == 0xadad && regs.x.ax != 0)
{
! unsigned char request_header[0x14];
! int status, i = 2, bsize = 0;
! /* Construct the request header for the CD-ROM device driver. */
! memset (request_header, 0, sizeof request_header);
! request_header[0] = sizeof request_header;
! request_header[2] = 3; /* IOCTL READ command */
! *(unsigned short *)&request_header[0xe] = __tb_offset;
! *(unsigned short *)&request_header[0x10] = __tb_segment;
! request_header[0x12] = 4; /* number of bytes to transfer */
!
! /* When the disk was just changed, we need to try twice. */
! do {
! /* Put control block into the transfer buffer. */
! _farpokeb (_dos_ds, __tb, 7); /* read sector size */
! _farpokeb (_dos_ds, __tb + 1, 0); /* cooked mode */
! _farpokew (_dos_ds, __tb + 2, 0); /* zero out the result field */
!
! /* Put request header into the transfer buffer and call the driver. */
! dosmemput (request_header, sizeof (request_header), __tb + 4);
! regs.x.ax = 0x1510;
! regs.x.cx = drive_number;
regs.x.es = __tb_segment;
! regs.x.bx = __tb_offset + 4;
__dpmi_int (0x2f, ®s);
! status = _farpeekw (_dos_ds, __tb + 7);
! bsize = _farpeekw (_dos_ds, __tb + 2);
! } while (--i && (status & 0x800f) == 0x800f); /* disk changed */
! if (status == 0x100 && _farpeekw (_dos_ds, __tb + 4 + 0x12) == 4)
! {
! request_header[0x12] = 5; /* number of bytes to transfer */
! /* Put control block into the transfer buffer. */
! _farpokeb (_dos_ds, __tb, 8); /* read volume size */
! _farpokel (_dos_ds, __tb + 1, 0); /* zero out the result field */
!
! /* Put request header into the transfer buffer and call the driver. */
! dosmemput (request_header, sizeof (request_header), __tb + 5);
! regs.x.ax = 0x1510;
! regs.x.cx = drive_number;
! regs.x.es = __tb_segment;
! regs.x.bx = __tb_offset + 5;
! __dpmi_int (0x2f, ®s);
! if (_farpeekw (_dos_ds, __tb + 8) == 0x100
! && _farpeekw (_dos_ds, __tb + 5 + 0x12) == 5)
{
! regs.x.ax = 1; /* fake: sectors per cluster */
! regs.x.cx = bsize;
! regs.x.bx = 0; /* no free space: cannot add data to CD-ROM */
! blocks = _farpeekl (_dos_ds, __tb + 1);
! cdrom_calls_used = 1;
}
}
}
***************
*** 172,175 ****
}
#endif
-
--- 151,153 ----
- Raw text -