ReactOS 0.4.17-dev-966-gf06eace
mcicda.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "wownt32.h"
#include "mmddk.h"
#include "winioctl.h"
#include "ntddcdrm.h"
#include "winternl.h"
#include "wine/debug.h"
#include "dsound.h"
Include dependency graph for mcicda.c:

Go to the source code of this file.

Classes

struct  WINE_MCICDAUDIO
 

Macros

#define WIN32_NO_STATUS
 
#define CDFRAMES_PERSEC   75
 
#define CDFRAMES_PERMIN   (CDFRAMES_PERSEC * 60)
 
#define FRAME_OF_ADDR(a)   ((a)[1] * CDFRAMES_PERMIN + (a)[2] * CDFRAMES_PERSEC + (a)[3])
 
#define FRAME_OF_TOC(toc, idx)   FRAME_OF_ADDR((toc).TrackData[idx - (toc).FirstTrack].Address)
 
#define RAW_SECTOR_SIZE   (2352)
 
#define CDDA_FRAG_SIZE   (32768)
 
#define CDDA_FRAG_COUNT   (3)
 
#define XX(x)   case (x): str = #x; break
 

Typedefs

typedef HRESULT(WINAPI * LPDIRECTSOUNDCREATE) (LPCGUID, LPDIRECTSOUND *, LPUNKNOWN)
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (mcicda)
 
static BOOL device_io (HANDLE dev, DWORD code, void *inbuffer, DWORD insize, void *outbuffer, DWORD outsize, DWORD *retsize, OVERLAPPED *overlapped)
 
static DWORD CALLBACK MCICDA_playLoop (void *ptr)
 
