home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is (C) Chris Wohlgemuth 1999
- */
- /*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING. If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #define INCL_DOS
- #define INCL_DOSDEVICES
- #define INCL_DOSDEVIOCTL
- #define INCL_DOSFILEMGR
-
- #include <os2.h>
- #include <stdio.h>
- #include <string.h>
- #include "cddb.h"
-
-
- #pragma pack(1)
-
- typedef struct{
- UCHAR ucFirstTrack;
- UCHAR ucLastTrack;
- ULONG ulLeadOut;
- }CDINFO;
-
- typedef struct{
- ULONG ulLeadOut;
- UCHAR ucFirstTrack;
- UCHAR ucLastTrack;
- }CDINFO2;
-
- typedef struct
- {
- ULONG ulTrackAddress;
- UCHAR ucTCInfo;
- }TRACKINFO;
-
- typedef struct
- {
- UCHAR signature[4];
- UCHAR ucTrackNum;
- }TINFOPARAM;
-
- typedef struct
- {
- UCHAR ucFrames;
- UCHAR ucSeconds;
- UCHAR ucMinutes;
- UCHAR ucNotUsed;
- }MSF;
-
- typedef struct
- {
- UCHAR signature[4];
- UCHAR ucAddressMode;
- UCHAR ucStartSector[4];
- UCHAR ucEndSector[4];
- }PLAYPARAM;
-
- #pragma pack()
-
-
- HFILE extern openDrive(char* drive);
- void extern closeDrive(HFILE hfDrive);
- LONG extern CDCalculateSize(MSF* msf1,MSF* msf2);
- /******************************************/
- /* Result:
- 0: Error
- -1: CD is Data Disk
- other: # Audio tracks */
- /******************************************/
- int extern CDQueryAudioCDTracks(HFILE hfDrive);
- ULONG extern CDQueryUPC(UCHAR* ucUPC, char * drive);
- /* Returns the size in bytes of a track on drive 'drive' (e.g. O:) */
- LONG extern CDQueryTrackSize(ULONG numTrack, char * drive);
- BOOL CDPlayTrack(ULONG numTrack, char * drive);
- BOOL extern CDStop(char * drive);
- LONG extern queryFreeDriveSpace(ULONG diskNum) ;
- /**************************************************************/
- /* This funktion returns the CD-Drives in the system */
- /* */
- /* iNumCD (output): # of CD-Drives */
- /* cFirstDrive (output): first cd-Drive letter */
- /* returns TRUE: We have cd-drives */
- /**************************************************************/
- BOOL extern CDQueryCDDrives(int *iNumCD, char * cFirstDrive);
- /* Returns a CDDB disc-ID for quering the database */
- /* Returns 0 if error. */
- LONG extern CDDBDiscID(char * drive, CDDBINFO * cddbInfo);
-
-
- LONG extern CDCalculateSize(MSF* msf1,MSF* msf2)
- {
- return ((msf2->ucMinutes*60+msf2->ucSeconds)*75+msf2->ucFrames)*2352-
- ((msf1->ucMinutes*60+msf1->ucSeconds)*75+msf1->ucFrames)*2352;
- }
-
- LONG extern CDCalculateSector2(MSF* msf1)
- {
- return ((msf1->ucMinutes*60+msf1->ucSeconds));
- }
-
- LONG extern CDCalculateSector(MSF* msf1)
- {
- return ((msf1->ucMinutes*60+msf1->ucSeconds)*75+msf1->ucFrames);
- }
-
-
- /****************************************/
- /* Input: drive (e.g. o:) */
- /****************************************/
- HFILE extern openDrive(char* drive)
- {
- HFILE hfDrive = 0;
- ULONG ulAction;
- ULONG rc;
-
- rc = DosOpen(drive, &hfDrive, &ulAction, 0,
- FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
- OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
- OPEN_FLAGS_DASD|OPEN_FLAGS_FAIL_ON_ERROR, NULL);
-
- if(rc)
- return NULL;//Error
-
- return hfDrive;
- }
-
- void extern closeDrive(HFILE hfDrive)
- {
- DosClose(hfDrive);
- }
-
- /******************************************/
- /* Result:
- 0: Error
- -1: CD is Data Disk
- other: # Audio tracks */
- /******************************************/
- int extern CDQueryAudioCDTracks(HFILE hfDrive)
- {
- ULONG ulParamLen;
- ULONG ulDataLen;
- ULONG rc;
- CDINFO cdInfo;
- TINFOPARAM tip;
- TRACKINFO trackInfo;
-
- ulDataLen=sizeof(cdInfo);
- ulParamLen=4;
-
- if(!hfDrive)
- return 0;
-
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
- "CD01", 4, &ulParamLen, &cdInfo,
- sizeof(cdInfo), &ulDataLen);
-
- if(rc) {
- return 0;//Error
- }
-
- ulDataLen=sizeof(trackInfo);
- ulParamLen=sizeof(TINFOPARAM);
- tip.signature[0]='C';
- tip.signature[1]='D';
- tip.signature[2]='0';
- tip.signature[3]='1';
- tip.ucTrackNum=1;
-
- /* We have a disc. Check if it's audio */
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
- &tip, sizeof(tip), &ulParamLen, &trackInfo,
- sizeof(trackInfo), &ulDataLen);
-
- if(rc) {
- return 0;//Error
- }
-
- if(trackInfo.ucTCInfo & 0x40) {
- return -1;//It's a data track
- }
-
- return cdInfo.ucLastTrack-cdInfo.ucFirstTrack+1;
-
- }
-
- /* Returns the UPC of CD in drive 'drive' (e.g. O:) */
- /* Size of ucUCP must be 10! */
- ULONG extern CDQueryUPC(UCHAR* ucUPC, char * drive)
- {
- HFILE hfDrive;
- ULONG ulParamLen;
- ULONG ulDataLen;
- ULONG rc;
- char setup[100];
-
- hfDrive=openDrive(drive);
- if(!hfDrive) return -1;
-
- do {
- DosBeep(1000,200);
- /* Get UPC info */
- ulDataLen=10;
- ulParamLen=4;
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMDISK, CDROMDISK_GETUPC,
- "CD01", 4, &ulParamLen, ucUPC,
- 10, &ulDataLen);
- sprintf(setup,"rc is: %x",rc);
-
- WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
- setup, "GET_UPC", 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE );
-
- if(rc)
- break;
- DosBeep(2000,200);
- closeDrive(hfDrive);
- return 0;
-
- }while(TRUE);
-
- /* No error */
- closeDrive(hfDrive);
- return -1;
- }
-
-
- /* Returns the size in bytes of a track on drive 'drive' (e.g. O:) */
- LONG extern CDQueryTrackSize(ULONG numTrack, char * drive)
- {
- HFILE hfDrive;
- ULONG ulParamLen;
- ULONG ulDataLen;
- ULONG rc;
- CDINFO cdInfo;
- TINFOPARAM tip;
- TRACKINFO trackInfo[2];
-
- hfDrive=openDrive(drive);
- if(!hfDrive) return 0;
-
- do {
- /* Get cd info */
- ulDataLen=sizeof(cdInfo);
- ulParamLen=4;
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
- "CD01", 4, &ulParamLen, &cdInfo,
- sizeof(cdInfo), &ulDataLen);
- if(rc)
- break;//Error
- ulDataLen=sizeof(trackInfo);
- ulParamLen=sizeof(TINFOPARAM);
- tip.signature[0]='C';
- tip.signature[1]='D';
- tip.signature[2]='0';
- tip.signature[3]='1';
- /* Get information about our track */
- tip.ucTrackNum=numTrack;
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
- &tip, sizeof(tip), &ulParamLen, &trackInfo[0],
- sizeof(trackInfo[0]), &ulDataLen);
- if(rc)
- break;//Error
-
- /* Get information about next track */
- tip.ucTrackNum=numTrack+1;
- if(tip.ucTrackNum<=cdInfo.ucLastTrack) {
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
- &tip, sizeof(tip), &ulParamLen, &trackInfo[1],
- sizeof(trackInfo[1]), &ulDataLen);
- if(rc)
- break;//Error
- }
- else {
- trackInfo[1].ulTrackAddress=cdInfo.ulLeadOut;
- /* #pragma pack(1) eingebaut */
-
- /*BYTE *cdInfoBytes;
- cdInfoBytes=(BYTE*)&cdInfo;
- cdInfoBytes+=2;
- trackInfo[1].ulTrackAddress=*((ULONG*)cdInfoBytes);*/
- }
- closeDrive(hfDrive);
- return CDCalculateSize((MSF*)&trackInfo[0].ulTrackAddress, (MSF*)&trackInfo[1].ulTrackAddress);
- }while(TRUE);
- closeDrive(hfDrive);
- return 0;
- }
-
- /* Returns sector info of track #numTrack */
- /* Starting with track 0 */
- LONG extern CDQueryTrackStartSector(ULONG numTrack, HFILE hfDrive)
- {
-
- ULONG ulParamLen;
- ULONG ulDataLen;
- ULONG rc;
- CDINFO cdInfo;
- TINFOPARAM tip;
- TRACKINFO trackInfo[2];
-
- do {
- /* Get cd info */
- ulDataLen=sizeof(cdInfo);
- ulParamLen=4;
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
- "CD01", 4, &ulParamLen, &cdInfo,
- sizeof(cdInfo), &ulDataLen);
- if(rc)
- break;//Error
-
- ulDataLen=sizeof(trackInfo);
- ulParamLen=sizeof(TINFOPARAM);
- tip.signature[0]='C';
- tip.signature[1]='D';
- tip.signature[2]='0';
- tip.signature[3]='1';
- /* Get information about our track */
- tip.ucTrackNum=numTrack+1;
- if(tip.ucTrackNum<=cdInfo.ucLastTrack) {
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
- &tip, sizeof(tip), &ulParamLen, &trackInfo[0],
- sizeof(trackInfo[0]), &ulDataLen);
- if(rc)
- break;//Error
- }else
- return CDCalculateSector((MSF*)&cdInfo.ulLeadOut);
-
-
- return CDCalculateSector((MSF*)&trackInfo[0].ulTrackAddress);
-
- }while(TRUE);
-
- /* error */
- printf("ERROR!!!!!!!!!\n");
- return 0;
- }
-
- /*****************************************/
- /* */
- /* Plays track #numTrack on */
- /* CD-Drive 'drive' */
- /* */
- /* Returns TRUE if successful */
- /* */
- /*****************************************/
- BOOL CDPlayTrack(ULONG numTrack, char * drive)
- {
- HFILE hfDrive;
- ULONG ulParamLen;
- ULONG ulDataLen;
- ULONG rc;
- CDINFO cdInfo;
- TINFOPARAM tip;
- TRACKINFO trackInfo[2];
- PLAYPARAM playParam;
-
- hfDrive=openDrive(drive);
- if(!hfDrive) return FALSE;
- do {
- /* Get cd info */
- ulDataLen=sizeof(cdInfo);
- ulParamLen=4;
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
- "CD01", 4, &ulParamLen, &cdInfo,
- sizeof(cdInfo), &ulDataLen);
- if(rc)
- break;//Error
- ulDataLen=sizeof(trackInfo);
- ulParamLen=sizeof(TINFOPARAM);
- tip.signature[0]='C';
- tip.signature[1]='D';
- tip.signature[2]='0';
- tip.signature[3]='1';
- /* Get information about our track */
- tip.ucTrackNum=numTrack;
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
- &tip, sizeof(tip), &ulParamLen, &trackInfo[0],
- sizeof(trackInfo[0]), &ulDataLen);
- if(rc)
- break;//Error
- /* Get information about next track */
- tip.ucTrackNum=numTrack+1;
- if(tip.ucTrackNum<=cdInfo.ucLastTrack) {
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
- &tip, sizeof(tip), &ulParamLen, &trackInfo[1],
- sizeof(trackInfo[1]), &ulDataLen);
- if(rc)
- break;//Error
- }
- else {
- /* The following does not work on my system. Compilerbug ?
- trackInfo[1].ulTrackAddress=cdInfo.ulLeadOut; */
- BYTE *cdInfoBytes;
- cdInfoBytes=(BYTE*)&cdInfo;
- cdInfoBytes+=2;
- trackInfo[1].ulTrackAddress=*((ULONG*)cdInfoBytes);
- }
-
- /* Play the Track... */
- ulParamLen=sizeof(PLAYPARAM);
- playParam.signature[0]='C';
- playParam.signature[1]='D';
- playParam.signature[2]='0';
- playParam.signature[3]='1';
- playParam.ucAddressMode=01;
- memcpy(&playParam.ucStartSector,&trackInfo[0].ulTrackAddress,4);
- memcpy(&playParam.ucEndSector,&trackInfo[1].ulTrackAddress,4);
-
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_PLAYAUDIO,
- &playParam, sizeof(playParam), &ulParamLen,0,
- 0, 0);
- if(rc)
- break;
- closeDrive(hfDrive);
- return TRUE;
- }while(TRUE);
- closeDrive(hfDrive);
- return FALSE;
- }
-
- BOOL extern CDStop(char * drive)
- {
- HFILE hfDrive;
- ULONG ulParamLen;
- ULONG rc;
-
- hfDrive=openDrive(drive);
- if(!hfDrive) return FALSE;
-
- do {
- /* Stop CD */
- ulParamLen=4;
- rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_STOPAUDIO,
- "CD01", 4, &ulParamLen,0,
- 0, 0);
- if(rc)
- break;//Error
- closeDrive(hfDrive);
- return TRUE;
- }while(TRUE);
- closeDrive(hfDrive);
- return FALSE;
- }
-
- LONG extern queryFreeDriveSpace(ULONG diskNum)
- {
- FSALLOCATE infoBuf;
-
- if(DosQueryFSInfo(diskNum,FSIL_ALLOC,&infoBuf,sizeof(infoBuf)))
- return 0;
-
- return infoBuf.cUnitAvail*infoBuf.cbSector*infoBuf.cSectorUnit;
- }
-
- /**************************************************************/
- /* */
- /* This funktion returns the CD-Drives in the system */
- /* */
- /* iNumCD (output): # of CD-Drives */
- /* cFirstDrive (output): first cd-Drive letter */
- /* returns TRUE: We have cd-drives */
- /* */
- /**************************************************************/
- BOOL extern CDQueryCDDrives(int *iNumCD, char * cFirstDrive)
- {
- HFILE hfDevice;
- ULONG ulAction;
- ULONG ulLen;
- static char cFirst=0;
- static int iNumCDLocal=0;
- static BOOL haveCD=FALSE;
- static BOOL done=FALSE;
- struct
- {
- USHORT usCountCD;
- USHORT usFirstCD;
- } CDInfo;
-
- if(!done){
- ulLen = sizeof(CDInfo);
- if(!DosOpen("\\DEV\\CD-ROM2$", &hfDevice, &ulAction, 0,
- FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
- OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL))
- {
- if(!DosDevIOCtl(hfDevice, 0x82, 0x60, NULL, 0, NULL, &CDInfo, ulLen, &ulLen))
- {
- if(CDInfo.usCountCD) {
- haveCD=TRUE;
- iNumCDLocal=CDInfo.usCountCD;
- cFirst='A'+ CDInfo.usFirstCD;
- }
- }
- DosClose(hfDevice);
- }
- done=TRUE;
- }
- *iNumCD=iNumCDLocal;
- *cFirstDrive=cFirst;
- return haveCD;
- }
-
-
- /*****************************************/
- /* */
- /* Query if a CD is avaiable in */
- /* CD-Drive 'drive' */
- /* */
- /* Input: drive num (starting with 0) */
- /* Returns TRUE if media is avaiable */
- /* */
- /*****************************************/
- BOOL CDQueryMedia(ULONG driveNum)
- {
- return FALSE;
- }
-
-
- int cddb_sum(int n)
- {
- int ret;
- //printf("n: %d ",n);
- for (ret = 0; n > 0; n /= 10) {
- ret += (n % 10);
- }
- //printf("ret: %d ",ret);
- return ret;
- }
-
- /* Returns a CDDB disc-ID for quering the database */
- /* Returns 0 if error. */
- LONG extern CDDBDiscID(char * drive, CDDBINFO * cddbInfo)
- {
- int numTracks,a;
- HFILE hfDrive;
- LONG sum;
- int t;
-
- do {
- hfDrive=openDrive(drive);
- if(!hfDrive)
- return 0;
-
- numTracks=CDQueryAudioCDTracks(hfDrive);
- if(numTracks==0||numTracks==-1)
- break;
- cddbInfo->numTracks=numTracks;
-
- sum=0;
- /* Calculating the id */
- for(a=0;a<numTracks;a++) {
- sum+= cddb_sum(CDQueryTrackStartSector(a, hfDrive)/75 );
- //printf("Track%d: %d\n",a,CDQueryTrackStartSector(a, hfDrive));
- cddbInfo->startSector[a]=CDQueryTrackStartSector(a, hfDrive);
- }
- t=CDQueryTrackStartSector(a, hfDrive)/75-CDQueryTrackStartSector(0, hfDrive)/75;
- /*printf("(a-1): %d 0: %d t: %d\n",CDQueryTrackStartSector(a, hfDrive),
- CDQueryTrackStartSector(0, hfDrive),t);*/
- //printf("discid: %x\n",((sum % 0xff) << 24 | (t << 8) | numTracks));
- //printf("Disclength: %d",(CDQueryTrackStartSector(a, hfDrive)-CDQueryTrackStartSector(0, hfDrive))/75);
- cddbInfo->discLength=(CDQueryTrackStartSector(a, hfDrive)-CDQueryTrackStartSector(0, hfDrive))/75;
- cddbInfo->discid=(sum % 0xff) << 24 | (t << 8) | numTracks;
- closeDrive(hfDrive);
- return cddbInfo->discid;
- }while(TRUE);
-
- /* error */
- closeDrive(hfDrive);
- return 0;
- }
-
-
-
-