source: branches/v2.9/mediafolder/c/helper/cd.cpp

Last change on this file was 2, checked in by stevenhl, 8 years ago

Import sources from cwmm-full.zip dated 2005-03-21

File size: 16.6 KB
Line 
1/*
2 * This file is (C) Chris Wohlgemuth 1999
3 */
4/*
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#define INCL_DOS
21#define INCL_DOSDEVICES
22#define INCL_DOSDEVIOCTL
23#define INCL_DOSFILEMGR
24
25#include <os2.h>
26#include <stdio.h>
27#include <string.h>
28#include "cddb.h"
29
30
31#pragma pack(1)
32
33typedef struct{
34 UCHAR ucFirstTrack;
35 UCHAR ucLastTrack;
36 ULONG ulLeadOut;
37}CDINFO;
38
39typedef struct{
40 ULONG ulLeadOut;
41 UCHAR ucFirstTrack;
42 UCHAR ucLastTrack;
43}CDINFO2;
44
45typedef struct
46{
47 ULONG ulTrackAddress;
48 UCHAR ucTCInfo;
49}TRACKINFO;
50
51typedef struct
52{
53 UCHAR signature[4];
54 UCHAR ucTrackNum;
55}TINFOPARAM;
56
57typedef struct
58{
59 UCHAR ucFrames;
60 UCHAR ucSeconds;
61 UCHAR ucMinutes;
62 UCHAR ucNotUsed;
63}MSF;
64
65typedef struct
66{
67 UCHAR signature[4];
68 UCHAR ucAddressMode;
69 UCHAR ucStartSector[4];
70 UCHAR ucEndSector[4];
71}PLAYPARAM;
72
73#pragma pack()
74
75
76HFILE extern openDrive(char* drive);
77void extern closeDrive(HFILE hfDrive);
78LONG extern CDCalculateSize(MSF* msf1,MSF* msf2);
79/******************************************/
80/* Result:
81 0: Error
82 -1: CD is Data Disk
83 other: # Audio tracks */
84/******************************************/
85int extern CDQueryAudioCDTracks(HFILE hfDrive);
86ULONG extern CDQueryUPC(UCHAR* ucUPC, char * drive);
87/* Returns the size in bytes of a track on drive 'drive' (e.g. O:) */
88LONG extern CDQueryTrackSize(ULONG numTrack, char * drive);
89BOOL CDPlayTrack(ULONG numTrack, char * drive);
90BOOL extern CDStop(char * drive);
91LONG extern queryFreeDriveSpace(ULONG diskNum) ;
92/**************************************************************/
93/* This funktion returns the CD-Drives in the system */
94/* */
95/* iNumCD (output): # of CD-Drives */
96/* cFirstDrive (output): first cd-Drive letter */
97/* returns TRUE: We have cd-drives */
98/**************************************************************/
99BOOL extern CDQueryCDDrives(int *iNumCD, char * cFirstDrive);
100/* Returns a CDDB disc-ID for quering the database */
101/* Returns 0 if error. */
102LONG extern CDDBDiscID(char * drive, CDDBINFO * cddbInfo);
103
104
105LONG extern CDCalculateSize(MSF* msf1,MSF* msf2)
106{
107 return ((msf2->ucMinutes*60+msf2->ucSeconds)*75+msf2->ucFrames)*2352-
108 ((msf1->ucMinutes*60+msf1->ucSeconds)*75+msf1->ucFrames)*2352;
109}
110
111LONG extern CDCalculateSector2(MSF* msf1)
112{
113 return ((msf1->ucMinutes*60+msf1->ucSeconds));
114}
115
116LONG extern CDCalculateSector(MSF* msf1)
117{
118 return ((msf1->ucMinutes*60+msf1->ucSeconds)*75+msf1->ucFrames);
119}
120
121
122/****************************************/
123/* Input: drive (e.g. o:) */
124/****************************************/
125HFILE extern openDrive(char* drive)
126{
127 HFILE hfDrive = 0;
128 ULONG ulAction;
129 ULONG rc;
130 //char text[100];
131
132 rc = DosOpen(drive, &hfDrive, &ulAction, 0,
133 FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
134 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
135 OPEN_FLAGS_DASD|OPEN_FLAGS_FAIL_ON_ERROR, NULL);
136#if 0
137sprintf(text, "%s %d %d", drive, rc, hfDrive);
138WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, text,"", 1234,MB_MOVEABLE);
139#endif
140 if(rc)
141 return NULLHANDLE;//Error
142
143 return hfDrive;
144}
145
146void extern closeDrive(HFILE hfDrive)
147{
148 DosClose(hfDrive);
149}
150
151/******************************************/
152/* Result:
153 0: Error
154 -1: CD is Data Disk
155 other: # Audio tracks */
156/******************************************/
157int extern CDQueryAudioCDTracks(HFILE hfDrive)
158{
159 ULONG ulParamLen;
160 ULONG ulDataLen;
161 ULONG rc;
162 CDINFO cdInfo;
163 TINFOPARAM tip;
164 TRACKINFO trackInfo;
165 //char text[100];
166
167 ulDataLen=sizeof(cdInfo);
168 ulParamLen=4;
169
170 if(!hfDrive)
171 return 0;
172
173 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
174 "CD01", 4, &ulParamLen, &cdInfo,
175 sizeof(cdInfo), &ulDataLen);
176#if 0
177DosBeep(100, 300);sprintf(text, "%d %d", rc, hfDrive);
178WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, text,"", 1234,MB_MOVEABLE);
179#endif
180 if(rc) {
181 return 0;//Error
182 }
183
184 ulDataLen=sizeof(trackInfo);
185 ulParamLen=sizeof(TINFOPARAM);
186 tip.signature[0]='C';
187 tip.signature[1]='D';
188 tip.signature[2]='0';
189 tip.signature[3]='1';
190 tip.ucTrackNum=1;
191
192 /* We have a disc. Check if it's audio */
193 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
194 &tip, sizeof(tip), &ulParamLen, &trackInfo,
195 sizeof(trackInfo), &ulDataLen);
196
197 if(rc) {
198 return 0;//Error
199 }
200
201 if(trackInfo.ucTCInfo & 0x40) {
202 return -1;//It's a data track
203 }
204
205 return cdInfo.ucLastTrack-cdInfo.ucFirstTrack+1;
206
207}
208
209/* Returns the UPC of CD in drive 'drive' (e.g. O:) */
210/* Size of ucUCP must be 10! */
211ULONG extern CDQueryUPC(UCHAR* ucUPC, char * drive)
212{
213 HFILE hfDrive;
214 ULONG ulParamLen;
215 ULONG ulDataLen;
216 ULONG rc;
217 char setup[100];
218
219 hfDrive=openDrive(drive);
220 if(!hfDrive) return -1;
221
222 do {
223 DosBeep(1000,200);
224 /* Get UPC info */
225 ulDataLen=10;
226 ulParamLen=4;
227 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMDISK, CDROMDISK_GETUPC,
228 "CD01", 4, &ulParamLen, ucUPC,
229 10, &ulDataLen);
230 sprintf(setup,"rc is: %x",rc);
231
232 WinMessageBox( HWND_DESKTOP, HWND_DESKTOP,
233 setup, "GET_UPC", 0UL, MB_OK | MB_ICONEXCLAMATION|MB_MOVEABLE );
234
235 if(rc)
236 break;
237 DosBeep(2000,200);
238 closeDrive(hfDrive);
239 return 0;
240
241 }while(TRUE);
242
243 /* No error */
244 closeDrive(hfDrive);
245 return -1;
246}
247
248
249/* Returns the size in bytes of a track on drive 'drive' (e.g. O:) */
250/* The track num starts with 1 */
251LONG extern CDQueryTrackSize(ULONG numTrack, char * drive)
252{
253 HFILE hfDrive;
254 ULONG ulParamLen;
255 ULONG ulDataLen;
256 ULONG rc;
257 CDINFO cdInfo;
258 TINFOPARAM tip;
259 TRACKINFO trackInfo[2];
260
261 hfDrive=openDrive(drive);
262 if(!hfDrive) return 0;
263
264 do {
265 /* Get cd info */
266 ulDataLen=sizeof(cdInfo);
267 ulParamLen=4;
268 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
269 "CD01", 4, &ulParamLen, &cdInfo,
270 sizeof(cdInfo), &ulDataLen);
271 if(rc)
272 break;//Error
273 ulDataLen=sizeof(trackInfo);
274 ulParamLen=sizeof(TINFOPARAM);
275 tip.signature[0]='C';
276 tip.signature[1]='D';
277 tip.signature[2]='0';
278 tip.signature[3]='1';
279 /* Get information about our track */
280 tip.ucTrackNum=numTrack;
281 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
282 &tip, sizeof(tip), &ulParamLen, &trackInfo[0],
283 sizeof(trackInfo[0]), &ulDataLen);
284 if(rc)
285 break;//Error
286
287 /* Get information about next track */
288 tip.ucTrackNum=numTrack+1;
289 if(tip.ucTrackNum<=cdInfo.ucLastTrack) {
290 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
291 &tip, sizeof(tip), &ulParamLen, &trackInfo[1],
292 sizeof(trackInfo[1]), &ulDataLen);
293 if(rc)
294 break;//Error
295 }
296 else {
297 trackInfo[1].ulTrackAddress=cdInfo.ulLeadOut;
298 /* #pragma pack(1) eingebaut */
299
300 /*BYTE *cdInfoBytes;
301 cdInfoBytes=(BYTE*)&cdInfo;
302 cdInfoBytes+=2;
303 trackInfo[1].ulTrackAddress=*((ULONG*)cdInfoBytes);*/
304 }
305 closeDrive(hfDrive);
306 return CDCalculateSize((MSF*)&trackInfo[0].ulTrackAddress, (MSF*)&trackInfo[1].ulTrackAddress);
307 }while(TRUE);
308 closeDrive(hfDrive);
309 return 0;
310}
311
312/* Returns the size in bytes of a track on drive 'drive' (e.g. O:) */
313/* The track num starts with 1 */
314LONG extern CDQueryTrackSecs(ULONG numTrack, char * drive)
315{
316 LONG lBytes;
317 if((lBytes=CDQueryTrackSize( numTrack, drive))!=0)
318 {
319 return lBytes/176400;
320 }
321 return 0;
322}
323
324/* Returns sector info of track #numTrack */
325/* Starting with track 0 */
326LONG extern CDQueryTrackStartSector(ULONG numTrack, HFILE hfDrive)
327{
328
329 ULONG ulParamLen;
330 ULONG ulDataLen;
331 ULONG rc;
332 CDINFO cdInfo;
333 TINFOPARAM tip;
334 TRACKINFO trackInfo[2];
335
336 do {
337 /* Get cd info */
338 ulDataLen=sizeof(cdInfo);
339 ulParamLen=4;
340 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
341 "CD01", 4, &ulParamLen, &cdInfo,
342 sizeof(cdInfo), &ulDataLen);
343 if(rc)
344 break;//Error
345
346 ulDataLen=sizeof(trackInfo);
347 ulParamLen=sizeof(TINFOPARAM);
348 tip.signature[0]='C';
349 tip.signature[1]='D';
350 tip.signature[2]='0';
351 tip.signature[3]='1';
352 /* Get information about our track */
353 tip.ucTrackNum=numTrack+1;
354 if(tip.ucTrackNum<=cdInfo.ucLastTrack) {
355 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
356 &tip, sizeof(tip), &ulParamLen, &trackInfo[0],
357 sizeof(trackInfo[0]), &ulDataLen);
358 if(rc)
359 break;//Error
360 }else
361 return CDCalculateSector((MSF*)&cdInfo.ulLeadOut);
362
363
364 return CDCalculateSector((MSF*)&trackInfo[0].ulTrackAddress);
365
366 }while(TRUE);
367
368 /* error */
369 printf("ERROR!!!!!!!!!\n");
370 return 0;
371}
372
373/*****************************************/
374/* */
375/* Plays track #numTrack on */
376/* CD-Drive 'drive' */
377/* */
378/* Returns TRUE if successful */
379/* */
380/*****************************************/
381BOOL CDPlayTrack(ULONG numTrack, char * drive)
382{
383 HFILE hfDrive;
384 ULONG ulParamLen;
385 ULONG ulDataLen;
386 ULONG rc;
387 CDINFO cdInfo;
388 TINFOPARAM tip;
389 TRACKINFO trackInfo[2];
390 PLAYPARAM playParam;
391
392 hfDrive=openDrive(drive);
393 if(!hfDrive) return FALSE;
394 do {
395 /* Get cd info */
396 ulDataLen=sizeof(cdInfo);
397 ulParamLen=4;
398 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
399 "CD01", 4, &ulParamLen, &cdInfo,
400 sizeof(cdInfo), &ulDataLen);
401 if(rc)
402 break;//Error
403 ulDataLen=sizeof(trackInfo);
404 ulParamLen=sizeof(TINFOPARAM);
405 tip.signature[0]='C';
406 tip.signature[1]='D';
407 tip.signature[2]='0';
408 tip.signature[3]='1';
409 /* Get information about our track */
410 tip.ucTrackNum=numTrack;
411 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
412 &tip, sizeof(tip), &ulParamLen, &trackInfo[0],
413 sizeof(trackInfo[0]), &ulDataLen);
414 if(rc)
415 break;//Error
416 /* Get information about next track */
417 tip.ucTrackNum=numTrack+1;
418 if(tip.ucTrackNum<=cdInfo.ucLastTrack) {
419 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
420 &tip, sizeof(tip), &ulParamLen, &trackInfo[1],
421 sizeof(trackInfo[1]), &ulDataLen);
422 if(rc)
423 break;//Error
424 }
425 else {
426 /* The following does not work on my system. Compilerbug ?
427 trackInfo[1].ulTrackAddress=cdInfo.ulLeadOut; */
428 BYTE *cdInfoBytes;
429 cdInfoBytes=(BYTE*)&cdInfo;
430 cdInfoBytes+=2;
431 trackInfo[1].ulTrackAddress=*((ULONG*)cdInfoBytes);
432 }
433
434 /* Play the Track... */
435 ulParamLen=sizeof(PLAYPARAM);
436 playParam.signature[0]='C';
437 playParam.signature[1]='D';
438 playParam.signature[2]='0';
439 playParam.signature[3]='1';
440 playParam.ucAddressMode=01;
441 memcpy(&playParam.ucStartSector,&trackInfo[0].ulTrackAddress,4);
442 memcpy(&playParam.ucEndSector,&trackInfo[1].ulTrackAddress,4);
443
444 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_PLAYAUDIO,
445 &playParam, sizeof(playParam), &ulParamLen,0,
446 0, 0);
447 if(rc)
448 break;
449 closeDrive(hfDrive);
450 return TRUE;
451 }while(TRUE);
452 closeDrive(hfDrive);
453 return FALSE;
454}
455
456BOOL extern CDStop(char * drive)
457{
458 HFILE hfDrive;
459 ULONG ulParamLen;
460 ULONG rc;
461
462 hfDrive=openDrive(drive);
463 if(!hfDrive) return FALSE;
464
465 do {
466 /* Stop CD */
467 ulParamLen=4;
468 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_STOPAUDIO,
469 "CD01", 4, &ulParamLen,0,
470 0, 0);
471 if(rc)
472 break;//Error
473 closeDrive(hfDrive);
474 return TRUE;
475 }while(TRUE);
476 closeDrive(hfDrive);
477 return FALSE;
478}
479
480LONG extern queryFreeDriveSpace(ULONG diskNum)
481{
482 FSALLOCATE infoBuf;
483
484 if(DosQueryFSInfo(diskNum,FSIL_ALLOC,&infoBuf,sizeof(infoBuf)))
485 return 0;
486
487 return infoBuf.cUnitAvail*infoBuf.cbSector*infoBuf.cSectorUnit;
488}
489
490/**************************************************************/
491/* */
492/* This funktion returns the CD-Drives in the system */
493/* */
494/* iNumCD (output): # of CD-Drives */
495/* cFirstDrive (output): first cd-Drive letter */
496/* returns TRUE: We have cd-drives */
497/* */
498/**************************************************************/
499BOOL extern CDQueryCDDrives(int *iNumCD, char * cFirstDrive)
500{
501 HFILE hfDevice;
502 ULONG ulAction;
503 ULONG ulLen;
504 static char cFirst=0;
505 static int iNumCDLocal=0;
506 static BOOL haveCD=FALSE;
507 static BOOL done=FALSE;
508 struct
509 {
510 USHORT usCountCD;
511 USHORT usFirstCD;
512 } CDInfo;
513
514 if(!done){
515 ulLen = sizeof(CDInfo);
516 if(!DosOpen("\\DEV\\CD-ROM2$", &hfDevice, &ulAction, 0,
517 FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
518 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL))
519 {
520 if(!DosDevIOCtl(hfDevice, 0x82, 0x60, NULL, 0, NULL, &CDInfo, ulLen, &ulLen))
521 {
522 if(CDInfo.usCountCD) {
523 haveCD=TRUE;
524 iNumCDLocal=CDInfo.usCountCD;
525 cFirst='A'+ CDInfo.usFirstCD;
526 }
527 }
528 DosClose(hfDevice);
529 }
530 done=TRUE;
531 }
532 *iNumCD=iNumCDLocal;
533 *cFirstDrive=cFirst;
534 return haveCD;
535}
536
537
538/*****************************************/
539/* */
540/* Query if a CD is avaiable in */
541/* CD-Drive 'drive' */
542/* */
543/* Input: drive num (starting with 0) */
544/* Returns TRUE if media is avaiable */
545/* */
546/*****************************************/
547BOOL CDQueryMedia(ULONG driveNum)
548{
549 return FALSE;
550}
551
552
553int cddb_sum(int n)
554{
555 int ret;
556 //printf("n: %d ",n);
557 for (ret = 0; n > 0; n /= 10) {
558 ret += (n % 10);
559 }
560 //printf("ret: %d ",ret);
561 return ret;
562}
563
564/* Returns a CDDB disc-ID for quering the database */
565/* Returns 0 if error. */
566LONG extern CDDBDiscID(char * drive, CDDBINFO * cddbInfo)
567{
568 int numTracks,a;
569 HFILE hfDrive;
570 LONG sum;
571 int t;
572
573
574 do {
575 hfDrive=openDrive(drive);
576 if(!hfDrive)
577 return 0;
578
579 numTracks=CDQueryAudioCDTracks(hfDrive);
580 if(numTracks==0||numTracks==-1)
581 break;
582 cddbInfo->numTracks=numTracks;
583
584 sum=0;
585 /* Calculating the id */
586 for(a=0;a<numTracks;a++) {
587 sum+= cddb_sum(CDQueryTrackStartSector(a, hfDrive)/75 );
588 //printf("Track%d: %d\n",a,CDQueryTrackStartSector(a, hfDrive));
589 cddbInfo->startSector[a]=CDQueryTrackStartSector(a, hfDrive);
590 }
591 t=CDQueryTrackStartSector(a, hfDrive)/75-CDQueryTrackStartSector(0, hfDrive)/75;
592 /*printf("(a-1): %d 0: %d t: %d\n",CDQueryTrackStartSector(a, hfDrive),
593 CDQueryTrackStartSector(0, hfDrive),t);*/
594 //printf("discid: %x\n",((sum % 0xff) << 24 | (t << 8) | numTracks));
595 //printf("Disclength: %d",(CDQueryTrackStartSector(a, hfDrive)-CDQueryTrackStartSector(0, hfDrive))/75);
596 cddbInfo->discLength=(CDQueryTrackStartSector(a, hfDrive)-CDQueryTrackStartSector(0, hfDrive))/75;
597 cddbInfo->discid=(sum % 0xff) << 24 | (t << 8) | numTracks;
598 closeDrive(hfDrive);
599 return cddbInfo->discid;
600 }while(TRUE);
601
602 /* error */
603 closeDrive(hfDrive);
604 return 0;
605}
606
607
608
Note: See TracBrowser for help on using the repository browser.