Always open/close the CD-ROM device for every Windows API CD-ROM

access.
This commit is contained in:
Andreas Mohr 2000-10-23 00:40:23 +00:00 committed by Alexandre Julliard
parent 6bfbc3d23e
commit 588ee35618
4 changed files with 336 additions and 229 deletions

View file

@ -69,7 +69,7 @@ static WINE_MCICDAUDIO* MCICDA_GetOpenDrv(UINT wDevID)
{ {
WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID); WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID);
if (wmcda == NULL || wmcda->nUseCount == 0 || wmcda->wcda.unixdev <= 0) { if (wmcda == NULL || wmcda->nUseCount == 0) {
WARN("Invalid wDevID=%u\n", wDevID); WARN("Invalid wDevID=%u\n", wDevID);
return 0; return 0;
} }
@ -215,6 +215,7 @@ static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpenPar
DWORD dwDeviceID; DWORD dwDeviceID;
WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID); WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID);
MCI_SEEK_PARMS seekParms; MCI_SEEK_PARMS seekParms;
int dev;
TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpOpenParms); TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpOpenParms);
@ -252,12 +253,16 @@ static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpenPar
} }
wmcda->mciMode = MCI_MODE_STOP; wmcda->mciMode = MCI_MODE_STOP;
wmcda->dwTimeFormat = MCI_FORMAT_MSF; wmcda->dwTimeFormat = MCI_FORMAT_MSF;
if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda)) {
dev = CDROM_OpenDev(&wmcda->wcda);
if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda, dev)) {
WARN("error reading TracksInfo !\n"); WARN("error reading TracksInfo !\n");
CDROM_CloseDev(dev);
return MCIERR_INTERNAL; return MCIERR_INTERNAL;
} }
MCICDA_Seek(wDevID, MCI_SEEK_TO_START, &seekParms); MCICDA_Seek(wDevID, MCI_SEEK_TO_START, &seekParms);
CDROM_CloseDev(dev);
return 0; return 0;
} }
@ -368,10 +373,13 @@ static DWORD MCICDA_Info(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSA lpParms)
ret = MCIERR_NO_IDENTITY; ret = MCIERR_NO_IDENTITY;
} else if (dwFlags & MCI_INFO_MEDIA_IDENTITY) { } else if (dwFlags & MCI_INFO_MEDIA_IDENTITY) {
DWORD res = 0; DWORD res = 0;
int dev = CDROM_OpenDev(&wmcda->wcda);
if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) { if (!CDROM_Audio_GetCDStatus(&wmcda->wcda, dev)) {
CDROM_CloseDev(dev);
return MCICDA_GetError(wmcda); return MCICDA_GetError(wmcda);
} }
CDROM_CloseDev(dev);
res = CDROM_Audio_GetSerial(&wmcda->wcda); res = CDROM_Audio_GetSerial(&wmcda->wcda);
if (wmcda->wcda.nTracks <= 2) { if (wmcda->wcda.nTracks <= 2) {
@ -422,7 +430,7 @@ static DWORD MCICDA_Status(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParm
if (dwFlags & MCI_STATUS_ITEM) { if (dwFlags & MCI_STATUS_ITEM) {
switch (lpParms->dwItem) { switch (lpParms->dwItem) {
case MCI_STATUS_CURRENT_TRACK: case MCI_STATUS_CURRENT_TRACK:
if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) { if (!CDROM_Audio_GetCDStatus(&wmcda->wcda, -1)) {
return MCICDA_GetError(wmcda); return MCICDA_GetError(wmcda);
} }
lpParms->dwReturn = wmcda->wcda.nCurTrack; lpParms->dwReturn = wmcda->wcda.nCurTrack;
@ -430,7 +438,7 @@ static DWORD MCICDA_Status(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParm
break; break;
case MCI_STATUS_LENGTH: case MCI_STATUS_LENGTH:
if (wmcda->wcda.nTracks == 0) { if (wmcda->wcda.nTracks == 0) {
if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda)) { if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda, -1)) {
WARN("error reading TracksInfo !\n"); WARN("error reading TracksInfo !\n");
return MCICDA_GetError(wmcda); return MCICDA_GetError(wmcda);
} }
@ -458,7 +466,7 @@ static DWORD MCICDA_Status(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParm
TRACE("LENGTH=%lu !\n", lpParms->dwReturn); TRACE("LENGTH=%lu !\n", lpParms->dwReturn);
break; break;
case MCI_STATUS_MODE: case MCI_STATUS_MODE:
if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) if (!CDROM_Audio_GetCDStatus(&wmcda->wcda, -1))
return MCICDA_GetError(wmcda); return MCICDA_GetError(wmcda);
lpParms->dwReturn = MCICDA_Mode(wmcda->wcda.cdaMode); lpParms->dwReturn = MCICDA_Mode(wmcda->wcda.cdaMode);
if (!lpParms->dwReturn) lpParms->dwReturn = wmcda->mciMode; if (!lpParms->dwReturn) lpParms->dwReturn = wmcda->mciMode;
@ -467,22 +475,24 @@ static DWORD MCICDA_Status(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParm
ret = MCI_RESOURCE_RETURNED; ret = MCI_RESOURCE_RETURNED;
break; break;
case MCI_STATUS_MEDIA_PRESENT: case MCI_STATUS_MEDIA_PRESENT:
if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) if(!CDROM_Audio_GetCDStatus(&wmcda->wcda, -1))
return MCICDA_GetError(wmcda); return MCICDA_GetError(wmcda);
lpParms->dwReturn = (wmcda->wcda.nTracks == 0) ? lpParms->dwReturn = (wmcda->wcda.nTracks == 0) ?
MAKEMCIRESOURCE(FALSE, MCI_FALSE) : MAKEMCIRESOURCE(TRUE, MCI_TRUE); MAKEMCIRESOURCE(FALSE, MCI_FALSE) : MAKEMCIRESOURCE(TRUE, MCI_TRUE);
TRACE("MCI_STATUS_MEDIA_PRESENT =%c!\n", LOWORD(lpParms->dwReturn) ? 'Y' : 'N'); TRACE("MCI_STATUS_MEDIA_PRESENT =%c!\n", LOWORD(lpParms->dwReturn) ? 'Y' : 'N');
ret = MCI_RESOURCE_RETURNED; ret = MCI_RESOURCE_RETURNED;
break; break;
case MCI_STATUS_NUMBER_OF_TRACKS: case MCI_STATUS_NUMBER_OF_TRACKS:
lpParms->dwReturn = CDROM_Audio_GetNumberOfTracks(&wmcda->wcda); lpParms->dwReturn = CDROM_Audio_GetNumberOfTracks(&wmcda->wcda, -1);
TRACE("MCI_STATUS_NUMBER_OF_TRACKS = %lu !\n", lpParms->dwReturn); TRACE("MCI_STATUS_NUMBER_OF_TRACKS = %lu !\n", lpParms->dwReturn);
if (lpParms->dwReturn == (WORD)-1) if (lpParms->dwReturn == (WORD)-1)
return MCICDA_GetError(wmcda); return MCICDA_GetError(wmcda);
break; break;
case MCI_STATUS_POSITION: case MCI_STATUS_POSITION:
if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) if (!CDROM_Audio_GetCDStatus(&wmcda->wcda, -1))
return MCICDA_GetError(wmcda); return MCICDA_GetError(wmcda);
if(wmcda->wcda.cdaMode == WINE_CDA_OPEN)
return MCIERR_HARDWARE;
lpParms->dwReturn = wmcda->wcda.dwCurFrame; lpParms->dwReturn = wmcda->wcda.dwCurFrame;
if (dwFlags & MCI_STATUS_START) { if (dwFlags & MCI_STATUS_START) {
lpParms->dwReturn = wmcda->wcda.dwFirstFrame; lpParms->dwReturn = wmcda->wcda.dwFirstFrame;
@ -517,7 +527,7 @@ static DWORD MCICDA_Status(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParm
else if (lpParms->dwTrack > wmcda->wcda.nTracks || lpParms->dwTrack == 0) else if (lpParms->dwTrack > wmcda->wcda.nTracks || lpParms->dwTrack == 0)
ret = MCIERR_OUTOFRANGE; ret = MCIERR_OUTOFRANGE;
else else
lpParms->dwReturn = (wmcda->wcda.lpbTrackFlags[lpParms->dwTrack - 1] & lpParms->dwReturn = (wmcda->wcda.lpbTrackFlags[lpParms->dwTrack - 1] &
CDROM_DATA_TRACK) ? MCI_CDA_TRACK_OTHER : MCI_CDA_TRACK_AUDIO; CDROM_DATA_TRACK) ? MCI_CDA_TRACK_OTHER : MCI_CDA_TRACK_AUDIO;
TRACE("MCI_CDA_STATUS_TYPE_TRACK[%ld]=%08lx\n", lpParms->dwTrack, lpParms->dwReturn); TRACE("MCI_CDA_STATUS_TYPE_TRACK[%ld]=%08lx\n", lpParms->dwTrack, lpParms->dwReturn);
break; break;
@ -539,46 +549,58 @@ static DWORD MCICDA_Play(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms)
int start, end; int start, end;
WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID); WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID);
DWORD ret = 0; DWORD ret = 0;
int dev = -1;
TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms); TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms);
if (lpParms == NULL) { if (lpParms == NULL)
ret = MCIERR_NULL_PARAMETER_BLOCK; return MCIERR_NULL_PARAMETER_BLOCK;
} else if (wmcda == NULL) {
ret = MCIERR_INVALID_DEVICE_ID; if (wmcda == NULL)
} else { return MCIERR_INVALID_DEVICE_ID;
if (wmcda->wcda.nTracks == 0) {
if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda)) { dev = CDROM_OpenDev(&wmcda->wcda);
WARN("error reading TracksInfo !\n"); if (wmcda->wcda.nTracks == 0) {
return MCIERR_DRIVER_INTERNAL; if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda, dev)) {
} WARN("error reading TracksInfo !\n");
} ret = MCIERR_DRIVER_INTERNAL;
wmcda->wcda.nCurTrack = 1; goto end;
if (dwFlags & MCI_FROM) {
start = MCICDA_CalcFrame(wmcda, lpParms->dwFrom);
TRACE("MCI_FROM=%08lX -> %u \n", lpParms->dwFrom, start);
} else {
if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) return MCIERR_DRIVER_INTERNAL;
start = wmcda->wcda.dwCurFrame;
}
if (dwFlags & MCI_TO) {
end = MCICDA_CalcFrame(wmcda, lpParms->dwTo);
TRACE("MCI_TO=%08lX -> %u \n", lpParms->dwTo, end);
} else {
end = wmcda->wcda.dwLastFrame;
}
if (CDROM_Audio_Play(&wmcda->wcda, start, end) == -1)
return MCIERR_HARDWARE;
wmcda->mciMode = MCI_MODE_PLAY;
if (dwFlags & MCI_NOTIFY) {
TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
/*
mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
*/
} }
} }
wmcda->wcda.nCurTrack = 1;
if (dwFlags & MCI_FROM) {
start = MCICDA_CalcFrame(wmcda, lpParms->dwFrom);
TRACE("MCI_FROM=%08lX -> %u \n", lpParms->dwFrom, start);
} else {
if (!CDROM_Audio_GetCDStatus(&wmcda->wcda, dev))
{
ret = MCIERR_DRIVER_INTERNAL;
goto end;
}
start = wmcda->wcda.dwCurFrame;
}
if (dwFlags & MCI_TO) {
end = MCICDA_CalcFrame(wmcda, lpParms->dwTo);
TRACE("MCI_TO=%08lX -> %u \n", lpParms->dwTo, end);
} else
end = wmcda->wcda.dwLastFrame;
if (CDROM_Audio_Play(&wmcda->wcda, start, end, dev) == -1)
{
ret = MCIERR_HARDWARE;
goto end;
}
wmcda->mciMode = MCI_MODE_PLAY;
if (dwFlags & MCI_NOTIFY) {
TRACE("MCI_NOTIFY_SUCCESSFUL %08lX !\n", lpParms->dwCallback);
/*
mciDriverNotify((HWND)LOWORD(lpParms->dwCallback),
wmcda->wNotifyDeviceID, MCI_NOTIFY_SUCCESSFUL);
*/
}
end:
if (dev != -1)
CDROM_CloseDev(dev);
return ret; return ret;
} }
@ -593,7 +615,7 @@ static DWORD MCICDA_Stop(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParms
if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
if (CDROM_Audio_Stop(&wmcda->wcda) == -1) if (CDROM_Audio_Stop(&wmcda->wcda, -1) == -1)
return MCIERR_HARDWARE; return MCIERR_HARDWARE;
wmcda->mciMode = MCI_MODE_STOP; wmcda->mciMode = MCI_MODE_STOP;
@ -616,7 +638,7 @@ static DWORD MCICDA_Pause(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpParm
if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
if (CDROM_Audio_Pause(&wmcda->wcda, 1) == -1) if (CDROM_Audio_Pause(&wmcda->wcda, 1, -1) == -1)
return MCIERR_HARDWARE; return MCIERR_HARDWARE;
wmcda->mciMode = MCI_MODE_PAUSE; wmcda->mciMode = MCI_MODE_PAUSE;
if (lpParms && (dwFlags & MCI_NOTIFY)) { if (lpParms && (dwFlags & MCI_NOTIFY)) {
@ -638,7 +660,7 @@ static DWORD MCICDA_Resume(UINT wDevID, DWORD dwFlags, LPMCI_GENERIC_PARMS lpPar
if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
if (CDROM_Audio_Pause(&wmcda->wcda, 0) == -1) if (CDROM_Audio_Pause(&wmcda->wcda, 0, -1) == -1)
return MCIERR_HARDWARE; return MCIERR_HARDWARE;
wmcda->mciMode = MCI_MODE_STOP; wmcda->mciMode = MCI_MODE_STOP;
if (lpParms && (dwFlags & MCI_NOTIFY)) { if (lpParms && (dwFlags & MCI_NOTIFY)) {
@ -680,7 +702,7 @@ static DWORD MCICDA_Seek(UINT wDevID, DWORD dwFlags, LPMCI_SEEK_PARMS lpParms)
TRACE("Seeking to ??=%lu\n", dwFlags); TRACE("Seeking to ??=%lu\n", dwFlags);
return MCIERR_UNSUPPORTED_FUNCTION; return MCIERR_UNSUPPORTED_FUNCTION;
} }
if (CDROM_Audio_Seek(&wmcda->wcda, at) == -1) { if (CDROM_Audio_Seek(&wmcda->wcda, at, -1) == -1) {
return MCIERR_HARDWARE; return MCIERR_HARDWARE;
} }
if (dwFlags & MCI_NOTIFY) { if (dwFlags & MCI_NOTIFY) {
@ -702,7 +724,7 @@ static DWORD MCICDA_SetDoor(UINT wDevID, int open)
if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID; if (wmcda == NULL) return MCIERR_INVALID_DEVICE_ID;
if (CDROM_SetDoor(&wmcda->wcda, open) == -1) if (CDROM_SetDoor(&wmcda->wcda, open, -1) == -1)
return MCIERR_HARDWARE; return MCIERR_HARDWARE;
wmcda->mciMode = (open) ? MCI_MODE_OPEN : MCI_MODE_STOP; wmcda->mciMode = (open) ? MCI_MODE_OPEN : MCI_MODE_STOP;
return 0; return 0;

View file

@ -26,7 +26,7 @@
#endif #endif
typedef struct { typedef struct {
int unixdev; const char *devname;
#if defined(linux) #if defined(linux)
struct cdrom_subchnl sc; struct cdrom_subchnl sc;
#elif defined(__FreeBSD__) || defined(__NetBSD__) #elif defined(__FreeBSD__) || defined(__NetBSD__)
@ -57,20 +57,22 @@ typedef struct {
#define WINE_CDA_PAUSE 0x05 #define WINE_CDA_PAUSE 0x05
int CDROM_Open(WINE_CDAUDIO* wcda, int drive); int CDROM_Open(WINE_CDAUDIO* wcda, int drive);
int CDROM_GetMediaType(WINE_CDAUDIO* wcda); int CDROM_OpenDev(WINE_CDAUDIO* wcda);
int CDROM_GetMediaType(WINE_CDAUDIO* wcda, int parentdev);
int CDROM_CloseDev(int dev);
int CDROM_Close(WINE_CDAUDIO* wcda); int CDROM_Close(WINE_CDAUDIO* wcda);
int CDROM_Reset(WINE_CDAUDIO* wcda); int CDROM_Reset(WINE_CDAUDIO* wcda, int parentdev);
int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD stop); int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD stop, int parentdev);
int CDROM_Audio_Stop(WINE_CDAUDIO* wcda); int CDROM_Audio_Stop(WINE_CDAUDIO* wcda, int parentdev);
int CDROM_Audio_Pause(WINE_CDAUDIO* wcda, int pauseOn); int CDROM_Audio_Pause(WINE_CDAUDIO* wcda, int pauseOn, int parentdev);
int CDROM_Audio_Seek(WINE_CDAUDIO* wcda, DWORD at); int CDROM_Audio_Seek(WINE_CDAUDIO* wcda, DWORD at, int parentdev);
int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open); int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open, int parentdev);
UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda); UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda, int parentdev);
BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda); BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda, int parentdev);
BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda); BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda, int parentdev);
WORD CDROM_Data_FindBestVoldesc(int fd); WORD CDROM_Data_FindBestVoldesc(int fd);
DWORD CDROM_Audio_GetSerial(WINE_CDAUDIO* wcda); DWORD CDROM_Audio_GetSerial(WINE_CDAUDIO* wcda);
DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda); DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda, int parentdev);
DWORD CDROM_GetSerial(int drive); DWORD CDROM_GetSerial(int drive);
DWORD CDROM_GetLabel(int drive, char *label); DWORD CDROM_GetLabel(int drive, char *label);

