home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_11 / nelson / block.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1994-01-12  |  6.6 KB  |  242 lines

  1. /* ----------------------------------------------------
  2.  *  block.cpp
  3.  *
  4.  *  Member function definitions,
  5.  *  IOCTL for block devices
  6.  * ------------------------------------------------- */
  7.  
  8. #include "block.h"
  9.  
  10. #ifndef NDEBUG
  11. #include <iostream.h>
  12.  
  13. void IoctlBlock::IoctlError( int errval )
  14. {
  15.     cerr << "*** class IoctlBlock: DOS error #"
  16.          << errval << " encountered, subfunction #"
  17.          << hex << _iregs.x.ax << dec << endl;
  18. }
  19. #endif      // NDEBUG
  20.  
  21. unsigned IoctlBlock::drive_info( int drive )
  22. {
  23.     _iregs.x.bx = drive;
  24.     int21_44h( drive_remote );
  25.     return _oregs.x.dx;
  26. }
  27.  
  28. IoctlBlock::IoctlBlock(int drive )
  29. {
  30.     _info = drive_info( drive );
  31.     _drive = _dos_error ? -1 : drive;
  32. }
  33.  
  34. IoctlBlock *IoctlBlock::Init(int drive )
  35. {
  36.    /* Return a pointer to a new, initialized object
  37.     * of type IoctlBlock, NULL if specified drive
  38.     * is invalid.
  39.     */
  40.  
  41.     IoctlBlock *obj = new IoctlBlock( drive);
  42.  
  43.     if( obj->_drive == -1 )   {   //bad drive
  44.             delete obj;
  45.             return (IoctlBlock *) 0;
  46.     }
  47.  
  48.     return obj;
  49. }
  50.  
  51. int IoctlBlock::block_ioctl( block_cmd minor_code,
  52.                              void *param_block     )
  53. {
  54.    /* Access DOS int21h/44h/0Dh for current disk
  55.     * drive, generic ioctl for block devices. Return
  56.     * 0 if successful, DOS error value if not.
  57.     */
  58.     _iregs.x.bx = _drive;
  59.     _iregs.h.ch = 0x08;    //category = disk drive
  60.     _iregs.h.cl = (char) minor_code;
  61.     _iregs.x.dx = FP_OFF( (void far *) param_block );
  62.     _sregs.ds   = FP_SEG( (void far *) param_block );
  63.     int21_44h( gen_ioctl_block );
  64.     return _dos_error ? _oregs.x.ax : 0;
  65. }
  66.  
  67. unsigned IoctlBlock::ioctl_data( ioctl_cmd fn,
  68.                                  unsigned count,
  69.                                  void *buffer )
  70. {
  71.    /* Send/receive I/O Control data to current block
  72.     * device. Return #bytes successfully transfered.
  73.     */
  74.     _iregs.x.bx = _drive;
  75.     _iregs.x.cx = count;     //#bytes to read/write
  76.     _iregs.x.dx = FP_OFF( (void far *) buffer );
  77.     _sregs.ds   = FP_SEG( (void far *) buffer );
  78.     int21_44h(fn);          //function number (4/5)
  79.     return _oregs.x.ax;   //#bytes xfered
  80. }
  81.  
  82. int IoctlBlock::sendIoctl( unsigned *count,
  83.                            void *buffer    )
  84. {
  85.    /* Send ioctl data to current drive.  Return 0 on
  86.     * success, or DOS error value if not.  Assigns
  87.     * #bytes successfully sent to 'count'.
  88.     */
  89.     *count = ioctl_data( send_ioctl_block,
  90.                              *count, buffer );
  91.     return _dos_error ? _oregs.x.ax : 0;
  92. }
  93.  
  94. int IoctlBlock::readIoctl( unsigned *count,
  95.                            void *buffer    )
  96. {
  97.     *count = ioctl_data( read_ioctl_block,
  98.                              *count, buffer );
  99.     return _dos_error ? _oregs.x.ax : 0;
  100. }
  101.  
  102. int IoctlBlock::isRemovable(void)
  103. {
  104.    /* Determine if current drive contains removable
  105.     * storage media.
  106.     */
  107.     if( isRemote() || !(_info & rmvMedia) )
  108.             return 0;   //assume fixed if on network
  109.                         //or if rmvMedia bit not set
  110.     _iregs.x.bx = _drive;
  111.     int21_44h( drive_removable );
  112.     return !_oregs.x.ax; //ax == 0 if removable
  113. }
  114.  
  115. int IoctlBlock::checkAlias( void )
  116. {
  117.    /* Return the active drive alias (if any) assigned
  118.     * to the current drive, 0 if no drive aliases have
  119.     * been assigned, or -1 on DOS error.
  120.     */
  121.     _iregs.x.bx = _drive;
  122.     int21_44h(get_log_drivemap);
  123.     return _dos_error ? -1 : (int) _oregs.h.al;
  124. }
  125.  
  126. int IoctlBlock::nextAlias( int drive_alias )
  127. {
  128.    /* Set next active (logical) drive number for the
  129.     * current drive and return active drive number, or
  130.     * -1 on DOS error.  Assumes prior call to function
  131.     * checkAlias().  Specified drive# is 1-based.....
  132.     */
  133.     _iregs.h.bl = (char) drive_alias;
  134.     int21_44h(set_log_drivemap);
  135.     return _dos_error ? -1 : (int) _oregs.h.al;
  136. }
  137.  
  138. int IoctlBlock::getParams( struct DEVICEPARAMS *dpms )
  139. {
  140.     return block_ioctl( get_params, (void *) dpms );
  141. }
  142.  
  143. int IoctlBlock::setParams( struct DEVICEPARAMS *dpms )
  144. {
  145.     return block_ioctl( set_params, (void *) dpms );
  146. }
  147.  
  148. int IoctlBlock::readSectors( struct RWBLOCK *tpms )
  149. {
  150.     tpms->spfun = 0;
  151.     return block_ioctl( read_track, tpms );
  152. }
  153.  
  154. int IoctlBlock::writeSectors( struct RWBLOCK *tpms )
  155. {
  156.     tpms->spfun = 0;
  157.     return block_ioctl( write_track, tpms );
  158. }
  159.  
  160. int IoctlBlock::getAccessFlag(void)
  161. {
  162.    /* Return current state of media access flag...
  163.     */
  164.     struct SPECIALFUNC sp;
  165.     sp.spfunc = sp.acc_flag = 0;
  166.     block_ioctl( get_access_flag, (void *) &sp);
  167.     return (int) sp.acc_flag;
  168. }
  169.  
  170. int IoctlBlock::setAccessFlag(int flag)
  171. {
  172.    /* Set media access flag.  Access flag = 0
  173.     * if access to media is blocked (unformatted).
  174.     * Return new flag state..........
  175.     */
  176.     struct SPECIALFUNC sp;
  177.     sp.spfunc = 0;
  178.     sp.acc_flag = (char) flag;
  179.     block_ioctl( set_access_flag, (void *) &sp);
  180.     return getAccessFlag();
  181. }
  182.  
  183. int IoctlBlock::format_track( int spec,
  184.                               int head, int cyl   )
  185. {
  186.    /* Format (and verify) a disk track.
  187.     */
  188.     struct FVBLOCK fvp;
  189.     fvp.spfunc = spec;    //0=format, 1=check
  190.     fvp.num_tracks = 0;
  191.     fvp.disk_head = head;
  192.     fvp.disk_cylinder = cyl;
  193.     block_ioctl( format_and_verify, (void *) &fvp );
  194.     return (int) fvp.spfunc;
  195. }
  196.  
  197. int IoctlBlock::formatTrack( int head, int cyl )
  198. {
  199.     format_track( 0, head, cyl) ;
  200.     return _dos_error ? _oregs.x.ax : 0;
  201. }
  202.  
  203. int IoctlBlock::verifyTrack( int head, int cyl )
  204. {
  205.    /* Verify a disk track .... */
  206.     struct FVBLOCK fvp;
  207.     fvp.spfunc = fvp.num_tracks = 0;
  208.     fvp.disk_head = head;
  209.     fvp.disk_cylinder = cyl;
  210.     return block_ioctl( verify_track,
  211.                         (void *) &fvp );
  212. }
  213.  
  214. int IoctlBlock::checkFunction( block_cmd cmd )
  215. {
  216.    /* Check availability of a specified IOCTL function
  217.     * 'cmd' for the current drive ........
  218.     */
  219.     if( _dos.version < 0x0500  ||
  220.         !(_info & queryIoctl)  ||
  221.         cmd == set_access_flag ||
  222.         cmd == get_access_flag    )
  223.             return unknown;     //query not supported
  224.  
  225.     _iregs.x.bx = _drive;
  226.     _iregs.h.ch = 0x08;    //category = disk drive
  227.     _iregs.h.cl = (char) cmd;
  228.     int21_44h( query_ioctl_block );
  229.  
  230.     if( _oregs.x.cflag == 0 )
  231.         return is_supported;
  232.  
  233.     switch( _oregs.x.ax )    {
  234.         case 0x0001:    return invalid_function;
  235.         case 0x0005:    return access_denied;
  236.         case 0x000f:    return invalid_drive;
  237.         default:        return unknown;
  238.     }
  239. }
  240.  
  241. /* ----- End of File ------------------------------- */
  242.