diff --git a/dlls/winmm/mcicda/mcicda.c b/dlls/winmm/mcicda/mcicda.c index f8bb0e1cfb2..6956167af34 100644 --- a/dlls/winmm/mcicda/mcicda.c +++ b/dlls/winmm/mcicda/mcicda.c @@ -69,7 +69,7 @@ static WINE_MCICDAUDIO* MCICDA_GetOpenDrv(UINT 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); return 0; } @@ -215,6 +215,7 @@ static DWORD MCICDA_Open(UINT wDevID, DWORD dwFlags, LPMCI_OPEN_PARMSA lpOpenPar DWORD dwDeviceID; WINE_MCICDAUDIO* wmcda = (WINE_MCICDAUDIO*)mciGetDriverData(wDevID); MCI_SEEK_PARMS seekParms; + int dev; 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->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"); + CDROM_CloseDev(dev); return MCIERR_INTERNAL; } MCICDA_Seek(wDevID, MCI_SEEK_TO_START, &seekParms); + CDROM_CloseDev(dev); return 0; } @@ -368,10 +373,13 @@ static DWORD MCICDA_Info(UINT wDevID, DWORD dwFlags, LPMCI_INFO_PARMSA lpParms) ret = MCIERR_NO_IDENTITY; } else if (dwFlags & MCI_INFO_MEDIA_IDENTITY) { 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); } + CDROM_CloseDev(dev); res = CDROM_Audio_GetSerial(&wmcda->wcda); 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) { switch (lpParms->dwItem) { case MCI_STATUS_CURRENT_TRACK: - if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) { + if (!CDROM_Audio_GetCDStatus(&wmcda->wcda, -1)) { return MCICDA_GetError(wmcda); } lpParms->dwReturn = wmcda->wcda.nCurTrack; @@ -430,7 +438,7 @@ static DWORD MCICDA_Status(UINT wDevID, DWORD dwFlags, LPMCI_STATUS_PARMS lpParm break; case MCI_STATUS_LENGTH: if (wmcda->wcda.nTracks == 0) { - if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda)) { + if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda, -1)) { WARN("error reading TracksInfo !\n"); 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); break; case MCI_STATUS_MODE: - if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) + if (!CDROM_Audio_GetCDStatus(&wmcda->wcda, -1)) return MCICDA_GetError(wmcda); lpParms->dwReturn = MCICDA_Mode(wmcda->wcda.cdaMode); 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; break; case MCI_STATUS_MEDIA_PRESENT: - if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) + if(!CDROM_Audio_GetCDStatus(&wmcda->wcda, -1)) return MCICDA_GetError(wmcda); - lpParms->dwReturn = (wmcda->wcda.nTracks == 0) ? + lpParms->dwReturn = (wmcda->wcda.nTracks == 0) ? MAKEMCIRESOURCE(FALSE, MCI_FALSE) : MAKEMCIRESOURCE(TRUE, MCI_TRUE); TRACE("MCI_STATUS_MEDIA_PRESENT =%c!\n", LOWORD(lpParms->dwReturn) ? 'Y' : 'N'); ret = MCI_RESOURCE_RETURNED; break; 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); if (lpParms->dwReturn == (WORD)-1) return MCICDA_GetError(wmcda); break; case MCI_STATUS_POSITION: - if (!CDROM_Audio_GetCDStatus(&wmcda->wcda)) + if (!CDROM_Audio_GetCDStatus(&wmcda->wcda, -1)) return MCICDA_GetError(wmcda); + if(wmcda->wcda.cdaMode == WINE_CDA_OPEN) + return MCIERR_HARDWARE; lpParms->dwReturn = wmcda->wcda.dwCurFrame; if (dwFlags & MCI_STATUS_START) { 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) ret = MCIERR_OUTOFRANGE; 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; TRACE("MCI_CDA_STATUS_TYPE_TRACK[%ld]=%08lx\n", lpParms->dwTrack, lpParms->dwReturn); break; @@ -539,46 +549,58 @@ static DWORD MCICDA_Play(UINT wDevID, DWORD dwFlags, LPMCI_PLAY_PARMS lpParms) int start, end; WINE_MCICDAUDIO* wmcda = MCICDA_GetOpenDrv(wDevID); DWORD ret = 0; + int dev = -1; TRACE("(%04X, %08lX, %p);\n", wDevID, dwFlags, lpParms); - if (lpParms == NULL) { - ret = MCIERR_NULL_PARAMETER_BLOCK; - } else if (wmcda == NULL) { - ret = MCIERR_INVALID_DEVICE_ID; - } else { - if (wmcda->wcda.nTracks == 0) { - if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda)) { - WARN("error reading TracksInfo !\n"); - return MCIERR_DRIVER_INTERNAL; - } - } - 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)) 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); - */ + if (lpParms == NULL) + return MCIERR_NULL_PARAMETER_BLOCK; + + if (wmcda == NULL) + return MCIERR_INVALID_DEVICE_ID; + + dev = CDROM_OpenDev(&wmcda->wcda); + if (wmcda->wcda.nTracks == 0) { + if (!CDROM_Audio_GetTracksInfo(&wmcda->wcda, dev)) { + WARN("error reading TracksInfo !\n"); + ret = MCIERR_DRIVER_INTERNAL; + goto end; } } + 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; } @@ -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 (CDROM_Audio_Stop(&wmcda->wcda) == -1) + if (CDROM_Audio_Stop(&wmcda->wcda, -1) == -1) return MCIERR_HARDWARE; 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 (CDROM_Audio_Pause(&wmcda->wcda, 1) == -1) + if (CDROM_Audio_Pause(&wmcda->wcda, 1, -1) == -1) return MCIERR_HARDWARE; wmcda->mciMode = MCI_MODE_PAUSE; 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 (CDROM_Audio_Pause(&wmcda->wcda, 0) == -1) + if (CDROM_Audio_Pause(&wmcda->wcda, 0, -1) == -1) return MCIERR_HARDWARE; wmcda->mciMode = MCI_MODE_STOP; 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); return MCIERR_UNSUPPORTED_FUNCTION; } - if (CDROM_Audio_Seek(&wmcda->wcda, at) == -1) { + if (CDROM_Audio_Seek(&wmcda->wcda, at, -1) == -1) { return MCIERR_HARDWARE; } 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 (CDROM_SetDoor(&wmcda->wcda, open) == -1) + if (CDROM_SetDoor(&wmcda->wcda, open, -1) == -1) return MCIERR_HARDWARE; wmcda->mciMode = (open) ? MCI_MODE_OPEN : MCI_MODE_STOP; return 0; diff --git a/include/cdrom.h b/include/cdrom.h index d8ba48d9a8b..44fed0942b1 100644 --- a/include/cdrom.h +++ b/include/cdrom.h @@ -26,7 +26,7 @@ #endif typedef struct { - int unixdev; + const char *devname; #if defined(linux) struct cdrom_subchnl sc; #elif defined(__FreeBSD__) || defined(__NetBSD__) @@ -57,20 +57,22 @@ typedef struct { #define WINE_CDA_PAUSE 0x05 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_Reset(WINE_CDAUDIO* wcda); -int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD stop); -int CDROM_Audio_Stop(WINE_CDAUDIO* wcda); -int CDROM_Audio_Pause(WINE_CDAUDIO* wcda, int pauseOn); -int CDROM_Audio_Seek(WINE_CDAUDIO* wcda, DWORD at); -int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open); -UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda); -BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda); -BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda); +int CDROM_Reset(WINE_CDAUDIO* wcda, int parentdev); +int CDROM_Audio_Play(WINE_CDAUDIO* wcda, DWORD start, DWORD stop, int parentdev); +int CDROM_Audio_Stop(WINE_CDAUDIO* wcda, int parentdev); +int CDROM_Audio_Pause(WINE_CDAUDIO* wcda, int pauseOn, int parentdev); +int CDROM_Audio_Seek(WINE_CDAUDIO* wcda, DWORD at, int parentdev); +int CDROM_SetDoor(WINE_CDAUDIO* wcda, int open, int parentdev); +UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda, int parentdev); +BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda, int parentdev); +BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda, int parentdev); WORD CDROM_Data_FindBestVoldesc(int fd); 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_GetLabel(int drive, char *label); diff --git a/misc/cdrom.c b/misc/cdrom.c index adc7337c3fe..6795e12ac16 100644 --- a/misc/cdrom.c +++ b/misc/cdrom.c @@ -23,6 +23,12 @@ DEFAULT_DEBUG_CHANNEL(cdrom); #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] * @@ -31,9 +37,8 @@ DEFAULT_DEBUG_CHANNEL(cdrom); */ int CDROM_Open(WINE_CDAUDIO* wcda, int drive) { - int i; + int i, dev; BOOL avail = FALSE; - const char *dev; if (drive == -1) { @@ -53,18 +58,20 @@ int CDROM_Open(WINE_CDAUDIO* wcda, int drive) WARN("No CD-ROM #%d found !\n", drive); 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", drive, 'A' + drive); return -1; } - wcda->unixdev = open(dev, O_RDONLY | O_NONBLOCK, 0); - if (wcda->unixdev == -1) { - WARN("can't open '%s'!. %s\n", dev, strerror(errno)); + /* Test whether device can be opened */ + dev = CDROM_OpenDev(wcda); + if (dev == -1) return -1; - } + else + CDROM_CloseDev(dev); + wcda->cdaMode = WINE_CDA_OPEN; /* to force reading tracks info */ wcda->nCurTrack = 0; wcda->nTracks = 0; @@ -73,19 +80,46 @@ int CDROM_Open(WINE_CDAUDIO* wcda, int drive) wcda->lpdwTrackLen = NULL; wcda->lpdwTrackPos = NULL; wcda->lpbTrackFlags = NULL; + TRACE("opened drive %c: (device %s)\n", 'A' + drive, wcda->devname); 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] */ -int CDROM_GetMediaType(WINE_CDAUDIO* wcda) +int CDROM_GetMediaType(WINE_CDAUDIO* wcda, int parentdev) { + int type = -1; #ifdef linux - return ioctl(wcda->unixdev, CDROM_DISC_STATUS); -#else - return -1; + int dev = CDROM_OPEN( wcda, parentdev ); + type = ioctl(dev, CDROM_DISC_STATUS); + CDROM_CLOSE( dev, parentdev ); #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->lpdwTrackPos != NULL) free(wcda->lpdwTrackPos); if (wcda->lpbTrackFlags != NULL) free(wcda->lpbTrackFlags); - close(wcda->unixdev); + TRACE("%s\n", wcda->devname); return 0; #else return -1; @@ -109,11 +143,13 @@ int CDROM_Close(WINE_CDAUDIO* wcda) * * 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 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) { 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] */ -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__) #ifdef linux struct cdrom_tochdr hdr; #else struct ioc_toc_header hdr; #endif - + int dev = CDROM_OPEN( wcda, parentdev ); + if (wcda->nTracks == 0) { #ifdef linux - if (ioctl(wcda->unixdev, CDROMREADTOCHDR, &hdr)) + if (ioctl(dev, CDROMREADTOCHDR, &hdr)) #else - if (ioctl(wcda->unixdev, CDIOREADTOCHEADER, &hdr)) + if (ioctl(dev, CDIOREADTOCHEADER, &hdr)) #endif { - WARN("(%p) -- Error occurred (%d)!\n", wcda, errno); - return (WORD)-1; + WARN("(%p) -- Error occurred (%s)!\n", wcda, strerror(errno)); + goto end; } #ifdef linux wcda->nFirstTrack = hdr.cdth_trk0; @@ -157,17 +195,19 @@ UINT16 CDROM_Audio_GetNumberOfTracks(WINE_CDAUDIO* wcda) #endif wcda->nTracks = wcda->nLastTrack - wcda->nFirstTrack + 1; } - return wcda->nTracks; -#else - return (WORD)-1; + ret = wcda->nTracks; +end: + CDROM_CLOSE( dev, parentdev ); #endif + return ret; } /************************************************************************** * 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__) int i, length; int start, last_start = 0; @@ -178,9 +218,11 @@ BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda) struct ioc_read_toc_entry entry; struct cd_toc_entry toc_buffer; #endif + int dev = CDROM_OPEN( wcda, parentdev ); 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); @@ -196,7 +238,7 @@ BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda) if (wcda->lpdwTrackLen == NULL || wcda->lpdwTrackPos == NULL || wcda->lpbTrackFlags == NULL) { WARN("error allocating track table !\n"); - return FALSE; + goto end; } memset(wcda->lpdwTrackLen, 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; #endif #ifdef linux - if (ioctl(wcda->unixdev, CDROMREADTOCENTRY, &entry)) + if (ioctl(dev, CDROMREADTOCENTRY, &entry)) #else - if (ioctl(wcda->unixdev, CDIOREADTOCENTRYS, &entry)) + if (ioctl(dev, CDIOREADTOCENTRYS, &entry)) #endif { WARN("error read entry (%s)\n", strerror(errno)); /* update status according to new status */ - CDROM_Audio_GetCDStatus(wcda); + CDROM_Audio_GetCDStatus(wcda, dev); - return FALSE; + goto end; } #ifdef linux start = CDFRAMES_PERSEC * (SECONDS_PERMIN * @@ -268,19 +310,22 @@ BOOL CDROM_Audio_GetTracksInfo(WINE_CDAUDIO* wcda) } wcda->dwLastFrame = last_start; TRACE("total_len=%u\n", total_length); - return TRUE; -#else - return FALSE; + ret = TRUE; +end: + CDROM_CLOSE( dev, parentdev ); #endif + return ret; } /************************************************************************** * 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__) - int oldmode = wcda->cdaMode; + int oldmode = wcda->cdaMode; + int ret = FALSE; + int dev = CDROM_OPEN( wcda, parentdev ); #ifdef linux wcda->sc.cdsc_format = CDROM_MSF; #else @@ -293,14 +338,14 @@ BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda) read_sc.data = (struct cd_sub_channel_info *)&wcda->sc; #endif #ifdef linux - if (ioctl(wcda->unixdev, CDROMSUBCHNL, &wcda->sc)) + if (ioctl(dev, CDROMSUBCHNL, &wcda->sc)) #else - if (ioctl(wcda->unixdev, CDIOCREADSUBCHANNEL, &read_sc)) + if (ioctl(dev, CDIOCREADSUBCHANNEL, &read_sc)) #endif { TRACE("opened or no_media (%s)!\n", strerror(errno)); wcda->cdaMode = WINE_CDA_OPEN; /* was NOT_READY */ - return TRUE; + goto end; } switch ( #ifdef linux @@ -377,12 +422,16 @@ BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda) #endif if (oldmode != wcda->cdaMode && oldmode == WINE_CDA_OPEN) { - if (!CDROM_Audio_GetTracksInfo(wcda)) { + if (!CDROM_Audio_GetTracksInfo(wcda, dev)) { 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 return FALSE; #endif @@ -391,14 +440,16 @@ BOOL CDROM_Audio_GetCDStatus(WINE_CDAUDIO* wcda) /************************************************************************** * 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__) #ifdef linux struct cdrom_msf msf; #else struct ioc_play_msf msf; #endif + int dev = CDROM_OPEN( wcda, parentdev ); #ifdef linux 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; #endif #ifdef linux - if (ioctl(wcda->unixdev, CDROMSTART)) + if (ioctl(dev, CDROMSTART)) #else - if (ioctl(wcda->unixdev, CDIOCSTART, NULL)) + if (ioctl(dev, CDIOCSTART, NULL)) #endif { WARN("motor doesn't start !\n"); - return -1; + goto end; } #ifdef linux - if (ioctl(wcda->unixdev, CDROMPLAYMSF, &msf)) + if (ioctl(dev, CDROMPLAYMSF, &msf)) #else - if (ioctl(wcda->unixdev, CDIOCPLAYMSF, &msf)) + if (ioctl(dev, CDIOCPLAYMSF, &msf)) #endif { WARN("device doesn't play !\n"); - return -1; + goto end; } #ifdef linux 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.end_m, msf.end_s, msf.end_f); #endif - return 0; -#else - return -1; + ret = 0; +end: + CDROM_CLOSE( dev, parentdev ); #endif + return ret; } /************************************************************************** * 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__) - int ret = 0; + int dev = CDROM_OPEN( wcda, parentdev ); #ifdef linux - ret = ioctl(wcda->unixdev, CDROMSTOP); + ret = ioctl(dev, CDROMSTOP); #else - ret = ioctl(wcda->unixdev, CDIOCSTOP, NULL); + ret = ioctl(dev, CDIOCSTOP, NULL); +#endif + CDROM_CLOSE( dev, parentdev ); #endif return ret; -#else - return -1; -#endif } /************************************************************************** * 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__) - int ret = 0; + int dev = CDROM_OPEN( wcda, parentdev ); #ifdef linux - ret = ioctl(wcda->unixdev, pauseOn ? CDROMPAUSE : CDROMRESUME); + ret = ioctl(dev, pauseOn ? CDROMPAUSE : CDROMRESUME); #else - ret = ioctl(wcda->unixdev, pauseOn ? CDIOCPAUSE : CDIOCRESUME, NULL); + ret = ioctl(dev, pauseOn ? CDIOCPAUSE : CDIOCRESUME, NULL); +#endif + CDROM_CLOSE( dev, parentdev ); #endif return ret; -#else - return -1; -#endif } /************************************************************************** * 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__) - int ret = 0; + int dev = CDROM_OPEN( wcda, parentdev ); #ifdef linux struct cdrom_msf0 msf; msf.minute = at / CDFRAMES_PERMIN; msf.second = (at % CDFRAMES_PERMIN) / CDFRAMES_PERSEC; msf.frame = at % CDFRAMES_PERSEC; - ret = ioctl(wcda->unixdev, CDROMSEEK, &msf); + ret = ioctl(dev, CDROMSEEK, &msf); #else /* FIXME: the current end for play is lost * use end of CD ROM instead */ 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 return ret; -#else - return -1; -#endif } /************************************************************************** * 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__) - int ret = 0; + int dev = CDROM_OPEN( wcda, parentdev ); + + TRACE("%d\n", open); #ifdef linux if (open) { - ret = ioctl(wcda->unixdev, CDROMEJECT); + ret = ioctl(dev, CDROMEJECT); } else { - ret = ioctl(wcda->unixdev, CDROMEJECT, 1); + ret = ioctl(dev, CDROMEJECT, 1); } #else - ret = (ioctl(wcda->unixdev, CDIOCALLOW, NULL)) || - (ioctl(wcda->unixdev, open ? CDIOCEJECT : CDIOCCLOSE, NULL)) || - (ioctl(wcda->unixdev, CDIOCPREVENT, NULL)); + ret = (ioctl(dev, CDIOCALLOW, NULL)) || + (ioctl(dev, open ? CDIOCEJECT : CDIOCCLOSE, NULL)) || + (ioctl(dev, CDIOCPREVENT, NULL)); #endif wcda->nTracks = 0; - return ret; -#else - return -1; + if (ret == -1) + WARN("failed (%s)\n", strerror(errno)); + CDROM_CLOSE( dev, parentdev ); #endif + return ret; } /************************************************************************** * 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__) - int ret = 0; + int dev = CDROM_OPEN( wcda, parentdev ); #ifdef linux - ret = ioctl(wcda->unixdev, CDROMRESET); + ret = ioctl(dev, CDROMRESET); #else - ret = ioctl(wcda->unixdev, CDIOCRESET, NULL); + ret = ioctl(dev, CDIOCRESET, NULL); +#endif + CDROM_CLOSE( dev, parentdev ); #endif return ret; -#else - return -1; -#endif } WORD CDROM_Data_FindBestVoldesc(int fd) @@ -627,9 +682,10 @@ DWORD CDROM_Audio_GetSerial(WINE_CDAUDIO* wcda) /************************************************************************** * 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 { unsigned long val; unsigned char p[4]; @@ -643,8 +699,8 @@ DWORD CDROM_Data_GetSerial(WINE_CDAUDIO* wcda) OSVERSIONINFOA ovi; int i; - lseek(wcda->unixdev,offs,SEEK_SET); - read(wcda->unixdev,buf,2048); + lseek(dev,offs,SEEK_SET); + read(dev,buf,2048); /* * OK, another braindead one... argh. Just believe it. * 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]; } } + CDROM_CLOSE( dev, parentdev ); return serial.val; } @@ -683,35 +740,38 @@ DWORD CDROM_GetSerial(int drive) if (!(CDROM_Open(&wcda, drive))) { - int media = CDROM_GetMediaType(&wcda); - LPSTR p; + int dev = CDROM_OpenDev(&wcda); + int media = CDROM_GetMediaType(&wcda, dev); - if (media == CDS_AUDIO) + switch (media) { - if (!(CDROM_Audio_GetCDStatus(&wcda))) { - ERR("couldn't get CD status !\n"); - CDROM_Close(&wcda); - return 0; - } - serial = CDROM_Audio_GetSerial(&wcda); + case CDS_AUDIO: + case CDS_MIXED: /* mixed is basically a mountable audio CD */ + if (!(CDROM_Audio_GetCDStatus(&wcda, dev))) { + ERR("couldn't get CD status !\n"); + goto end; + } + 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) - TRACE("%sCD serial number is %04x-%04x.\n", - p, HIWORD(serial), LOWORD(serial)); + TRACE("CD serial number is %04x-%04x.\n", + HIWORD(serial), LOWORD(serial)); else 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); } return serial; @@ -722,24 +782,26 @@ static const char empty_label[] = " "; /************************************************************************** * 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 - 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 */ DWORD unicode_id = 0; if (offs) { - if ((lseek(wcda->unixdev, offs+0x58, SEEK_SET) == offs+0x58) - && (read(wcda->unixdev, &unicode_id, 3) == 3)) + if ((lseek(dev, offs+0x58, SEEK_SET) == offs+0x58) + && (read(dev, &unicode_id, 3) == 3)) { int ver = (unicode_id & 0xff0000) >> 16; - if ((lseek(wcda->unixdev, offs+0x28, SEEK_SET) != offs+0x28) - || (read(wcda->unixdev, &label_read, LABEL_LEN) != LABEL_LEN)) + if ((lseek(dev, offs+0x28, SEEK_SET) != offs+0x28) + || (read(dev, &label_read, LABEL_LEN) != LABEL_LEN)) goto failure; + CDROM_CLOSE( dev, parentdev ); if ((LOWORD(unicode_id) == 0x2f25) /* Unicode ID */ && ((ver == 0x40) || (ver == 0x43) || (ver == 0x45))) { /* yippee, unicode */ @@ -761,6 +823,7 @@ DWORD CDROM_Data_GetLabel(WINE_CDAUDIO* wcda, char *label) } } failure: + CDROM_CLOSE( dev, parentdev ); ERR("error reading label !\n"); strcpy(label, empty_label); return 0; @@ -772,44 +835,62 @@ failure: DWORD CDROM_GetLabel(int drive, char *label) { WINE_CDAUDIO wcda; - DWORD res = 1; + DWORD ret = 1; if (!(CDROM_Open(&wcda, drive))) { - int media = CDROM_GetMediaType(&wcda); - LPSTR p; + int dev = CDROM_OpenDev(&wcda); + int media = CDROM_GetMediaType(&wcda, dev); + LPSTR cdname = NULL; - if (media == CDS_AUDIO) + switch (media) { - strcpy(label, "Audio CD "); - } - else - if (media == CDS_NO_INFO) - { - 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; - } + case CDS_AUDIO: + cdname = "Audio"; + strcpy(label, "Audio CD "); + break; - p = (media == CDS_AUDIO) ? "Audio " : - (media > CDS_AUDIO) ? "Data " : ""; - TRACE("%sCD label is '%s'.\n", - p, label); + case CDS_DATA_1: /* fall through for all data CD types !! */ + if (!cdname) cdname = "Data_1"; + case CDS_DATA_2: + 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); + TRACE("%s CD: label is '%s'.\n", + cdname, label); } else - res = 0; + ret = 0; - return res; + return ret; } diff --git a/msdos/int2f.c b/msdos/int2f.c index 639126fd33b..da254c92c24 100644 --- a/msdos/int2f.c +++ b/msdos/int2f.c @@ -466,6 +466,7 @@ static void MSCDEX_Handler(CONTEXT86* context) case 0x10: /* direct driver access */ { static WINE_CDAUDIO wcda; + int dev = -1; BYTE* driver_request; BYTE* io_stru; BYTE Error = 255; /* No Error */ @@ -482,12 +483,11 @@ static void MSCDEX_Handler(CONTEXT86* context) driver_request[3] = 5; /* bad request length */ return; } - /* FIXME - would be better to open the device at the beginning of the wine session... - * - the device is also never closed... + /* FIXME * - 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]); for (drive = 0; @@ -505,7 +505,7 @@ static void MSCDEX_Handler(CONTEXT86* context) /* set status to 0 */ PTR_AT(driver_request, 3, WORD) = 0; - CDROM_Audio_GetCDStatus(&wcda); + CDROM_Audio_GetCDStatus(&wcda, dev); switch (driver_request[2]) { case 3: @@ -681,18 +681,18 @@ static void MSCDEX_Handler(CONTEXT86* context) TRACE(" --> IOCTL OUTPUT <%d>\n", io_stru[0]); switch (io_stru[0]) { case 0: /* eject */ - CDROM_SetDoor(&wcda, 1); + CDROM_SetDoor(&wcda, 1, dev); TRACE(" ----> EJECT\n"); break; case 2: /* reset drive */ - CDROM_Reset(&wcda); + CDROM_Reset(&wcda, dev); TRACE(" ----> RESET\n"); break; case 3: /* Audio Channel Control */ FIXME(" ----> AUDIO CHANNEL CONTROL (NIY)\n"); break; case 5: /* close tray */ - CDROM_SetDoor(&wcda, 0); + CDROM_SetDoor(&wcda, 0, dev); TRACE(" ----> CLOSE TRAY\n"); break; default: @@ -721,7 +721,7 @@ static void MSCDEX_Handler(CONTEXT86* context) LOBYTE(LOWORD(at)); /* fall thru */ case 0: /* HSG addressing mode */ - CDROM_Audio_Seek(&wcda, at); + CDROM_Audio_Seek(&wcda, at, dev); break; default: ERR("Unsupported address mode !!\n"); @@ -754,7 +754,7 @@ static void MSCDEX_Handler(CONTEXT86* context) LOBYTE(LOWORD(end)); /* fall thru */ case 0: /* HSG addressing mode */ - CDROM_Audio_Play(&wcda, beg, end); + CDROM_Audio_Play(&wcda, beg, end, dev); break; default: ERR("Unsupported address mode !!\n"); @@ -766,21 +766,21 @@ static void MSCDEX_Handler(CONTEXT86* context) case 133: if (wcda.cdaMode == WINE_CDA_PLAY) { - CDROM_Audio_Pause(&wcda, 1); + CDROM_Audio_Pause(&wcda, 1, dev); TRACE(" --> STOP AUDIO (Paused)\n"); } else { - CDROM_Audio_Stop(&wcda); + CDROM_Audio_Stop(&wcda, dev); TRACE(" --> STOP AUDIO (Stopped)\n"); } break; case 136: TRACE(" --> RESUME AUDIO\n"); - CDROM_Audio_Pause(&wcda, 0); + CDROM_Audio_Pause(&wcda, 0, dev); break; default: - FIXME(" ioctl uninplemented <%d>\n", driver_request[2]); + FIXME(" ioctl unimplemented <%d>\n", driver_request[2]); Error = 0x0c; } @@ -790,6 +790,8 @@ static void MSCDEX_Handler(CONTEXT86* context) driver_request[3] = Error; } + CDROM_CloseDev(dev); + CDROM_Close(&wcda); /* setting status bits * 3 == playing && done * 1 == done