delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1997/09/14/14:54:18

Date: Sun, 14 Sep 1997 20:06:01 +0300 (IDT)
From: Eli Zaretskii <eliz AT is DOT elta DOT co DOT il>
To: DJ Delorie <dj AT delorie DOT com>
cc: djgpp-workers AT delorie DOT com
Subject: statfs in 970831
Message-ID: <Pine.SUN.3.91.970914200421.20461E-100000@is>
MIME-Version: 1.0

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, &regs);
    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, &regs);
!     _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, &regs);
!       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, &regs);
! 	      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, &regs);
! 	      }
! 	    } 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, &regs);
    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, &regs);
!       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, &regs);
!       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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019