source: trunk/src/winmm/mcicda/mcicda.cpp@ 10367

Last change on this file since 10367 was 4982, checked in by sandervl, 25 years ago

PD: MCI_STATUS_POSITION bugfix

File size: 31.5 KB
Line 
1/* -*- tab-width: 8; c-basic-offset: 4 -*- */
2/*
3 * MCI CDAUDIO Driver for OS/2
4 *
5 * Copyright 1994 Martin Ayotte
6 * Copyright 1998-99 Eric Pouech
7 * Copyright 2000 Chris Wohlgemuth
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13#include <os2win.h>
14#include <string.h>
15#include "winuser.h"
16////#include "driver.h"
17#include "mmddk.h"
18#include "cdrom.h"
19#include "debugtools.h"
20
21DEFAULT_DEBUG_CHANNEL(cdaudio)
22
23
24/*-----------------------------------------------------------------------*/
25
26/**************************************************************************
27 * CDAUDIO_drvOpen [internal]
28 */
29static DWORD CDAUDIO_drvOpen(LPSTR str, LPMCI_OPEN_DRIVER_PARMSA modp)
30{
31 WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MCICDAUDIO));
32
33 if (!wmcda)
34 return 0;
35
36 wmcda->wDevID = modp->wDeviceID;
37 mciSetDriverData(wmcda->wDevID, (DWORD)wmcda);
38 modp->wCustomCommandTable = MCI_NO_COMMAND_TABLE;
39 modp->wType = MCI_DEVTYPE_CD_AUDIO;
40 return modp->wDeviceID;
41}
42
43/**************************************************************************
44 * CDAUDIO_drvClose [internal]
45 */
46static DWORD CDAUDIO_drvClose(DWORD dwDevID)
47{
48 WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(dwDevID);
49
50 if (wmcda) {
51 HeapFree(GetProcessHeap(), 0, wmcda);
52 mciSetDriverData(dwDevID, 0);
53 }
54 return 0;
55}
56
57/**************************************************************************
58 * CDAUDIO_mciGetOpenDrv [internal]
59 */
60static WINE_MCICDAUDIO* CDAUDIO_mciGetOpenDrv(UINT wDevID)
61{
62 WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID);
63
64 if (wmcda == NULL || wmcda->nUseCount == 0 /*|| wmcda->wcda.unixdev <= 0*/ ) {
65 WARN("CDAUDIO_mciGetOpenDrv(UINT wDevID): Invalid wDevID=%u\n", wDevID);
66 return 0;
67 }
68 return wmcda;
69}
70
71/**************************************************************************
72 * CDAUDIO_mciMode [internal]
73 */
74static int CDAUDIO_mciMode(int wcdaMode)
75{
76 switch (wcdaMode) {
77 case WINE_CDA_DONTKNOW: return MCI_MODE_STOP;/* 0x20d */
78 case WINE_CDA_NOTREADY: return MCI_MODE_STOP;/* 0x20d */
79 case WINE_CDA_OPEN: return MCI_MODE_OPEN;
80 case WINE_CDA_PLAY: return MCI_MODE_PLAY;
81 case WINE_CDA_STOP: return MCI_MODE_STOP;/* 0x20d */
82 case WINE_CDA_PAUSE: return MCI_MODE_PAUSE;
83 default:
84 FIXME("Unknown mode %04x\n", wcdaMode);
85 }
86 return MCI_MODE_STOP;
87}
88
89/**************************************************************************
90 * CDAUDIO_mciGetError [internal]
91 */
92static int CDAUDIO_mciGetError(WINE_MCICDAUDIO* wmcda)
93{
94 switch (wmcda->wcda.cdaMode) {
95 case WINE_CDA_DONTKNOW:
96 case WINE_CDA_NOTREADY: return MCIERR_DEVICE_NOT_READY;
97 case WINE_CDA_OPEN: return MCIERR_DEVICE_OPEN;
98 case WINE_CDA_PLAY:
99 case WINE_CDA_STOP:
100 case WINE_CDA_PAUSE: break;
101 default:
102 FIXME("Unknown mode %04x\n", wmcda->wcda.cdaMode);
103 }
104 return MCIERR_DRIVER_INTERNAL;
105}
106
107/**************************************************************************
108 * CDAUDIO_CalcFrame [internal]
109 */
110static DWORD CDAUDIO_CalcFrame(WINE_MCICDAUDIO* wmcda, DWORD dwTime)
111{
112 DWORD dwFrame = 0;
113 UINT wTrack;
114
115 TRACE("(%p, %08lX, %lu);\n", wmcda, wmcda->dwTimeFormat, dwTime);
116
117 switch (wmcda->dwTimeFormat) {
118 case MCI_FORMAT_MILLISECONDS:
119 dwFrame = ((dwTime - 1) * CDFRAMES_PERSEC + 500) / 1000;
120 TRACE("MILLISECONDS %lu\n", dwFrame);
121 break;
122 case MCI_FORMAT_MSF:
123 TRACE("MSF %02u:%02u:%02u\n",
124 MCI_MSF_MINUTE(dwTime), MCI_MSF_SECOND(dwTime), MCI_MSF_FRAME(dwTime));
125 dwFrame += CDFRAMES_PERMIN * MCI_MSF_MINUTE(dwTime);
126 dwFrame += CDFRAMES_PERSEC * MCI_MSF_SECOND(dwTime);
127 dwFrame += MCI_MSF_FRAME(dwTime);
128 break;
129 case MCI_FORMAT_TMSF:
130 default: /* unknown format ! force TMSF ! ... */
131 wTrack = MCI_TMSF_TRACK(dwTime);
132 TRACE("MSF %02u-%02u:%02u:%02u\n",
133 MCI_TMSF_TRACK(dwTime), MCI_TMSF_MINUTE(dwTime),
134 MCI_TMSF_SECOND(dwTime), MCI_TMSF_FRAME(dwTime));
135 TRACE("TMSF trackpos[%u]=%lu\n",
136 wTrack, wmcda->wcda.lpdwTrackPos[wTrack - 1]);
137 dwFrame = wmcda->wcda.lpdwTrackPos[wTrack - 1];
138 dwFrame += CDFRAMES_PERMIN * MCI_TMSF_MINUTE(dwTime);
139 dwFrame += CDFRAMES_PERSEC * MCI_TMSF_SECOND(dwTime);
140 dwFrame += MCI_TMSF_FRAME(dwTime);
141 break;
142 }
143 return dwFrame;
144}
145
146/**************************************************************************
147 * CDAUDIO_CalcTime [internal]
148 */
149static DWORD CDAUDIO_CalcTime(WINE_MCICDAUDIO* wmcda, DWORD tf, DWORD dwFrame,
150 LPDWORD lpRet)
151{
152 DWORD dwTime = 0;
153 UINT wTrack;
154 UINT wMinutes;
155 UINT wSeconds;
156 UINT wFrames;
157
158 TRACE("(%p, %08lX, %lu);\n", wmcda, tf, dwFrame);
159
160 switch (tf) {
161 case MCI_FORMAT_MILLISECONDS:
162 dwTime = (dwFrame * 1000) / CDFRAMES_PERSEC + 1;
163 TRACE("MILLISECONDS %lu\n", dwTime);
164 *lpRet = 0;
165 break;
166 case MCI_FORMAT_MSF:
167 wMinutes = dwFrame / CDFRAMES_PERMIN;
168 wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
169 wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes - CDFRAMES_PERSEC * wSeconds;
170 dwTime = MCI_MAKE_MSF(wMinutes, wSeconds, wFrames);
171 TRACE("MSF %02u:%02u:%02u -> dwTime=%lu\n",
172 wMinutes, wSeconds, wFrames, dwTime);
173 *lpRet = MCI_COLONIZED3_RETURN;
174 break;
175 case MCI_FORMAT_TMSF:
176 default: /* unknown format ! force TMSF ! ... */
177 if (dwFrame < wmcda->wcda.dwFirstFrame || dwFrame > wmcda->wcda.dwLastFrame) {
178 ERR("Out of range value %lu [%lu,%lu]\n",
179 dwFrame, wmcda->wcda.dwFirstFrame, wmcda->wcda.dwLastFrame);
180 *lpRet = 0;
181 return 0;
182 }
183 for (wTrack = 1; wTrack < wmcda->wcda.nTracks; wTrack++) {
184 if (wmcda->wcda.lpdwTrackPos[wTrack] > dwFrame)
185 break;
186 }
187 dwFrame -= wmcda->wcda.lpdwTrackPos[wTrack - 1];
188 wMinutes = dwFrame / CDFRAMES_PERMIN;
189 wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
190 wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes - CDFRAMES_PERSEC * wSeconds;
191 dwTime = MCI_MAKE_TMSF(wTrack, wMinutes, wSeconds, wFrames);
192 TRACE("%02u-%02u:%02u:%02u\n", wTrack, wMinutes, wSeconds, wFrames);
193 *lpRet = MCI_COLONIZED4_RETURN;
194 break;
195 }
196 return dwTime;
197}
198
199static DWORD CDAUDIO_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms);
200static DWORD CDAUDIO_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
201
202/**************************************************************************
203 * CDAUDIO_mciOpen [internal]
204 */
205static DWORD CDAUDIO_mciOpen(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpenParms)
206{
207 DWORD dwDeviceID;
208 WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID);
209 MCI_SEEK_PARMS seekParms;
210
211 dprintf(("CDAUDIO_mciOpen: (wDevID: %04X, dwFlags: %08lX, %p);\n", wDevID, dwFlags, lpOpenParms));
212
213
214 if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
215 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
216
217 dwDeviceID = lpOpenParms->wDeviceID;
218
219 if (wmcda->nUseCount > 0) {
220 /* The driver is already open on this channel */
221 /* If the driver was opened shareable before and this open specifies */
222 /* shareable then increment the use count */
223 if (wmcda->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
224 ++wmcda->nUseCount;
225 else
226 return MCIERR_MUST_USE_SHAREABLE;
227 } else {
228 wmcda->nUseCount = 1;
229 wmcda->fShareable = dwFlags & MCI_OPEN_SHAREABLE;
230 }
231 if (dwFlags & MCI_OPEN_ELEMENT) {
232 if (dwFlags & MCI_OPEN_ELEMENT_ID) {
233 WARN("MCI_OPEN_ELEMENT_ID %8lx ! Abort", (DWORD)lpOpenParms->lpstrElementName);
234 return MCIERR_NO_ELEMENT_ALLOWED;
235 }
236 /* Cdplayer.exe puts the driveletter into lpOpenParms->lpstrElementName */
237 TRACE("CDAUDIO_mciOpen(): MCI_OPEN_ELEMENT: %s\n",lpOpenParms->lpstrElementName);
238
239 if(strlen(lpOpenParms->lpstrElementName)==2)
240 strcpy(wmcda->wcda.chrDrive,lpOpenParms->lpstrElementName);/* Save */
241 /*return MCIERR_NO_ELEMENT_ALLOWED;
242 bon 19991106 allows cdplayer.exe to run*/
243 }
244 else if (dwFlags & MCI_OPEN_TYPE) {/*MCI_OPEN_TYPE 0x00002000L*/
245 TRACE("CDAUDIO_mciOpen(): MCI_OPEN_TYPE: %s\n",lpOpenParms->lpstrDeviceType);
246 wmcda->wcda.chrDrive[0]=0; /* Mark that we don't have a drive */
247 if(lpOpenParms->lpstrDeviceType)
248 strncpy(wmcda->wcda.chrDeviceType,lpOpenParms->lpstrDeviceType,sizeof(wmcda->wcda.chrDeviceType)-1);
249 else
250 wmcda->wcda.chrDeviceType[0]=0;
251 }
252
253 wmcda->wNotifyDeviceID = dwDeviceID;
254
255
256 if (!CDAUDIO_Open(&wmcda->wcda)) {
257#if 0
258 /* We're always successful because we open the driver not the disk */
259 --wmcda->nUseCount;
260 return MCIERR_HARDWARE;
261#endif
262 }
263
264 wmcda->mciMode = MCI_MODE_STOP;
265 wmcda->dwTimeFormat = MCI_FORMAT_MSF;
266 if (!CDAUDIO_GetTracksInfo(&wmcda->wcda)) {
267 WARN("error reading TracksInfo !\n");
268 //CDAUDIO_Close(&wmcda->wcda);
269 //return MCIERR_INTERNAL;
270 }
271
272 //CDAUDIO_mciSeek(wDevID, MCI_SEEK_TO_START, &seekParms);
273
274 return 0;
275}
276
277/**************************************************************************
278 * CDAUDIO_mciClose [internal]
279 */
280static DWORD CDAUDIO_mciClose(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
281{
282 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
283
284 TRACE("Entering CDAUDIO_mciClose... (%04X, %08lX, %p) wmcd: %X;\n", wDevID, dwParam, lpParms, wmcda);
285
286 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
287
288 if (wmcda->nUseCount == 1) {
289 CDAUDIO_Close(&wmcda->wcda);
290 }
291 wmcda->nUseCount--;
292 return 0;
293}
294
295/**************************************************************************
296 * CDAUDIO_mciGetDevCaps [internal]
297 */
298static DWORD CDAUDIO_mciGetDevCaps(UINT wDevID, DWORD dwFlags,
299 LPMCI_GETDEVCAPS_PARMS lpParms)
300{
301 DWORD ret = 0;
302
303 TRACE("CDAUDIO_mciGetDevCaps: (%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
304
305 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
306
307 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
308 TRACE("MCI_GETDEVCAPS_ITEM dwItem=%08lX;\n", lpParms->dwItem);
309
310 switch (lpParms->dwItem) {
311 case MCI_GETDEVCAPS_CAN_RECORD: /* 0x00000001L */
312 lpParms->dwReturn = FALSE;
313 break;
314 case MCI_GETDEVCAPS_HAS_AUDIO: /* 0x00000002L */
315 lpParms->dwReturn = TRUE;
316 break;
317 case MCI_GETDEVCAPS_HAS_VIDEO: /* 0x00000003L */
318 lpParms->dwReturn = FALSE;
319 break;
320 case MCI_GETDEVCAPS_DEVICE_TYPE: /* 0x00000004L */
321 lpParms->dwReturn = MCI_DEVTYPE_CD_AUDIO;
322 break;
323 case MCI_GETDEVCAPS_USES_FILES: /* 0x00000005L */
324 lpParms->dwReturn = FALSE;
325 break;
326 case MCI_GETDEVCAPS_COMPOUND_DEVICE: /* 0x00000006L */
327 lpParms->dwReturn = FALSE;
328 break;
329 case MCI_GETDEVCAPS_CAN_EJECT: /* 0x00000007L*/
330 lpParms->dwReturn = TRUE;
331 break;
332 case MCI_GETDEVCAPS_CAN_PLAY: /* 0x00000008L*/
333 lpParms->dwReturn = TRUE;
334 break;
335 case MCI_GETDEVCAPS_CAN_SAVE: /* 0x00000009L */
336 lpParms->dwReturn = FALSE;
337 break;
338 default:
339 ERR("Unsupported %lx devCaps item\n", lpParms->dwItem);
340 return MCIERR_UNRECOGNIZED_COMMAND;
341 }
342 } else {
343 TRACE("No GetDevCaps-Item !\n");
344 return MCIERR_UNRECOGNIZED_COMMAND;
345 }
346 TRACE("lpParms->dwReturn=%08lX;\n", lpParms->dwReturn);
347 return ret;
348
349#if 0
350 /* This is Wine stuff */
351 if (dwFlags & MCI_GETDEVCAPS_ITEM) {
352 TRACE("MCI_GETDEVCAPS_ITEM dwItem=%08lX;\n", lpParms->dwItem);
353
354 switch (lpParms->dwItem) {
355 case MCI_GETDEVCAPS_CAN_RECORD: /* 0x00000001L */
356 lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
357 ret = MCI_RESOURCE_RETURNED;
358 break;
359 case MCI_GETDEVCAPS_HAS_AUDIO: /* 0x00000002L */
360 lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
361 ret = MCI_RESOURCE_RETURNED;
362 break;
363 case MCI_GETDEVCAPS_HAS_VIDEO: /* 0x00000003L */
364 lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
365 ret = MCI_RESOURCE_RETURNED;
366 break;
367 case MCI_GETDEVCAPS_DEVICE_TYPE: /* 0x00000004L */
368 lpParms->dwReturn = MAKEMCIRESOURCE(MCI_DEVTYPE_CD_AUDIO, MCI_DEVTYPE_CD_AUDIO);
369 ret = MCI_RESOURCE_RETURNED;
370 break;
371 case MCI_GETDEVCAPS_USES_FILES: /* 0x00000005L */
372 lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
373 ret = MCI_RESOURCE_RETURNED;
374 break;
375 case MCI_GETDEVCAPS_COMPOUND_DEVICE: /* 0x00000006L */
376 lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
377 ret = MCI_RESOURCE_RETURNED;
378 break;
379 case MCI_GETDEVCAPS_CAN_EJECT: /* 0x00000007L*/
380 lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
381 ret = MCI_RESOURCE_RETURNED;
382 break;
383 case MCI_GETDEVCAPS_CAN_PLAY: /* 0x00000008L*/
384 lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
385 ret = MCI_RESOURCE_RETURNED;
386 break;
387 case MCI_GETDEVCAPS_CAN_SAVE: /* 0x00000009L */
388 lpParms->dwReturn = MAKEMCIRESOURCE(FALSE, MCI_FALSE);
389 ret = MCI_RESOURCE_RETURNED;
390 break;
391 default:
392 ERR("Unsupported %lx devCaps item\n", lpParms->dwItem);
393 return MCIERR_UNRECOGNIZED_COMMAND;
394 }
395 } else {
396 TRACE("No GetDevCaps-Item !\n");
397 return MCIERR_UNRECOGNIZED_COMMAND;
398 }
399 TRACE("lpParms->dwReturn=%08lX;\n", lpParms->dwReturn);
400 return ret;
401#endif
402}
403
404/**************************************************************************
405 * CDAUDIO_mciInfo [internal]
406 */
407static DWORD CDAUDIO_mciInfo(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSA lpParms)
408{
409 LPSTR str = NULL;
410 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
411 DWORD ret = 0;
412 char buffer[16];
413
414 TRACE("Entering CDAUDIO_mciInfo... (%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
415
416 if (lpParms == NULL || lpParms->lpstrReturn == NULL)
417 return MCIERR_NULL_PARAMETER_BLOCK;
418 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
419
420 TRACE("buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize);
421
422 if (dwFlags & MCI_INFO_PRODUCT) {/* 0x00000100L */
423 str = "Odins audio CD";
424 } else if (dwFlags & MCI_INFO_MEDIA_UPC) { /* 0x00000400L */
425 // ret = MCIERR_NO_IDENTITY;
426 ret = 0; // No Info about MCIERR_NO_IDENTITY
427 } else if (dwFlags & MCI_INFO_MEDIA_IDENTITY) { /* 0x00000800L */
428 DWORD msf, res = 0, dummy;
429 int i;
430
431 if (!CDAUDIO_GetCDStatus(&wmcda->wcda)) {
432 return CDAUDIO_mciGetError(wmcda);
433 }
434
435 for (i = 0; i < wmcda->wcda.nTracks; i++) {
436 msf = CDAUDIO_CalcTime(wmcda, MCI_FORMAT_MSF, wmcda->wcda.lpdwTrackPos[i], &dummy);
437 res += (MCI_MSF_MINUTE(msf) << 16) +
438 (MCI_MSF_SECOND(msf) << 8) +
439 (MCI_MSF_FRAME(msf));
440 }
441 if (wmcda->wcda.nTracks <= 2) {
442 /* there are some other values added when # of tracks < 3
443 * for most Audio CD it will do without
444 */
445 FIXME("Value is not correct !! "
446 "Please report will full audio CD information (-debugmsg +cdaudio)\n");
447 }
448 sprintf(buffer, "%lu", res);
449 str = buffer;
450 } else {
451 WARN("Don't know this info command (%lu)\n", dwFlags);
452 ret = MCIERR_UNRECOGNIZED_COMMAND;
453 }
454 if (str) {
455 if (lpParms->dwRetSize <= strlen(str)) {
456 lstrcpynA(lpParms->lpstrReturn, str, lpParms->dwRetSize - 1);
457 ret = MCIERR_PARAM_OVERFLOW;
458 } else {
459 strcpy(lpParms->lpstrReturn, str);
460 }
461 } else {
462 *lpParms->lpstrReturn = 0;
463 }
464 TRACE("CDAUDIO_mciInfo returns => %s (ret=%ld)\n", lpParms->lpstrReturn, ret);
465 return ret;
466}
467
468/**************************************************************************
469 * CDAUDIO_mciStatus [internal]
470 */
471static DWORD CDAUDIO_mciStatus(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
472{
473 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
474 DWORD ret = 0;
475
476 TRACE("Entering CDAUDIO_mciStatus (%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
477
478 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
479 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
480
481 if (dwFlags & MCI_NOTIFY) {
482 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
483 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
484 wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
485 }
486 if (dwFlags & MCI_STATUS_ITEM) { /* MCI_STATUS_ITEM 0x00000100L */
487 TRACE("item: %lx!\n", lpParms->dwItem);
488 switch (lpParms->dwItem) {
489 case MCI_STATUS_CURRENT_TRACK: /* 0x00000008L */
490 if (!CDAUDIO_GetCDStatus(&wmcda->wcda)) {
491 return CDAUDIO_mciGetError(wmcda);
492 }
493 lpParms->dwReturn = wmcda->wcda.nCurTrack;
494 TRACE("CURRENT_TRACK=%lu!\n", lpParms->dwReturn);
495 break;
496 case MCI_STATUS_LENGTH: /* 0x00000001L */
497 if (wmcda->wcda.nTracks == 0) {
498 if (!CDAUDIO_GetTracksInfo(&wmcda->wcda)) {
499 WARN("error reading TracksInfo !\n");
500 return CDAUDIO_mciGetError(wmcda);
501 }
502 }
503 if (dwFlags & MCI_TRACK) {
504 TRACE("MCI_TRACK #%lu LENGTH=??? !\n", lpParms->dwTrack);
505 if (lpParms->dwTrack > wmcda->wcda.nTracks || lpParms->dwTrack == 0)
506 return MCIERR_OUTOFRANGE;
507 lpParms->dwReturn = wmcda->wcda.lpdwTrackLen[lpParms->dwTrack - 1];
508 } else {
509 lpParms->dwReturn = wmcda->wcda.dwLastFrame;
510 }
511 lpParms->dwReturn = CDAUDIO_CalcTime(wmcda,
512 (wmcda->dwTimeFormat == MCI_FORMAT_TMSF)
513 ? MCI_FORMAT_MSF : wmcda->dwTimeFormat,
514 lpParms->dwReturn,
515 &ret);
516 TRACE("LENGTH=%lu !\n", lpParms->dwReturn);
517 break;
518 case MCI_STATUS_MODE: /* 0x00000004L */
519 if (!CDAUDIO_GetCDStatus(&wmcda->wcda))
520 return CDAUDIO_mciGetError(wmcda);
521 lpParms->dwReturn = CDAUDIO_mciMode(wmcda->wcda.cdaMode);
522 if (!lpParms->dwReturn)
523 lpParms->dwReturn = wmcda->mciMode;
524 TRACE("MCI_STATUS_MODE=%08lX !\n", lpParms->dwReturn);
525#if 0
526 /* What's Wine doing here??? */
527 lpParms->dwReturn = MAKEMCIRESOURCE(lpParms->dwReturn, lpParms->dwReturn);
528 ret = MCI_RESOURCE_RETURNED;
529#endif
530 break;
531 case MCI_STATUS_MEDIA_PRESENT: /* 0x00000005L */
532 if (!CDAUDIO_GetCDStatus(&wmcda->wcda))
533 return CDAUDIO_mciGetError(wmcda);
534 lpParms->dwReturn = (wmcda->wcda.nTracks == 0) ? FALSE : TRUE;
535 TRACE("MCI_STATUS_MEDIA_PRESENT =%c!\n", LOWORD(lpParms->dwReturn) ? 'Y' : 'N');
536#if 0
537 /* What's Wine doing here??? */
538 lpParms->dwReturn = (wmcda->wcda.nTracks == 0) ?
539 MAKEMCIRESOURCE(FALSE, MCI_FALSE) : MAKEMCIRESOURCE(TRUE, MCI_TRUE);
540 TRACE("MCI_STATUS_MEDIA_PRESENT =%c!\n", LOWORD(lpParms->dwReturn) ? 'Y' : 'N');
541 ret = MCI_RESOURCE_RETURNED;
542#endif
543 break;
544 case MCI_STATUS_NUMBER_OF_TRACKS: /* 0x00000003L */
545 lpParms->dwReturn = CDAUDIO_GetNumberOfTracks(&wmcda->wcda);
546 TRACE("MCI_STATUS_NUMBER_OF_TRACKS = %lu !\n", lpParms->dwReturn);
547 if (lpParms->dwReturn == (WORD)-1)
548 return CDAUDIO_mciGetError(wmcda);
549 break;
550 case MCI_STATUS_POSITION: /* 0x00000002L */
551 if (!CDAUDIO_GetCDStatus(&wmcda->wcda))
552 return CDAUDIO_mciGetError(wmcda);
553 lpParms->dwReturn = wmcda->wcda.dwCurFrame;
554 if (dwFlags & MCI_STATUS_START) {
555 lpParms->dwReturn = wmcda->wcda.dwFirstFrame;
556 TRACE("get MCI_STATUS_START !\n");
557 }
558 if (dwFlags & MCI_TRACK) {
559 if (lpParms->dwTrack > wmcda->wcda.nTracks || lpParms->dwTrack == 0)
560 return MCIERR_OUTOFRANGE;
561#ifndef __WIN32OS2__
562 if(wmcda->wcda.nCurTrack)
563#endif
564 lpParms->dwReturn = wmcda->wcda.lpdwTrackPos[lpParms->dwTrack - 1];
565 //TRACE("get MCI_TRACK #%lu, track position: %lu !\n", lpParms->dwTrack, lpParms->dwReturn);
566 }
567 lpParms->dwReturn = CDAUDIO_CalcTime(wmcda, wmcda->dwTimeFormat, lpParms->dwReturn, &ret);
568 TRACE("MCI_STATUS_POSITION=%08lX, track %d !\n", lpParms->dwReturn, lpParms->dwTrack);
569 break;
570 case MCI_STATUS_READY: /* 0x00000007L */
571 TRACE("MCI_STATUS_READY !\n");
572 lpParms->dwReturn = (wmcda->wcda.cdaMode == WINE_CDA_DONTKNOW ||
573 wmcda->wcda.cdaMode == WINE_CDA_NOTREADY) ? FALSE : TRUE;
574 TRACE("MCI_STATUS_READY=%u!\n", LOWORD(lpParms->dwReturn));
575#if 0
576 /* What's Wine doing here??? */
577 lpParms->dwReturn = (wmcda->wcda.cdaMode == WINE_CDA_DONTKNOW ||
578 wmcda->wcda.cdaMode == WINE_CDA_NOTREADY) ?
579 MAKEMCIRESOURCE(FALSE, MCI_FALSE) : MAKEMCIRESOURCE(TRUE, MCI_TRUE);
580 TRACE("MCI_STATUS_READY=%u!\n", LOWORD(lpParms->dwReturn));
581 ret = MCI_RESOURCE_RETURNED;
582#endif
583 break;
584 case MCI_STATUS_TIME_FORMAT: /* 0x00000006L */
585#if 0
586 /* What's Wine doing here??? */
587 lpParms->dwReturn = MAKEMCIRESOURCE(wmcda->dwTimeFormat, wmcda->dwTimeFormat);
588 ret = MCI_RESOURCE_RETURNED;
589#endif
590 lpParms->dwReturn = wmcda->dwTimeFormat;
591 TRACE("MCI_STATUS_TIME_FORMAT=%08x!\n", LOWORD(lpParms->dwReturn));
592 break;
593 case 4001: /* FIXME: for boggus FullCD */
594 case MCI_CDA_STATUS_TYPE_TRACK:
595 if (!(dwFlags & MCI_TRACK))
596 ret = MCIERR_MISSING_PARAMETER;
597 else if (lpParms->dwTrack > wmcda->wcda.nTracks || lpParms->dwTrack == 0)
598 ret = MCIERR_OUTOFRANGE;
599 else
600 lpParms->dwReturn = (wmcda->wcda.lpbTrackFlags[lpParms->dwTrack - 1] &
601 CDROM_DATA_TRACK) ? MCI_CDA_TRACK_OTHER : MCI_CDA_TRACK_AUDIO;
602 TRACE("MCI_CDA_STATUS_TYPE_TRACK[%ld]=%08lx\n", lpParms->dwTrack, lpParms->dwReturn);
603 break;
604 default:
605 FIXME("unknown command %08lX !\n", lpParms->dwItem);
606 return MCIERR_UNRECOGNIZED_COMMAND;
607 }
608 } else {
609 WARN("not MCI_STATUS_ITEM !\n");
610 }
611 return ret;
612}
613
614/**************************************************************************
615 * CDAUDIO_mciPlay [internal]
616 */
617static DWORD CDAUDIO_mciPlay(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
618{
619 int start, end;
620 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
621 DWORD ret = 0;
622
623 TRACE("Entering CDAUDIO_mciPlay (%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
624
625 if (lpParms == NULL) {
626 ret = MCIERR_NULL_PARAMETER_BLOCK;
627 } else if (wmcda == NULL) {
628 ret = MCIERR_INVALID_DEVICE_ID;
629 } else {
630 if (wmcda->wcda.nTracks == 0) {
631 if (!CDAUDIO_GetTracksInfo(&wmcda->wcda)) {
632 WARN("error reading TracksInfo !\n");
633 return MCIERR_DRIVER_INTERNAL;
634 }
635 }
636 wmcda->wcda.nCurTrack = 1;
637 if (dwFlags & MCI_FROM) {
638 start = CDAUDIO_CalcFrame(wmcda, lpParms->dwFrom);
639 TRACE("MCI_FROM=%08lX -> %u \n", lpParms->dwFrom, start);
640 } else {
641 if (!CDAUDIO_GetCDStatus(&wmcda->wcda)) return MCIERR_DRIVER_INTERNAL;
642 start = wmcda->wcda.dwCurFrame;
643 }
644 if (dwFlags & MCI_TO) {
645 end = CDAUDIO_CalcFrame(wmcda, lpParms->dwTo);
646 TRACE("MCI_TO=%08lX -> %u \n", lpParms->dwTo, end);
647 } else {
648 end = wmcda->wcda.dwLastFrame;
649 }
650
651 if (CDAUDIO_Play(&wmcda->wcda, start, end) == -1)
652 return MCIERR_HARDWARE;
653 wmcda->mciMode = MCI_MODE_PLAY;
654 if (dwFlags & MCI_NOTIFY) {
655 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
656 /*
657 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
658 wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
659 */
660 }
661 }
662 return ret;
663}
664
665/**************************************************************************
666 * CDAUDIO_mciStop [internal]
667 */
668static DWORD CDAUDIO_mciStop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
669{
670 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
671
672 TRACE("Entering CDAUDIO_mciStop (%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
673
674 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
675
676 if (CDAUDIO_Stop(&wmcda->wcda) == -1)
677 return MCIERR_HARDWARE;
678
679 wmcda->mciMode = MCI_MODE_STOP;
680 if (lpParms && (dwFlags & MCI_NOTIFY)) {
681 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
682 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
683 wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
684 }
685 return 0;
686}
687
688/**************************************************************************
689 * CDAUDIO_mciPause [internal]
690 */
691static DWORD CDAUDIO_mciPause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
692{
693 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
694
695 TRACE("Entering CDAUDIO_mciPause (%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
696
697 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
698
699 if (CDAUDIO_Pause(&wmcda->wcda, 1) == -1)
700 return MCIERR_HARDWARE;
701 wmcda->mciMode = MCI_MODE_PAUSE;
702 if (lpParms && (dwFlags & MCI_NOTIFY)) {
703 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
704 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
705 wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
706 }
707 return 0;
708}
709
710/**************************************************************************
711 * CDAUDIO_mciResume [internal]
712 */
713static DWORD CDAUDIO_mciResume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
714{
715 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
716
717 TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
718
719 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
720
721 if (CDAUDIO_Pause(&wmcda->wcda, 0) == -1)
722 return MCIERR_HARDWARE;
723 wmcda->mciMode = MCI_MODE_STOP;
724 if (lpParms && (dwFlags & MCI_NOTIFY)) {
725 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
726 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
727 wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
728 }
729 return 0;
730}
731
732/**************************************************************************
733 * CDAUDIO_mciSeek [internal]
734 */
735static DWORD CDAUDIO_mciSeek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
736{
737 DWORD at;
738 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
739
740 TRACE("Entering CDAUDIO_mciSeek (%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
741
742 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
743 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
744
745 wmcda->mciMode = MCI_MODE_SEEK;
746 switch (dwFlags & ~(MCI_NOTIFY|MCI_WAIT)) {
747 case MCI_SEEK_TO_START:
748 TRACE("Seeking to start\n");
749 at = wmcda->wcda.dwFirstFrame;
750 break;
751 case MCI_SEEK_TO_END:
752 TRACE("Seeking to end\n");
753 at = wmcda->wcda.dwLastFrame;
754 break;
755 case MCI_TO: /* 0x00000008L */
756 TRACE("Seeking to %lu\n", lpParms->dwTo);
757 at = lpParms->dwTo;
758 break;
759 default:
760 TRACE("Seeking to ??=%lu\n", dwFlags);
761 return MCIERR_UNSUPPORTED_FUNCTION;
762 }
763 if (CDAUDIO_Seek(&wmcda->wcda, at) == -1) {
764 return MCIERR_HARDWARE;
765 }
766 if (dwFlags & MCI_NOTIFY) {
767 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
768 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
769 wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
770 }
771 return 0;
772}
773
774/**************************************************************************
775 * CDAUDIO_mciSetDoor [internal]
776 */
777static DWORD CDAUDIO_mciSetDoor(UINT wDevID, int open)
778{
779 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
780
781 TRACE("(%04x, %s) !\n", wDevID, (open) ? "OPEN" : "CLOSE");
782
783 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
784
785 if (CDAUDIO_SetDoor(&wmcda->wcda, open) == -1)
786 return MCIERR_HARDWARE;
787 wmcda->mciMode = (open) ? MCI_MODE_OPEN : MCI_MODE_STOP;
788 return 0;
789}
790
791/**************************************************************************
792 * CDAUDIO_mciSet [internal]
793 */
794static DWORD CDAUDIO_mciSet(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
795{
796 WINE_MCICDAUDIO* wmcda = CDAUDIO_mciGetOpenDrv(wDevID);
797
798 TRACE("Entering CDAUDIO_mciSet (%04X, %08lX, %p, %08lX);\n", wDevID, dwFlags, lpParms, wmcda);
799
800 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
801 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;;
802
803 TRACE("dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
804 TRACE("dwAudio=%08lX\n", lpParms->dwAudio);
805
806 if (dwFlags & MCI_SET_TIME_FORMAT) {
807 switch (lpParms->dwTimeFormat) {
808 case MCI_FORMAT_MILLISECONDS: /* 0 */
809 TRACE("MCI_FORMAT_MILLISECONDS !\n");
810 break;
811 case MCI_FORMAT_MSF: /* 2 */
812 TRACE("MCI_FORMAT_MSF !\n");
813 break;
814#if 0
815 case MCI_FORMAT_FRAMES: /* 3 */
816 TRACE("MCI_FORMAT_FRAMES !\n");
817 break;
818 case MCI_FORMAT_SAMPLES: /* 9 */
819 TRACE("MCI_FORMAT_SAMPLES !\n");
820 break;
821#endif
822 case MCI_FORMAT_TMSF: /* 10 */
823 TRACE("MCI_FORMAT_TMSF !\n");
824 break;
825 default:
826 WARN("bad time format !\n");
827 return MCIERR_BAD_TIME_FORMAT;
828 }
829 wmcda->dwTimeFormat = lpParms->dwTimeFormat;
830 } /* end of if (dwFlags & MCI_SET_TIME_FORMAT) */
831
832 if (dwFlags & MCI_SET_DOOR_OPEN) {
833 CDAUDIO_mciSetDoor(wDevID, TRUE);
834 }
835 if (dwFlags & MCI_SET_DOOR_CLOSED) {
836 CDAUDIO_mciSetDoor(wDevID, FALSE);
837 }
838
839 if (dwFlags & MCI_SET_ON){
840 if(dwFlags & MCI_SET_AUDIO) {
841 TRACE("MCI_SET_AUDIO -> %x !\n",lpParms->dwAudio);
842 FIXME("FIXME: MCI_SET_ON for cdaudio not implemented (is it necessary?)\n");
843 return 0;
844 }
845 }
846
847 if (dwFlags & MCI_SET_VIDEO) return MCIERR_UNSUPPORTED_FUNCTION;
848 if (dwFlags & MCI_SET_OFF) return MCIERR_UNSUPPORTED_FUNCTION;
849 if (dwFlags & MCI_NOTIFY) {
850 TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n",
851 lpParms->dwCallback);
852 mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
853 wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
854 }
855 return 0;
856}
857
858/**************************************************************************
859 * MCICDAUDIO_DriverProc [sample driver]
860 */
861LONG CALLBACK MCICDAUDIO_DriverProc(DWORD dwDevID, HDRVR hDriv, DWORD wMsg,
862 DWORD dwParam1, DWORD dwParam2)
863{
864
865 switch(wMsg) {
866 case DRV_LOAD: return 1;
867 case DRV_FREE: return 1;
868 case DRV_OPEN: return CDAUDIO_drvOpen((LPSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSA)dwParam2);
869 case DRV_CLOSE: return CDAUDIO_drvClose(dwDevID);
870 case DRV_ENABLE: return 1;
871 case DRV_DISABLE: return 1;
872 case DRV_QUERYCONFIGURE:
873 TRACE("Received DRV_QUERYCONFIGURE command [%lu] \n", wMsg);
874 return 0; /* We can't configure */
875 case DRV_CONFIGURE:
876 TRACE("Received DRV_CONFIGURE command [%lu] \n", wMsg);
877 //MessageBoxA(0, "CD audio Driver !", "Odin Driver", MB_OK);
878 return 1;
879 case DRV_INSTALL: return DRVCNF_RESTART;
880 case DRV_REMOVE: return DRVCNF_RESTART;
881
882 case MCI_OPEN_DRIVER: return CDAUDIO_mciOpen(dwDevID, dwParam1, (LPMCI_OPEN_PARMSA)dwParam2);
883 case MCI_CLOSE_DRIVER: return CDAUDIO_mciClose(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
884 case MCI_GETDEVCAPS: return CDAUDIO_mciGetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
885 case MCI_INFO: return CDAUDIO_mciInfo(dwDevID, dwParam1, (LPMCI_INFO_PARMSA)dwParam2);
886 case MCI_STATUS: return CDAUDIO_mciStatus(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
887 case MCI_SET: return CDAUDIO_mciSet(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
888 case MCI_PLAY: return CDAUDIO_mciPlay(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
889 case MCI_STOP: return CDAUDIO_mciStop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
890 case MCI_PAUSE: return CDAUDIO_mciPause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
891 case MCI_RESUME: return CDAUDIO_mciResume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
892 case MCI_SEEK: return CDAUDIO_mciSeek(dwDevID, dwParam1, (LPMCI_SEEK_PARMS)dwParam2);
893 /* FIXME: I wonder if those two next items are really called ? */
894 case MCI_SET_DOOR_OPEN: return CDAUDIO_mciSetDoor(dwDevID, TRUE);
895 case MCI_SET_DOOR_CLOSED: return CDAUDIO_mciSetDoor(dwDevID, FALSE);
896 /* commands that should be supported */
897 case MCI_LOAD:
898 case MCI_SAVE:
899 case MCI_FREEZE:
900 case MCI_PUT:
901 case MCI_REALIZE:
902 case MCI_UNFREEZE:
903 case MCI_UPDATE:
904 case MCI_WHERE:
905 case MCI_STEP:
906 case MCI_SPIN:
907 case MCI_ESCAPE:
908 case MCI_COPY:
909 case MCI_CUT:
910 case MCI_DELETE:
911 case MCI_PASTE:
912 FIXME("Unsupported yet command [%lu]\n", wMsg);
913 break;
914 /* commands that should report an error */
915 case MCI_WINDOW:
916 TRACE("Received command [%lu] (MCI_WINDOW). Why do we get video messages???\n", wMsg);
917 break;
918 case MCI_CONFIGURE:
919 TRACE("Received Command [%lu] (MCI_CONFIGURE). Why do we get video messages???\n", wMsg);
920 break;
921
922
923 case MCI_OPEN:
924 case MCI_CLOSE:
925 ERR("Shouldn't receive a MCI_OPEN or CLOSE message\n");
926 break;
927 default:
928 TRACE("Sending msg [%lXh] to default driver proc\n", wMsg);
929 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
930 }
931 return MCIERR_UNRECOGNIZED_COMMAND;
932}
933
934/*-----------------------------------------------------------------------*/
Note: See TracBrowser for help on using the repository browser.