View file

@ -23,6 +23,12 @@ DEFAULT_DEBUG_CHANNEL(cdrom);
#define MAX_CDAUDIO_TRACKS 256 #define MAX_CDAUDIO_TRACKS 256
#define CDROM_OPEN(wcda,parentdev) \
(((parentdev) == -1) ? CDROM_OpenDev(wcda) : (parentdev))
#define CDROM_CLOSE(dev,parentdev) \
(((parentdev) == -1) ? CDROM_CloseDev(dev) : 0)
/************************************************************************** /**************************************************************************
* CDROM_Open [internal] * CDROM_Open [internal]
* *
@ -31,9 +37,8 @@ DEFAULT_DEBUG_CHANNEL(cdrom);
*/ */
int CDROM_Open(WINE_CDAUDIO* wcda, int drive) int CDROM_Open(WINE_CDAUDIO* wcda, int drive)
{ {
int i; int i, dev;
BOOL avail = FALSE; BOOL avail = FALSE;
const char *dev;
if (drive == -1) if (drive == -1)
{ {
@ -53,18 +58,20 @@ int CDROM_Open(WINE_CDAUDIO* wcda, int drive)
WARN("No CD-ROM #%d found !\n", drive); WARN("No CD-ROM #%d found !\n", drive);
return -1; return -1;
} }
if ((dev = DRIVE_GetDevice(drive)) == NULL) if ((wcda->devname = DRIVE_GetDevice(drive)) == NULL)
{ {
WARN("No device entry for CD-ROM #%d (drive %c:) found !\n", WARN("No device entry for CD-ROM #%d (drive %c:) found !\n",
drive, 'A' + drive); drive, 'A' + drive);
return -1; return -1;
} }
wcda->unixdev = open(dev, O_RDONLY | O_NONBLOCK, 0); /* Test whether device can be opened */
if (wcda->unixdev == -1) { dev = CDROM_OpenDev(wcda);
WARN("can't open '%s'!. %s\n", dev, strerror(errno)); if (dev == -1)
return -1; return -1;
} else
CDROM_CloseDev(dev);
wcda->cdaMode = WINE_CDA_OPEN; /* to force reading tracks info */ wcda->cdaMode = WINE_CDA_OPEN; /* to force reading tracks info */
wcda->nCurTrack = 0; wcda->nCurTrack = 0;
wcda->nTracks = 0; wcda->nTracks = 0;
@ -73,19 +80,46 @@ int CDROM_Open(WINE_CDAUDIO* wcda, int drive)
wcda->lpdwTrackLen = NULL; wcda->lpdwTrackLen = NULL;
wcda->lpdwTrackPos = NULL; wcda->lpdwTrackPos = NULL;
wcda->lpbTrackFlags = NULL; wcda->lpbTrackFlags = NULL;
TRACE("opened drive %c: (device %s)\n", 'A' + drive, wcda->devname);
return 0; return 0;
} }
/**************************************************************************
* CDROM_OpenDev [internal]
*
*/
int CDROM_OpenDev(WINE_CDAUDIO* wcda)
{
int dev = open(wcda->devname, O_RDONLY | O_NONBLOCK, 0);
if (dev == -1)
WARN("can't open device '%s'! (%s)\n", wcda->devname, strerror(errno));
TRACE("-> %d\n", dev);
return dev;
}
/************************************************************************** /**************************************************************************
* CDROM_GetMediaType [internal] * CDROM_GetMediaType [internal]
*/ */
int CDROM_GetMediaType(WINE_CDAUDIO* wcda) int CDROM_GetMediaType(WINE_CDAUDIO* wcda, int parentdev)
{ {
int type = -1;
#ifdef linux #ifdef linux
return ioctl(wcda->unixdev, CDROM_DISC_STATUS); int dev = CDROM_OPEN( wcda, parentdev );
#else type = ioctl(dev, CDROM_DISC_STATUS);
return -1; CDROM_CLOSE( dev, parentdev );
#endif #endif
TRACE("-> %d\n", type);
return type;
}
/**************************************************************************
* CDROM_Close [internal]
*/
int CDROM_CloseDev(int dev)
{
TRACE("%d\n", dev);
return close(dev);
} }
/************************************************************************** /**************************************************************************
@ -97,7 +131,7 @@ int CDROM_Close(WINE_CDAUDIO* wcda)
if (wcda->lpdwTrackLen != NULL) free(wcda->lpdwTrackLen); if (wcda->lpdwTrackLen != NULL) free(wcda->lpdwTrackLen);
if (wcda->lpdwTrackPos != NULL) free(wcda->lpdwTrackPos); if (wcda->lpdwTrackPos != NULL) free(wcda->lpdwTrackPos);
if (wcda->lpbTrackFlags != NULL) free(wcda->lpbTrackFlags); if (wcda->lpbTrackFlags != NULL) free(wcda->lpbTrackFlags);
close(wcda->unixdev); TRACE("%s\n", wcda->devname);
return 0; return 0;
#else #else
return -1; return -1;
@ -109,11 +143,13 @@ int CDROM_Close(WINE_CDAUDIO* wcda)
* *
* upc has to be 14 bytes long * upc has to be 14 bytes long
*/ */
int CDROM_Get_UPC(WINE_CDAUDIO* wcda, LPSTR upc) int CDROM_Get_UPC(WINE_CDAUDIO* wcda, LPSTR upc, int parentdev)
{ {
#ifdef linux #ifdef linux
struct cdrom_mcn mcn; struct cdrom_mcn mcn;
int status = ioctl(wcda->unixdev, CDROM_GET_MCN, &mcn); int dev = CDROM_OPEN( wcda, parentdev );
int status = ioctl(dev, CDROM_GET_MCN, &mcn);
CDROM_CLOSE( dev, parentdev );
if (status) if (status)
{ {
ERR("ioctl() failed with code %d\n",status); ERR("ioctl() failed with code %d\n",status);
@ -129,24 +165,26 @@ int CDROM_Get_UPC(WINE_CDAUDIO* wcda, LPSTR upc)
/************************************************************************** /**************************************************************************
* CDROM_Audio_GetNumberOfTracks [internal] * CDROM_Audio_GetNumberOfTracks [internal]
*/ */
UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda) UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda, int parentdev)
{ {
UINT16 ret = (UINT16)-1;
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
#ifdef linux #ifdef linux
struct cdrom_tochdr hdr; struct cdrom_tochdr hdr;
#else #else
struct ioc_toc_header hdr; struct ioc_toc_header hdr;
#endif #endif
int dev = CDROM_OPEN( wcda, parentdev );
if (wcda->nTracks == 0) { if (wcda->nTracks == 0) {
#ifdef linux #ifdef linux
if (ioctl(wcda->unixdev, CDROMREADTOCHDR, &hdr)) if (ioctl(dev, CDROMREADTOCHDR, &hdr))
#else #else
if (ioctl(wcda->unixdev, CDIOREADTOCHEADER, &hdr)) if (ioctl(dev, CDIOREADTOCHEADER, &hdr))
#endif #endif
{ {
WARN("(%p) -- Error occurred (%d)!\n", wcda, errno); WARN("(%p) -- Error occurred (%s)!\n", wcda, strerror(errno));
return (WORD)-1; goto end;
} }
#ifdef linux #ifdef linux
wcda->nFirstTrack = hdr.cdth_trk0; wcda->nFirstTrack = hdr.cdth_trk0;
@ -157,17 +195,19 @@ UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda)
#endif #endif
wcda->nTracks = wcda->nLastTrack - wcda->nFirstTrack + 1; wcda->nTracks = wcda->nLastTrack - wcda->nFirstTrack + 1;
} }
return wcda->nTracks; ret = wcda->nTracks;
#else end:
return (WORD)-1; CDROM_CLOSE( dev, parentdev );
#endif #endif
return ret;
} }
/************************************************************************** /**************************************************************************
* CDROM_Audio_GetTracksInfo [internal] * CDROM_Audio_GetTracksInfo [internal]
*/ */
BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda) BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda, int parentdev)
{ {
BOOL ret = FALSE;
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
int i, length; int i, length;
int start, last_start = 0; int start, last_start = 0;
@ -178,9 +218,11 @@ BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda)
struct ioc_read_toc_entry entry; struct ioc_read_toc_entry entry;
struct cd_toc_entry toc_buffer; struct cd_toc_entry toc_buffer;
#endif #endif
int dev = CDROM_OPEN( wcda, parentdev );
if (wcda->nTracks == 0) { if (wcda->nTracks == 0) {
if (CDROM_Audio_GetNumberOfTracks(wcda) == (WORD)-1) return FALSE; if (CDROM_Audio_GetNumberOfTracks(wcda, dev) == (WORD)-1)
goto end;
} }
TRACE("nTracks=%u\n", wcda->nTracks); TRACE("nTracks=%u\n", wcda->nTracks);
@ -196,7 +238,7 @@ BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda)
if (wcda->lpdwTrackLen == NULL || wcda->lpdwTrackPos == NULL || if (wcda->lpdwTrackLen == NULL || wcda->lpdwTrackPos == NULL ||
wcda->lpbTrackFlags == NULL) { wcda->lpbTrackFlags == NULL) {
WARN("error allocating track table !\n"); WARN("error allocating track table !\n");
return FALSE; goto end;
} }
memset(wcda->lpdwTrackLen, 0, (wcda->nTracks + 1) * sizeof(DWORD)); memset(wcda->lpdwTrackLen, 0, (wcda->nTracks + 1) * sizeof(DWORD));
memset(wcda->lpdwTrackPos, 0, (wcda->nTracks + 1) * sizeof(DWORD)); memset(wcda->lpdwTrackPos, 0, (wcda->nTracks + 1) * sizeof(DWORD));
@ -224,16 +266,16 @@ BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda)
entry.data = &toc_buffer; entry.data = &toc_buffer;
#endif #endif
#ifdef linux #ifdef linux
if (ioctl(wcda->unixdev, CDROMREADTOCENTRY, &entry)) if (ioctl(dev, CDROMREADTOCENTRY, &entry))
#else #else
if (ioctl(wcda->unixdev, CDIOREADTOCENTRYS, &entry)) if (ioctl(dev, CDIOREADTOCENTRYS, &entry))
#endif #endif
{ {
WARN("error read entry (%s)\n", strerror(errno)); WARN("error read entry (%s)\n", strerror(errno));
/* update status according to new status */ /* update status according to new status */
CDROM_Audio_GetCDStatus(wcda); CDROM_Audio_GetCDStatus(wcda, dev);
return FALSE; goto end;
} }
#ifdef linux #ifdef linux
start = CDFRAMES_PERSEC * (SECONDS_PERMIN * start = CDFRAMES_PERSEC * (SECONDS_PERMIN *
@ -268,19 +310,22 @@ BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda)
} }
wcda->dwLastFrame = last_start; wcda->dwLastFrame = last_start;
TRACE("total_len=%u\n", total_length); TRACE("total_len=%u\n", total_length);
return TRUE; ret = TRUE;
#else end:
return FALSE; CDROM_CLOSE( dev, parentdev );
#endif #endif
return ret;
} }
/************************************************************************** /**************************************************************************
* CDROM_Audio_GetCDStatus [internal] * CDROM_Audio_GetCDStatus [internal]
*/ */
BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda) BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda, int parentdev)
{ {
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
int oldmode = wcda->cdaMode; int oldmode = wcda->cdaMode;
int ret = FALSE;
int dev = CDROM_OPEN( wcda, parentdev );
#ifdef linux #ifdef linux
wcda->sc.cdsc_format = CDROM_MSF; wcda->sc.cdsc_format = CDROM_MSF;
#else #else
@ -293,14 +338,14 @@ BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda)
read_sc.data = (struct cd_sub_channel_info *)&wcda->sc; read_sc.data = (struct cd_sub_channel_info *)&wcda->sc;
#endif #endif
#ifdef linux #ifdef linux
if (ioctl(wcda->unixdev, CDROMSUBCHNL, &wcda->sc)) if (ioctl(dev, CDROMSUBCHNL, &wcda->sc))
#else #else
if (ioctl(wcda->unixdev, CDIOCREADSUBCHANNEL, &read_sc)) if (ioctl(dev, CDIOCREADSUBCHANNEL, &read_sc))
#endif #endif
{ {
TRACE("opened or no_media (%s)!\n", strerror(errno)); TRACE("opened or no_media (%s)!\n", strerror(errno));
wcda->cdaMode = WINE_CDA_OPEN; /* was NOT_READY */ wcda->cdaMode = WINE_CDA_OPEN; /* was NOT_READY */
return TRUE; goto end;
} }
switch ( switch (
#ifdef linux #ifdef linux
@ -377,12 +422,16 @@ BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda)
#endif #endif
if (oldmode != wcda->cdaMode && oldmode == WINE_CDA_OPEN) { if (oldmode != wcda->cdaMode && oldmode == WINE_CDA_OPEN) {
if (!CDROM_Audio_GetTracksInfo(wcda)) { if (!CDROM_Audio_GetTracksInfo(wcda, dev)) {
WARN("error updating TracksInfo !\n"); WARN("error updating TracksInfo !\n");
return FALSE; goto end;
} }
} }
return TRUE; if (wcda->cdaMode != WINE_CDA_OPEN)
ret = TRUE;
end:
CDROM_CLOSE( dev, parentdev );
return ret;
#else #else
return FALSE; return FALSE;
#endif #endif
@ -391,14 +440,16 @@ BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda)
/************************************************************************** /**************************************************************************
* CDROM_Audio_Play [internal] * CDROM_Audio_Play [internal]
*/ */
int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD end) int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD end, int parentdev)
{ {
int ret = -1;
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
#ifdef linux #ifdef linux
struct cdrom_msf msf; struct cdrom_msf msf;
#else #else
struct ioc_play_msf msf; struct ioc_play_msf msf;
#endif #endif
int dev = CDROM_OPEN( wcda, parentdev );
#ifdef linux #ifdef linux
msf.cdmsf_min0 = start / CDFRAMES_PERMIN; msf.cdmsf_min0 = start / CDFRAMES_PERMIN;
@ -416,22 +467,22 @@ int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD end)
msf.end_f = end % CDFRAMES_PERSEC; msf.end_f = end % CDFRAMES_PERSEC;
#endif #endif
#ifdef linux #ifdef linux
if (ioctl(wcda->unixdev, CDROMSTART)) if (ioctl(dev, CDROMSTART))
#else #else
if (ioctl(wcda->unixdev, CDIOCSTART, NULL)) if (ioctl(dev, CDIOCSTART, NULL))
#endif #endif
{ {
WARN("motor doesn't start !\n"); WARN("motor doesn't start !\n");
return -1; goto end;
} }
#ifdef linux #ifdef linux
if (ioctl(wcda->unixdev, CDROMPLAYMSF, &msf)) if (ioctl(dev, CDROMPLAYMSF, &msf))
#else #else
if (ioctl(wcda->unixdev, CDIOCPLAYMSF, &msf)) if (ioctl(dev, CDIOCPLAYMSF, &msf))
#endif #endif
{ {
WARN("device doesn't play !\n"); WARN("device doesn't play !\n");
return -1; goto end;
} }
#ifdef linux #ifdef linux
TRACE("msf = %d:%d:%d %d:%d:%d\n", TRACE("msf = %d:%d:%d %d:%d:%d\n",
@ -442,117 +493,121 @@ int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD end)
msf.start_m, msf.start_s, msf.start_f, msf.start_m, msf.start_s, msf.start_f,
msf.end_m, msf.end_s, msf.end_f); msf.end_m, msf.end_s, msf.end_f);
#endif #endif
return 0; ret = 0;
#else end:
return -1; CDROM_CLOSE( dev, parentdev );
#endif #endif
return ret;
} }
/************************************************************************** /**************************************************************************
* CDROM_Audio_Stop [internal] * CDROM_Audio_Stop [internal]
*/ */
int CDROM_Audio_Stop(WINE_CDAUDIO* wcda) int CDROM_Audio_Stop(WINE_CDAUDIO* wcda, int parentdev)
{ {
int ret = -1;
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
int ret = 0; int dev = CDROM_OPEN( wcda, parentdev );
#ifdef linux #ifdef linux
ret = ioctl(wcda->unixdev, CDROMSTOP); ret = ioctl(dev, CDROMSTOP);
#else #else
ret = ioctl(wcda->unixdev, CDIOCSTOP, NULL); ret = ioctl(dev, CDIOCSTOP, NULL);
#endif
CDROM_CLOSE( dev, parentdev );
#endif #endif
return ret; return ret;
#else
return -1;
#endif
} }
/************************************************************************** /**************************************************************************
* CDROM_Audio_Pause [internal] * CDROM_Audio_Pause [internal]
*/ */
int CDROM_Audio_Pause(WINE_CDAUDIO* wcda, int pauseOn) int CDROM_Audio_Pause(WINE_CDAUDIO* wcda, int pauseOn, int parentdev)
{ {
int ret = -1;
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
int ret = 0; int dev = CDROM_OPEN( wcda, parentdev );
#ifdef linux #ifdef linux
ret = ioctl(wcda->unixdev, pauseOn ? CDROMPAUSE : CDROMRESUME); ret = ioctl(dev, pauseOn ? CDROMPAUSE : CDROMRESUME);
#else #else
ret = ioctl(wcda->unixdev, pauseOn ? CDIOCPAUSE : CDIOCRESUME, NULL); ret = ioctl(dev, pauseOn ? CDIOCPAUSE : CDIOCRESUME, NULL);
#endif
CDROM_CLOSE( dev, parentdev );
#endif #endif
return ret; return ret;
#else
return -1;
#endif
} }
/************************************************************************** /**************************************************************************
* CDROM_Audio_Seek [internal] * CDROM_Audio_Seek [internal]
*/ */
int CDROM_Audio_Seek(WINE_CDAUDIO* wcda, DWORD at) int CDROM_Audio_Seek(WINE_CDAUDIO* wcda, DWORD at, int parentdev)
{ {
int ret = -1;
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
int ret = 0; int dev = CDROM_OPEN( wcda, parentdev );
#ifdef linux #ifdef linux
struct cdrom_msf0 msf; struct cdrom_msf0 msf;
msf.minute = at / CDFRAMES_PERMIN; msf.minute = at / CDFRAMES_PERMIN;
msf.second = (at % CDFRAMES_PERMIN) / CDFRAMES_PERSEC; msf.second = (at % CDFRAMES_PERMIN) / CDFRAMES_PERSEC;
msf.frame = at % CDFRAMES_PERSEC; msf.frame = at % CDFRAMES_PERSEC;
ret = ioctl(wcda->unixdev, CDROMSEEK, &msf); ret = ioctl(dev, CDROMSEEK, &msf);
#else #else
/* FIXME: the current end for play is lost /* FIXME: the current end for play is lost
* use end of CD ROM instead * use end of CD ROM instead
*/ */
FIXME("Could a BSD expert implement the seek function ?\n"); FIXME("Could a BSD expert implement the seek function ?\n");
CDROM_Audio_Play(wcda, at, wcda->lpdwTrackPos[wcda->nTracks] + wcda->lpdwTrackLen[wcda->nTracks]); CDROM_Audio_Play(wcda, at, wcda->lpdwTrackPos[wcda->nTracks] + wcda->lpdwTrackLen[wcda->nTracks], dev);
#endif
CDROM_CLOSE( dev, parentdev );
#endif #endif
return ret; return ret;
#else
return -1;
#endif
} }
/************************************************************************** /**************************************************************************
* CDROM_SetDoor [internal] * CDROM_SetDoor [internal]
*/ */
int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open) int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open, int parentdev)
{ {
int ret = -1;
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
int ret = 0; int dev = CDROM_OPEN( wcda, parentdev );
TRACE("%d\n", open);
#ifdef linux #ifdef linux
if (open) { if (open) {
ret = ioctl(wcda->unixdev, CDROMEJECT); ret = ioctl(dev, CDROMEJECT);
} else { } else {
ret = ioctl(wcda->unixdev, CDROMEJECT, 1); ret = ioctl(dev, CDROMEJECT, 1);
} }
#else #else
ret = (ioctl(wcda->unixdev, CDIOCALLOW, NULL)) || ret = (ioctl(dev, CDIOCALLOW, NULL)) ||
(ioctl(wcda->unixdev, open ? CDIOCEJECT : CDIOCCLOSE, NULL)) || (ioctl(dev, open ? CDIOCEJECT : CDIOCCLOSE, NULL)) ||
(ioctl(wcda->unixdev, CDIOCPREVENT, NULL)); (ioctl(dev, CDIOCPREVENT, NULL));
#endif #endif
wcda->nTracks = 0; wcda->nTracks = 0;
return ret; if (ret == -1)
#else WARN("failed (%s)\n", strerror(errno));
return -1; CDROM_CLOSE( dev, parentdev );
#endif #endif
return ret;
} }
/************************************************************************** /**************************************************************************
* CDROM_Reset [internal] * CDROM_Reset [internal]
*/ */
int CDROM_Reset(WINE_CDAUDIO* wcda) int CDROM_Reset(WINE_CDAUDIO* wcda, int parentdev)
{ {
int ret = -1;
#if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) #if defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__)
int ret = 0; int dev = CDROM_OPEN( wcda, parentdev );
#ifdef linux #ifdef linux
ret = ioctl(wcda->unixdev, CDROMRESET); ret = ioctl(dev, CDROMRESET);
#else #else
ret = ioctl(wcda->unixdev, CDIOCRESET, NULL); ret = ioctl(dev, CDIOCRESET, NULL);
#endif
CDROM_CLOSE( dev, parentdev );
#endif #endif
return ret; return ret;
#else
return -1;
#endif
} }
WORD CDROM_Data_FindBestVoldesc(int fd) WORD CDROM_Data_FindBestVoldesc(int fd)
@ -627,9 +682,10 @@ DWORD CDROM_Audio_GetSerial(WINE_CDAUDIO* wcda)
/************************************************************************** /**************************************************************************
* CDROM_Data_GetSerial [internal] * CDROM_Data_GetSerial [internal]
*/ */
DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda) DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda, int parentdev)
{ {
WORD offs = CDROM_Data_FindBestVoldesc(wcda->unixdev); int dev = CDROM_OPEN( wcda, parentdev );
WORD offs = CDROM_Data_FindBestVoldesc(dev);
union { union {
unsigned long val; unsigned long val;
unsigned char p[4]; unsigned char p[4];
@ -643,8 +699,8 @@ DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda)
OSVERSIONINFOA ovi; OSVERSIONINFOA ovi;
int i; int i;
lseek(wcda->unixdev,offs,SEEK_SET); lseek(dev,offs,SEEK_SET);
read(wcda->unixdev,buf,2048); read(dev,buf,2048);
/* /*
* OK, another braindead one... argh. Just believe it. * OK, another braindead one... argh. Just believe it.
* Me$$ysoft chose to reverse the serial number in NT4/W2K. * Me$$ysoft chose to reverse the serial number in NT4/W2K.
@ -666,6 +722,7 @@ DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda)
serial.p[b3] += buf[i+b3]; serial.p[b3] += buf[i+b3];
} }
} }
CDROM_CLOSE( dev, parentdev );
return serial.val; return serial.val;
} }
@ -683,35 +740,38 @@ DWORD CDROM_GetSerial(int drive)
if (!(CDROM_Open(&wcda, drive))) if (!(CDROM_Open(&wcda, drive)))
{ {
int media = CDROM_GetMediaType(&wcda); int dev = CDROM_OpenDev(&wcda);
LPSTR p; int media = CDROM_GetMediaType(&wcda, dev);
if (media == CDS_AUDIO) switch (media)
{ {
if (!(CDROM_Audio_GetCDStatus(&wcda))) { case CDS_AUDIO:
ERR("couldn't get CD status !\n"); case CDS_MIXED: /* mixed is basically a mountable audio CD */
CDROM_Close(&wcda); if (!(CDROM_Audio_GetCDStatus(&wcda, dev))) {
return 0; ERR("couldn't get CD status !\n");
} goto end;
serial = CDROM_Audio_GetSerial(&wcda); }
serial = CDROM_Audio_GetSerial(&wcda);
break;
case CDS_DATA_1:
case CDS_DATA_2:
case CDS_XA_2_1:
case CDS_XA_2_2:
case -1: /* ioctl() error: ISO9660 image file given ? */
/* hopefully a data CD */
serial = CDROM_Data_GetSerial(&wcda, dev);
break;
default:
WARN("Strange CD type (%d) or empty ?\n", media);
} }
else
if ((media > CDS_AUDIO)
|| (media == -1) /* ioctl() error: ISO9660 image file given ? */
)
/* hopefully a data CD */
serial = CDROM_Data_GetSerial(&wcda);
else
WARN("Strange CD type (%d) or empty ?\n", media);
p = (media == CDS_AUDIO) ? "Audio " :
(media > CDS_AUDIO) ? "Data " : "";
if (serial) if (serial)
TRACE("%sCD serial number is %04x-%04x.\n", TRACE("CD serial number is %04x-%04x.\n",
p, HIWORD(serial), LOWORD(serial)); HIWORD(serial), LOWORD(serial));
else else
if (media >= CDS_AUDIO) if (media >= CDS_AUDIO)
ERR("couldn't get %sCD serial !\n", p); ERR("couldn't get CD serial !\n");
end:
CDROM_CloseDev(dev);
CDROM_Close(&wcda); CDROM_Close(&wcda);
} }
return serial; return serial;
@ -722,24 +782,26 @@ static const char empty_label[] = " ";
/************************************************************************** /**************************************************************************
* CDROM_Data_GetLabel [internal] * CDROM_Data_GetLabel [internal]
*/ */
DWORD CDROM_Data_GetLabel(WINE_CDAUDIO* wcda, char *label) DWORD CDROM_Data_GetLabel(WINE_CDAUDIO* wcda, char *label, int parentdev)
{ {
#define LABEL_LEN 32+1 #define LABEL_LEN 32+1
WORD offs = CDROM_Data_FindBestVoldesc(wcda->unixdev); int dev = CDROM_OPEN( wcda, parentdev );
WORD offs = CDROM_Data_FindBestVoldesc(dev);
WCHAR label_read[LABEL_LEN]; /* Unicode possible, too */ WCHAR label_read[LABEL_LEN]; /* Unicode possible, too */
DWORD unicode_id = 0; DWORD unicode_id = 0;
if (offs) if (offs)
{ {
if ((lseek(wcda->unixdev, offs+0x58, SEEK_SET) == offs+0x58) if ((lseek(dev, offs+0x58, SEEK_SET) == offs+0x58)
&& (read(wcda->unixdev, &unicode_id, 3) == 3)) && (read(dev, &unicode_id, 3) == 3))
{ {
int ver = (unicode_id & 0xff0000) >> 16; int ver = (unicode_id & 0xff0000) >> 16;
if ((lseek(wcda->unixdev, offs+0x28, SEEK_SET) != offs+0x28) if ((lseek(dev, offs+0x28, SEEK_SET) != offs+0x28)
|| (read(wcda->unixdev, &label_read, LABEL_LEN) != LABEL_LEN)) || (read(dev, &label_read, LABEL_LEN) != LABEL_LEN))
goto failure; goto failure;
CDROM_CLOSE( dev, parentdev );
if ((LOWORD(unicode_id) == 0x2f25) /* Unicode ID */ if ((LOWORD(unicode_id) == 0x2f25) /* Unicode ID */
&& ((ver == 0x40) || (ver == 0x43) || (ver == 0x45))) && ((ver == 0x40) || (ver == 0x43) || (ver == 0x45)))
{ /* yippee, unicode */ { /* yippee, unicode */
@ -761,6 +823,7 @@ DWORD CDROM_Data_GetLabel(WINE_CDAUDIO* wcda, char *label)
} }
} }
failure: failure:
CDROM_CLOSE( dev, parentdev );
ERR("error reading label !\n"); ERR("error reading label !\n");
strcpy(label, empty_label); strcpy(label, empty_label);
return 0; return 0;
@ -772,44 +835,62 @@ failure:
DWORD CDROM_GetLabel(int drive, char *label) DWORD CDROM_GetLabel(int drive, char *label)
{ {
WINE_CDAUDIO wcda; WINE_CDAUDIO wcda;
DWORD res = 1; DWORD ret = 1;
if (!(CDROM_Open(&wcda, drive))) if (!(CDROM_Open(&wcda, drive)))
{ {
int media = CDROM_GetMediaType(&wcda); int dev = CDROM_OpenDev(&wcda);
LPSTR p; int media = CDROM_GetMediaType(&wcda, dev);
LPSTR cdname = NULL;
if (media == CDS_AUDIO) switch (media)
{ {
strcpy(label, "Audio CD "); case CDS_AUDIO:
} cdname = "Audio";
else strcpy(label, "Audio CD ");
if (media == CDS_NO_INFO) break;
{
strcpy(label, empty_label);
}
else
if ((media > CDS_AUDIO)
|| (media == -1) /* ioctl() error: ISO9660 image file given ? */
)
/* hopefully a data CD */
CDROM_Data_GetLabel(&wcda, label);
else
{
WARN("Strange CD type (%d) or empty ?\n", media);
strcpy(label, empty_label);
res = 0;
}
p = (media == CDS_AUDIO) ? "Audio " : case CDS_DATA_1: /* fall through for all data CD types !! */
(media > CDS_AUDIO) ? "Data " : ""; if (!cdname) cdname = "Data_1";
TRACE("%sCD label is '%s'.\n", case CDS_DATA_2:
p, label); if (!cdname) cdname = "Data_2";
case CDS_XA_2_1:
if (!cdname) cdname = "XA 2.1";
case CDS_XA_2_2:
if (!cdname) cdname = "XA 2.2";
case -1:
if (!cdname) cdname = "Unknown/ISO file";
/* common code *here* !! */
/* hopefully a data CD */
CDROM_Data_GetLabel(&wcda, label, dev);
break;
case CDS_MIXED:
cdname = "Mixed mode";
ERR("We don't have a way of determining the label of a mixed mode CD - Linux doesn't allow raw access !!\n");
/* fall through */
case CDS_NO_INFO:
if (!cdname) cdname = "No_info";
strcpy(label, empty_label);
break;
default:
WARN("Strange CD type (%d) or empty ?\n", media);
cdname = "Strange/empty";
strcpy(label, empty_label);
ret = 0;
break;
}
CDROM_CloseDev(dev);
CDROM_Close(&wcda); CDROM_Close(&wcda);
TRACE("%s CD: label is '%s'.\n",
cdname, label);
} }
else else
res = 0; ret = 0;
return res; return ret;
} }

View file

@ -466,6 +466,7 @@ static void MSCDEX_Handler(CONTEXT86* context)
case 0x10: /* direct driver access */ case 0x10: /* direct driver access */
{ {
static WINE_CDAUDIO wcda; static WINE_CDAUDIO wcda;
int dev = -1;
BYTE* driver_request; BYTE* driver_request;
BYTE* io_stru; BYTE* io_stru;
BYTE Error = 255; /* No Error */ BYTE Error = 255; /* No Error */
@ -482,12 +483,11 @@ static void MSCDEX_Handler(CONTEXT86* context)
driver_request[3] = 5; /* bad request length */ driver_request[3] = 5; /* bad request length */
return; return;
} }
/* FIXME - would be better to open the device at the beginning of the wine session... /* FIXME
* - the device is also never closed...
* - the current implementation only supports a single CD ROM * - the current implementation only supports a single CD ROM
*/ */
if (wcda.unixdev <= 0) CDROM_Open(&wcda, -1);
CDROM_Open(&wcda, -1); dev = CDROM_OpenDev(&wcda);
TRACE("CDROM device driver -> command <%d>\n", (unsigned char)driver_request[2]); TRACE("CDROM device driver -> command <%d>\n", (unsigned char)driver_request[2]);
for (drive = 0; for (drive = 0;
@ -505,7 +505,7 @@ static void MSCDEX_Handler(CONTEXT86* context)
/* set status to 0 */ /* set status to 0 */
PTR_AT(driver_request, 3, WORD) = 0; PTR_AT(driver_request, 3, WORD) = 0;
CDROM_Audio_GetCDStatus(&wcda); CDROM_Audio_GetCDStatus(&wcda, dev);
switch (driver_request[2]) { switch (driver_request[2]) {
case 3: case 3:
@ -681,18 +681,18 @@ static void MSCDEX_Handler(CONTEXT86* context)
TRACE(" --> IOCTL OUTPUT <%d>\n", io_stru[0]); TRACE(" --> IOCTL OUTPUT <%d>\n", io_stru[0]);
switch (io_stru[0]) { switch (io_stru[0]) {
case 0: /* eject */ case 0: /* eject */
CDROM_SetDoor(&wcda, 1); CDROM_SetDoor(&wcda, 1, dev);
TRACE(" ----> EJECT\n"); TRACE(" ----> EJECT\n");
break; break;
case 2: /* reset drive */ case 2: /* reset drive */
CDROM_Reset(&wcda); CDROM_Reset(&wcda, dev);
TRACE(" ----> RESET\n"); TRACE(" ----> RESET\n");
break; break;
case 3: /* Audio Channel Control */ case 3: /* Audio Channel Control */
FIXME(" ----> AUDIO CHANNEL CONTROL (NIY)\n"); FIXME(" ----> AUDIO CHANNEL CONTROL (NIY)\n");
break; break;
case 5: /* close tray */ case 5: /* close tray */
CDROM_SetDoor(&wcda, 0); CDROM_SetDoor(&wcda, 0, dev);
TRACE(" ----> CLOSE TRAY\n"); TRACE(" ----> CLOSE TRAY\n");
break; break;
default: default:
@ -721,7 +721,7 @@ static void MSCDEX_Handler(CONTEXT86* context)
LOBYTE(LOWORD(at)); LOBYTE(LOWORD(at));
/* fall thru */ /* fall thru */
case 0: /* HSG addressing mode */ case 0: /* HSG addressing mode */
CDROM_Audio_Seek(&wcda, at); CDROM_Audio_Seek(&wcda, at, dev);
break; break;
default: default:
ERR("Unsupported address mode !!\n"); ERR("Unsupported address mode !!\n");
@ -754,7 +754,7 @@ static void MSCDEX_Handler(CONTEXT86* context)
LOBYTE(LOWORD(end)); LOBYTE(LOWORD(end));
/* fall thru */ /* fall thru */
case 0: /* HSG addressing mode */ case 0: /* HSG addressing mode */
CDROM_Audio_Play(&wcda, beg, end); CDROM_Audio_Play(&wcda, beg, end, dev);
break; break;
default: default:
ERR("Unsupported address mode !!\n"); ERR("Unsupported address mode !!\n");
@ -766,21 +766,21 @@ static void MSCDEX_Handler(CONTEXT86* context)
case 133: case 133:
if (wcda.cdaMode == WINE_CDA_PLAY) { if (wcda.cdaMode == WINE_CDA_PLAY) {
CDROM_Audio_Pause(&wcda, 1); CDROM_Audio_Pause(&wcda, 1, dev);
TRACE(" --> STOP AUDIO (Paused)\n"); TRACE(" --> STOP AUDIO (Paused)\n");
} else { } else {
CDROM_Audio_Stop(&wcda); CDROM_Audio_Stop(&wcda, dev);
TRACE(" --> STOP AUDIO (Stopped)\n"); TRACE(" --> STOP AUDIO (Stopped)\n");
} }
break; break;
case 136: case 136:
TRACE(" --> RESUME AUDIO\n"); TRACE(" --> RESUME AUDIO\n");
CDROM_Audio_Pause(&wcda, 0); CDROM_Audio_Pause(&wcda, 0, dev);
break; break;
default: default:
FIXME(" ioctl uninplemented <%d>\n", driver_request[2]); FIXME(" ioctl unimplemented <%d>\n", driver_request[2]);
Error = 0x0c; Error = 0x0c;
} }
@ -790,6 +790,8 @@ static void MSCDEX_Handler(CONTEXT86* context)
driver_request[3] = Error; driver_request[3] = Error;
} }
CDROM_CloseDev(dev);
CDROM_Close(&wcda);
/* setting status bits /* setting status bits
* 3 == playing && done * 3 == playing && done
* 1 == done * 1 == done