[4709] | 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 | *
|
---|
| 7 | * Project Odin Software License can be found in LICENSE.TXT
|
---|
| 8 | *
|
---|
| 9 | */
|
---|
| 10 |
|
---|
| 11 |
|
---|
[2473] | 12 | #include <os2win.h>
|
---|
| 13 | #include "cdrom.h"
|
---|
[4709] | 14 | #include <debugtools.h>
|
---|
| 15 | #include <string.h>
|
---|
[2473] | 16 |
|
---|
[21916] | 17 | /*
|
---|
[4709] | 18 | * FIXME: Should use the right errorcodes for SetLastError if a function fails.
|
---|
| 19 | */
|
---|
| 20 |
|
---|
[2473] | 21 | int CDAUDIO_Open(WINE_CDAUDIO* wcda)
|
---|
| 22 | {
|
---|
[4709] | 23 | ULONG yyrc;
|
---|
| 24 | USHORT sel;
|
---|
| 25 | HFILE hFile;
|
---|
| 26 | int iNumCD;
|
---|
| 27 | char chrFirstCD[3]={0};
|
---|
| 28 | int i;
|
---|
| 29 |
|
---|
| 30 | dprintf(("MCICDA-CDROM: Trying to open drive %s...\n",wcda->chrDrive));
|
---|
| 31 |
|
---|
| 32 | if(strlen(wcda->chrDrive)==2) {
|
---|
| 33 | if((wcda->hfOS2Handle=os2CDOpen(wcda->chrDrive))==NULL) {
|
---|
[21916] | 34 | SetLastError(ERROR_WRONG_DISK);
|
---|
[4709] | 35 | /* We always return TRUE because we want to open the driver not the disk */
|
---|
| 36 | }
|
---|
| 37 | return TRUE;
|
---|
| 38 | }
|
---|
| 39 |
|
---|
[21916] | 40 | if(!stricmp(wcda->chrDeviceType,"cdaudio")) {
|
---|
[4709] | 41 | /* We try any CDROM in the system until one can be opened */
|
---|
| 42 | if(!os2CDQueryCDDrives(&iNumCD, chrFirstCD)) {
|
---|
[21916] | 43 | SetLastError(ERROR_WRONG_DISK);
|
---|
[4709] | 44 | return FALSE;/* Can't get drives in system */
|
---|
| 45 | }
|
---|
[21916] | 46 |
|
---|
[4709] | 47 | chrFirstCD[1]=':';
|
---|
| 48 | for(i=0;i<iNumCD;i++) {
|
---|
| 49 | chrFirstCD[0]++;
|
---|
[21916] | 50 | if((wcda->hfOS2Handle=os2CDOpen(chrFirstCD))!=NULL) {
|
---|
[4709] | 51 | return TRUE;
|
---|
| 52 | }
|
---|
| 53 | }
|
---|
| 54 | SetLastError(ERROR_WRONG_DISK);
|
---|
[21916] | 55 | /* We always return TRUE because we want to open the driver not the disk */
|
---|
| 56 | /* Can't open CD */
|
---|
[4709] | 57 | }
|
---|
| 58 | /* We always return TRUE because we want to open the driver not the disk */
|
---|
| 59 | return TRUE;
|
---|
[2473] | 60 | }
|
---|
| 61 |
|
---|
[4709] | 62 | int CDAUDIO_Close(WINE_CDAUDIO* wcda)
|
---|
[2473] | 63 | {
|
---|
[4709] | 64 | ULONG rc;
|
---|
[21916] | 65 |
|
---|
[4709] | 66 | dprintf(("MCICDA-CDROM: CDAUDIO_Close: Closing drive: %s...\n",wcda->chrDrive));
|
---|
[21916] | 67 |
|
---|
[4709] | 68 | if(wcda->hfOS2Handle==NULL) {
|
---|
| 69 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 70 | return FALSE;
|
---|
| 71 | }
|
---|
[21916] | 72 |
|
---|
[4709] | 73 | if((rc=os2CDClose(wcda->hfOS2Handle))!=0) {
|
---|
| 74 | dprintf(("MCICDA-CDROM: CDAUDIO_Close:rc=%d \n",rc));
|
---|
| 75 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 76 | return FALSE;
|
---|
| 77 | }
|
---|
| 78 | wcda->hfOS2Handle=NULL;
|
---|
| 79 | dprintf(("MCICDA-CDROM: CDAUDIO_Close: Drive %s closed\n",wcda->chrDrive));
|
---|
| 80 | return TRUE;
|
---|
[2473] | 81 | }
|
---|
| 82 |
|
---|
| 83 | int CDAUDIO_Reset(WINE_CDAUDIO* wcda)
|
---|
| 84 | {
|
---|
| 85 | dprintf(("MCICDA-CDROM: CDAUDIO_Reset not implemented.\n"));
|
---|
| 86 | SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
---|
| 87 | return FALSE;
|
---|
| 88 | }
|
---|
| 89 |
|
---|
| 90 | int CDAUDIO_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD stop)
|
---|
| 91 | {
|
---|
[4709] | 92 | ULONG rc;
|
---|
| 93 |
|
---|
| 94 | /* FIXME: error handling is missing */
|
---|
| 95 | //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
---|
| 96 | if(!wcda->hfOS2Handle) {
|
---|
| 97 | CDAUDIO_Open(wcda);/* Get new handle */
|
---|
| 98 | if(!wcda->hfOS2Handle) {
|
---|
| 99 | WARN("hfOS2Handle isn't valid and can't get new one\n");
|
---|
| 100 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 101 | return 1;
|
---|
| 102 | }
|
---|
| 103 | }
|
---|
| 104 |
|
---|
| 105 | CDAUDIO_GetCDStatus(wcda);
|
---|
| 106 | if(wcda->cdaMode==WINE_CDA_PLAY||wcda->cdaMode==WINE_CDA_PAUSE)
|
---|
| 107 | CDAUDIO_Stop(wcda);
|
---|
| 108 | rc=os2CDPlayRange(wcda->hfOS2Handle , start, stop);
|
---|
| 109 | return 0;
|
---|
[2473] | 110 | }
|
---|
| 111 |
|
---|
| 112 | int CDAUDIO_Stop(WINE_CDAUDIO* wcda)
|
---|
| 113 | {
|
---|
[4709] | 114 | // SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
---|
| 115 | /* FIXME: error handling is missing */
|
---|
| 116 | if(!wcda->hfOS2Handle) {
|
---|
| 117 | CDAUDIO_Open(wcda);/* Get new handle */
|
---|
| 118 | if(!wcda->hfOS2Handle) {
|
---|
| 119 | WARN("hfOS2Handle isn't valid and can't get new one\n");
|
---|
| 120 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 121 | return 1;
|
---|
| 122 | }
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | os2CDStop(wcda->hfOS2Handle);
|
---|
| 126 | return 0;
|
---|
[2473] | 127 | }
|
---|
| 128 |
|
---|
| 129 | int CDAUDIO_Pause(WINE_CDAUDIO* wcda, int pauseOn)
|
---|
| 130 | {
|
---|
[4709] | 131 |
|
---|
| 132 | //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
---|
| 133 | /* FIXME: error handling is missing */
|
---|
| 134 | if(!wcda->hfOS2Handle) {
|
---|
| 135 | CDAUDIO_Open(wcda);/* Get new handle */
|
---|
| 136 | if(!wcda->hfOS2Handle) {
|
---|
| 137 | WARN("hfOS2Handle isn't valid and can't get new one\n");
|
---|
| 138 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 139 | return 1;
|
---|
| 140 | }
|
---|
| 141 | }
|
---|
| 142 |
|
---|
| 143 | if(pauseOn)
|
---|
| 144 | os2CDStop(wcda->hfOS2Handle);
|
---|
| 145 | else
|
---|
| 146 | os2CDResume(wcda->hfOS2Handle);
|
---|
| 147 | return 0;
|
---|
[2473] | 148 | }
|
---|
| 149 |
|
---|
| 150 | int CDAUDIO_Seek(WINE_CDAUDIO* wcda, DWORD at)
|
---|
| 151 | {
|
---|
[4709] | 152 | /* FIXME: error handling is missing */
|
---|
| 153 | //SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
---|
| 154 | if(!wcda->hfOS2Handle) {
|
---|
| 155 | CDAUDIO_Open(wcda);/* Get new handle */
|
---|
| 156 | if(!wcda->hfOS2Handle) {
|
---|
| 157 | WARN("hfOS2Handle isn't valid and can't get new one\n");
|
---|
| 158 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 159 | return 1;
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
[21916] | 162 |
|
---|
[4709] | 163 | os2CDSeek(wcda->hfOS2Handle, at);
|
---|
| 164 | return 0;
|
---|
[2473] | 165 | }
|
---|
| 166 |
|
---|
| 167 | int CDAUDIO_SetDoor(WINE_CDAUDIO* wcda, int open)
|
---|
| 168 | {
|
---|
[4709] | 169 |
|
---|
| 170 | /* FIXME: error handling is missing */
|
---|
| 171 | if(!wcda->hfOS2Handle) {
|
---|
| 172 | CDAUDIO_Open(wcda);/* Get new handle */
|
---|
| 173 | if(!wcda->hfOS2Handle) {
|
---|
| 174 | WARN("hfOS2Handle isn't valid and can't get new one\n");
|
---|
| 175 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 176 | return 1;
|
---|
| 177 | }
|
---|
| 178 | }
|
---|
[21916] | 179 |
|
---|
[4709] | 180 | CDAUDIO_Stop(wcda);
|
---|
| 181 | if(open) {
|
---|
| 182 | os2CDEject(wcda->hfOS2Handle);
|
---|
| 183 | }
|
---|
| 184 | else
|
---|
[4965] | 185 | os2CDCloseTray(wcda->hfOS2Handle);
|
---|
[4709] | 186 |
|
---|
| 187 | return 0;
|
---|
[2473] | 188 | }
|
---|
| 189 |
|
---|
[4709] | 190 |
|
---|
| 191 | /******************************************/
|
---|
[21916] | 192 | /* Result:
|
---|
[4709] | 193 | 0: Error
|
---|
| 194 | -1: CD is Data Disk
|
---|
| 195 | other: # Audio tracks */
|
---|
| 196 | /******************************************/
|
---|
| 197 | int CDAUDIO_GetNumberOfTracks(WINE_CDAUDIO* wcda)
|
---|
[2473] | 198 | {
|
---|
[4709] | 199 | int rcOS2;
|
---|
| 200 |
|
---|
| 201 | if(!wcda->hfOS2Handle) {
|
---|
| 202 | CDAUDIO_Open(wcda);/* Get new handle */
|
---|
| 203 | if(!wcda->hfOS2Handle) {
|
---|
| 204 | WARN("hfOS2Handle isn't valid and can't get new one\n");
|
---|
| 205 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 206 | return 0;
|
---|
| 207 | }
|
---|
| 208 | }
|
---|
| 209 |
|
---|
| 210 | rcOS2=os2GetNumTracks(wcda->hfOS2Handle,&wcda->ulLeadOut);
|
---|
| 211 | switch(rcOS2)
|
---|
| 212 | {
|
---|
| 213 | case -1:
|
---|
| 214 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 215 | return -1;
|
---|
| 216 | case 0:
|
---|
[21916] | 217 | SetLastError(ERROR_WRONG_DISK);
|
---|
[5005] | 218 | return 1;
|
---|
[4709] | 219 | default:
|
---|
| 220 | break;
|
---|
| 221 | }
|
---|
| 222 |
|
---|
| 223 | wcda->nTracks=rcOS2;
|
---|
| 224 | wcda->nFirstTrack=1;
|
---|
| 225 | wcda->nLastTrack=rcOS2;
|
---|
| 226 | return rcOS2;
|
---|
[2473] | 227 | }
|
---|
| 228 |
|
---|
| 229 | BOOL CDAUDIO_GetTracksInfo(WINE_CDAUDIO* wcda)
|
---|
| 230 | {
|
---|
[4709] | 231 |
|
---|
| 232 | int i, length;
|
---|
| 233 | ULONG start, last_start = 0;
|
---|
| 234 | int total_length = 0;
|
---|
[5005] | 235 | BOOL flAudioTrack;
|
---|
[4709] | 236 |
|
---|
| 237 | if(!wcda->hfOS2Handle) {
|
---|
| 238 | CDAUDIO_Open(wcda);/* Get new handle */
|
---|
| 239 | if(!wcda->hfOS2Handle) {
|
---|
| 240 | WARN("hfOS2Handle isn't valid and can't get new one\n");
|
---|
| 241 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 242 | return FALSE;
|
---|
| 243 | }
|
---|
| 244 | }
|
---|
[21916] | 245 |
|
---|
[4709] | 246 | if (wcda->nTracks == 0) {
|
---|
| 247 | if (CDAUDIO_GetNumberOfTracks(wcda) <= 0)
|
---|
| 248 | return FALSE;
|
---|
| 249 | }
|
---|
[21916] | 250 |
|
---|
[4709] | 251 | TRACE("nTracks=%u\n", wcda->nTracks);
|
---|
[21916] | 252 |
|
---|
[4709] | 253 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
[21916] | 254 |
|
---|
| 255 | if (wcda->lpdwTrackLen != NULL)
|
---|
[4709] | 256 | free(wcda->lpdwTrackLen);
|
---|
| 257 | wcda->lpdwTrackLen = (LPDWORD)malloc((wcda->nTracks + 1) * sizeof(DWORD));
|
---|
[21916] | 258 | if (wcda->lpdwTrackPos != NULL)
|
---|
[4709] | 259 | free(wcda->lpdwTrackPos);
|
---|
| 260 | wcda->lpdwTrackPos = (LPDWORD)malloc((wcda->nTracks + 1) * sizeof(DWORD));
|
---|
| 261 | if (wcda->lpbTrackFlags != NULL)
|
---|
| 262 | free(wcda->lpbTrackFlags);
|
---|
| 263 | wcda->lpbTrackFlags = (LPBYTE)malloc((wcda->nTracks + 1) * sizeof(BYTE));
|
---|
[21916] | 264 |
|
---|
[4709] | 265 | if (wcda->lpdwTrackLen == NULL || wcda->lpdwTrackPos == NULL ||
|
---|
| 266 | wcda->lpbTrackFlags == NULL) {
|
---|
| 267 | WARN("error allocating track table !\n");
|
---|
| 268 | /* Freeing the already allocated mem */
|
---|
[21916] | 269 | if (wcda->lpdwTrackLen != NULL)
|
---|
[4709] | 270 | free(wcda->lpdwTrackLen);
|
---|
[21916] | 271 | if (wcda->lpdwTrackPos != NULL)
|
---|
[4709] | 272 | free(wcda->lpdwTrackPos);
|
---|
| 273 | if (wcda->lpbTrackFlags != NULL)
|
---|
| 274 | free(wcda->lpbTrackFlags);
|
---|
| 275 | wcda->lpbTrackFlags=NULL;
|
---|
| 276 | wcda->lpdwTrackPos=NULL;
|
---|
| 277 | wcda->lpdwTrackLen= NULL;
|
---|
| 278 | return FALSE;
|
---|
| 279 | }
|
---|
| 280 | memset(wcda->lpdwTrackLen, 0, (wcda->nTracks + 1) * sizeof(DWORD));
|
---|
| 281 | memset(wcda->lpdwTrackPos, 0, (wcda->nTracks + 1) * sizeof(DWORD));
|
---|
| 282 | memset(wcda->lpbTrackFlags, 0, (wcda->nTracks + 1) * sizeof(BYTE));
|
---|
[21916] | 283 |
|
---|
[4709] | 284 | for (i = 0; i <= wcda->nTracks; i++) {
|
---|
[5005] | 285 | if((start=os2CDQueryTrackStartSector(wcda->hfOS2Handle,i,&flAudioTrack))==0)
|
---|
[4709] | 286 | {
|
---|
| 287 | WARN("error reading start sector for track %d\n", i+1);
|
---|
| 288 | /* Freeing the already allocated mem */
|
---|
[21916] | 289 | if (wcda->lpdwTrackLen != NULL)
|
---|
[4709] | 290 | free(wcda->lpdwTrackLen);
|
---|
[21916] | 291 | if (wcda->lpdwTrackPos != NULL)
|
---|
[4709] | 292 | free(wcda->lpdwTrackPos);
|
---|
| 293 | if (wcda->lpbTrackFlags != NULL)
|
---|
| 294 | free(wcda->lpbTrackFlags);
|
---|
| 295 | wcda->lpbTrackFlags=NULL;
|
---|
| 296 | wcda->lpdwTrackPos=NULL;
|
---|
| 297 | wcda->lpdwTrackLen= NULL;
|
---|
| 298 | return FALSE;
|
---|
| 299 | }
|
---|
| 300 | start-=150;
|
---|
[21916] | 301 |
|
---|
[4709] | 302 | if (i == 0) {
|
---|
| 303 | last_start = start;
|
---|
| 304 | wcda->dwFirstFrame = start;
|
---|
| 305 | TRACE("dwFirstOffset=%u\n", start);
|
---|
| 306 | } else {
|
---|
| 307 | length = start - last_start;
|
---|
| 308 | last_start = start;
|
---|
| 309 | start = last_start - length;
|
---|
| 310 | total_length += length;
|
---|
| 311 | wcda->lpdwTrackLen[i - 1] = length;
|
---|
| 312 | wcda->lpdwTrackPos[i - 1] = start;
|
---|
| 313 | TRACE("track #%u start=%u len=%u\n", i, start, length);
|
---|
| 314 | }
|
---|
| 315 | //if(wcda->ulCDROMStatus & )
|
---|
[5005] | 316 | if (!flAudioTrack)
|
---|
[21916] | 317 | wcda->lpbTrackFlags[i] = CDROM_DATA_TRACK;
|
---|
[5005] | 318 | else
|
---|
| 319 | wcda->lpbTrackFlags[i] = 0;
|
---|
[4709] | 320 | //TRACE("track #%u flags=%02x\n", i + 1, wcda->lpbTrackFlags[i]);
|
---|
| 321 | }/* for */
|
---|
[21916] | 322 |
|
---|
[4709] | 323 | wcda->dwLastFrame = last_start;
|
---|
| 324 | TRACE("total_len=%u Leaving CDAUDIO_GetTracksInfo...\n", total_length);
|
---|
[21916] | 325 |
|
---|
[4709] | 326 | return TRUE;
|
---|
[2473] | 327 | }
|
---|
| 328 |
|
---|
[4709] | 329 |
|
---|
[2473] | 330 | BOOL CDAUDIO_GetCDStatus(WINE_CDAUDIO* wcda)
|
---|
| 331 | {
|
---|
[4709] | 332 | ULONG ulRet;
|
---|
| 333 | int oldmode = wcda->cdaMode;
|
---|
| 334 |
|
---|
| 335 | if(!wcda->hfOS2Handle) {
|
---|
| 336 | CDAUDIO_Open(wcda);/* Get new handle */
|
---|
| 337 | if(!wcda->hfOS2Handle) {
|
---|
| 338 | WARN("hfOS2Handle isn't valid and can't get new one\n");
|
---|
| 339 | SetLastError(ERROR_INVALID_PARAMETER);
|
---|
| 340 | return FALSE;
|
---|
| 341 | }
|
---|
| 342 | }
|
---|
| 343 |
|
---|
| 344 | if(!os2GetCDStatus(wcda->hfOS2Handle, &wcda->ulCDROMStatus)) {
|
---|
| 345 | WARN("os2GetCDStatus(wcda->hfOS2Handle, &wcda->ulCDROMStatus) returned FALSE\n");
|
---|
| 346 | return FALSE;
|
---|
| 347 | }
|
---|
[21916] | 348 | /* Current mode */
|
---|
[4709] | 349 | //wcda->cdaMode=WINE_CDA_STOP;
|
---|
| 350 | if(wcda->ulCDROMStatus & 0x1L)
|
---|
| 351 | wcda->cdaMode=WINE_CDA_OPEN; /* Door open */
|
---|
| 352 | else if(wcda->ulCDROMStatus & 0x1000L)
|
---|
| 353 | wcda->cdaMode=WINE_CDA_PLAY; /* Playing */
|
---|
| 354 | else if(wcda->ulCDROMStatus & 0x800L)
|
---|
| 355 | wcda->cdaMode=WINE_CDA_NOTREADY;
|
---|
| 356 | else
|
---|
| 357 | wcda->cdaMode=WINE_CDA_STOP;
|
---|
| 358 |
|
---|
| 359 | if(wcda->cdaMode==WINE_CDA_OPEN && wcda->hfOS2Handle) {
|
---|
| 360 | CDAUDIO_Close(wcda);
|
---|
| 361 | return FALSE;
|
---|
| 362 | }
|
---|
| 363 |
|
---|
| 364 | if(!os2GetCDAudioStatus(wcda->hfOS2Handle, &wcda->usCDAudioStatus)) {
|
---|
| 365 | WARN("os2GetCDAudioStatus(wcda->hfOS2Handle, &wcda->usCDAudioStatus) returned FALSE rc=%x %d\n",wcda->usCDAudioStatus,wcda->usCDAudioStatus);
|
---|
| 366 | return FALSE;
|
---|
| 367 |
|
---|
| 368 | }
|
---|
| 369 | else {
|
---|
| 370 | if(wcda->usCDAudioStatus & 1)
|
---|
| 371 | wcda->cdaMode=WINE_CDA_PAUSE;
|
---|
| 372 | os2CDGetHeadLocation(wcda->hfOS2Handle,&wcda->dwCurFrame);
|
---|
| 373 | os2CDQueryCurTrack(wcda->hfOS2Handle, &wcda->nCurTrack);
|
---|
| 374 | }
|
---|
| 375 |
|
---|
| 376 | if (oldmode != wcda->cdaMode && oldmode == WINE_CDA_OPEN) {
|
---|
| 377 | TRACE("Updating TracksInfo !\n");
|
---|
| 378 | if (!CDAUDIO_GetTracksInfo(wcda)) {
|
---|
| 379 | WARN("error updating TracksInfo !\n");
|
---|
| 380 | return FALSE;
|
---|
| 381 | }
|
---|
| 382 | }
|
---|
| 383 |
|
---|
| 384 | dprintf(("MCICDA-CDROM: Leaving CDAUDIO_GetCDStatus... cdaMode: %x\n",wcda->cdaMode));
|
---|
| 385 | if (wcda->cdaMode != WINE_CDA_OPEN)
|
---|
| 386 | return TRUE;
|
---|
[21916] | 387 | else
|
---|
[4709] | 388 | return FALSE;
|
---|
[2473] | 389 | }
|
---|
| 390 |
|
---|
| 391 |
|
---|
[4709] | 392 |
|
---|
| 393 |
|
---|
| 394 |
|
---|
| 395 |
|
---|
| 396 |
|
---|
| 397 |
|
---|
| 398 |
|
---|
| 399 |
|
---|
| 400 |
|
---|