ReactOS 0.4.15-dev-7953-g1f49173
mcicda.c File Reference
#include "config.h"
#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 "wine/winternl.h"
#include "wine/debug.h"
#include "wine/unicode.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(WINAPILPDIRECTSOUNDCREATE) (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_MCICDAUDIOMCICDA_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 55 of file mcicda.c.

◆ CDDA_FRAG_SIZE

#define CDDA_FRAG_SIZE   (32768)

Definition at line 53 of file mcicda.c.

◆ CDFRAMES_PERMIN

#define CDFRAMES_PERMIN   (CDFRAMES_PERSEC * 60)

Definition at line 45 of file mcicda.c.

◆ CDFRAMES_PERSEC

#define CDFRAMES_PERSEC   75

Definition at line 44 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 46 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 47 of file mcicda.c.

◆ RAW_SECTOR_SIZE

#define RAW_SECTOR_SIZE   (2352)

Definition at line 50 of file mcicda.c.

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 28 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 79 of file mcicda.c.

Function Documentation

◆ CDROM_Audio_GetSerial()

static DWORD CDROM_Audio_GetSerial ( CDROM_TOC toc)
static

Definition at line 621 of file mcicda.c.

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}
#define FRAME_OF_TOC(toc, idx)
Definition: mcicda.c:47
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
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 82 of file mcicda.c.

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}
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)
unsigned int BOOL
Definition: ntddk_ex.h:94
const unsigned char * inbuffer
Definition: jpeglib.h:983
const unsigned char size_t insize
Definition: jpeglib.h:984
unsigned char size_t * outsize
Definition: jpeglib.h:981
#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
int ret

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 332 of file mcicda.c.

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",
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)) +
371 break;
372 }
373 return dwFrame;
374}
#define NULL
Definition: types.h:112
#define CDFRAMES_PERMIN
Definition: mcicda.c:45
#define CDFRAMES_PERSEC
Definition: mcicda.c:44
static BOOL device_io(HANDLE dev, DWORD code, void *inbuffer, DWORD insize, void *outbuffer, DWORD outsize, DWORD *retsize, OVERLAPPED *overlapped)
Definition: mcicda.c:82
GLenum const GLvoid * addr
Definition: glext.h:9621
#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
unsigned int UINT
Definition: ndis.h:50
DWORD dwTime
Definition: solitaire.cpp:27
HANDLE handle
Definition: mcicda.c:64
DWORD dwTimeFormat
Definition: mcicda.c:63
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 379 of file mcicda.c.

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}
#define ERR(fmt,...)
Definition: debug.h:110
#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 534 of file mcicda.c.

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}
#define CloseHandle
Definition: compat.h:739
static WINE_MCICDAUDIO * MCICDA_GetOpenDrv(UINT wDevID)
Definition: mcicda.c:230
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:247
#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:59
DWORD_PTR dwCallback
Definition: mmsystem.h:1517

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:183
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:441
static DWORD MCICDA_Close(UINT wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
Definition: mcicda.c:534
static DWORD MCICDA_GetDevCaps(UINT wDevID, DWORD dwFlags, LPMCI_GETDEVCAPS_PARMS lpParms)
Definition: mcicda.c:555
static DWORD MCICDA_drvClose(DWORD dwDevID)
Definition: mcicda.c:214
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:654
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
#define MCI_OPEN_DRIVER
Definition: mmddk.h:338
#define MCI_CLOSE_DRIVER
Definition: mmddk.h:339
int WINAPI MessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
#define MB_OK
Definition: winuser.h:790
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

◆ MCICDA_drvClose()

static DWORD MCICDA_drvClose ( DWORD  dwDevID)
static

Definition at line 214 of file mcicda.c.

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}
#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:74
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:887
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:894
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 183 of file mcicda.c.

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);
207 wmcda->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": WINE_MCICDAUDIO.cs");
208 return modp->wDeviceID;
209}
#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
HRESULT(WINAPI * LPDIRECTSOUNDCREATE)(LPCGUID, LPDIRECTSOUND *, LPUNKNOWN)
Definition: mcicda.c:79
static LPDIRECTSOUNDCREATE pDirectSoundCreate
Definition: mcicda.c:80
#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:58
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65

Referenced by MCICDA_DriverProc().

◆ MCICDA_GetDevCaps()

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

Definition at line 555 of file mcicda.c.

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;
577 break;
581 break;
585 break;
589 break;
593 break;
597 break;
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}
#define WARN(fmt,...)
Definition: debug.h:112
#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_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176

Referenced by MCICDA_DriverProc().

◆ MCICDA_GetError()

static int MCICDA_GetError ( WINE_MCICDAUDIO wmcda)
static

Definition at line 316 of file mcicda.c.

