source: trunk/src/winmm/mcicda/os2cdrom.cpp@ 5120

Last change on this file since 5120 was 5005, checked in by sandervl, 25 years ago

PD: CD Track fixes

File size: 12.2 KB
Line 
1/* -*- tab-width: 8; c-basic-offset: 4 -*- */
2/*
3 * MCI CDAUDIO Driver for OS/2. Interface to OS/2 DosIOCtrl()
4 *
5 * Copyright 2000 Chris Wohlgemuth
6 * 2001 Przemyslaw Dobrowolski
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11
12#define INCL_DOSDEVICES
13#define INCL_DOSDEVIOCTL
14#define INCL_DOS
15
16#include <os2wrap.h>
17//#include <cdrom.h>
18
19#pragma pack(1)
20
21typedef struct{
22 UCHAR ucFirstTrack;
23 UCHAR ucLastTrack;
24 ULONG ulLeadOut;
25}CDINFO;
26
27typedef struct
28{
29 int ADR_data_for_track:4; // ADR data for track
30 int preemphasis:1; // 0 = Audio without preemphasis
31 // 1 = Audio with preemphasis
32 int cdda_permitted:1; // 0 = Digital copy prohibited
33 // 1 = Digital copy permitted
34 int type_of_track:1; // 0 = Audio track
35 // 1 = Data track
36 int channels:1; // 0 = Two-channel audio
37 // 1 = Four-channel audio
38}TRACKTYPE;
39
40typedef struct
41{
42 ULONG ulTrackAddress;
43 TRACKTYPE track_type;
44}CDTRACKINFO;
45
46typedef struct
47{
48 UCHAR signature[4];
49 UCHAR ucTrackNum;
50}TINFOPARAM;
51
52typedef struct
53{
54 UCHAR ucFrames;
55 UCHAR ucSeconds;
56 UCHAR ucMinutes;
57 UCHAR ucNotUsed;
58}MSF;
59
60typedef struct
61{
62 USHORT usStatusBits;
63 ULONG ulStarting;
64 ULONG ulEnding;
65}AUDIOSTATUS;
66
67typedef struct
68{
69 UCHAR signature[4];
70 UCHAR ucAddressMode;
71 ULONG ulStartSector;
72 ULONG ulEndSector;
73}PLAYPARAM2;
74
75typedef struct
76{
77 UCHAR signature[4];
78 UCHAR ucAddressMode;
79 ULONG ulTo;
80}SEEKPARAM;
81
82typedef struct
83{
84 UCHAR ucCtrlAdr;
85 UCHAR ucTrack;
86 UCHAR ucIndex;
87 UCHAR ucTrackMins;
88 UCHAR ucTrackSecs;
89 UCHAR UCTrackFrames;
90 UCHAR ucNull;
91 UCHAR ucDiskMins;
92 UCHAR ucDiskSecs;
93 UCHAR ucDiskFrames;
94}SUBCHANNELQ;
95
96#pragma pack()
97
98
99LONG static _CDCalculateSector(MSF* msf1)
100{
101 return ((msf1->ucMinutes*60+msf1->ucSeconds)*75+msf1->ucFrames);
102}
103
104
105HFILE os2CDOpen(char *drive)
106{
107 HFILE hfDrive = 0;
108 ULONG ulAction;
109 ULONG rc;
110
111 rc = DosOpen(drive, &hfDrive, &ulAction, 0,
112 FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
113 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY |
114 OPEN_FLAGS_DASD|OPEN_FLAGS_FAIL_ON_ERROR, NULL);
115
116 if(rc)
117 return 0;//Error
118
119 return hfDrive;
120}
121
122ULONG os2CDClose(ULONG hfOS2Handle)
123{
124 return DosClose(hfOS2Handle);
125}
126
127/******************************************/
128/* Result:
129 0: Error
130 -1: CD is Data Disk
131 other: # Audio tracks */
132/******************************************/
133int os2GetNumTracks(HFILE hfOS2Handle, ULONG *ulLeadOut)
134{
135 ULONG ulParamLen;
136 ULONG ulDataLen;
137 ULONG rc;
138 CDINFO cdInfo;
139 TINFOPARAM tip;
140 CDTRACKINFO trackInfo;
141
142 ulDataLen=sizeof(cdInfo);
143 ulParamLen=4;
144
145 if(!hfOS2Handle)
146 return 0;
147
148 rc = DosDevIOCtl(hfOS2Handle, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
149 "CD01", 4, &ulParamLen, &cdInfo,
150 sizeof(cdInfo), &ulDataLen);
151
152 if(rc) {
153 return 0;//Error
154 }
155
156 ulDataLen=sizeof(trackInfo);
157 ulParamLen=sizeof(TINFOPARAM);
158 tip.signature[0]='C';
159 tip.signature[1]='D';
160 tip.signature[2]='0';
161 tip.signature[3]='1';
162 tip.ucTrackNum=1;
163
164 /* We have a disc. Check if it's audio */
165 rc = DosDevIOCtl(hfOS2Handle, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
166 &tip, sizeof(tip), &ulParamLen, &trackInfo,
167 sizeof(trackInfo), &ulDataLen);
168
169 if(rc) {
170 return 0;//Error
171 }
172
173// PD: Don't return error when data track is found.
174// if(trackInfo.ucTCInfo & 0x40) {
175// return -1;//It's a data track
176// }
177
178 *ulLeadOut=cdInfo.ulLeadOut;
179 return cdInfo.ucLastTrack-cdInfo.ucFirstTrack+1;
180}
181
182BOOL os2GetCDStatus(HFILE hfOS2Handle, ULONG *ulStatus)
183{
184 ULONG ulParamLen;
185 ULONG ulDeviceStatus;
186 ULONG ulDataLen;
187 ULONG rc;
188
189 ulDeviceStatus=0;
190
191 /* Get status */
192 ulDataLen=sizeof(ulDeviceStatus);
193 ulParamLen=4;
194 rc = DosDevIOCtl(hfOS2Handle, IOCTL_CDROMDISK, CDROMDISK_DEVICESTATUS,
195 "CD01", 4, &ulParamLen, &ulDeviceStatus,
196 sizeof(ulDeviceStatus), &ulDataLen);
197 if(rc) {
198 return FALSE;//Error
199 }
200
201 *ulStatus=ulDeviceStatus;
202 return TRUE;
203}
204
205BOOL os2GetCDAudioStatus(HFILE hfOS2Handle, USHORT *usStatus)
206{
207 AUDIOSTATUS asStatus;
208 ULONG ulParamLen;
209 ULONG ulDataLen;
210 ULONG rc;
211
212 /* Get status */
213
214 ulDataLen=sizeof(asStatus);
215 ulParamLen=4;
216
217 /* Get information */
218 rc = DosDevIOCtl(hfOS2Handle, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOSTATUS,
219 "CD01", 4, &ulParamLen, &asStatus,
220 sizeof(asStatus), &ulDataLen);
221 if(rc) {
222 *usStatus=rc;
223 return FALSE;//Error
224 }
225 *usStatus=asStatus.usStatusBits;
226 return TRUE;
227}
228
229/* Returns sector info of track #numTrack */
230/* Starting with track 0 */
231ULONG os2CDQueryTrackStartSector( HFILE hfDrive, ULONG numTrack, BOOL *pflAudio)
232{
233 ULONG ulParamLen;
234 ULONG ulDataLen;
235 ULONG rc;
236 CDINFO cdInfo;
237 TINFOPARAM tip;
238 CDTRACKINFO trackInfo[2];
239
240 do {
241 if(!hfDrive)
242 break;
243
244 /* Get cd info */
245 ulDataLen=sizeof(cdInfo);
246 ulParamLen=4;
247 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIODISK,
248 "CD01", 4, &ulParamLen, &cdInfo,
249 sizeof(cdInfo), &ulDataLen);
250 if(rc)
251 break;//Error
252
253 ulDataLen=sizeof(trackInfo);
254 ulParamLen=sizeof(TINFOPARAM);
255 tip.signature[0]='C';
256 tip.signature[1]='D';
257 tip.signature[2]='0';
258 tip.signature[3]='1';
259 /* Get information about our track */
260 tip.ucTrackNum=numTrack+1;
261 if(tip.ucTrackNum<=cdInfo.ucLastTrack) {
262 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_GETAUDIOTRACK,
263 &tip, sizeof(tip), &ulParamLen, &trackInfo[0],
264 sizeof(trackInfo[0]), &ulDataLen);
265 if(rc)
266 break;//Error
267
268 *pflAudio=!trackInfo[0].track_type.type_of_track;
269
270 }else
271 return _CDCalculateSector((MSF*)&cdInfo.ulLeadOut);
272
273
274 return _CDCalculateSector((MSF*)&trackInfo[0].ulTrackAddress);
275
276 }while(TRUE);
277
278 /* error */
279 return 0;
280}
281
282
283BOOL os2CDEject(HFILE hfDrive)
284{
285 ULONG ulParamLen;
286 ULONG rc;
287
288 if(!hfDrive)
289 return FALSE;
290
291 ulParamLen=4;
292 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMDISK, CDROMDISK_EJECTDISK,
293 "CD01", 4, &ulParamLen,0,
294 0, 0);
295 if(rc)
296 return FALSE;//Error
297
298 return TRUE;
299}
300
301#ifndef CDROMDISK_CLOSETRAY
302#define CDROMDISK_CLOSETRAY 0x0045
303#endif
304
305BOOL os2CDCloseTray(HFILE hfDrive)
306{
307 ULONG ulParamLen;
308 ULONG rc;
309
310 if(!hfDrive)
311 return FALSE;
312
313 ulParamLen=4;
314 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMDISK, CDROMDISK_CLOSETRAY,
315 "CD01", 4, &ulParamLen,0,
316 0, 0);
317 if(rc)
318 return FALSE;//Error
319
320 return TRUE;
321}
322
323BOOL os2CDStop(HFILE hfDrive)
324{
325 ULONG ulParamLen;
326 ULONG rc;
327
328 if(!hfDrive)
329 return FALSE;
330
331
332
333 /* Stop CD */
334 ulParamLen=4;
335 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_STOPAUDIO,
336 "CD01", 4, &ulParamLen,0,
337 0, 0);
338 if(rc)
339 return FALSE;//Error
340
341 return TRUE;
342}
343
344
345/*****************************************/
346/* */
347/* Plays frame range */
348/* */
349/* Returns TRUE if successful */
350/* */
351/*****************************************/
352BOOL os2CDPlayRange(HFILE hfDrive ,ULONG ulFrom, ULONG ulTo)
353{
354 ULONG ulParamLen;
355 ULONG ulDataLen;
356 ULONG rc;
357 CDINFO cdInfo;
358 TINFOPARAM tip;
359 CDTRACKINFO trackInfo[2];
360 PLAYPARAM2 playParam={0};
361
362 if(!hfDrive)
363 return FALSE;
364
365 //memcpy(&playParam,PlayParam, sizeof(playParam));
366 /* Play the Track... */
367 ulParamLen=sizeof(PLAYPARAM2);
368 playParam.signature[0]='C';
369 playParam.signature[1]='D';
370 playParam.signature[2]='0';
371 playParam.signature[3]='1';
372 //playParam.ucAddressMode=01;
373 playParam.ulStartSector=ulFrom;
374 playParam.ulEndSector=ulTo;
375
376 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_PLAYAUDIO,
377 &playParam, sizeof(playParam), &ulParamLen,0,
378 0, 0);
379 return rc;
380 if(rc)
381 return FALSE;
382
383 return TRUE;
384}
385
386BOOL os2CDResume(HFILE hfDrive)
387{
388 ULONG ulParamLen;
389 ULONG rc;
390
391 if(!hfDrive)
392 return FALSE;
393
394 /* Stop CD */
395 ulParamLen=4;
396 rc = DosDevIOCtl(hfDrive, IOCTL_CDROMAUDIO, CDROMAUDIO_RESUMEAUDIO,
397 "CD01", 4, &ulParamLen,0,
398 0, 0);
399 if(rc)
400 return FALSE;//Error
401
402 return TRUE;
403}
404
405BOOL os2CDGetHeadLocation(HFILE hfOS2Handle, ULONG *ulHeadLocation)
406{
407 UCHAR ucParam[5]={0};
408 ULONG ulParamLen;
409 ULONG ulDeviceStatus;
410 ULONG ulDataLen;
411 ULONG rc;
412
413 ulDeviceStatus=0;
414
415 if(!hfOS2Handle)
416 return FALSE;
417
418 /* Get Location */
419 ulDataLen=sizeof(ulDeviceStatus);
420 ulParamLen=5;
421 ucParam[0]='C';
422 ucParam[1]='D';
423 ucParam[2]='0';
424 ucParam[3]='1';
425 ucParam[4]=0;
426
427 rc = DosDevIOCtl(hfOS2Handle, IOCTL_CDROMDISK, CDROMDISK_GETHEADLOC,
428 &ucParam, 5, &ulParamLen, &ulDeviceStatus,
429 sizeof(ulDeviceStatus), &ulDataLen);
430 if(rc) {
431 return FALSE;//Error
432 }
433
434 *ulHeadLocation=ulDeviceStatus;
435 return TRUE;
436
437}
438
439BOOL os2CDSeek(HFILE hfOS2Handle, ULONG ulTo)
440{
441 SEEKPARAM sp={0};
442 ULONG ulParamLen;
443 ULONG rc;
444
445 if(!hfOS2Handle)
446 return FALSE;
447
448 sp.signature[0]='C';
449 sp.signature[1]='D';
450 sp.signature[2]='0';
451 sp.signature[3]='1';
452 sp.ulTo=ulTo;
453
454 ulParamLen=sizeof(sp);
455
456 /* We have a disc. Check if it's audio */
457 rc = DosDevIOCtl(hfOS2Handle, IOCTL_CDROMDISK, CDROMDISK_SEEK,
458 &sp, sizeof(sp), &ulParamLen, 0,
459 0, 0);
460
461 if(rc) {
462 return FALSE;//Error
463 }
464
465 return TRUE;
466}
467
468BOOL os2CDQueryCurTrack(HFILE hfOS2Handle, UINT * uiCurTrack)
469{
470 ULONG ulParamLen;
471 ULONG ulDeviceStatus;
472 ULONG ulDataLen;
473 ULONG rc;
474 SUBCHANNELQ scq;
475
476
477 if(!hfOS2Handle)
478 return FALSE;
479
480
481 /* Get status */
482 ulDataLen=sizeof(scq);
483 ulParamLen=4;
484 rc = DosDevIOCtl(hfOS2Handle, IOCTL_CDROMAUDIO, CDROMAUDIO_GETSUBCHANNELQ,
485 "CD01", 4, &ulParamLen, &scq,
486 sizeof(scq), &ulDataLen);
487 if(rc) {
488 return FALSE;//Error
489 }
490 *uiCurTrack=(scq.ucTrack & 0xF)+(scq.ucTrack & 0xF0)*10;
491 return TRUE;
492}
493
494/**************************************************************/
495/* */
496/* This funktion returns the CD-Drives in the system */
497/* */
498/* iNumCD (output): # of CD-Drives */
499/* cFirstDrive (output): first cd-Drive letter */
500/* returns TRUE: We have cd-drives */
501/* */
502/**************************************************************/
503BOOL os2CDQueryCDDrives(int *iNumCD, char * cFirstDrive)
504{
505 HFILE hfDevice;
506 ULONG ulAction;
507 ULONG ulLen;
508 static char cFirst=0;
509 static int iNumCDLocal=0;
510 static BOOL haveCD=FALSE;
511 static BOOL done=FALSE;
512
513 struct
514 {
515 USHORT usCountCD;
516 USHORT usFirstCD;
517 } CDInfo;
518
519 if(!done){
520 ulLen = sizeof(CDInfo);
521 if(!DosOpen("\\DEV\\CD-ROM2$", &hfDevice, &ulAction, 0,
522 FILE_NORMAL, OPEN_ACTION_OPEN_IF_EXISTS,
523 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, NULL))
524 {
525 if(!DosDevIOCtl(hfDevice, 0x82, 0x60, NULL, 0, NULL, &CDInfo, ulLen, &ulLen))
526 {
527 if(CDInfo.usCountCD) {
528 haveCD=TRUE;
529 iNumCDLocal=CDInfo.usCountCD;
530 cFirst='A'+ CDInfo.usFirstCD;
531 }
532 }
533 DosClose(hfDevice);
534 }
535 done=TRUE;
536 }
537 *iNumCD=iNumCDLocal;
538 *cFirstDrive=cFirst;
539 return haveCD;
540}
541
542
543
544
545
546
547
548
549
550
Note: See TracBrowser for help on using the repository browser.