static DWORD MCICDA_drvOpen (LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
 
static DWORD MCICDA_drvClose (DWORD dwDevID)
 
static WINE_MCICDAUDIO * MCICDA_GetOpenDrv (UINT wDevID)
 
static void MCICDA_Notify (DWORD_PTR hWndCallBack, WINE_MCICDAUDIO *wmcda, UINT wStatus)
 
static BOOL MCICDA_ReadTOC (WINE_MCICDAUDIO *wmcda, CDROM_TOC *toc, DWORD *br)
 
static DWORD MCICDA_GetStatus (WINE_MCICDAUDIO *wmcda)
 
static int MCICDA_GetError (WINE_MCICDAUDIO *wmcda)
 
static DWORD MCICDA_CalcFrame (WINE_MCICDAUDIO *wmcda, DWORD dwTime)
 
static DWORD MCICDA_CalcTime (WINE_MCICDAUDIO *wmcda, DWORD tf, DWORD dwFrame, LPDWORD lpRet)
 
static DWORD MCICDA_Stop (UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD MCICDA_Open (UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpOpenParms)
 
static DWORD MCICDA_Close (UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD MCICDA_GetDevCaps (UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
 
static DWORD CDROM_Audio_GetSerial (CDROM_TOC *toc)
 
static DWORD MCICDA_Info (UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
 
static DWORD MCICDA_Status (UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
 
static DWORD MCICDA_SkipDataTracks (WINE_MCICDAUDIO *wmcda, DWORD *frame)
 
static DWORD MCICDA_Play (UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
 
static DWORD MCICDA_Pause (UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD MCICDA_Resume (UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
 
static DWORD MCICDA_Seek (UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
 
static DWORD MCICDA_SetDoor (UINT wDevID, BOOL open)
 
static DWORD MCICDA_Set (UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
 
LRESULT CALLBACK MCICDA_DriverProc (DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
 

Variables

static LPDIRECTSOUNDCREATE pDirectSoundCreate
 

Macro Definition Documentation

◆ CDDA_FRAG_COUNT

#define CDDA_FRAG_COUNT   (3)

Definition at line 57 of file mcicda.c.

◆ CDDA_FRAG_SIZE

#define CDDA_FRAG_SIZE   (32768)

Definition at line 55 of file mcicda.c.

◆ CDFRAMES_PERMIN

#define CDFRAMES_PERMIN   (CDFRAMES_PERSEC * 60)

Definition at line 47 of file mcicda.c.

◆ CDFRAMES_PERSEC

#define CDFRAMES_PERSEC   75

Definition at line 46 of file mcicda.c.

◆ FRAME_OF_ADDR

#define FRAME_OF_ADDR (   a)    ((a)[1] * CDFRAMES_PERMIN + (a)[2] * CDFRAMES_PERSEC + (a)[3])

Definition at line 48 of file mcicda.c.

◆ FRAME_OF_TOC

#define FRAME_OF_TOC (   toc,
  idx 
)    FRAME_OF_ADDR((toc).TrackData[idx - (toc).FirstTrack].Address)

Definition at line 49 of file mcicda.c.

◆ RAW_SECTOR_SIZE

#define RAW_SECTOR_SIZE   (2352)

Definition at line 52 of file mcicda.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 27 of file mcicda.c.

◆ XX

#define XX (   x)    case (x): str = #x; break

Typedef Documentation

◆ LPDIRECTSOUNDCREATE

typedef HRESULT(WINAPI * LPDIRECTSOUNDCREATE) (LPCGUID, LPDIRECTSOUND *, LPUNKNOWN)

Definition at line 81 of file mcicda.c.

Function Documentation

◆ CDROM_Audio_GetSerial()

static DWORD CDROM_Audio_GetSerial ( CDROM_TOC *  toc)
static

Definition at line 623 of file mcicda.c.

624{
625 DWORD serial = 0;
626 int i;
627 WORD wMagic;
628 DWORD dwStart, dwEnd;
629
630 /*
631 * wMagic collects the wFrames from track 1
632 * dwStart, dwEnd collect the beginning and end of the disc respectively, in
633 * frames.
634 * There it is collected for correcting the serial when there are less than
635 * 3 tracks.
636 */
637 wMagic = toc->TrackData[0].Address[3];
638 dwStart = FRAME_OF_TOC(*toc, toc->FirstTrack);
639
640 for (i = 0; i <= toc->LastTrack - toc->FirstTrack; i++) {
641 serial += (toc->TrackData[i].Address[1] << 16) |
642 (toc->TrackData[i].Address[2] << 8) | toc->TrackData[i].Address[3];
643 }
644 dwEnd = FRAME_OF_TOC(*toc, toc->LastTrack + 1);
645
646 if (toc->LastTrack - toc->FirstTrack + 1 < 3)
647 serial += wMagic + (dwEnd - dwStart);
648
649 return serial;
650}
#define FRAME_OF_TOC(toc, idx)
Definition: mcicda.c:49
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
uint32_t serial
Definition: fsck.fat.h:29
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
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS]
Definition: ntddcdrm.h:199
UCHAR LastTrack
Definition: ntddcdrm.h:198
UCHAR FirstTrack
Definition: ntddcdrm.h:197
UCHAR Address[4]
Definition: ntddcdrm.h:141

Referenced by MCICDA_Info().

◆ device_io()

static BOOL device_io ( HANDLE  dev,
DWORD  code,
void *  inbuffer,
DWORD  insize,
void *  outbuffer,
DWORD  outsize,
DWORD *  retsize,
OVERLAPPED *  overlapped 
)
static

Definition at line 84 of file mcicda.c.

85{
86 const char *str;
88
89#define XX(x) case (x): str = #x; break
90 switch (code)
91 {
102 default: str = wine_dbg_sprintf("UNKNOWN (0x%lx)", code);
103 };
104#undef XX
105 TRACE("Device %p, Code %s -> Return %d, Bytes %lu\n", dev, str, ret, *retsize);
106 return ret;
107}
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
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
#define XX(x)
return ret
Definition: mutex.c:147
unsigned int BOOL
Definition: ntddk_ex.h:94
const unsigned char * inbuffer
Definition: jpeglib.h:985
const unsigned char size_t insize
Definition: jpeglib.h:986
unsigned char size_t * outsize
Definition: jpeglib.h:983
#define IOCTL_CDROM_SEEK_AUDIO_MSF
Definition: ntddcdrm.h:37
#define IOCTL_CDROM_PAUSE_AUDIO
Definition: ntddcdrm.h:43
#define IOCTL_CDROM_STOP_AUDIO
Definition: ntddcdrm.h:40
#define IOCTL_CDROM_READ_Q_CHANNEL
Definition: ntddcdrm.h:58
#define IOCTL_CDROM_PLAY_AUDIO_MSF
Definition: ntddcdrm.h:52
#define IOCTL_CDROM_RESUME_AUDIO
Definition: ntddcdrm.h:46
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:34
#define IOCTL_CDROM_RAW_READ
Definition: ntddcdrm.h:67
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:110
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
const WCHAR * str
namespace GUID const ADDRINFOEXW ADDRINFOEXW struct timeval OVERLAPPED * overlapped
Definition: sock.c:81
#define TRACE(s)
Definition: solgame.cpp:4
Definition: inflate.c:139

Referenced by MCICDA_CalcFrame(), MCICDA_CalcTime(), MCICDA_GetStatus(), MCICDA_Info(), MCICDA_Pause(), MCICDA_Play(), MCICDA_playLoop(), MCICDA_ReadTOC(), MCICDA_Resume(), MCICDA_Seek(), MCICDA_SetDoor(), MCICDA_Status(), and MCICDA_Stop().

◆ MCICDA_CalcFrame()

static DWORD MCICDA_CalcFrame ( WINE_MCICDAUDIO *  wmcda,
DWORD  dwTime 
)
static

Definition at line 334 of file mcicda.c.

335{
336 DWORD dwFrame = 0;
337 UINT wTrack;
338 CDROM_TOC toc;
339 DWORD br;
340 BYTE* addr;
341
342 TRACE("(%p, %08lX, %lu);\n", wmcda, wmcda->dwTimeFormat, dwTime);
343
344 switch (wmcda->dwTimeFormat) {
346 dwFrame = ((dwTime - 1) * CDFRAMES_PERSEC + 500) / 1000;
347 TRACE("MILLISECONDS %lu\n", dwFrame);
348 break;
349 case MCI_FORMAT_MSF:
350 TRACE("MSF %02u:%02u:%02u\n",
354 dwFrame += MCI_MSF_FRAME(dwTime);
355 break;
356 case MCI_FORMAT_TMSF:
357 default: /* unknown format ! force TMSF ! ... */
358 wTrack = MCI_TMSF_TRACK(dwTime);
359 if (!device_io(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0,
360 &toc, sizeof(toc), &br, NULL))
361 return 0;
362 if (wTrack < toc.FirstTrack || wTrack > toc.LastTrack)
363 return 0;
364 TRACE("MSF %02u-%02u:%02u:%02u\n",
367 addr = toc.TrackData[wTrack - toc.FirstTrack].Address;
368 TRACE("TMSF trackpos[%u]=%d:%d:%d\n",
369 wTrack, addr[1], addr[2], addr[3]);
370 dwFrame = CDFRAMES_PERMIN * (addr[1] + MCI_TMSF_MINUTE(dwTime)) +
373 break;
374 }
375 return dwFrame;
376}
#define NULL
Definition: types.h:112
#define CDFRAMES_PERMIN
Definition: mcicda.c:47
#define CDFRAMES_PERSEC
Definition: mcicda.c:46
static BOOL device_io(HANDLE dev, DWORD code, void *inbuffer, DWORD insize, void *outbuffer, DWORD outsize, DWORD *retsize, OVERLAPPED *overlapped)
Definition: mcicda.c:84
GLenum const GLvoid * addr
Definition: glext.h:9621
unsigned int UINT
Definition: sysinfo.c:13
#define MCI_TMSF_MINUTE(t)
Definition: mmsystem.h:717
#define MCI_TMSF_SECOND(t)
Definition: mmsystem.h:718
#define MCI_FORMAT_MILLISECONDS
Definition: mmsystem.h:701
#define MCI_FORMAT_TMSF
Definition: mmsystem.h:711
#define MCI_MSF_MINUTE(t)
Definition: mmsystem.h:712
#define MCI_TMSF_FRAME(t)
Definition: mmsystem.h:719
#define MCI_MSF_FRAME(t)
Definition: mmsystem.h:714
#define MCI_TMSF_TRACK(t)
Definition: mmsystem.h:716
#define MCI_FORMAT_MSF
Definition: mmsystem.h:703
#define MCI_MSF_SECOND(t)
Definition: mmsystem.h:713
DWORD dwTime
Definition: solitaire.cpp:27
HANDLE handle
Definition: mcicda.c:66
DWORD dwTimeFormat
Definition: mcicda.c:65
unsigned char BYTE
Definition: xxhash.c:193

Referenced by MCICDA_Play(), and MCICDA_Seek().

◆ MCICDA_CalcTime()

static DWORD MCICDA_CalcTime ( WINE_MCICDAUDIO *  wmcda,
DWORD  tf,
DWORD  dwFrame,
LPDWORD  lpRet 
)
static

Definition at line 381 of file mcicda.c.

382{
383 DWORD dwTime = 0;
384 UINT wTrack;
385 UINT wMinutes;
386 UINT wSeconds;
387 UINT wFrames;
388 CDROM_TOC toc;
389 DWORD br;
390
391 TRACE("(%p, %08lX, %lu);\n", wmcda, tf, dwFrame);
392
393 switch (tf) {
395 dwTime = (dwFrame * 1000) / CDFRAMES_PERSEC + 1;
396 TRACE("MILLISECONDS %lu\n", dwTime);
397 *lpRet = 0;
398 break;
399 case MCI_FORMAT_MSF:
400 wMinutes = dwFrame / CDFRAMES_PERMIN;
401 wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
402 wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes - CDFRAMES_PERSEC * wSeconds;
403 dwTime = MCI_MAKE_MSF(wMinutes, wSeconds, wFrames);
404 TRACE("MSF %02u:%02u:%02u -> dwTime=%lu\n",
405 wMinutes, wSeconds, wFrames, dwTime);
406 *lpRet = MCI_COLONIZED3_RETURN;
407 break;
408 case MCI_FORMAT_TMSF:
409 default: /* unknown format ! force TMSF ! ... */
410 if (!device_io(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0,
411 &toc, sizeof(toc), &br, NULL))
412 return 0;
413 if (dwFrame < FRAME_OF_TOC(toc, toc.FirstTrack) ||
414 dwFrame > FRAME_OF_TOC(toc, toc.LastTrack + 1)) {
415 ERR("Out of range value %lu [%u,%u]\n",
416 dwFrame, FRAME_OF_TOC(toc, toc.FirstTrack),
417 FRAME_OF_TOC(toc, toc.LastTrack + 1));
418 *lpRet = 0;
419 return 0;
420 }
421 for (wTrack = toc.FirstTrack; wTrack <= toc.LastTrack; wTrack++) {
422 if (FRAME_OF_TOC(toc, wTrack) > dwFrame)
423 break;
424 }
425 wTrack--;
426 dwFrame -= FRAME_OF_TOC(toc, wTrack);
427 wMinutes = dwFrame / CDFRAMES_PERMIN;
428 wSeconds = (dwFrame - CDFRAMES_PERMIN * wMinutes) / CDFRAMES_PERSEC;
429 wFrames = dwFrame - CDFRAMES_PERMIN * wMinutes - CDFRAMES_PERSEC * wSeconds;
430 dwTime = MCI_MAKE_TMSF(wTrack, wMinutes, wSeconds, wFrames);
431 TRACE("%02u-%02u:%02u:%02u\n", wTrack, wMinutes, wSeconds, wFrames);
432 *lpRet = MCI_COLONIZED4_RETURN;
433 break;
434 }
435 return dwTime;
436}
#define ERR(fmt,...)
Definition: precomp.h:57
#define MCI_COLONIZED3_RETURN
Definition: mmddk.h:370
#define MCI_COLONIZED4_RETURN
Definition: mmddk.h:371
HFONT tf
Definition: icontest.c:17
#define MCI_MAKE_TMSF(t, m, s, f)
Definition: mmsystem.h:720
#define MCI_MAKE_MSF(m, s, f)
Definition: mmsystem.h:715

Referenced by MCICDA_Status().

◆ MCICDA_Close()

static DWORD MCICDA_Close ( UINT  wDevID,
DWORD  dwParam,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 536 of file mcicda.c.

537{
538 WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
539
540 TRACE("(%04X, %08lX, %p);\n", wDevID, dwParam, lpParms);
541
542 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
543
544 MCICDA_Stop(wDevID, MCI_WAIT, NULL);
545
546 if (--wmcda->nUseCount == 0) {
547 CloseHandle(wmcda->handle);
548 }
549 if ((dwParam & MCI_NOTIFY) && lpParms)
551 return 0;
552}
#define CloseHandle
Definition: compat.h:739
static WINE_MCICDAUDIO * MCICDA_GetOpenDrv(UINT wDevID)
Definition: mcicda.c:232
static DWORD MCICDA_Stop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:1082
static void MCICDA_Notify(DWORD_PTR hWndCallBack, WINE_MCICDAUDIO *wmcda, UINT wStatus)
Definition: mcicda.c:249
#define MCI_NOTIFY
Definition: mmsystem.h:729
#define MCIERR_INVALID_DEVICE_ID
Definition: mmsystem.h:569
#define MCI_WAIT
Definition: mmsystem.h:730
#define MCI_NOTIFY_SUCCESSFUL
Definition: mmsystem.h:725
int nUseCount
Definition: mcicda.c:61
DWORD_PTR dwCallback
Definition: mmsystem.h:1519

Referenced by MCICDA_DriverProc().

◆ MCICDA_DriverProc()

LRESULT CALLBACK MCICDA_DriverProc ( DWORD_PTR  dwDevID,
HDRVR  hDriv,
UINT  wMsg,
LPARAM  dwParam1,
LPARAM  dwParam2 
)

Definition at line 1310 of file mcicda.c.

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}
static DWORD MCICDA_drvOpen(LPCWSTR str, LPMCI_OPEN_DRIVER_PARMSW modp)
Definition: mcicda.c:185
static DWORD MCICDA_Resume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:1150
static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSW lpOpenParms)
Definition: mcicda.c:443
static DWORD MCICDA_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:536
static DWORD MCICDA_GetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
Definition: mcicda.c:557
static DWORD MCICDA_drvClose(DWORD dwDevID)
Definition: mcicda.c:216
static DWORD MCICDA_Status(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParms)
Definition: mcicda.c:708
static DWORD MCICDA_Play(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
Definition: mcicda.c:898
static DWORD MCICDA_Seek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
Definition: mcicda.c:1176
static DWORD MCICDA_Pause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:1120
static DWORD MCICDA_Info(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSW lpParms)
Definition: mcicda.c:656
static DWORD MCICDA_Set(UINT wDevID, DWORD dwFlags, LPMCI_SET_PARMS lpParms)
Definition: mcicda.c:1263
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
#define DRV_LOAD(x)
#define MCI_CUT
Definition: mmsystem.h:671
#define MCI_SAVE
Definition: mmsystem.h:661
#define DRV_CLOSE
Definition: mmsystem.h:122
#define MCI_BREAK
Definition: mmsystem.h:660
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define MCI_GETDEVCAPS
Definition: mmsystem.h:654
#define MCI_RESUME
Definition: mmsystem.h:675
#define MCI_DELETE
Definition: mmsystem.h:676
#define MCI_FREEZE
Definition: mmsystem.h:668
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define MCI_WINDOW
Definition: mmsystem.h:665
#define MCI_STATUS
Definition: mmsystem.h:662
#define MCI_COPY
Definition: mmsystem.h:672
#define MCI_ESCAPE
Definition: mmsystem.h:648
#define MCIERR_UNRECOGNIZED_COMMAND
Definition: mmsystem.h:571
#define MCI_SET
Definition: mmsystem.h:656
#define MCI_LOAD
Definition: mmsystem.h:670
#define MCI_UPDATE
Definition: mmsystem.h:674
#define DRV_REMOVE
Definition: mmsystem.h:128
#define DRV_ENABLE
Definition: mmsystem.h:120
#define MCI_STOP
Definition: mmsystem.h:651
#define MCI_CLOSE
Definition: mmsystem.h:647
#define MCI_SEEK
Definition: mmsystem.h:650
#define DRV_CONFIGURE
Definition: mmsystem.h:125
#define DRV_OPEN
Definition: mmsystem.h:121
#define MCI_WHERE
Definition: mmsystem.h:667
#define DRV_INSTALL
Definition: mmsystem.h:127
#define MCI_OPEN
Definition: mmsystem.h:646
#define MCI_UNFREEZE
Definition: mmsystem.h:669
#define MCI_PUT
Definition: mmsystem.h:666
#define MCI_SPIN
Definition: mmsystem.h:655
#define MCI_PAUSE
Definition: mmsystem.h:652
#define MCI_INFO
Definition: mmsystem.h:653
#define MCI_PASTE
Definition: mmsystem.h:673
#define DRV_FREE
Definition: mmsystem.h:124
#define MCIERR_UNSUPPORTED_FUNCTION
Definition: mmsystem.h:584
#define MCI_PLAY
Definition: mmsystem.h:649
#define MCI_STEP
Definition: mmsystem.h:657
#define MCI_REALIZE
Definition: mmsystem.h:664
#define MCI_RECORD
Definition: mmsystem.h:658
#define DRV_DISABLE
Definition: mmsystem.h:123
int WINAPI MessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
#define MB_OK
Definition: winuser.h:801
#define MCI_OPEN_DRIVER
Definition: mmddk.h:338
#define MCI_CLOSE_DRIVER
Definition: mmddk.h:339
const uint16_t * LPCWSTR
Definition: typedefs.h:57

◆ MCICDA_drvClose()

static DWORD MCICDA_drvClose ( DWORD  dwDevID)
static

Definition at line 216 of file mcicda.c.

217{
219
220 if (wmcda) {
221 wmcda->cs.DebugInfo->Spare[0] = 0;
222 DeleteCriticalSection(&wmcda->cs);
223 HeapFree(GetProcessHeap(), 0, wmcda);
224 mciSetDriverData(dwDevID, 0);
225 }
226 return (dwDevID == 0xFFFFFFFF) ? 1 : 0;
227}
#define GetProcessHeap()
Definition: compat.h:736
#define HeapFree(x, y, z)
Definition: compat.h:735
BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData)
DWORD WINAPI mciGetDriverData(UINT uDeviceID)
Definition: mci.c:2233
CRITICAL_SECTION cs
Definition: mcicda.c:76
PRTL_CRITICAL_SECTION_DEBUG DebugInfo
Definition: rtltypes.h:1478
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)

Referenced by MCICDA_DriverProc().

◆ MCICDA_drvOpen()

static DWORD MCICDA_drvOpen ( LPCWSTR  str,
LPMCI_OPEN_DRIVER_PARMSW  modp 
)
static

Definition at line 185 of file mcicda.c.

186{
187 static HMODULE dsHandle;
188 WINE_MCICDAUDIO* wmcda;
189
190 if (!modp) return 0xFFFFFFFF;
191 /* FIXME: MCIERR_CANNOT_LOAD_DRIVER if there's no drive of type CD-ROM */
192
194
195 if (!wmcda)
196 return 0;
197
198 if (!dsHandle) {
199 dsHandle = LoadLibraryA("dsound.dll");
200 if(dsHandle)
201 pDirectSoundCreate = (LPDIRECTSOUNDCREATE)GetProcAddress(dsHandle, "DirectSoundCreate");
202 }
203
204 wmcda->wDevID = modp->wDeviceID;
205 mciSetDriverData(wmcda->wDevID, (DWORD_PTR)wmcda);
209 wmcda->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": WINE_MCICDAUDIO.cs");
210 return modp->wDeviceID;
211}
#define GetProcAddress(x, y)
Definition: compat.h:753
#define HeapAlloc
Definition: compat.h:733
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
BOOL WINAPI InitializeCriticalSectionEx(OUT LPCRITICAL_SECTION lpCriticalSection, IN DWORD dwSpinCount, IN DWORD flags)
Definition: sync.c:107
HRESULT(WINAPI * LPDIRECTSOUNDCREATE)(LPCGUID, LPDIRECTSOUND *, LPUNKNOWN)
Definition: mcicda.c:81
static LPDIRECTSOUNDCREATE pDirectSoundCreate
Definition: mcicda.c:82
#define MCI_NO_COMMAND_TABLE
Definition: mmddk.h:375
#define MCI_DEVTYPE_CD_AUDIO
Definition: mmsystem.h:683
UINT wCustomCommandTable
Definition: mmddk.h:438
UINT wDevID
Definition: mcicda.c:60
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO
Definition: winnt_old.h:1156

Referenced by MCICDA_DriverProc().

◆ MCICDA_GetDevCaps()

static DWORD MCICDA_GetDevCaps ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_GETDEVCAPS_PARMS  lpParms 
)
static

Definition at line 557 of file mcicda.c.

559{
561 DWORD ret = 0;
562
563 TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
564
565 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
566 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
567
569 TRACE("MCI_GETDEVCAPS_ITEM dwItem=%08lX;\n", lpParms->dwItem);
570
571 switch (lpParms->dwItem) {
575 break;
579 break;
583 break;
587 break;
591 break;
595 break;
599 break;
603 break;
607 break;
608 default:
609 WARN("Unsupported %lx devCaps item\n", lpParms->dwItem);
611 }
612 } else {
613 TRACE("No GetDevCaps-Item !\n");
615 }
616 TRACE("lpParms->dwReturn=%08lX;\n", lpParms->dwReturn);
617 if (dwFlags & MCI_NOTIFY) {
619 }
620 return ret;
621}
#define WARN(fmt,...)
Definition: precomp.h:61
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define MAKEMCIRESOURCE(wRet, wRes)
Definition: mmddk.h:388
#define MCI_FALSE
Definition: mmddk.h:340
#define MCI_TRUE
Definition: mmddk.h:341
#define MCI_RESOURCE_RETURNED
Definition: mmddk.h:369
#define MCI_GETDEVCAPS_CAN_SAVE
Definition: mmsystem.h:767
#define MCI_GETDEVCAPS_HAS_VIDEO
Definition: mmsystem.h:761
#define MCI_GETDEVCAPS_CAN_RECORD
Definition: mmsystem.h:759
#define MCI_GETDEVCAPS_DEVICE_TYPE
Definition: mmsystem.h:762
#define MCI_GETDEVCAPS_COMPOUND_DEVICE
Definition: mmsystem.h:764
#define MCI_GETDEVCAPS_USES_FILES
Definition: mmsystem.h:763
#define MCI_GETDEVCAPS_CAN_PLAY
Definition: mmsystem.h:766
#define MCI_GETDEVCAPS_CAN_EJECT
Definition: mmsystem.h:765
#define MCIERR_MISSING_PARAMETER
Definition: mmsystem.h:583
#define MCIERR_NULL_PARAMETER_BLOCK
Definition: mmsystem.h:605
#define MCI_GETDEVCAPS_ITEM
Definition: mmsystem.h:758
#define MCI_GETDEVCAPS_HAS_AUDIO
Definition: mmsystem.h:760
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141

Referenced by MCICDA_DriverProc().

◆ MCICDA_GetError()

static int MCICDA_GetError ( WINE_MCICDAUDIO *  wmcda)
static

Definition at line 318 of file mcicda.c.

319{
320 switch (GetLastError())
321 {
324 case ERROR_IO_DEVICE: return MCIERR_HARDWARE;
325 default:
326 FIXME("Unknown mode %lu\n", GetLastError());
327 }
329}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define MCIERR_HARDWARE
Definition: mmsystem.h:572
#define MCIERR_DEVICE_NOT_READY
Definition: mmsystem.h:586
#define MCIERR_DRIVER_INTERNAL
Definition: mmsystem.h:582
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_IO_DEVICE
Definition: winerror.h:977
#define ERROR_NOT_READY
Definition: winerror.h:246

Referenced by MCICDA_Info(), MCICDA_Play(), MCICDA_Seek(), MCICDA_SkipDataTracks(), and MCICDA_Status().

◆ MCICDA_GetOpenDrv()

static WINE_MCICDAUDIO * MCICDA_GetOpenDrv ( UINT  wDevID)
static

Definition at line 232 of file mcicda.c.

233{
235
236 if (wmcda == NULL || wmcda->nUseCount == 0) {
237 WARN("Invalid wDevID=%u\n", wDevID);
238 return 0;
239 }
240 return wmcda;
241}

Referenced by MCICDA_Close(), MCICDA_Info(), MCICDA_Pause(), MCICDA_Play(), MCICDA_Resume(), MCICDA_Seek(), MCICDA_Set(), MCICDA_SetDoor(), MCICDA_Status(), and MCICDA_Stop().

◆ MCICDA_GetStatus()

static DWORD MCICDA_GetStatus ( WINE_MCICDAUDIO *  wmcda)
static

Definition at line 272 of file mcicda.c.

273{
276 DWORD br;
278
280 if(wmcda->hThread != 0) {
282 HRESULT hr;
283
285 if(SUCCEEDED(hr)) {
289 else
291 }
292 else
294 }
295 }
296 else if (!device_io(wmcda->handle, IOCTL_CDROM_READ_Q_CHANNEL, &fmt, sizeof(fmt),
297 &data, sizeof(data), &br, NULL)) {
299 } else {
300 switch (data.CurrentPosition.Header.AudioStatus)
301 {
308 default:
309 break;
310 }
311 }
312 return mode;
313}
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
HRESULT hr
Definition: delayimp.cpp:582
#define IDirectSoundBuffer_GetStatus(p, a)
Definition: dsound.h:582
#define DSBSTATUS_PLAYING
Definition: dsound.h:196
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum mode
Definition: glext.h:6217
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define MCI_MODE_PLAY
Definition: mmsystem.h:696
#define MCI_MODE_OPEN
Definition: mmsystem.h:700
#define MCI_MODE_STOP
Definition: mmsystem.h:695
#define MCI_MODE_NOT_READY
Definition: mmsystem.h:694
#define MCI_MODE_PAUSE
Definition: mmsystem.h:699
#define AUDIO_STATUS_IN_PROGRESS
Definition: ntddcdrm.h:314
#define AUDIO_STATUS_NO_STATUS
Definition: ntddcdrm.h:318
#define AUDIO_STATUS_PLAY_COMPLETE
Definition: ntddcdrm.h:316
#define AUDIO_STATUS_PAUSED
Definition: ntddcdrm.h:315
#define AUDIO_STATUS_NOT_SUPPORTED
Definition: ntddcdrm.h:313
#define AUDIO_STATUS_PLAY_ERROR
Definition: ntddcdrm.h:317
HANDLE hThread
Definition: mcicda.c:69
HANDLE stopEvent
Definition: mcicda.c:70
IDirectSoundBuffer * dsBuf
Definition: mcicda.c:74
Definition: dsound.c:943
Definition: ps.c:97
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define WAIT_OBJECT_0
Definition: winbase.h:383

Referenced by MCICDA_Status().

◆ MCICDA_Info()

static DWORD MCICDA_Info ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_INFO_PARMSW  lpParms 
)
static

Definition at line 656 of file mcicda.c.

657{
658 LPCWSTR str = NULL;
659 WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
660 DWORD ret = 0;
661 WCHAR buffer[16];
662
663 TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
664
665 if (lpParms == NULL || lpParms->lpstrReturn == NULL)
667 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
668
669 TRACE("buf=%p, len=%lu\n", lpParms->lpstrReturn, lpParms->dwRetSize);
670
672 str = L"Wine's audio CD";
673 } else if (dwFlags & MCI_INFO_MEDIA_UPC) {
675 } else if (dwFlags & MCI_INFO_MEDIA_IDENTITY) {
676 DWORD res = 0;
677 CDROM_TOC toc;
678 DWORD br;
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
687 str = buffer;
688 } else {
689 WARN("Don't know this info command (%lu)\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}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define lstrcpynW
Definition: compat.h:738
static DWORD CDROM_Audio_GetSerial(CDROM_TOC *toc)
Definition: mcicda.c:623
static int MCICDA_GetError(WINE_MCICDAUDIO *wmcda)
Definition: mcicda.c:318
#define swprintf
Definition: precomp.h:40
#define L(x)
Definition: resources.c:13
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
#define debugstr_w
Definition: kernel32.h:32
#define MCI_INFO_PRODUCT
Definition: mmsystem.h:752
#define MCI_INFO_MEDIA_IDENTITY
Definition: mmsystem.h:755
#define MCIERR_NO_IDENTITY
Definition: mmsystem.h:643
#define MCIERR_PARAM_OVERFLOW
Definition: mmsystem.h:578
#define MCI_INFO_MEDIA_UPC
Definition: mmsystem.h:754
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
short WCHAR
Definition: pedump.c:58
DWORD_PTR dwCallback
Definition: mmsystem.h:1581

Referenced by MCICDA_DriverProc().

◆ MCICDA_Notify()

static void MCICDA_Notify ( DWORD_PTR  hWndCallBack,
WINE_MCICDAUDIO *  wmcda,
UINT  wStatus 
)
static

Definition at line 249 of file mcicda.c.

250{
251 MCIDEVICEID wDevID = wmcda->wNotifyDeviceID;
253 if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_SUPERSEDED);
254 mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus);
255}
BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
Definition: mci.c:2223
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define MCI_NOTIFY_SUPERSEDED
Definition: mmsystem.h:726
UINT MCIDEVICEID
Definition: mmsystem.h:961
#define LOWORD(l)
Definition: pedump.c:82
MCIDEVICEID wNotifyDeviceID
Definition: mcicda.c:63
HANDLE hCallback
Definition: mcicda.c:64
#define HWND_32(h16)
Definition: wownt32.h:29

Referenced by MCICDA_Close(), MCICDA_GetDevCaps(), MCICDA_Info(), MCICDA_Pause(), MCICDA_Resume(), MCICDA_Seek(), MCICDA_Set(), MCICDA_Status(), and MCICDA_Stop().

◆ MCICDA_Open()

static DWORD MCICDA_Open ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_OPEN_PARMSW  lpOpenParms 
)
static

Definition at line 443 of file mcicda.c.

444{
445 MCIDEVICEID dwDeviceID;
446 DWORD ret;
448 WCHAR root[7], drive = 0;
449
450 TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpOpenParms);
451
452 if (lpOpenParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
453 if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
454
455 dwDeviceID = lpOpenParms->wDeviceID;
456
457 if (wmcda->nUseCount > 0) {
458 /* The driver is already open on this channel */
459 /* If the driver was opened shareable before and this open specifies */
460 /* shareable then increment the use count */
461 if (wmcda->fShareable && (dwFlags & MCI_OPEN_SHAREABLE))
462 ++wmcda->nUseCount;
463 else
465 } else {
466 wmcda->nUseCount = 1;
468 }
471 WARN("MCI_OPEN_ELEMENT_ID %p! Abort\n", lpOpenParms->lpstrElementName);
473 goto the_error;
474 }
475 TRACE("MCI_OPEN_ELEMENT element name: %s\n", debugstr_w(lpOpenParms->lpstrElementName));
476 /* Only the first letter counts since w2k
477 * Win9x-NT accept only d: and w98SE accepts d:\foobar as well.
478 * Play d:\Track03.cda plays from the first track, not #3. */
479 if (!isalpha(lpOpenParms->lpstrElementName[0]))
480 {
482 goto the_error;
483 }
484 drive = toupper(lpOpenParms->lpstrElementName[0]);
485 root[0] = drive; root[1] = ':'; root[2] = '\\'; root[3] = '\0';
487 {
489 goto the_error;
490 }
491 }
492 else
493 {
494 root[0] = 'A'; root[1] = ':'; root[2] = '\\'; root[3] = '\0';
495 for ( ; root[0] <= 'Z'; root[0]++)
496 {
498 {
499 drive = root[0];
500 break;
501 }
502 }
503 if (!drive)
504 {
505 ret = MCIERR_CANNOT_LOAD_DRIVER; /* drvOpen should return this */
506 goto the_error;
507 }
508 }
509
510 wmcda->wNotifyDeviceID = dwDeviceID;
512
513 /* now, open the handle */
514 root[0] = root[1] = '\\'; root[2] = '.'; root[3] = '\\'; root[4] = drive; root[5] = ':'; root[6] = '\0';
516 if (wmcda->handle == INVALID_HANDLE_VALUE)
517 {
519 goto the_error;
520 }
521
522 if (dwFlags & MCI_NOTIFY) {
524 dwDeviceID, MCI_NOTIFY_SUCCESSFUL);
525 }
526 return 0;
527
528 the_error:
529 --wmcda->nUseCount;
530 return ret;
531}
#define isalpha(c)
Definition: acclib.h:74
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_SHARE_READ
Definition: compat.h:136
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
int CDECL toupper(int c)
Definition: ctype.c:514
#define MCIERR_FLAGS_NOT_COMPATIBLE
Definition: mmsystem.h:593
#define MCI_OPEN_SHAREABLE
Definition: mmsystem.h:734
#define MCI_OPEN_ELEMENT_ID
Definition: mmsystem.h:737
#define MCI_OPEN_ELEMENT
Definition: mmsystem.h:735
#define MCIERR_CANNOT_LOAD_DRIVER
Definition: mmsystem.h:576
#define MCIERR_INVALID_FILE
Definition: mmsystem.h:604
#define MCIERR_MUST_USE_SHAREABLE
Definition: mmsystem.h:599
BOOL fShareable
Definition: mcicda.c:62
DWORD_PTR dwCallback
Definition: mmsystem.h:1531
LPCWSTR lpstrElementName
Definition: mmsystem.h:1534
MCIDEVICEID wDeviceID
Definition: mmsystem.h:1532
#define DRIVE_CDROM
Definition: winbase.h:279

Referenced by MCICDA_DriverProc().

◆ MCICDA_Pause()

static DWORD MCICDA_Pause ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 1120 of file mcicda.c.

1121{
1122 WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1123 HANDLE oldcb;
1124 DWORD br;
1125
1126 TRACE("(%04X, %08lX, %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}
#define IDirectSoundBuffer_Stop(p)
Definition: dsound.h:591
#define FAILED(hr)
Definition: intsafe.h:51
#define MCI_NOTIFY_ABORTED
Definition: mmsystem.h:727

Referenced by MCICDA_DriverProc().

◆ MCICDA_Play()

static DWORD MCICDA_Play ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_PLAY_PARMS  lpParms 
)
static

Definition at line 898 of file mcicda.c.

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, %08lX, %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=%08lX -> %lu\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=%08lX -> %lu\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 %lu to %lu\n", start, end);
945
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;
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;
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) {
1059 wmcda->dsObj = NULL;
1060 }
1061 }
1062
1064 play.StartingS = (start / CDFRAMES_PERSEC) % 60;
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;
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}
#define WAVE_FORMAT_PCM
Definition: constants.h:425
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:137
static DWORD MCICDA_SkipDataTracks(WINE_MCICDAUDIO *wmcda, DWORD *frame)
Definition: mcicda.c:867
#define CDDA_FRAG_SIZE
Definition: mcicda.c:55
#define CDDA_FRAG_COUNT
Definition: mcicda.c:57
#define FRAME_OF_ADDR(a)
Definition: mcicda.c:48
static DWORD MCICDA_CalcFrame(WINE_MCICDAUDIO *wmcda, DWORD dwTime)
Definition: mcicda.c:334
#define RAW_SECTOR_SIZE
Definition: mcicda.c:52
static BOOL MCICDA_ReadTOC(WINE_MCICDAUDIO *wmcda, CDROM_TOC *toc, DWORD *br)
Definition: mcicda.c:260
static DWORD CALLBACK MCICDA_playLoop(void *ptr)
Definition: mcicda.c:109
#define INFINITE
Definition: serial.h:102
#define IDirectSoundBuffer_Unlock(p, a, b, c, d)
Definition: dsound.h:592
#define DSBCAPS_GLOBALFOCUS
Definition: dsound.h:219
#define DSBCAPS_GETCURRENTPOSITION2
Definition: dsound.h:220
#define DSBLOCK_ENTIREBUFFER
Definition: dsound.h:204
#define DSSCL_PRIORITY
Definition: dsound.h:248
#define IDirectSoundBuffer_Play(p, a, b, c)
Definition: dsound.h:585
#define IDirectSound_Release(p)
Definition: dsound.h:453
#define DSBPLAY_LOOPING
Definition: dsound.h:189
#define IDirectSoundBuffer_Lock(p, a, b, c, d, e, f, g)
Definition: dsound.h:584
#define IDirectSound_SetCooperativeLevel(p, a, b)
Definition: dsound.h:458
#define IDirectSound_CreateSoundBuffer(p, a, b, c)
Definition: dsound.h:455
#define IDirectSoundBuffer_Release(p)
Definition: dsound.h:574
GLuint start
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
#define MCI_TO
Definition: mmsystem.h:732
#define MCIERR_OUTOFRANGE
Definition: mmsystem.h:592
#define MCI_NOTIFY_FAILURE
Definition: mmsystem.h:728
#define MCI_FROM
Definition: mmsystem.h:731
D3D11_SHADER_VARIABLE_DESC desc
Definition: reflection.c:1683
#define min(a, b)
Definition: monoChain.cc:55
@ CDDA
Definition: ntddcdrm.h:381
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:628
#define memset(x, y, z)
Definition: compat.h:39
IDirectSound * dsObj
Definition: mcicda.c:73
DWORD end
Definition: mcicda.c:71
DWORD start
Definition: mcicda.c:71
TRACK_MODE_TYPE TrackMode
Definition: ntddcdrm.h:396
ULONG SectorCount
Definition: ntddcdrm.h:395
LARGE_INTEGER DiskOffset
Definition: ntddcdrm.h:394
DWORD_PTR dwCallback
Definition: mmsystem.h:1539
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:573
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:669
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by MCICDA_DriverProc().