317{
318 switch (GetLastError())
319 {
322 case ERROR_IO_DEVICE: return MCIERR_HARDWARE;
323 default:
324 FIXME("Unknown mode %u\n", GetLastError());
325 }
327}
#define FIXME(fmt,...)
Definition: debug.h:111
#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:653
#define ERROR_NOT_READY
Definition: winerror.h:124

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 230 of file mcicda.c.

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

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 270 of file mcicda.c.

271{
274 DWORD br;
276
278 if(wmcda->hThread != 0) {
280 HRESULT hr;
281
283 if(SUCCEEDED(hr)) {
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 {
306 default:
307 break;
308 }
309 }
310 return mode;
311}
#define IOCTL_CDROM_CURRENT_POSITION
Definition: cdrw_usr.h:1354
#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
HRESULT hr
Definition: shlfolder.c:183
HANDLE hThread
Definition: mcicda.c:67
HANDLE stopEvent
Definition: mcicda.c:68
IDirectSoundBuffer * dsBuf
Definition: mcicda.c:72
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:406

Referenced by MCICDA_Status().

◆ MCICDA_Info()

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

Definition at line 654 of file mcicda.c.

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
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
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}
#define lstrcpynW
Definition: compat.h:738
static DWORD CDROM_Audio_GetSerial(CDROM_TOC *toc)
Definition: mcicda.c:621
static int MCICDA_GetError(WINE_MCICDAUDIO *wmcda)
Definition: mcicda.c:316
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
#define sprintfW
Definition: unicode.h:58
DWORD_PTR dwCallback
Definition: mmsystem.h:1579
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by MCICDA_DriverProc().

◆ MCICDA_Notify()

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

Definition at line 247 of file mcicda.c.

248{
249 MCIDEVICEID wDevID = wmcda->wNotifyDeviceID;
251 if (old) mciDriverNotify(old, wDevID, MCI_NOTIFY_SUPERSEDED);
252 mciDriverNotify(HWND_32(LOWORD(hWndCallBack)), wDevID, wStatus);
253}
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:959
#define LOWORD(l)
Definition: pedump.c:82
MCIDEVICEID wNotifyDeviceID
Definition: mcicda.c:61
HANDLE hCallback
Definition: mcicda.c:62
#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 441 of file mcicda.c.

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 }
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;
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) {
522 dwDeviceID, MCI_NOTIFY_SUCCESSFUL);
523 }
524 return 0;
525
526 the_error:
527 --wmcda->nUseCount;
528 return ret;
529}
#define isalpha(c)
Definition: acclib.h:74
int toupper(int c)
Definition: utclib.c:881
#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
#define DRIVE_CDROM
Definition: machpc98.h:119
#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:60
DWORD_PTR dwCallback
Definition: mmsystem.h:1529
LPCWSTR lpstrElementName
Definition: mmsystem.h:1532
MCIDEVICEID wDeviceID
Definition: mmsystem.h:1530

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, %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}
#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, %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
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:53
#define CDDA_FRAG_COUNT
Definition: mcicda.c:55
#define FRAME_OF_ADDR(a)
Definition: mcicda.c:46
static DWORD MCICDA_CalcFrame(WINE_MCICDAUDIO *wmcda, DWORD dwTime)
Definition: mcicda.c:332
#define RAW_SECTOR_SIZE
Definition: mcicda.c:50
static BOOL MCICDA_ReadTOC(WINE_MCICDAUDIO *wmcda, CDROM_TOC *toc, DWORD *br)
Definition: mcicda.c:258
static DWORD CALLBACK MCICDA_playLoop(void *ptr)
Definition: mcicda.c:107
#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
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#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
static const WCHAR desc[]
Definition: protectdata.c:36
#define min(a, b)
Definition: monoChain.cc:55
@ CDDA
Definition: ntddcdrm.h:381
#define memset(x, y, z)
Definition: compat.h:39
IDirectSound * dsObj
Definition: mcicda.c:71
DWORD end
Definition: mcicda.c:69
DWORD start
Definition: mcicda.c:69
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:1537
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
LONGLONG QuadPart
Definition: typedefs.h:114
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656

Referenced by MCICDA_DriverProc().

◆ MCICDA_playLoop()

static DWORD CALLBACK MCICDA_playLoop ( void ptr)
static

Definition at line 107 of file mcicda.c.

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}
#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:790
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 258 of file mcicda.c.

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}

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, %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}

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, %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}
#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:1543

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, %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 }
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 %X %x\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:1607
DWORD dwTimeFormat
Definition: mmsystem.h:1608

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: acwin.h:95

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, %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;
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;
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 {
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[%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}
static DWORD MCICDA_GetStatus(WINE_MCICDAUDIO *wmcda)
Definition: mcicda.c:270
static DWORD MCICDA_CalcTime(WINE_MCICDAUDIO *wmcda, DWORD tf, DWORD dwFrame, LPDWORD lpRet)
Definition: mcicda.c:379
#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:1567
DWORD_PTR dwCallback
Definition: mmsystem.h:1566
#define HRESULT_CODE(hr)
Definition: winerror.h:76

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, %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;
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