home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / cdtst105.zip / readcd.cpp < prev    next >
C/C++ Source or Header  |  1999-01-30  |  6KB  |  232 lines

  1. /* CD drive functions (C) 1998-1999 Samuel Audet <guardia@cam.org> */
  2.  
  3. #define INCL_PM
  4. #define INCL_DOSDEVIOCTL
  5. #define INCL_DOS
  6. #include <os2.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stdio.h>
  10.  
  11. #include "miscsam.h"
  12. #include "pmsam.h"
  13. #include "readcd.h"
  14.  
  15. const char TAG[4] = {'C','D','0','1'};
  16.  
  17. CD_drive::~CD_drive()
  18. {
  19.    free(trackInfo);
  20.    if(opened) close();
  21. }
  22.  
  23. CD_drive::CD_drive()
  24. {
  25.    memset(this,0,sizeof(*this));
  26. }
  27.  
  28.  
  29. bool CD_drive::open(char *drive)
  30. {
  31.    ULONG ulAction;
  32.    ULONG rc;
  33.  
  34.    rc = DosOpen(drive, &hCDDrive, &ulAction, 0,
  35.                 FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
  36.                 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
  37.                 OPEN_FLAGS_DASD, NULL);
  38.  
  39.    if(rc)
  40.    {
  41.       updateError("DosOpen failed with return code %d opening drive %s",rc,drive);
  42.       return false;
  43.    }
  44.  
  45.    opened = true;
  46.    return true;
  47. }
  48.  
  49. bool CD_drive::close()
  50. {
  51.    ULONG rc;
  52.    rc = DosClose(hCDDrive);
  53.    opened = false;
  54.    if(rc)
  55.    {
  56.       updateError("DosClose failed with return code %d closing drive",rc);
  57.       return false;
  58.    }
  59.  
  60.    return true;
  61. }
  62.  
  63. bool CD_drive::readCDInfo()
  64. {
  65.    ULONG ulParamLen;
  66.    ULONG ulDataLen;
  67.    ULONG rc;
  68.    BOOL returnBool = FALSE;
  69.    char tag[4];
  70.  
  71.    memcpy(tag,TAG,4);
  72.  
  73.    rc = DosDevIOCtl(hCDDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
  74.                     tag, 4, &ulParamLen, &cdInfo,
  75.                     sizeof(cdInfo), &ulDataLen);
  76.    if(rc)
  77.       updateError("DosDevIOCtl failed with return code 0x%x reading CD info",rc);
  78.    else
  79.       returnBool = TRUE;
  80.  
  81.    return returnBool;
  82. }
  83.  
  84. bool CD_drive::readTrackInfo(char track, CDTRACKINFO *trackInfo2)
  85. {
  86.    ULONG ulParamLen;
  87.    ULONG ulDataLen;
  88.    ULONG rc;
  89.    BOOL returnBool = FALSE;
  90.  
  91.    CDAUDIOTRACKINFOPARAM trackParam;
  92.    CDAUDIOTRACKINFODATA  trackInfo[2];
  93.  
  94.    memcpy(trackParam.signature,TAG,4);
  95.  
  96.    trackParam.trackNum = track;
  97.    rc = DosDevIOCtl(hCDDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
  98.                     &trackParam, sizeof(trackParam),
  99.                     &ulParamLen, &trackInfo[0],
  100.                     sizeof(trackInfo[0]), &ulDataLen);
  101.    if(rc)
  102.       updateError("DosDevIOCtl failed with return code 0x%x reading track %d info",rc,track);
  103.    else
  104.    {
  105.       trackParam.trackNum = track+1;
  106.       rc = 0;
  107.       if(trackParam.trackNum <= cdInfo.lastTrack)
  108.       {
  109.          rc = DosDevIOCtl(hCDDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
  110.                           &trackParam, sizeof(trackParam),
  111.                           &ulParamLen, &trackInfo[1],
  112.                           sizeof(trackInfo[1]), &ulDataLen);
  113.  
  114.          if(rc)
  115.             updateError("DosDevIOCtl failed with return code 0x%x",rc);
  116.       }
  117.       else
  118.           trackInfo[1].address = cdInfo.leadOutAddress;
  119.  
  120.       if(!rc)
  121.       {
  122.          ULONG LBA[2];
  123.          MSF length;
  124.  
  125.          LBA[0] = getLBA(trackInfo[0].address);
  126.          LBA[1] = getLBA(trackInfo[1].address);
  127.  
  128.          /* -150 because we want length, not an address */
  129.          length = getMSF(LBA[1]-LBA[0]-150);
  130.  
  131.          trackInfo2->start = trackInfo[0].address;
  132.          trackInfo2->end = trackInfo[1].address;
  133.          trackInfo2->length = length;
  134.          trackInfo2->size = (LBA[1]-LBA[0])*2352;
  135.          trackInfo2->data = (trackInfo[0].info & 0x40) ? TRUE : FALSE;
  136.          trackInfo2->channels = (trackInfo[0].info & 0x80) ? 4 : 2;
  137.          trackInfo2->number = track;
  138.  
  139.          returnBool = TRUE;
  140.       }
  141.    }
  142.    return returnBool;
  143. }
  144.  
  145.  
  146. bool CD_drive::fillTrackInfo()
  147. {
  148.    int i,e;
  149.  
  150.    trackInfo = (CDTRACKINFO *) realloc(trackInfo, getCount() * sizeof(*trackInfo));
  151.  
  152.    e = 0;
  153.    for(i = cdInfo.firstTrack; i <= cdInfo.lastTrack; i++)
  154.       if(!readTrackInfo(i, &trackInfo[e++]))
  155.          return false;
  156.  
  157.    return true;
  158. }
  159.  
  160.  
  161. bool CD_drive::play(char track)
  162. {
  163.    ULONG ulParamLen;
  164.    ULONG ulDataLen;
  165.    ULONG rc;
  166.    BOOL returnBool = FALSE;
  167.    CDPLAYAUDIOPARAM playParam;
  168.    CDTRACKINFO trackInfo;
  169.  
  170.    memcpy(playParam.signature,TAG,4);
  171.    playParam.addressingMode = MODE_MSF;
  172.  
  173.    if(!readTrackInfo(track, &trackInfo))
  174.        return FALSE;
  175.    playParam.start = trackInfo.start;
  176.    playParam.end = trackInfo.end;
  177.  
  178.    rc = DosDevIOCtl(hCDDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_PLAYAUDIO,
  179.                     &playParam, sizeof(playParam),
  180.                     &ulParamLen, NULL,
  181.                     0, &ulDataLen);
  182.    if(rc)
  183.       updateError("DosDevIOCtl failed with return code 0x%x playing track %d",rc,track);
  184.    else
  185.       returnBool = TRUE;
  186.  
  187.    return returnBool;
  188. }
  189.  
  190. bool CD_drive::stop()
  191. {
  192.    ULONG ulParamLen;
  193.    ULONG ulDataLen;
  194.    ULONG rc;
  195.    BOOL returnBool = FALSE;
  196.    char tag[4];
  197.  
  198.    memcpy(tag,TAG,4);
  199.  
  200.    rc = DosDevIOCtl(hCDDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_STOPAUDIO,
  201.                     tag, 4, &ulParamLen, NULL, 0, &ulDataLen);
  202.    if(rc)
  203.       updateError("DosDevIOCtl failed with return code 0x%x stopping playing.",rc);
  204.    else
  205.       returnBool = TRUE;
  206.    return returnBool;
  207. }
  208.  
  209. bool CD_drive::readSectors(CDREADLONGDATA data[], ULONG number, ULONG start)
  210. {
  211.    ULONG ulParamLen;
  212.    ULONG ulDataLen;
  213.    ULONG rc;
  214.    BOOL returnBool = FALSE;
  215.    CDREADLONGPARAM readParam = {0};
  216.  
  217.    memcpy(readParam.signature,TAG,4);
  218.    readParam.addressingMode = MODE_LBA;
  219.    readParam.numberSectors = number;
  220.    readParam.startSector = start;
  221.  
  222.    rc = DosDevIOCtl(hCDDrive, IOCTL_CDROMDISK, CDROMDISK_READLONG,
  223.                     &readParam, sizeof(readParam), &ulParamLen,
  224.                     data, sizeof(*data)*number, &ulDataLen);
  225.  
  226.    if(rc)
  227.       updateError("DosDevIOCtl failed with return code 0x%x reading sector %d-%d",rc,start,start+number-1);
  228.    else
  229.       returnBool = TRUE;
  230.    return returnBool;
  231. }
  232.