◆ MCICDA_playLoop()

static DWORD CALLBACK MCICDA_playLoop ( void *  ptr)
static

Definition at line 109 of file mcicda.c.

110{
112 DWORD lastPos, curPos, endPos, br;
113 void *cdData;
114 DWORD lockLen, fragLen;
115 DSBCAPS caps;
116 RAW_READ_INFO rdInfo;
117 HRESULT hr = DS_OK;
118
119 memset(&caps, 0, sizeof(caps));
120 caps.dwSize = sizeof(caps);
121 hr = IDirectSoundBuffer_GetCaps(wmcda->dsBuf, &caps);
122
123 fragLen = caps.dwBufferBytes/CDDA_FRAG_COUNT;
124 curPos = lastPos = 0;
125 endPos = ~0u;
126 while (SUCCEEDED(hr) && endPos != lastPos &&
129 if ((curPos-lastPos+caps.dwBufferBytes)%caps.dwBufferBytes < fragLen) {
130 Sleep(1);
131 continue;
132 }
133
134 EnterCriticalSection(&wmcda->cs);
135 rdInfo.DiskOffset.QuadPart = wmcda->start<<11;
136 rdInfo.SectorCount = min(fragLen/RAW_SECTOR_SIZE, wmcda->end-wmcda->start);
137 rdInfo.TrackMode = CDDA;
138
139 hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, lastPos, fragLen, &cdData, &lockLen, NULL, NULL, 0);
140 if (hr == DSERR_BUFFERLOST) {
143 LeaveCriticalSection(&wmcda->cs);
144 break;
145 }
146 hr = IDirectSoundBuffer_Lock(wmcda->dsBuf, lastPos, fragLen, &cdData, &lockLen, NULL, NULL, 0);
147 }
148
149 if (SUCCEEDED(hr)) {
150 if (rdInfo.SectorCount > 0) {
151 if (!device_io(wmcda->handle, IOCTL_CDROM_RAW_READ, &rdInfo, sizeof(rdInfo), cdData, lockLen, &br, NULL))
152 WARN("CD read failed at sector %ld: 0x%lx\n", wmcda->start, GetLastError());
153 }
154 if (rdInfo.SectorCount*RAW_SECTOR_SIZE < lockLen) {
155 if(endPos == ~0u) endPos = lastPos;
156 memset((BYTE*)cdData + rdInfo.SectorCount*RAW_SECTOR_SIZE, 0,
157 lockLen - rdInfo.SectorCount*RAW_SECTOR_SIZE);
158 }
159 hr = IDirectSoundBuffer_Unlock(wmcda->dsBuf, cdData, lockLen, NULL, 0);
160 }
161
162 lastPos += fragLen;
163 lastPos %= caps.dwBufferBytes;
164 wmcda->start += rdInfo.SectorCount;
165
166 LeaveCriticalSection(&wmcda->cs);
167 }
169 SetEvent(wmcda->stopEvent);
170
171 /* A design bug in native: the independent CD player called by the
172 * MCI has no means to signal end of playing, therefore the MCI
173 * notification is left hanging. MCI_NOTIFY_SUPERSEDED will be
174 * signaled by the next command that has MCI_NOTIFY set (or
175 * MCI_NOTIFY_ABORTED for MCI_PLAY). */
176
177 return 0;
178}
#define IDirectSoundBuffer_Restore(p)
Definition: dsound.h:593
#define IDirectSoundBuffer_GetCurrentPosition(p, a, b)
Definition: dsound.h:577
#define DS_OK
Definition: dsound.h:116
#define IDirectSoundBuffer_GetCaps(p, a)
Definition: dsound.h:576
#define DSERR_BUFFERLOST
Definition: dsound.h:131
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
static PVOID ptr
Definition: dispmode.c:27
DWORD dwBufferBytes
Definition: dsound.h:241
DWORD dwSize
Definition: dsound.h:239
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)

