ReactOS  0.4.14-dev-57-g333b8f1
mcicda.c
Go to the documentation of this file.
1 /*
2  * MCI driver for audio CD (MCICDA)
3  *
4  * Copyright 1994 Martin Ayotte
5  * Copyright 1998-99 Eric Pouech
6  * Copyright 2000 Andreas Mohr
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include "config.h"
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <string.h>
27 
28 #define WIN32_NO_STATUS
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "winuser.h"
33 #include "wownt32.h"
34 #include "mmddk.h"
35 #include "winioctl.h"
36 #include "ntddcdrm.h"
37 #include "wine/winternl.h"
38 #include "wine/debug.h"
39 #include "wine/unicode.h"
40 #include "dsound.h"
41 
43 
44 #define CDFRAMES_PERSEC 75
45 #define CDFRAMES_PERMIN (CDFRAMES_PERSEC * 60)
46 #define FRAME_OF_ADDR(a) ((a)[1] * CDFRAMES_PERMIN + (a)[2] * CDFRAMES_PERSEC + (a)[3])
47 #define FRAME_OF_TOC(toc, idx) FRAME_OF_ADDR((toc).TrackData[idx - (toc).FirstTrack].Address)
48 
49 /* Defined by red-book standard; do not change! */
50 #define RAW_SECTOR_SIZE (2352)
51 
52 /* Must be >= RAW_SECTOR_SIZE */
53 #define CDDA_FRAG_SIZE (32768)
54 /* Must be >= 2 */
55 #define CDDA_FRAG_COUNT (3)
56 
57 typedef struct {
59  int nUseCount; /* Incremented for each shared open */
60  BOOL fShareable; /* TRUE if first open was shareable */
61  MCIDEVICEID wNotifyDeviceID; /* MCI device ID with a pending notification */
62  HANDLE hCallback; /* Callback handle for pending notification */
65 
66  /* The following are used for digital playback only */
70 
71  IDirectSound *dsObj;
72  IDirectSoundBuffer *dsBuf;
73 
76 
77 /*-----------------------------------------------------------------------*/
78 
81 
83 {
84  const char *str;
86 
87 #define XX(x) case (x): str = #x; break
88  switch (code)
89  {
100  default: str = wine_dbg_sprintf("UNKNOWN (0x%x)", code);
101  };
102 #undef XX
103  TRACE("Device %p, Code %s -> Return %d, Bytes %u\n", dev, str, ret, *retsize);
104  return ret;
105 }
106 
108 {
110  DWORD lastPos, curPos, endPos, br;
111  void *cdData;
112  DWORD lockLen, fragLen;
113  DSBCAPS caps;
114  RAW_READ_INFO rdInfo;
115  HRESULT hr = DS_OK;
116 
117  memset(&caps, 0, sizeof(caps));
118  caps.dwSize = sizeof(caps);
119  hr = IDirectSoundBuffer_GetCaps(wmcda->dsBuf, &caps);
120 
121  fragLen = caps.dwBufferBytes/CDDA_FRAG_COUNT;
122  curPos = lastPos = 0;
123  endPos = ~0u;
124  while (SUCCEEDED(hr) && endPos != lastPos &&
127  if ((curPos-lastPos+caps.dwBufferBytes)%caps.dwBufferBytes < fragLen) {
128  Sleep(1);
129  continue;
130  }
131 
132  EnterCriticalSection(&wmcda->cs);
133  rdInfo.DiskOffset.QuadPart = wmcda->start<<11;
134  rdInfo.SectorCount = min(fragLen/RAW_SECTOR_SIZE, wmcda->end-wmcda->start);
135  rdInfo.TrackMode = CDDA;
136 
137  hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, lastPos, fragLen, &cdData, &lockLen, NULL, NULL, 0);
138  if (hr == DSERR_BUFFERLOST) {
141  LeaveCriticalSection(&wmcda->cs);
142  break;
143  }
144  hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, lastPos, fragLen, &cdData, &lockLen, NULL, NULL, 0);
145  }
146 
147  if (SUCCEEDED(hr)) {
148  if (rdInfo.SectorCount > 0) {
149  if (!device_io(wmcda->handle, IOCTL_CDROM_RAW_READ, &rdInfo, sizeof(rdInfo), cdData, lockLen, &br, NULL))
150  WARN("CD read failed at sector %d: 0x%x\n", wmcda->start, GetLastError());
151  }
152  if (rdInfo.SectorCount*RAW_SECTOR_SIZE < lockLen) {
153  if(endPos == ~0u) endPos = lastPos;
154  memset((BYTE*)cdData + rdInfo.SectorCount*RAW_SECTOR_SIZE, 0,
155  lockLen - rdInfo.SectorCount*RAW_SECTOR_SIZE);
156  }
157  hr = IDirectSoundBuffer_Unlock(wmcda->dsBuf, cdData, lockLen, NULL, 0);
158  }
159 
160  lastPos += fragLen;
161  lastPos %= caps.dwBufferBytes;
162  wmcda->start += rdInfo.SectorCount;
163 
164  LeaveCriticalSection(&wmcda->cs);
165  }
167  SetEvent(wmcda->stopEvent);
168 
169  /* A design bug in native: the independent CD player called by the
170  * MCI has no means to signal end of playing, therefore the MCI
171  * notification is left hanging. MCI_NOTIFY_SUPERSEDED will be
172  * signaled by the next command that has MCI_NOTIFY set (or
173  * MCI_NOTIFY_ABORTED for MCI_PLAY). */
174 
175  return 0;
176 }
177 
178 
179 
180 /**************************************************************************
181  * MCICDA_drvOpen [internal]
182  */
184 {
185  static HMODULE dsHandle;
186  WINE_MCICDAUDIO* wmcda;
187 
188  if (!modp) return 0xFFFFFFFF;
189  /* FIXME: MCIERR_CANNOT_LOAD_DRIVER if there's no drive of type CD-ROM */
190 
192 
193  if (!wmcda)
194  return 0;
195 
196  if (!dsHandle) {
197  dsHandle = LoadLibraryA("dsound.dll");
198  if(dsHandle)
199  pDirectSoundCreate = (LPDIRECTSOUNDCREATE)GetProcAddress(dsHandle, "DirectSoundCreate");
200  }
201 
202  wmcda->wDevID = modp->wDeviceID;
203  mciSetDriverData(wmcda->wDevID, (DWORD_PTR)wmcda);
205  modp->wType = MCI_DEVTYPE_CD_AUDIO;
206  InitializeCriticalSection(&wmcda->cs);
207  wmcda->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": WINE_MCICDAUDIO.cs");
208  return modp->wDeviceID;
209 }
210 
211 /**************************************************************************
212  * MCICDA_drvClose [internal]
213  */
214 static DWORD MCICDA_drvClose(DWORD dwDevID)
215 {
217 
218  if (wmcda) {
219  wmcda->cs.DebugInfo->Spare[0] = 0;
220  DeleteCriticalSection(&wmcda->cs);
221  HeapFree(GetProcessHeap(), 0, wmcda);
222  mciSetDriverData(dwDevID, 0);
223  }
224  return (dwDevID == 0xFFFFFFFF) ? 1 : 0;
225 }
226 
227 /**************************************************************************
228  * MCICDA_GetOpenDrv [internal]
229  */
231 {
233 
234  if (wmcda == NULL || wmcda->nUseCount == 0) {
235  WARN("Invalid wDevID=%u\n", wDevID);
236  return 0;
237  }
238  return wmcda;
239 }
240 
241 /**************************************************************************
242  * MCICDA_mciNotify [internal]
243  *
244  * Notifications in MCI work like a 1-element queue.
245  * Each new notification request supersedes the previous one.
246  */
247 static void MCICDA_Notify(DWORD_PTR hWndCallBack, WINE_MCICDAUDIO* wmcda, UINT wStatus)
248 {
249  MCIDEVICEID wDevID = wmcda->wNotifyDeviceID;
251  if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_SUPERSEDED);
252  mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus);
253 }
254 
255 /**************************************************************************
256  * MCICDA_ReadTOC [internal]
257  */
259 {
260  if (!device_io(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0, toc, sizeof(*toc), br, NULL)) {
261  WARN("error reading TOC !\n");
262  return FALSE;
263  }
264  return TRUE;
265 }
266 
267 /**************************************************************************
268  * MCICDA_GetStatus [internal]
269  */
271 {
274  DWORD br;
276 
278  if(wmcda->hThread != 0) {
279  DWORD status;
280  HRESULT hr;
281 
283  if(SUCCEEDED(hr)) {
284  if(!(status&DSBSTATUS_PLAYING)) {
287  else
289  }
290  else
292  }
293  }
294  else if (!device_io(wmcda->handle, IOCTL_CDROM_READ_Q_CHANNEL, &fmt, sizeof(fmt),
295  &data, sizeof(data), &br, NULL)) {
297  } else {
298  switch (data.CurrentPosition.Header.AudioStatus)
299  {
301  case AUDIO_STATUS_PAUSED: mode = MCI_MODE_PAUSE; break;
306  default:
307  break;
308  }
309  }
310  return mode;
311 }
312 
313 /**************************************************************************
314  * MCICDA_GetError [internal]
315  */
317 {
318  switch (GetLastError())
319  {
321  case ERROR_NOT_SUPPORTED:
322  case ERROR_IO_DEVICE: return MCIERR_HARDWARE;
323  default:
324  FIXME("Unknown mode %u\n", GetLastError());
325  }
326  return MCIERR_DRIVER_INTERNAL;
327 }
328 
329 /**************************************************************************
330  * MCICDA_CalcFrame [internal]
331  */
333 {
334  DWORD dwFrame = 0;
335  UINT wTrack;
336  CDROM_TOC toc;
337  DWORD br;
338  BYTE* addr;
339 
340  TRACE("(%p, %08X, %u);\n", wmcda, wmcda->dwTimeFormat, dwTime);
341 
342  switch (wmcda->dwTimeFormat) {
344  dwFrame = ((dwTime - 1) * CDFRAMES_PERSEC + 500) / 1000;
345  TRACE("MILLISECONDS %u\n", dwFrame);
346  break;
347  case MCI_FORMAT_MSF:
348  TRACE("MSF %02u:%02u:%02u\n",
350  dwFrame += CDFRAMES_PERMIN * MCI_MSF_MINUTE(dwTime);
351  dwFrame += CDFRAMES_PERSEC * MCI_MSF_SECOND(dwTime);
352  dwFrame += MCI_MSF_FRAME(dwTime);
353  break;
354  case MCI_FORMAT_TMSF:
355  default: /* unknown format ! force TMSF ! ... */
356  wTrack = MCI_TMSF_TRACK(dwTime);
357  if (!device_io(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0,
358  &toc, sizeof(toc), &br, NULL))
359  return 0;
360  if (wTrack < toc.FirstTrack || wTrack > toc.LastTrack)
361  return 0;
362  TRACE("MSF %02u-%02u:%02u:%02u\n",
365  addr = toc.TrackData[wTrack - toc.FirstTrack].Address;
366  TRACE("TMSF trackpos[%u]=%d:%d:%d\n",
367  wTrack, addr[1], addr[2], addr[3]);
368  dwFrame = CDFRAMES_PERMIN * (addr[1] + MCI_TMSF_MINUTE(dwTime)) +
370  addr[3] + MCI_TMSF_FRAME(dwTime);
371  break;
372  }
373  return dwFrame;
374 }
375 
376 /**************************************************************************
377  * MCICDA_CalcTime [internal]
378  */
379 static DWORD MCICDA_CalcTime(WINE_MCICDAUDIO* wmcda, DWORD tf, DWORD dwFrame, LPDWORD lpRet)
380 {
381  DWORD dwTime = 0;
382  UINT wTrack;
383  UINT wMinutes;
384  UINT wSeconds;
385  UINT wFrames;
386  CDROM_TOC toc;
387  DWORD br;
388 
389  TRACE("(%p, %08X, %u);\n", wmcda, tf, dwFrame);
390 
391  switch (tf) {
393  dwTime = (dwFrame * 1000) / CDFRAMES_PERSEC + 1;
394  TRACE("MILLISECONDS %u\n", dwTime);
395  *lpRet = 0;
396  break;
397  case MCI_FORMAT_MSF:
398  wMinutes = dwFrame / CDFRAMES_PERMIN;
399  wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
400  wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes - CDFRAMES_PERSEC * wSeconds;
401  dwTime = MCI_MAKE_MSF(wMinutes, wSeconds, wFrames);
402  TRACE("MSF %02u:%02u:%02u -> dwTime=%u\n",
403  wMinutes, wSeconds, wFrames, dwTime);
404  *lpRet = MCI_COLONIZED3_RETURN;
405  break;
406  case MCI_FORMAT_TMSF:
407  default: /* unknown format ! force TMSF ! ... */
408  if (!device_io(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0,
409  &toc, sizeof(toc), &br, NULL))
410  return 0;
411  if (dwFrame < FRAME_OF_TOC(toc, toc.FirstTrack) ||
412  dwFrame > FRAME_OF_TOC(toc, toc.LastTrack + 1)) {
413  ERR("Out of range value %u [%u,%u]\n",
414  dwFrame, FRAME_OF_TOC(toc, toc.FirstTrack),
415  FRAME_OF_TOC(toc, toc.LastTrack + 1));
416  *lpRet = 0;
417  return 0;
418  }
419  for (wTrack = toc.FirstTrack; wTrack <= toc.LastTrack; wTrack++) {
420  if (FRAME_OF_TOC(toc, wTrack) > dwFrame)
421  break;
422  }
423  wTrack--;
424  dwFrame -= FRAME_OF_TOC(toc, wTrack);
425  wMinutes = dwFrame / CDFRAMES_PERMIN;
426  wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
427  wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes - CDFRAMES_PERSEC * wSeconds;
428  dwTime = MCI_MAKE_TMSF(wTrack, wMinutes, wSeconds, wFrames);
429  TRACE("%02u-%02u:%02u:%02u\n", wTrack, wMinutes, wSeconds, wFrames);
430  *lpRet = MCI_COLONIZED4_RETURN;
431  break;
432  }
433  return dwTime;
434 }
435 
436 static DWORD MCICDA_Stop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms);
437 
438 /**************************************************************************
439  * MCICDA_Open [internal]
440  */
441 static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpOpenParms)
442 {
443  MCIDEVICEID dwDeviceID;
444  DWORD ret;
446  WCHAR root[7], drive = 0;
447 
448  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpOpenParms);
449 
450  if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
451  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
452 
453  dwDeviceID = lpOpenParms->wDeviceID;
454 
455  if (wmcda->nUseCount > 0) {
456  /* The driver is already open on this channel */
457  /* If the driver was opened shareable before and this open specifies */
458  /* shareable then increment the use count */
459  if (wmcda->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
460  ++wmcda->nUseCount;
461  else
463  } else {
464  wmcda->nUseCount = 1;
466  }
467  if (dwFlags & MCI_OPEN_ELEMENT) {
469  WARN("MCI_OPEN_ELEMENT_ID %p! Abort\n", lpOpenParms->lpstrElementName);
471  goto the_error;
472  }
473  TRACE("MCI_OPEN_ELEMENT element name: %s\n", debugstr_w(lpOpenParms->lpstrElementName));
474  /* Only the first letter counts since w2k
475  * Win9x-NT accept only d: and w98SE accepts d:\foobar as well.
476  * Play d:\Track03.cda plays from the first track, not #3. */
477  if (!isalpha(lpOpenParms->lpstrElementName[0]))
478  {
480  goto the_error;
481  }
482  drive = toupper(lpOpenParms->lpstrElementName[0]);
483  root[0] = drive; root[1] = ':'; root[2] = '\\'; root[3] = '\0';
485  {
487  goto the_error;
488  }
489  }
490  else
491  {
492  root[0] = 'A'; root[1] = ':'; root[2] = '\\'; root[3] = '\0';
493  for ( ; root[0] <= 'Z'; root[0]++)
494  {
496  {
497  drive = root[0];
498  break;
499  }
500  }
501  if (!drive)
502  {
503  ret = MCIERR_CANNOT_LOAD_DRIVER; /* drvOpen should return this */
504  goto the_error;
505  }
506  }
507 
508  wmcda->wNotifyDeviceID = dwDeviceID;
509  wmcda->dwTimeFormat = MCI_FORMAT_MSF;
510 
511  /* now, open the handle */
512  root[0] = root[1] = '\\'; root[2] = '.'; root[3] = '\\'; root[4] = drive; root[5] = ':'; root[6] = '\0';
514  if (wmcda->handle == INVALID_HANDLE_VALUE)
515  {
517  goto the_error;
518  }
519 
520  if (dwFlags & MCI_NOTIFY) {
521  mciDriverNotify(HWND_32(LOWORD(lpOpenParms->dwCallback)),
522  dwDeviceID, MCI_NOTIFY_SUCCESSFUL);
523  }
524  return 0;
525 
526  the_error:
527  --wmcda->nUseCount;
528  return ret;
529 }
530 
531 /**************************************************************************
532  * MCICDA_Close [internal]
533  */
534 static DWORD MCICDA_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
535 {
536  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
537 
538  TRACE("(%04X, %08X, %p);\n", wDevID, dwParam, lpParms);
539 
540  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
541 
542  MCICDA_Stop(wDevID, MCI_WAIT, NULL);
543 
544  if (--wmcda->nUseCount == 0) {
545  CloseHandle(wmcda->handle);
546  }
547  if ((dwParam & MCI_NOTIFY) && lpParms)
549  return 0;
550 }
551 
552 /**************************************************************************
553  * MCICDA_GetDevCaps [internal]
554  */
556  LPMCI_GETDEVCAPS_PARMS lpParms)
557 {
559  DWORD ret = 0;
560 
561  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
562 
563  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
564  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
565 
567  TRACE("MCI_GETDEVCAPS_ITEM dwItem=%08X;\n", lpParms->dwItem);
568 
569  switch (lpParms->dwItem) {
573  break;
575  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
577  break;
581  break;
585  break;
589  break;
593  break;
595  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
597  break;
599  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
601  break;
605  break;
606  default:
607  WARN("Unsupported %x devCaps item\n", lpParms->dwItem);
609  }
610  } else {
611  TRACE("No GetDevCaps-Item !\n");
613  }
614  TRACE("lpParms->dwReturn=%08X;\n", lpParms->dwReturn);
615  if (dwFlags & MCI_NOTIFY) {
617  }
618  return ret;
619 }
620 
622 {
623  DWORD serial = 0;
624  int i;
625  WORD wMagic;
626  DWORD dwStart, dwEnd;
627 
628  /*
629  * wMagic collects the wFrames from track 1
630  * dwStart, dwEnd collect the beginning and end of the disc respectively, in
631  * frames.
632  * There it is collected for correcting the serial when there are less than
633  * 3 tracks.
634  */
635  wMagic = toc->TrackData[0].Address[3];
636  dwStart = FRAME_OF_TOC(*toc, toc->FirstTrack);
637 
638  for (i = 0; i <= toc->LastTrack - toc->FirstTrack; i++) {
639  serial += (toc->TrackData[i].Address[1] << 16) |
640  (toc->TrackData[i].Address[2] << 8) | toc->TrackData[i].Address[3];
641  }
642  dwEnd = FRAME_OF_TOC(*toc, toc->LastTrack + 1);
643 
644  if (toc->LastTrack - toc->FirstTrack + 1 < 3)
645  serial += wMagic + (dwEnd - dwStart);
646 
647  return serial;
648 }
649 
650 
651 /**************************************************************************
652  * MCICDA_Info [internal]
653  */
655 {
656  LPCWSTR str = NULL;
657  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
658  DWORD ret = 0;
659  WCHAR buffer[16];
660 
661  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
662 
663  if (lpParms == NULL || lpParms->lpstrReturn == NULL)
665  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
666 
667  TRACE("buf=%p, len=%u\n", lpParms->lpstrReturn, lpParms->dwRetSize);
668 
669  if (dwFlags & MCI_INFO_PRODUCT) {
670  static const WCHAR wszAudioCd[] = {'W','i','n','e','\'','s',' ','a','u','d','i','o',' ','C','D',0};
671  str = wszAudioCd;
672  } else if (dwFlags & MCI_INFO_MEDIA_UPC) {
674  } else if (dwFlags & MCI_INFO_MEDIA_IDENTITY) {
675  DWORD res = 0;
676  CDROM_TOC toc;
677  DWORD br;
678  static const WCHAR wszLu[] = {'%','l','u',0};
679 
680  if (!device_io(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0,
681  &toc, sizeof(toc), &br, NULL)) {
682  return MCICDA_GetError(wmcda);
683  }
684 
685  res = CDROM_Audio_GetSerial(&toc);
686  sprintfW(buffer, wszLu, res);
687  str = buffer;
688  } else {
689  WARN("Don't know this info command (%u)\n", dwFlags);
691  }
692  if (!ret) {
693  TRACE("=> %s\n", debugstr_w(str));
694  if (lpParms->dwRetSize) {
695  /* FIXME? Since NT, mciwave, mciseq and mcicda set dwRetSize
696  * to the number of characters written, excluding \0. */
697  lstrcpynW(lpParms->lpstrReturn, str, lpParms->dwRetSize);
698  } else ret = MCIERR_PARAM_OVERFLOW;
699  }
702  return ret;
703 }
704 
705 /**************************************************************************
706  * MCICDA_Status [internal]
707  */
709 {
710  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
711  DWORD ret = 0;
714  CDROM_TOC toc;
715  DWORD br;
716 
717  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
718 
719  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
720  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
721 
722  if (dwFlags & MCI_STATUS_ITEM) {
723  TRACE("dwItem = %x\n", lpParms->dwItem);
724  switch (lpParms->dwItem) {
727  if (!device_io(wmcda->handle, IOCTL_CDROM_READ_Q_CHANNEL, &fmt, sizeof(fmt),
728  &data, sizeof(data), &br, NULL))
729  {
730  return MCICDA_GetError(wmcda);
731  /* alt. data.CurrentPosition.TrackNumber = 1; -- what native yields */
732  }
733  lpParms->dwReturn = data.CurrentPosition.TrackNumber;
734  TRACE("CURRENT_TRACK=%lu\n", lpParms->dwReturn);
735  break;
736  case MCI_STATUS_LENGTH:
737  if (!MCICDA_ReadTOC(wmcda, &toc, &br))
738  return MCICDA_GetError(wmcda);
739 
740  if (dwFlags & MCI_TRACK) {
741  TRACE("MCI_TRACK #%u LENGTH=??? !\n", lpParms->dwTrack);
742  if (lpParms->dwTrack < toc.FirstTrack || lpParms->dwTrack > toc.LastTrack)
743  return MCIERR_OUTOFRANGE;
744  lpParms->dwReturn = FRAME_OF_TOC(toc, lpParms->dwTrack + 1) -
745  FRAME_OF_TOC(toc, lpParms->dwTrack);
746  /* Windows returns one frame less than the total track length for the
747  last track on the CD. See CDDB HOWTO. Verified on Win95OSR2. */
748  if (lpParms->dwTrack == toc.LastTrack)
749  lpParms->dwReturn--;
750  } else {
751  /* Sum of the lengths of all of the tracks. Inherits the
752  'off by one frame' behavior from the length of the last track.
753  See above comment. */
754  lpParms->dwReturn = FRAME_OF_TOC(toc, toc.LastTrack + 1) -
755  FRAME_OF_TOC(toc, toc.FirstTrack) - 1;
756  }
757  lpParms->dwReturn = MCICDA_CalcTime(wmcda,
758  (wmcda->dwTimeFormat == MCI_FORMAT_TMSF)
759  ? MCI_FORMAT_MSF : wmcda->dwTimeFormat,
760  lpParms->dwReturn,
761  &ret);
762  TRACE("LENGTH=%lu\n", lpParms->dwReturn);
763  break;
764  case MCI_STATUS_MODE:
765  lpParms->dwReturn = MCICDA_GetStatus(wmcda);
766  TRACE("MCI_STATUS_MODE=%08lX\n", lpParms->dwReturn);
767  lpParms->dwReturn = MAKEMCIRESOURCE(lpParms->dwReturn, lpParms->dwReturn);
769  break;
771  lpParms->dwReturn = (MCICDA_GetStatus(wmcda) == MCI_MODE_OPEN) ?
773  TRACE("MCI_STATUS_MEDIA_PRESENT =%c!\n", LOWORD(lpParms->dwReturn) ? 'Y' : 'N');
775  break;
777  if (!MCICDA_ReadTOC(wmcda, &toc, &br))
778  return MCICDA_GetError(wmcda);
779 
780  lpParms->dwReturn = toc.LastTrack - toc.FirstTrack + 1;
781  TRACE("MCI_STATUS_NUMBER_OF_TRACKS = %lu\n", lpParms->dwReturn);
782  if (lpParms->dwReturn == (WORD)-1)
783  return MCICDA_GetError(wmcda);
784  break;
785  case MCI_STATUS_POSITION:
786  switch (dwFlags & (MCI_STATUS_START | MCI_TRACK)) {
787  case MCI_STATUS_START:
788  if (!MCICDA_ReadTOC(wmcda, &toc, &br))
789  return MCICDA_GetError(wmcda);
790 
791  lpParms->dwReturn = FRAME_OF_TOC(toc, toc.FirstTrack);
792  TRACE("get MCI_STATUS_START !\n");
793  break;
794  case MCI_TRACK:
795  if (!MCICDA_ReadTOC(wmcda, &toc, &br))
796  return MCICDA_GetError(wmcda);
797 
798  if (lpParms->dwTrack < toc.FirstTrack || lpParms->dwTrack > toc.LastTrack)
799  return MCIERR_OUTOFRANGE;
800  lpParms->dwReturn = FRAME_OF_TOC(toc, lpParms->dwTrack);
801  TRACE("get MCI_TRACK #%u !\n", lpParms->dwTrack);
802  break;
803  case 0:
805  if (!device_io(wmcda->handle, IOCTL_CDROM_READ_Q_CHANNEL, &fmt, sizeof(fmt),
806  &data, sizeof(data), &br, NULL)) {
807  return MCICDA_GetError(wmcda);
808  }
809  lpParms->dwReturn = FRAME_OF_ADDR(data.CurrentPosition.AbsoluteAddress);
810  break;
811  default:
813  }
814  lpParms->dwReturn = MCICDA_CalcTime(wmcda, wmcda->dwTimeFormat, lpParms->dwReturn, &ret);
815  TRACE("MCI_STATUS_POSITION=%08lX\n", lpParms->dwReturn);
816  break;
817  case MCI_STATUS_READY:
818  TRACE("MCI_STATUS_READY !\n");
819  switch (MCICDA_GetStatus(wmcda))
820  {
821  case MCI_MODE_NOT_READY:
822  case MCI_MODE_OPEN:
824  break;
825  default:
826  lpParms->dwReturn = MAKEMCIRESOURCE(TRUE, MCI_TRUE);
827  break;
828  }
829  TRACE("MCI_STATUS_READY=%u!\n", LOWORD(lpParms->dwReturn));
831  break;
834  TRACE("MCI_STATUS_TIME_FORMAT=%08x!\n", LOWORD(lpParms->dwReturn));
836  break;
837  case 4001: /* FIXME: for bogus FullCD */
839  if (!(dwFlags & MCI_TRACK))
841  else {
842  if (!MCICDA_ReadTOC(wmcda, &toc, &br))
843  return MCICDA_GetError(wmcda);
844 
845  if (lpParms->dwTrack < toc.FirstTrack || lpParms->dwTrack > toc.LastTrack)
847  else
848  lpParms->dwReturn = (toc.TrackData[lpParms->dwTrack - toc.FirstTrack].Control & 0x04) ?
850  /* FIXME: MAKEMCIRESOURCE "audio" | "other", localised */
851  }
852  TRACE("MCI_CDA_STATUS_TYPE_TRACK[%d]=%ld\n", lpParms->dwTrack, lpParms->dwReturn);
853  break;
854  default:
855  FIXME("unknown command %08X !\n", lpParms->dwItem);
857  }
858  } else return MCIERR_MISSING_PARAMETER;
859  if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
861  return ret;
862 }
863 
864 /**************************************************************************
865  * MCICDA_SkipDataTracks [internal]
866  */
868 {
869  int i;
870  DWORD br;
871  CDROM_TOC toc;
872  if (!MCICDA_ReadTOC(wmcda, &toc, &br))
873  return MCICDA_GetError(wmcda);
874 
875  if (*frame < FRAME_OF_TOC(toc,toc.FirstTrack) ||
876  *frame >= FRAME_OF_TOC(toc,toc.LastTrack+1)) /* lead-out */
877  return MCIERR_OUTOFRANGE;
878  for(i=toc.LastTrack+1;i>toc.FirstTrack;i--)
879  if ( FRAME_OF_TOC(toc, i) <= *frame ) break;
880  /* i points to last track whose start address is not greater than frame.
881  * Now skip non-audio tracks */
882  for(;i<=toc.LastTrack;i++)
883  if ( ! (toc.TrackData[i-toc.FirstTrack].Control & 4) )
884  break;
885  /* The frame will be an address in the next audio track or
886  * address of lead-out. */
887  if ( FRAME_OF_TOC(toc, i) > *frame )
888  *frame = FRAME_OF_TOC(toc, i);
889  /* Lead-out is an invalid seek position (on Linux as well). */
890  if (*frame == FRAME_OF_TOC(toc,toc.LastTrack+1))
891  (*frame)--;
892  return 0;
893 }
894 
895 /**************************************************************************
896  * MCICDA_Play [internal]
897  */
899 {
900  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
901  DWORD ret = 0, start, end;
902  HANDLE oldcb;
903  DWORD br;
907  CDROM_TOC toc;
908 
909  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
910 
911  if (lpParms == NULL)
913 
914  if (wmcda == NULL)
916 
917  if (!MCICDA_ReadTOC(wmcda, &toc, &br))
918  return MCICDA_GetError(wmcda);
919 
920  if (dwFlags & MCI_FROM) {
921  start = MCICDA_CalcFrame(wmcda, lpParms->dwFrom);
922  if ( (ret=MCICDA_SkipDataTracks(wmcda, &start)) )
923  return ret;
924  TRACE("MCI_FROM=%08X -> %u\n", lpParms->dwFrom, start);
925  } else {
927  if (!device_io(wmcda->handle, IOCTL_CDROM_READ_Q_CHANNEL, &fmt, sizeof(fmt),
928  &data, sizeof(data), &br, NULL)) {
929  return MCICDA_GetError(wmcda);
930  }
931  start = FRAME_OF_ADDR(data.CurrentPosition.AbsoluteAddress);
932  if ( (ret=MCICDA_SkipDataTracks(wmcda, &start)) )
933  return ret;
934  }
935  if (dwFlags & MCI_TO) {
936  end = MCICDA_CalcFrame(wmcda, lpParms->dwTo);
937  if ( (ret=MCICDA_SkipDataTracks(wmcda, &end)) )
938  return ret;
939  TRACE("MCI_TO=%08X -> %u\n", lpParms->dwTo, end);
940  } else {
941  end = FRAME_OF_TOC(toc, toc.LastTrack + 1) - 1;
942  }
943  if (end < start) return MCIERR_OUTOFRANGE;
944  TRACE("Playing from %u to %u\n", start, end);
945 
946  oldcb = InterlockedExchangePointer(&wmcda->hCallback,
947  (dwFlags & MCI_NOTIFY) ? HWND_32(LOWORD(lpParms->dwCallback)) : NULL);
948  if (oldcb) mciDriverNotify(oldcb, wmcda->wNotifyDeviceID, MCI_NOTIFY_ABORTED);
949 
950  if (start == end || start == FRAME_OF_TOC(toc,toc.LastTrack+1)-1) {
951  if (dwFlags & MCI_NOTIFY) {
952  oldcb = InterlockedExchangePointer(&wmcda->hCallback, NULL);
953  if (oldcb) mciDriverNotify(oldcb, wDevID, MCI_NOTIFY_SUCCESSFUL);
954  }
955  return MMSYSERR_NOERROR;
956  }
957 
958  if (wmcda->hThread != 0) {
959  SetEvent(wmcda->stopEvent);
961 
962  CloseHandle(wmcda->hThread);
963  wmcda->hThread = 0;
964  CloseHandle(wmcda->stopEvent);
965  wmcda->stopEvent = 0;
966 
969  wmcda->dsBuf = NULL;
970  IDirectSound_Release(wmcda->dsObj);
971  wmcda->dsObj = NULL;
972  }
973 
974  if (pDirectSoundCreate) {
977  DWORD lockLen;
978  void *cdData;
979  HRESULT hr;
980 
981  hr = pDirectSoundCreate(NULL, &wmcda->dsObj, NULL);
982  if (SUCCEEDED(hr)) {
984 
985  /* The "raw" frame is relative to the start of the first track */
986  wmcda->start = start - FRAME_OF_TOC(toc, toc.FirstTrack);
987  wmcda->end = end - FRAME_OF_TOC(toc, toc.FirstTrack);
988 
989  memset(&format, 0, sizeof(format));
990  format.wFormatTag = WAVE_FORMAT_PCM;
991  format.nChannels = 2;
992  format.nSamplesPerSec = 44100;
993  format.wBitsPerSample = 16;
994  format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
995  format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
996  format.cbSize = 0;
997 
998  memset(&desc, 0, sizeof(desc));
999  desc.dwSize = sizeof(desc);
1002  desc.lpwfxFormat = &format;
1003 
1004  hr = IDirectSound_CreateSoundBuffer(wmcda->dsObj, &desc, &wmcda->dsBuf, NULL);
1005  }
1006  if (SUCCEEDED(hr)) {
1007  hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, 0, 0, &cdData, &lockLen,
1009  }
1010  if (SUCCEEDED(hr)) {
1011  RAW_READ_INFO rdInfo;
1012  int readok;
1013 
1014  rdInfo.DiskOffset.QuadPart = wmcda->start<<11;
1015  rdInfo.SectorCount = min(desc.dwBufferBytes/RAW_SECTOR_SIZE,
1016  wmcda->end-wmcda->start);
1017  rdInfo.TrackMode = CDDA;
1018 
1019  readok = device_io(wmcda->handle, IOCTL_CDROM_RAW_READ,
1020  &rdInfo, sizeof(rdInfo), cdData, lockLen,
1021  &br, NULL);
1022  IDirectSoundBuffer_Unlock(wmcda->dsBuf, cdData, lockLen, NULL, 0);
1023 
1024  if (readok) {
1025  wmcda->start += rdInfo.SectorCount;
1026  wmcda->stopEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
1027  }
1028  if (wmcda->stopEvent != 0)
1029  wmcda->hThread = CreateThread(NULL, 0, MCICDA_playLoop, wmcda, 0, &br);
1030  if (wmcda->hThread != 0) {
1032  if (SUCCEEDED(hr)) {
1033  /* FIXME: implement MCI_WAIT and send notification only in that case */
1034  if (0) {
1035  oldcb = InterlockedExchangePointer(&wmcda->hCallback, NULL);
1036  if (oldcb) mciDriverNotify(oldcb, wmcda->wNotifyDeviceID,
1038  }
1039  return ret;
1040  }
1041 
1042  SetEvent(wmcda->stopEvent);
1044  CloseHandle(wmcda->hThread);
1045  wmcda->hThread = 0;
1046  }
1047  }
1048 
1049  if (wmcda->stopEvent != 0) {
1050  CloseHandle(wmcda->stopEvent);
1051  wmcda->stopEvent = 0;
1052  }
1053  if (wmcda->dsBuf) {
1055  wmcda->dsBuf = NULL;
1056  }
1057  if (wmcda->dsObj) {
1058  IDirectSound_Release(wmcda->dsObj);
1059  wmcda->dsObj = NULL;
1060  }
1061  }
1062 
1063  play.StartingM = start / CDFRAMES_PERMIN;
1064  play.StartingS = (start / CDFRAMES_PERSEC) % 60;
1065  play.StartingF = start % CDFRAMES_PERSEC;
1066  play.EndingM = end / CDFRAMES_PERMIN;
1067  play.EndingS = (end / CDFRAMES_PERSEC) % 60;
1068  play.EndingF = end % CDFRAMES_PERSEC;
1069  if (!device_io(wmcda->handle, IOCTL_CDROM_PLAY_AUDIO_MSF, &play, sizeof(play),
1070  NULL, 0, &br, NULL)) {
1071  wmcda->hCallback = NULL;
1072  ret = MCIERR_HARDWARE;
1073  }
1074  /* The independent CD player has no means to signal MCI_NOTIFY when it's done.
1075  * Native sends a notification with MCI_WAIT only. */
1076  return ret;
1077 }
1078 
1079 /**************************************************************************
1080  * MCICDA_Stop [internal]
1081  */
1083 {
1084  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1085  HANDLE oldcb;
1086  DWORD br;
1087 
1088  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
1089 
1090  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
1091 
1092  oldcb = InterlockedExchangePointer(&wmcda->hCallback, NULL);
1093  if (oldcb) mciDriverNotify(oldcb, wmcda->wNotifyDeviceID, MCI_NOTIFY_ABORTED);
1094 
1095  if (wmcda->hThread != 0) {
1096  SetEvent(wmcda->stopEvent);
1098 
1099  CloseHandle(wmcda->hThread);
1100  wmcda->hThread = 0;
1101  CloseHandle(wmcda->stopEvent);
1102  wmcda->stopEvent = 0;
1103 
1105  wmcda->dsBuf = NULL;
1106  IDirectSound_Release(wmcda->dsObj);
1107  wmcda->dsObj = NULL;
1108  }
1109  else if (!device_io(wmcda->handle, IOCTL_CDROM_STOP_AUDIO, NULL, 0, NULL, 0, &br, NULL))
1110  return MCIERR_HARDWARE;
1111 
1112  if ((dwFlags & MCI_NOTIFY) && lpParms)
1114  return 0;
1115 }
1116 
1117 /**************************************************************************
1118  * MCICDA_Pause [internal]
1119  */
1121 {
1122  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1123  HANDLE oldcb;
1124  DWORD br;
1125 
1126  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
1127 
1128  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
1129 
1130  oldcb = InterlockedExchangePointer(&wmcda->hCallback, NULL);
1131  if (oldcb) mciDriverNotify(oldcb, wmcda->wNotifyDeviceID, MCI_NOTIFY_ABORTED);
1132 
1133  if (wmcda->hThread != 0) {
1134  /* Don't bother calling stop if the playLoop thread has already stopped */
1135  if(WaitForSingleObject(wmcda->stopEvent, 0) != WAIT_OBJECT_0 &&
1137  return MCIERR_HARDWARE;
1138  }
1139  else if (!device_io(wmcda->handle, IOCTL_CDROM_PAUSE_AUDIO, NULL, 0, NULL, 0, &br, NULL))
1140  return MCIERR_HARDWARE;
1141 
1142  if ((dwFlags & MCI_NOTIFY) && lpParms)
1144  return 0;
1145 }
1146 
1147 /**************************************************************************
1148  * MCICDA_Resume [internal]
1149  */
1151 {
1152  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1153  DWORD br;
1154 
1155  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
1156 
1157  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
1158 
1159  if (wmcda->hThread != 0) {
1160  /* Don't restart if the playLoop thread has already stopped */
1161  if(WaitForSingleObject(wmcda->stopEvent, 0) != WAIT_OBJECT_0 &&
1163  return MCIERR_HARDWARE;
1164  }
1165  else if (!device_io(wmcda->handle, IOCTL_CDROM_RESUME_AUDIO, NULL, 0, NULL, 0, &br, NULL))
1166  return MCIERR_HARDWARE;
1167 
1168  if ((dwFlags & MCI_NOTIFY) && lpParms)
1170  return 0;
1171 }
1172 
1173 /**************************************************************************
1174  * MCICDA_Seek [internal]
1175  */
1177 {
1178  DWORD at;
1179  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1181  DWORD br, position, ret;
1182  CDROM_TOC toc;
1183 
1184  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
1185 
1186  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
1187  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1188 
1190  if (!position) return MCIERR_MISSING_PARAMETER;
1191  if (position&(position-1)) return MCIERR_FLAGS_NOT_COMPATIBLE;
1192 
1193  /* Stop sends MCI_NOTIFY_ABORTED when needed.
1194  * Tests show that native first sends ABORTED and reads the TOC,
1195  * then only checks the position flags, then stops and seeks. */
1196  MCICDA_Stop(wDevID, MCI_WAIT, 0);
1197 
1198  if (!MCICDA_ReadTOC(wmcda, &toc, &br))
1199  return MCICDA_GetError(wmcda);
1200 
1201  switch (position) {
1202  case MCI_SEEK_TO_START:
1203  TRACE("Seeking to start\n");
1204  at = FRAME_OF_TOC(toc,toc.FirstTrack);
1205  if ( (ret=MCICDA_SkipDataTracks(wmcda, &at)) )
1206  return ret;
1207  break;
1208  case MCI_SEEK_TO_END:
1209  TRACE("Seeking to end\n");
1210  /* End is prior to lead-out
1211  * yet Win9X seeks to even one frame less than that. */
1212  at = FRAME_OF_TOC(toc, toc.LastTrack + 1) - 1;
1213  if ( (ret=MCICDA_SkipDataTracks(wmcda, &at)) )
1214  return ret;
1215  break;
1216  case MCI_TO:
1217  TRACE("Seeking to %u\n", lpParms->dwTo);
1218  at = MCICDA_CalcFrame(wmcda, lpParms->dwTo);
1219  if ( (ret=MCICDA_SkipDataTracks(wmcda, &at)) )
1220  return ret;
1221  break;
1222  default:
1224  }
1225 
1226  {
1227  seek.M = at / CDFRAMES_PERMIN;
1228  seek.S = (at / CDFRAMES_PERSEC) % 60;
1229  seek.F = at % CDFRAMES_PERSEC;
1230  if (!device_io(wmcda->handle, IOCTL_CDROM_SEEK_AUDIO_MSF, &seek, sizeof(seek),
1231  NULL, 0, &br, NULL))
1232  return MCIERR_HARDWARE;
1233  }
1234 
1235  if (dwFlags & MCI_NOTIFY)
1237  return 0;
1238 }
1239 
1240 /**************************************************************************
1241  * MCICDA_SetDoor [internal]
1242  */
1244 {
1245  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1246  DWORD br;
1247 
1248  TRACE("(%04x, %s) !\n", wDevID, (open) ? "OPEN" : "CLOSE");
1249 
1250  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
1251 
1252  if (!device_io(wmcda->handle,
1254  NULL, 0, NULL, 0, &br, NULL))
1255  return MCIERR_HARDWARE;
1256 
1257  return 0;
1258 }
1259 
1260 /**************************************************************************
1261  * MCICDA_Set [internal]
1262  */
1264 {
1265  WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1266 
1267  TRACE("(%04X, %08X, %p);\n", wDevID, dwFlags, lpParms);
1268 
1269  if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
1270 
1271  if (dwFlags & MCI_SET_DOOR_OPEN) {
1272  MCICDA_SetDoor(wDevID, TRUE);
1273  }
1274  if (dwFlags & MCI_SET_DOOR_CLOSED) {
1275  MCICDA_SetDoor(wDevID, FALSE);
1276  }
1277 
1278  /* only functions which require valid lpParms below this line ! */
1279  if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1280  /*
1281  TRACE("dwTimeFormat=%08lX\n", lpParms->dwTimeFormat);
1282  */
1283  if (dwFlags & MCI_SET_TIME_FORMAT) {
1284  switch (lpParms->dwTimeFormat) {
1286  TRACE("MCI_FORMAT_MILLISECONDS !\n");
1287  break;
1288  case MCI_FORMAT_MSF:
1289  TRACE("MCI_FORMAT_MSF !\n");
1290  break;
1291  case MCI_FORMAT_TMSF:
1292  TRACE("MCI_FORMAT_TMSF !\n");
1293  break;
1294  default:
1295  return MCIERR_BAD_TIME_FORMAT;
1296  }
1297  wmcda->dwTimeFormat = lpParms->dwTimeFormat;
1298  }
1299  if (dwFlags & MCI_SET_AUDIO) /* one xp machine ignored it */
1300  TRACE("SET_AUDIO %X %x\n", dwFlags, lpParms->dwAudio);
1301 
1302  if (dwFlags & MCI_NOTIFY)
1304  return 0;
1305 }
1306 
1307 /**************************************************************************
1308  * DriverProc (MCICDA.@)
1309  */
1310 LRESULT CALLBACK MCICDA_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
1311  LPARAM dwParam1, LPARAM dwParam2)
1312 {
1313  switch(wMsg) {
1314  case DRV_LOAD: return 1;
1315  case DRV_FREE: return 1;
1316  case DRV_OPEN: return MCICDA_drvOpen((LPCWSTR)dwParam1, (LPMCI_OPEN_DRIVER_PARMSW)dwParam2);
1317  case DRV_CLOSE: return MCICDA_drvClose(dwDevID);
1318  case DRV_ENABLE: return 1;
1319  case DRV_DISABLE: return 1;
1320  case DRV_QUERYCONFIGURE: return 1;
1321  case DRV_CONFIGURE: MessageBoxA(0, "MCI audio CD driver !", "Wine Driver", MB_OK); return 1;
1322  case DRV_INSTALL: return DRVCNF_RESTART;
1323  case DRV_REMOVE: return DRVCNF_RESTART;
1324  }
1325 
1326  if (dwDevID == 0xFFFFFFFF) return MCIERR_UNSUPPORTED_FUNCTION;
1327 
1328  switch (wMsg) {
1329  case MCI_OPEN_DRIVER: return MCICDA_Open(dwDevID, dwParam1, (LPMCI_OPEN_PARMSW)dwParam2);
1330  case MCI_CLOSE_DRIVER: return MCICDA_Close(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
1331  case MCI_GETDEVCAPS: return MCICDA_GetDevCaps(dwDevID, dwParam1, (LPMCI_GETDEVCAPS_PARMS)dwParam2);
1332  case MCI_INFO: return MCICDA_Info(dwDevID, dwParam1, (LPMCI_INFO_PARMSW)dwParam2);
1333  case MCI_STATUS: return MCICDA_Status(dwDevID, dwParam1, (LPMCI_STATUS_PARMS)dwParam2);
1334  case MCI_SET: return MCICDA_Set(dwDevID, dwParam1, (LPMCI_SET_PARMS)dwParam2);
1335  case MCI_PLAY: return MCICDA_Play(dwDevID, dwParam1, (LPMCI_PLAY_PARMS)dwParam2);
1336  case MCI_STOP: return MCICDA_Stop(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
1337  case MCI_PAUSE: return MCICDA_Pause(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
1338  case MCI_RESUME: return MCICDA_Resume(dwDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
1339  case MCI_SEEK: return MCICDA_Seek(dwDevID, dwParam1, (LPMCI_SEEK_PARMS)dwParam2);
1340  /* commands that should report an error as they are not supported in
1341  * the native version */
1342  case MCI_RECORD:
1343  case MCI_LOAD:
1344  case MCI_SAVE:
1346  case MCI_BREAK:
1347  case MCI_FREEZE:
1348  case MCI_PUT:
1349  case MCI_REALIZE:
1350  case MCI_UNFREEZE:
1351  case MCI_UPDATE:
1352  case MCI_WHERE:
1353  case MCI_STEP:
1354  case MCI_SPIN:
1355  case MCI_ESCAPE:
1356  case MCI_COPY:
1357  case MCI_CUT:
1358  case MCI_DELETE:
1359  case MCI_PASTE:
1360  case MCI_WINDOW:
1361  TRACE("Unsupported command [0x%x]\n", wMsg);
1362  break;
1363  case MCI_OPEN:
1364  case MCI_CLOSE:
1365  ERR("Shouldn't receive a MCI_OPEN or CLOSE message\n");
1366  break;
1367  default:
1368  TRACE("Sending msg [0x%x] to default driver proc\n", wMsg);
1369  return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1370  }
1372 }
1373 
1374 /*-----------------------------------------------------------------------*/
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
#define IDirectSoundBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsound.h:584
#define DRV_DISABLE
Definition: mmsystem.h:123
BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData)
#define MCI_UNFREEZE
Definition: mmsystem.h:669
#define AUDIO_STATUS_PAUSED
Definition: ntddcdrm.h:282
#define MCI_NO_COMMAND_TABLE
Definition: mmddk.h:375
static void MCICDA_Notify(DWORD_PTR hWndCallBack, WINE_MCICDAUDIO *wmcda, UINT wStatus)
Definition: mcicda.c:247
#define HRESULT
Definition: msvc.h:9
#define MCI_ESCAPE
Definition: mmsystem.h:648
const unsigned char * inbuffer
Definition: jpeglib.h:982
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
DWORD WINAPI mciGetDriverData(UINT uDeviceID)
Definition: mci.c:2066
IDirectSound * dsObj
Definition: mcicda.c:71
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define ERROR_IO_DEVICE
Definition: winerror.h:653
#define MCI_INFO_PRODUCT
Definition: mmsystem.h:752
#define MCI_COPY
Definition: mmsystem.h:672
#define DSBCAPS_GETCURRENTPOSITION2
Definition: dsound.h:220
#define MCIERR_CANNOT_LOAD_DRIVER
Definition: mmsystem.h:576
#define MCI_STATUS_ITEM
Definition: mmsystem.h:742
#define DWORD_PTR
Definition: treelist.c:76
#define AUDIO_STATUS_NO_STATUS
Definition: ntddcdrm.h:285
HRESULT hr
Definition: shlfolder.c:183
#define MCI_WAIT
Definition: mmsystem.h:730
DWORD dwSize
Definition: dsound.h:239
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define MCI_MSF_FRAME(t)
Definition: mmsystem.h:714
DWORD dwTimeFormat
Definition: mmsystem.h:1608
UCHAR FirstTrack
Definition: ntddcdrm.h:164
#define MCI_COLONIZED3_RETURN
Definition: mmddk.h:370
#define open
Definition: acwin.h:95
#define MCI_STATUS_NUMBER_OF_TRACKS
Definition: mmsystem.h:746
#define IDirectSoundBuffer_Release(p)
Definition: dsound.h:574
#define MCI_GETDEVCAPS_CAN_SAVE
Definition: mmsystem.h:767
#define MCI_FORMAT_TMSF
Definition: mmsystem.h:711
UINT wDevID
Definition: mcicda.c:58
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
#define WARN(fmt,...)
Definition: debug.h:111
static LPDIRECTSOUNDCREATE pDirectSoundCreate
Definition: mcicda.c:80
#define MCI_CDA_TRACK_AUDIO
Definition: mmsystem.h:817
#define MCIERR_DRIVER_INTERNAL
Definition: mmsystem.h:582
HANDLE handle
Definition: mcicda.c:64
static DWORD CDROM_Audio_GetSerial(CDROM_TOC *toc)
Definition: mcicda.c:621
#define MCI_STEP
Definition: mmsystem.h:657
#define CALLBACK
Definition: compat.h:27
const char * fmt
Definition: wsprintf.c:30
#define MCI_TMSF_SECOND(t)
Definition: mmsystem.h:718
DWORD_PTR dwCallback
Definition: mmsystem.h:1537
ULONG SectorCount
Definition: ntddcdrm.h:353
HFONT tf
Definition: icontest.c:17
DWORD start
Definition: mcicda.c:69
static BOOL MCICDA_ReadTOC(WINE_MCICDAUDIO *wmcda, CDROM_TOC *toc, DWORD *br)
Definition: mcicda.c:258
#define MCI_PASTE
Definition: mmsystem.h:673
#define CDFRAMES_PERMIN
Definition: mcicda.c:45
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define MCI_GETDEVCAPS_COMPOUND_DEVICE
Definition: mmsystem.h:764
#define AUDIO_STATUS_NOT_SUPPORTED
Definition: ntddcdrm.h:280
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
#define MCI_PLAY
Definition: mmsystem.h:649
GLuint buffer
Definition: glext.h:5915
static DWORD MCICDA_Pause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:1120
#define DRV_CLOSE
Definition: mmsystem.h:122
#define isalpha(c)
Definition: acclib.h:74
#define CDDA_FRAG_SIZE
Definition: mcicda.c:53
#define MCI_RESUME
Definition: mmsystem.h:675
#define MCI_BREAK
Definition: mmsystem.h:660
static BOOL device_io(HANDLE dev, DWORD code, void *inbuffer, DWORD insize, void *outbuffer, DWORD outsize, DWORD *retsize, OVERLAPPED *overlapped)
Definition: mcicda.c:82
#define MCI_SET_AUDIO
Definition: mmsystem.h:775
UCHAR Address[4]
Definition: ntddcdrm.h:108
GLuint GLuint end
Definition: gl.h:1545
#define MCI_RESOURCE_RETURNED
Definition: mmddk.h:369
#define MCI_FREEZE
Definition: mmsystem.h:668
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define MCI_GETDEVCAPS_CAN_RECORD
Definition: mmsystem.h:759
#define MAKEMCIRESOURCE(wRet, wRes)
Definition: mmddk.h:388
#define MCI_SET_DOOR_CLOSED
Definition: mmsystem.h:773
#define MCI_STATUS_POSITION
Definition: mmsystem.h:745
#define MCI_CDA_TRACK_OTHER
Definition: mmsystem.h:818
#define DSERR_BUFFERLOST
Definition: dsound.h:131
static DWORD MCICDA_Seek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
Definition: mcicda.c:1176
#define MCI_SAVE
Definition: mmsystem.h:661
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define FILE_SHARE_READ
Definition: compat.h:125
#define lstrcpynW
Definition: compat.h:397
#define IOCTL_CDROM_RAW_READ
Definition: ntddcdrm.h:64
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define DRV_OPEN
Definition: mmsystem.h:121
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:271
#define MCI_STOP
Definition: mmsystem.h:651
static DWORD MCICDA_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:534
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
Definition: dsound.h:577
#define MCI_WINDOW
Definition: mmsystem.h:665
int WINAPI MessageBoxA(_In_opt_ HWND, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ UINT)
static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpOpenParms)
Definition: mcicda.c:441
HANDLE hThread
Definition: mcicda.c:67
DWORD_PTR dwReturn
Definition: mmsystem.h:1567
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2056
static DWORD MCICDA_Stop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:1082
#define MCI_GETDEVCAPS_USES_FILES
Definition: mmsystem.h:763
#define MCI_SET
Definition: mmsystem.h:656
#define AUDIO_STATUS_PLAY_ERROR
Definition: ntddcdrm.h:284
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define WAVE_FORMAT_PCM
Definition: constants.h:425
LPCWSTR lpstrElementName
Definition: mmsystem.h:1532
HANDLE stopEvent
Definition: mcicda.c:68
#define MCI_OPEN_ELEMENT_ID
Definition: mmsystem.h:737
#define MCIERR_FLAGS_NOT_COMPATIBLE
Definition: mmsystem.h:593
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
unsigned int BOOL
Definition: ntddk_ex.h:94
static DWORD MCICDA_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
Definition: mcicda.c:183
#define MCI_RECORD
Definition: mmsystem.h:658
UINT wCustomCommandTable
Definition: mmddk.h:438
LRESULT CALLBACK MCICDA_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
Definition: mcicda.c:1310
static LPUNKNOWN
Definition: ndr_ole.c:49
#define debugstr_w
Definition: kernel32.h:32
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
#define FIXME(fmt,...)
Definition: debug.h:110
#define IDirectSoundBuffer_GetCaps(p, a)
Definition: dsound.h:576
#define MCI_CDA_STATUS_TYPE_TRACK
Definition: mmsystem.h:816
static DWORD MCICDA_CalcFrame(WINE_MCICDAUDIO *wmcda, DWORD dwTime)
Definition: mcicda.c:332
#define MCI_WHERE
Definition: mmsystem.h:667
#define IOCTL_CDROM_STOP_AUDIO
Definition: ntddcdrm.h:91
static PVOID ptr
Definition: dispmode.c:27
static DWORD MCICDA_GetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
Definition: mcicda.c:555
#define MCI_GETDEVCAPS_DEVICE_TYPE
Definition: mmsystem.h:762
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:96
#define IOCTL_CDROM_SEEK_AUDIO_MSF
Definition: ntddcdrm.h:82
static DWORD MCICDA_SetDoor(UINT wDevID, BOOL open)
Definition: mcicda.c:1243
const WCHAR * str
const struct builtin_class_descr * desc
Definition: regcontrol.c:48
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:136
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
smooth NULL
Definition: ftsmooth.c:416
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:652
#define ERROR_NOT_READY
Definition: winerror.h:124
#define IOCTL_CDROM_PLAY_AUDIO_MSF
Definition: ntddcdrm.h:61
#define MCI_MSF_MINUTE(t)
Definition: mmsystem.h:712
LONG_PTR LPARAM
Definition: windef.h:208
#define XX(x)
#define DRV_LOAD(x)
DWORD_PTR dwCallback
Definition: mmsystem.h:1579
#define MCI_OPEN
Definition: mmsystem.h:646
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
static DWORD MCICDA_GetStatus(WINE_MCICDAUDIO *wmcda)
Definition: mcicda.c:270
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define DRV_REMOVE
Definition: mmsystem.h:128
#define MCI_INFO
Definition: mmsystem.h:653
#define MCI_NOTIFY_FAILURE
Definition: mmsystem.h:728
#define OPEN_EXISTING
Definition: compat.h:426
#define AUDIO_STATUS_IN_PROGRESS
Definition: ntddcdrm.h:281
#define MCI_GETDEVCAPS_HAS_VIDEO
Definition: mmsystem.h:761
#define MCI_OPEN_DRIVER
Definition: mmddk.h:334
#define MCIERR_PARAM_OVERFLOW
Definition: mmsystem.h:578
#define FRAME_OF_TOC(toc, idx)
Definition: mcicda.c:47
DWORD dwTime
Definition: solitaire.cpp:25
#define MCI_STATUS
Definition: mmsystem.h:662
static DWORD MCICDA_Play(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
Definition: mcicda.c:898
#define DSBCAPS_GLOBALFOCUS
Definition: dsound.h:219
#define MCI_MSF_SECOND(t)
Definition: mmsystem.h:713
const GUID * LPCGUID
Definition: dplay.h:376
int toupper(int c)
Definition: utclib.c:881
#define DS_OK
Definition: dsound.h:116
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define WAIT_OBJECT_0
Definition: winbase.h:387
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define MCI_STATUS_LENGTH
Definition: mmsystem.h:744
#define DRV_CONFIGURE
Definition: mmsystem.h:125
TRACK_MODE_TYPE TrackMode
Definition: ntddcdrm.h:354
#define DSBPLAY_LOOPING
Definition: dsound.h:189
__wchar_t WCHAR
Definition: xmlstorage.h:180
CRITICAL_SECTION cs
Definition: mcicda.c:74
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define MCI_OPEN_SHAREABLE
Definition: mmsystem.h:734
#define MCI_SET_TIME_FORMAT
Definition: mmsystem.h:774
static DWORD MCICDA_SkipDataTracks(WINE_MCICDAUDIO *wmcda, DWORD *frame)
Definition: mcicda.c:867
int nUseCount
Definition: mcicda.c:59
LONG HRESULT
Definition: typedefs.h:77
#define MCIERR_BAD_TIME_FORMAT
Definition: mmsystem.h:601
DWORD end
Definition: mcicda.c:69
DWORD dwBufferBytes
Definition: dsound.h:241
DWORD_PTR dwCallback
Definition: mmsystem.h:1607
#define WINAPI
Definition: msvc.h:8
#define IDirectSoundBuffer_GetStatus(p, a)
Definition: dsound.h:582
#define MCI_REALIZE
Definition: mmsystem.h:664
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL fShareable
Definition: mcicda.c:60
IDirectSoundBuffer * dsBuf
Definition: mcicda.c:72
DWORD_PTR dwCallback
Definition: mmsystem.h:1529
#define DRV_FREE
Definition: mmsystem.h:124
unsigned char unsigned long * outsize
Definition: jpeglib.h:979
#define MCI_STATUS_MODE
Definition: mmsystem.h:747
#define MCI_STATUS_START
Definition: mmsystem.h:743
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:859
DWORD_PTR dwCallback
Definition: mmsystem.h:1543
WINE_DEFAULT_DEBUG_CHANNEL(mcicda)
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
UCHAR LastTrack
Definition: ntddcdrm.h:165
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
int ret
GLenum const GLvoid * addr
Definition: glext.h:9621
Definition: ntddcdrm.h:348
#define MCI_LOAD
Definition: mmsystem.h:670
#define DSBSTATUS_PLAYING
Definition: dsound.h:196
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
UCHAR Control
Definition: ntddcdrm.h:104
#define MCI_GETDEVCAPS_HAS_AUDIO
Definition: mmsystem.h:760
#define MCI_STATUS_CURRENT_TRACK
Definition: mmsystem.h:751
#define AUDIO_STATUS_PLAY_COMPLETE
Definition: ntddcdrm.h:283
const unsigned char unsigned long insize
Definition: jpeglib.h:982
static int MCICDA_GetError(WINE_MCICDAUDIO *wmcda)
Definition: mcicda.c:316
unsigned char BYTE
Definition: mem.h:68
#define MCI_CUT
Definition: mmsystem.h:671
#define MCI_DEVTYPE_CD_AUDIO
Definition: mmsystem.h:683
#define MCI_SEEK_TO_END
Definition: mmsystem.h:741
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
#define MCIERR_NO_IDENTITY
Definition: mmsystem.h:643
#define MCI_GETDEVCAPS_ITEM
Definition: mmsystem.h:758
#define GENERIC_READ
Definition: compat.h:124
#define MCI_FALSE
Definition: mmddk.h:340
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
uint32_t DWORD_PTR
Definition: typedefs.h:63
static DWORD MCICDA_drvClose(DWORD dwDevID)
Definition: mcicda.c:214
GLenum mode
Definition: glext.h:6217
#define IDirectSound_SetCooperativeLevel(p, a, b)
Definition: dsound.h:458
#define MCI_CLOSE_DRIVER
Definition: mmddk.h:335
#define IOCTL_CDROM_PAUSE_AUDIO
Definition: ntddcdrm.h:58
#define IDirectSoundBuffer_Restore(p)
Definition: dsound.h:593
#define MCI_SEEK_TO_START
Definition: mmsystem.h:740
#define DRV_ENABLE
Definition: mmsystem.h:120
#define IDirectSoundBuffer_Stop(p)
Definition: dsound.h:591
#define MCI_FORMAT_MSF
Definition: mmsystem.h:703
#define IOCTL_CDROM_RESUME_AUDIO
Definition: ntddcdrm.h:79
#define ERR(fmt,...)
Definition: debug.h:109
#define FRAME_OF_ADDR(a)
Definition: mcicda.c:46
DWORD_PTR dwCallback
Definition: mmsystem.h:1566
static DWORD MCICDA_CalcTime(WINE_MCICDAUDIO *wmcda, DWORD tf, DWORD dwFrame, LPDWORD lpRet)
Definition: mcicda.c:379
#define HWND_32(h16)
Definition: wownt32.h:29
#define CDDA_FRAG_COUNT
Definition: mcicda.c:55
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED * overlapped
Definition: sock.c:82
#define MCI_TMSF_MINUTE(t)
Definition: mmsystem.h:717
static char drive[2]
Definition: batch.c:28
uint32_t serial
Definition: fsck.fat.h:64
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define MCI_INFO_MEDIA_UPC
Definition: mmsystem.h:754
#define IDirectSound_Release(p)
Definition: dsound.h:453
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
#define MCI_NOTIFY_SUPERSEDED
Definition: mmsystem.h:726
GLuint start
Definition: gl.h:1545
static DWORD CALLBACK MCICDA_playLoop(void *ptr)
Definition: mcicda.c:107
#define MCI_PUT
Definition: mmsystem.h:666
DWORD_PTR dwCallback
Definition: mmsystem.h:1517
#define MCI_MAKE_TMSF(t, m, s, f)
Definition: mmsystem.h:720
#define IDirectSound_CreateSoundBuffer(p, a, b, c)
Definition: dsound.h:455
#define MCI_OPEN_ELEMENT
Definition: mmsystem.h:735
#define sprintfW
Definition: unicode.h:58
#define DRIVE_CDROM
Definition: winbase.h:251
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:99
#define CDFRAMES_PERSEC
Definition: mcicda.c:44
static DWORD MCICDA_Resume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:1150
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define MB_OK
Definition: winuser.h:784
#define MCI_MAKE_MSF(m, s, f)
Definition: mmsystem.h:715
#define MCIERR_DEVICE_NOT_READY
Definition: mmsystem.h:586
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define MCI_CLOSE
Definition: mmsystem.h:647
#define MCI_GETDEVCAPS
Definition: mmsystem.h:654
#define MCI_TRACK
Definition: mmsystem.h:733
#define MCI_TRUE
Definition: mmddk.h:341
UINT MCIDEVICEID
Definition: mmsystem.h:959
#define CreateFileW
Definition: compat.h:400
#define MCI_TMSF_FRAME(t)
Definition: mmsystem.h:719
#define MCI_COLONIZED4_RETURN
Definition: mmddk.h:371
struct IDirectSound * LPDIRECTSOUND
Definition: dsound.h:70
static WINE_MCICDAUDIO * MCICDA_GetOpenDrv(UINT wDevID)
Definition: mcicda.c:230
#define MCI_TMSF_TRACK(t)
Definition: mmsystem.h:716
#define MCIERR_UNRECOGNIZED_COMMAND
Definition: mmsystem.h:571
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
#define HRESULT_CODE(hr)
Definition: winerror.h:76
#define MCIERR_HARDWARE
Definition: mmsystem.h:572
GLuint res
Definition: glext.h:9613
HRESULT(WINAPI * LPDIRECTSOUNDCREATE)(LPCGUID, LPDIRECTSOUND *, LPUNKNOWN)
Definition: mcicda.c:79
uint32_t * LPDWORD
Definition: typedefs.h:57
#define MCI_GETDEVCAPS_CAN_EJECT
Definition: mmsystem.h:765
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define MCI_PAUSE
Definition: mmsystem.h:652
#define MCI_MODE_OPEN
Definition: mmsystem.h:700
#define MCI_FROM
Definition: mmsystem.h:731
DWORD dwTimeFormat
Definition: mcicda.c:63
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]
Definition: ntddcdrm.h:166
#define DRV_INSTALL
Definition: mmsystem.h:127
#define RAW_SECTOR_SIZE
Definition: mcicda.c:50
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
#define GetProcAddress(x, y)
Definition: compat.h:410
static DWORD MCICDA_Info(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
Definition: mcicda.c:654
LARGE_INTEGER DiskOffset
Definition: ntddcdrm.h:352
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:73
#define MCIERR_MUST_USE_SHAREABLE
Definition: mmsystem.h:599
MCIDEVICEID wDeviceID
Definition: mmsystem.h:1530
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_INFO_MEDIA_IDENTITY
Definition: mmsystem.h:755
#define MCI_STATUS_TIME_FORMAT
Definition: mmsystem.h:749
LONG_PTR LRESULT
Definition: windef.h:209
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define IDirectSoundBuffer_Play(p, a, b, c)
Definition: dsound.h:585
#define INFINITE
Definition: serial.h:102
static DWORD MCICDA_Set(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
Definition: mcicda.c:1263
#define IDirectSoundBuffer_Unlock(p, a, b, c, d)
Definition: dsound.h:592
#define MCI_STATUS_MEDIA_PRESENT
Definition: mmsystem.h:748
#define memset(x, y, z)
Definition: compat.h:39
#define DSSCL_PRIORITY
Definition: dsound.h:248
#define IOCTL_CDROM_READ_Q_CHANNEL
Definition: ntddcdrm.h:70
static SERVICE_STATUS status
Definition: service.c:31
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define MCI_SPIN
Definition: mmsystem.h:655
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204
#define LOWORD(l)
Definition: pedump.c:82
Definition: dsound.c:943
#define HeapFree(x, y, z)
Definition: compat.h:394
#define MCI_UPDATE
Definition: mmsystem.h:674
#define MCI_SEEK
Definition: mmsystem.h:650
#define MCI_DELETE
Definition: mmsystem.h:676
#define MCI_TO
Definition: mmsystem.h:732
static DWORD MCICDA_Status(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
Definition: mcicda.c:708
MCIDEVICEID wNotifyDeviceID
Definition: mcicda.c:61
#define SUCCEEDED(hr)
Definition: intsafe.h:57
#define MCI_SET_DOOR_OPEN
Definition: mmsystem.h:772
LONGLONG QuadPart
Definition: typedefs.h:112
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:852
#define MCI_FORMAT_RETURN_BASE
Definition: mmddk.h:343
HANDLE hCallback
Definition: mcicda.c:62
#define MCI_STATUS_READY
Definition: mmsystem.h:750
#define MCI_GETDEVCAPS_CAN_PLAY
Definition: mmsystem.h:766
Definition: ps.c:97