Referenced by MCICDA_Play().

◆ MCICDA_ReadTOC()

static BOOL MCICDA_ReadTOC ( WINE_MCICDAUDIO *  wmcda,
CDROM_TOC *  toc,
DWORD *  br 
)
static

Definition at line 260 of file mcicda.c.

261{
262 if (!device_io(wmcda->handle, IOCTL_CDROM_READ_TOC, NULL, 0, toc, sizeof(*toc), br, NULL)) {
263 WARN("error reading TOC !\n");
264 return FALSE;
265 }
266 return TRUE;
267}

Referenced by MCICDA_Play(), MCICDA_Seek(), MCICDA_SkipDataTracks(), and MCICDA_Status().

◆ MCICDA_Resume()

static DWORD MCICDA_Resume ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 1150 of file mcicda.c.

1151{
1152 WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1153 DWORD br;
1154
1155 TRACE("(%04X, %08lX, %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}

Referenced by MCICDA_DriverProc().

◆ MCICDA_Seek()

static DWORD MCICDA_Seek ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_SEEK_PARMS  lpParms 
)
static

Definition at line 1176 of file mcicda.c.

1177{
1178 DWORD at;
1179 WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1181 DWORD br, position, ret;
1182 CDROM_TOC toc;
1183
1184 TRACE("(%04X, %08lX, %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 %lu\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}
#define MCI_SEEK_TO_END
Definition: mmsystem.h:741
#define MCI_SEEK_TO_START
Definition: mmsystem.h:740
int seek(void *fd, ulong off, int mode)
Definition: pe.c:51
DWORD_PTR dwCallback
Definition: mmsystem.h:1545

Referenced by MCICDA_DriverProc().

◆ MCICDA_Set()

static DWORD MCICDA_Set ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_SET_PARMS  lpParms 
)
static

Definition at line 1263 of file mcicda.c.

1264{
1265 WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1266
1267 TRACE("(%04X, %08lX, %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 }
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 */
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:
1296 }
1297 wmcda->dwTimeFormat = lpParms->dwTimeFormat;
1298 }
1299 if (dwFlags & MCI_SET_AUDIO) /* one xp machine ignored it */
1300 TRACE("SET_AUDIO %lX %lx\n", dwFlags, lpParms->dwAudio);
1301
1302 if (dwFlags & MCI_NOTIFY)
1304 return 0;
1305}
static DWORD MCICDA_SetDoor(UINT wDevID, BOOL open)
Definition: mcicda.c:1243
#define MCI_SET_AUDIO
Definition: mmsystem.h:775
#define MCI_SET_DOOR_OPEN
Definition: mmsystem.h:772
#define MCI_SET_TIME_FORMAT
Definition: mmsystem.h:774
#define MCI_SET_DOOR_CLOSED
Definition: mmsystem.h:773
#define MCIERR_BAD_TIME_FORMAT
Definition: mmsystem.h:601
DWORD_PTR dwCallback
Definition: mmsystem.h:1609
DWORD dwTimeFormat
Definition: mmsystem.h:1610

Referenced by MCICDA_DriverProc().

◆ MCICDA_SetDoor()

static DWORD MCICDA_SetDoor ( UINT  wDevID,
BOOL  open 
)
static

Definition at line 1243 of file mcicda.c.

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}
#define open
Definition: io.h:44

Referenced by MCICDA_Set().

◆ MCICDA_SkipDataTracks()

static DWORD MCICDA_SkipDataTracks ( WINE_MCICDAUDIO *  wmcda,
DWORD *  frame 
)
static

Definition at line 867 of file mcicda.c.

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}
UCHAR Control
Definition: ntddcdrm.h:137

Referenced by MCICDA_Play(), and MCICDA_Seek().

◆ MCICDA_Status()

static DWORD MCICDA_Status ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_STATUS_PARMS  lpParms 
)
static

Definition at line 708 of file mcicda.c.

709{
710 WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
711 DWORD ret = 0;
714 CDROM_TOC toc;
715 DWORD br;
716
717 TRACE("(%04X, %08lX, %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 = %lx\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=%Iu\n", lpParms->dwReturn);
735 break;
737 if (!MCICDA_ReadTOC(wmcda, &toc, &br))
738 return MCICDA_GetError(wmcda);
739
740 if (dwFlags & MCI_TRACK) {
741 TRACE("MCI_TRACK #%lu 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=%Iu\n", lpParms->dwReturn);
763 break;
764 case MCI_STATUS_MODE:
765 lpParms->dwReturn = MCICDA_GetStatus(wmcda);
766 TRACE("MCI_STATUS_MODE=%08IX\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 = %Iu\n", lpParms->dwReturn);
782 if (lpParms->dwReturn == (WORD)-1)
783 return MCICDA_GetError(wmcda);
784 break;
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 #%lu !\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=%08IX\n", lpParms->dwReturn);
816 break;
817 case MCI_STATUS_READY:
818 TRACE("MCI_STATUS_READY !\n");
819 switch (MCICDA_GetStatus(wmcda))
820 {
822 case MCI_MODE_OPEN:
824 break;
825 default:
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[%ld]=%Id\n", lpParms->dwTrack, lpParms->dwReturn);
853 break;
854 default:
855 FIXME("unknown command %08lX !\n", lpParms->dwItem);
857 }
858 } else return MCIERR_MISSING_PARAMETER;
859 if ((dwFlags & MCI_NOTIFY) && HRESULT_CODE(ret)==0)
861 return ret;
862}
static DWORD MCICDA_GetStatus(WINE_MCICDAUDIO *wmcda)
Definition: mcicda.c:272
static DWORD MCICDA_CalcTime(WINE_MCICDAUDIO *wmcda, DWORD tf, DWORD dwFrame, LPDWORD lpRet)
Definition: mcicda.c:381
#define MCI_FORMAT_RETURN_BASE
Definition: mmddk.h:343
#define MCI_CDA_TRACK_OTHER
Definition: mmsystem.h:818
#define MCI_STATUS_POSITION
Definition: mmsystem.h:745
#define MCI_TRACK
Definition: mmsystem.h:733
#define MCI_CDA_TRACK_AUDIO
Definition: mmsystem.h:817
#define MCI_STATUS_START
Definition: mmsystem.h:743
#define MCI_STATUS_CURRENT_TRACK
Definition: mmsystem.h:751
#define MCI_STATUS_NUMBER_OF_TRACKS
Definition: mmsystem.h:746
#define MCI_STATUS_LENGTH
Definition: mmsystem.h:744
#define MCI_STATUS_MODE
Definition: mmsystem.h:747
#define MCI_CDA_STATUS_TYPE_TRACK
Definition: mmsystem.h:816
#define MCI_STATUS_MEDIA_PRESENT
Definition: mmsystem.h:748
#define MCI_STATUS_TIME_FORMAT
Definition: mmsystem.h:749
#define MCI_STATUS_ITEM
Definition: mmsystem.h:742
#define MCI_STATUS_READY
Definition: mmsystem.h:750
DWORD_PTR dwReturn
Definition: mmsystem.h:1569
DWORD_PTR dwCallback
Definition: mmsystem.h:1568
#define HRESULT_CODE(hr)
Definition: winerror.h:188

Referenced by MCICDA_DriverProc().

◆ MCICDA_Stop()

static DWORD MCICDA_Stop ( UINT  wDevID,
DWORD  dwFlags,
LPMCI_GENERIC_PARMS  lpParms 
)
static

Definition at line 1082 of file mcicda.c.

1083{
1084 WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
1085 HANDLE oldcb;
1086 DWORD br;
1087
1088 TRACE("(%04X, %08lX, %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;
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}

Referenced by MCICDA_Close(), MCICDA_DriverProc(), and MCICDA_Seek().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( mcicda  )

Variable Documentation

◆ pDirectSoundCreate