diff --git a/lib/driver/MSWindows/win32.c b/lib/driver/MSWindows/win32.c index 5161ba0d..bb30f502 100644 --- a/lib/driver/MSWindows/win32.c +++ b/lib/driver/MSWindows/win32.c @@ -1,5 +1,5 @@ /* - $Id: win32.c,v 1.24 2005/03/06 00:54:50 rocky Exp $ + $Id: win32.c,v 1.25 2005/03/07 00:55:31 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein @@ -26,7 +26,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: win32.c,v 1.24 2005/03/06 00:54:50 rocky Exp $"; +static const char _rcsid[] = "$Id: win32.c,v 1.25 2005/03/07 00:55:31 rocky Exp $"; #include #include @@ -163,6 +163,26 @@ audio_set_volume_win32 ( void *p_user_data, cdio_audio_volume_t *p_volume) } } +static driver_return_code_t +audio_stop_win32 ( void *p_user_data) +{ + if ( WIN_NT ) { + return audio_stop_win32ioctl (p_user_data); + } else { + return DRIVER_OP_UNSUPPORTED; /* not yet, but soon I hope */ + } +} + +static driver_return_code_t +close_tray_win32 ( void *p_user_data) +{ + if ( WIN_NT ) { + return close_tray_win32ioctl (p_user_data); + } else { + return DRIVER_OP_UNSUPPORTED; /* not yet, but soon I hope */ + } +} + /* General ioctl() CD-ROM command function */ static bool _cdio_mciSendCommand(int id, UINT msg, DWORD flags, void *arg) @@ -536,7 +556,7 @@ read_toc_win32 (void *p_user_data) Eject media. Return 1 if successful, 0 otherwise. */ static int -_cdio_eject_media (void *p_user_data) { +eject_media_win32 (void *p_user_data) { #ifdef _XBOX return DRIVER_OP_UNSUPPORTED; #else @@ -576,7 +596,7 @@ _cdio_eject_media (void *p_user_data) { Return the value associated with the key "arg". */ static const char * -_get_arg_win32 (void *p_user_data, const char key[]) +get_arg_win32 (void *p_user_data, const char key[]) { _img_private_t *p_env = p_user_data; @@ -835,9 +855,11 @@ cdio_open_am_win32 (const char *psz_orig_source, const char *psz_access_mode) _funcs.audio_read_subchannel = audio_read_subchannel_win32; _funcs.audio_resume = audio_resume_win32; _funcs.audio_set_volume = audio_set_volume_win32; - _funcs.eject_media = _cdio_eject_media; + _funcs.audio_stop = audio_stop_win32; + _funcs.close_tray = close_tray_win32; + _funcs.eject_media = eject_media_win32; _funcs.free = free_win32; - _funcs.get_arg = _get_arg_win32; + _funcs.get_arg = get_arg_win32; _funcs.get_cdtext = get_cdtext_generic; _funcs.get_default_device = cdio_get_default_device_win32; _funcs.get_devices = cdio_get_devices_win32; diff --git a/lib/driver/MSWindows/win32.h b/lib/driver/MSWindows/win32.h index 162fd004..bc47b2e4 100644 --- a/lib/driver/MSWindows/win32.h +++ b/lib/driver/MSWindows/win32.h @@ -1,5 +1,5 @@ /* - $Id: win32.h,v 1.6 2005/03/06 00:54:50 rocky Exp $ + $Id: win32.h,v 1.7 2005/03/07 00:55:31 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -95,6 +95,15 @@ driver_return_code_t audio_read_subchannel_win32ioctl (void *p_user_data, cdio_subchannel_t *p_subchannel); +/*! + Set the volume of an audio CD. + + @param p_cdio the CD object to be acted upon. + +*/ +driver_return_code_t +audio_stop_win32ioctl ( void *p_user_data ); + /*! Set the volume of an audio CD. @@ -105,6 +114,14 @@ driver_return_code_t audio_set_volume_win32ioctl ( void *p_user_data, cdio_audio_volume_t *p_volume); +/*! + Close the tray of a CD-ROM + + @param p_user_data the CD object to be acted upon. + +*/ +driver_return_code_t close_tray_win32ioctl (void *p_user_data); + /*! Reads an audio device using the DeviceIoControl method into data starting from lsn. Returns 0 if no error. diff --git a/lib/driver/MSWindows/win32_ioctl.c b/lib/driver/MSWindows/win32_ioctl.c index fb5c5d35..850a8cdd 100644 --- a/lib/driver/MSWindows/win32_ioctl.c +++ b/lib/driver/MSWindows/win32_ioctl.c @@ -1,5 +1,5 @@ /* - $Id: win32_ioctl.c,v 1.19 2005/03/06 11:21:52 rocky Exp $ + $Id: win32_ioctl.c,v 1.20 2005/03/07 00:55:31 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -26,7 +26,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: win32_ioctl.c,v 1.19 2005/03/06 11:21:52 rocky Exp $"; +static const char _rcsid[] = "$Id: win32_ioctl.c,v 1.20 2005/03/07 00:55:31 rocky Exp $"; #ifdef HAVE_WIN32_CDROM @@ -60,6 +60,7 @@ static const char _rcsid[] = "$Id: win32_ioctl.c,v 1.19 2005/03/06 11:21:52 rock #include #include +#include #include "cdio_assert.h" #include #include "cdtext_private.h" @@ -111,7 +112,7 @@ audio_pause_win32ioctl (void *p_user_data) bool b_success = DeviceIoControl(p_env->h_device_handle, IOCTL_CDROM_PAUSE_AUDIO, - NULL, (DWORD) 0, NULL, 0, &dw_bytes_returned, 0); + NULL, (DWORD) 0, NULL, 0, &dw_bytes_returned, NULL); if ( ! b_success ) { char *psz_msg = NULL; @@ -150,7 +151,7 @@ audio_play_msf_win32ioctl (void *p_user_data, msf_t *p_start_msf, bool b_success = DeviceIoControl(p_env->h_device_handle, IOCTL_CDROM_PLAY_AUDIO_MSF, - NULL, (DWORD) 0, NULL, 0, &dw_bytes_returned, 0); + &play, sizeof(play), NULL, 0, &dw_bytes_returned, NULL); if ( ! b_success ) { char *psz_msg = NULL; @@ -167,6 +168,39 @@ audio_play_msf_win32ioctl (void *p_user_data, msf_t *p_start_msf, } + +/* Like cdio_lsn_to_msf bout without the to_bcd8 encoding */ +static void +lsn_to_msf (lsn_t lsn, msf_t *msf) +{ + int m, s, f; + + cdio_assert (msf != 0); + + if ( lsn >= -CDIO_PREGAP_SECTORS ){ + m = (lsn + CDIO_PREGAP_SECTORS) / CDIO_CD_FRAMES_PER_MIN; + lsn -= m * CDIO_CD_FRAMES_PER_MIN; + s = (lsn + CDIO_PREGAP_SECTORS) / CDIO_CD_FRAMES_PER_SEC; + lsn -= s * CDIO_CD_FRAMES_PER_SEC; + f = lsn + CDIO_PREGAP_SECTORS; + } else { + m = (lsn + CDIO_CD_MAX_LSN) / CDIO_CD_FRAMES_PER_MIN; + lsn -= m * (CDIO_CD_FRAMES_PER_MIN); + s = (lsn+CDIO_CD_MAX_LSN) / CDIO_CD_FRAMES_PER_SEC; + lsn -= s * CDIO_CD_FRAMES_PER_SEC; + f = lsn + CDIO_CD_MAX_LSN; + } + + if (m > 99) { + cdio_warn ("number of minutes (%d) truncated to 99.", m); + m = 99; + } + + msf->m = m; + msf->s = s; + msf->f = f; +} + /*! Read Audio Subchannel information @@ -178,6 +212,8 @@ audio_read_subchannel_win32ioctl (void *p_user_data, cdio_subchannel_t *p_subchannel) { const _img_private_t *p_env = p_user_data; + lba_t abs_lba; + lba_t rel_lba; DWORD dw_bytes_returned; CDROM_SUB_Q_DATA_FORMAT q_data_format; SUB_Q_CHANNEL_DATA q_subchannel_data; @@ -201,8 +237,25 @@ audio_read_subchannel_win32ioctl (void *p_user_data, LocalFree(psz_msg); return DRIVER_OP_ERROR; } - memcpy(p_subchannel, &q_subchannel_data.CurrentPosition, - sizeof(cdio_subchannel_t)); + p_subchannel->audio_status = + q_subchannel_data.CurrentPosition.Header.AudioStatus; + p_subchannel->track = + q_subchannel_data.CurrentPosition.TrackNumber; + p_subchannel->index = + q_subchannel_data.CurrentPosition.IndexNumber; + p_subchannel->index = + q_subchannel_data.CurrentPosition.IndexNumber; + p_subchannel->address = q_subchannel_data.CurrentPosition.ADR; + p_subchannel->control = q_subchannel_data.CurrentPosition.Control; + + abs_lba = + CDIO_MMC_GET_LEN32(q_subchannel_data.CurrentPosition.AbsoluteAddress); + rel_lba = + CDIO_MMC_GET_LEN32(q_subchannel_data.CurrentPosition.TrackRelativeAddress); + + lsn_to_msf(abs_lba, &p_subchannel->abs_addr.msf); + lsn_to_msf(rel_lba, &p_subchannel->rel_addr.msf); + return DRIVER_OP_SUCCESS; } @@ -221,7 +274,7 @@ audio_resume_win32ioctl (void *p_user_data) bool b_success = DeviceIoControl(p_env->h_device_handle, IOCTL_CDROM_RESUME_AUDIO, - NULL, (DWORD) 0, NULL, 0, &dw_bytes_returned, 0); + NULL, (DWORD) 0, NULL, 0, &dw_bytes_returned, NULL); if ( ! b_success ) { char *psz_msg = NULL; @@ -254,7 +307,67 @@ audio_set_volume_win32ioctl (void *p_user_data, bool b_success = DeviceIoControl(p_env->h_device_handle, IOCTL_CDROM_SET_VOLUME, p_volume, (DWORD) sizeof(cdio_audio_volume_t), - NULL, 0, &dw_bytes_returned, 0); + NULL, 0, &dw_bytes_returned, NULL); + + if ( ! b_success ) { + char *psz_msg = NULL; + long int i_err = GetLastError(); + FORMAT_ERROR(i_err, psz_msg); + if (psz_msg) + cdio_info("Error: %s", psz_msg); + else + cdio_info("Error: %ld", i_err); + LocalFree(psz_msg); + return DRIVER_OP_ERROR; + } + return DRIVER_OP_SUCCESS; +} + +/*! + Stop playing an audio CD. + + @param p_user_data the CD object to be acted upon. + +*/ +driver_return_code_t +audio_stop_win32ioctl (void *p_user_data) +{ + const _img_private_t *p_env = p_user_data; + DWORD dw_bytes_returned; + + bool b_success = + DeviceIoControl(p_env->h_device_handle, IOCTL_CDROM_STOP_AUDIO, + NULL, (DWORD) 0, NULL, 0, &dw_bytes_returned, NULL); + + if ( ! b_success ) { + char *psz_msg = NULL; + long int i_err = GetLastError(); + FORMAT_ERROR(i_err, psz_msg); + if (psz_msg) + cdio_info("Error: %s", psz_msg); + else + cdio_info("Error: %ld", i_err); + LocalFree(psz_msg); + return DRIVER_OP_ERROR; + } + return DRIVER_OP_SUCCESS; +} + +/*! + Close the tray of a CD-ROM + + @param p_user_data the CD object to be acted upon. + +*/ +driver_return_code_t +close_tray_win32ioctl (void *p_user_data) +{ + const _img_private_t *p_env = p_user_data; + DWORD dw_bytes_returned; + + bool b_success = + DeviceIoControl(p_env->h_device_handle, IOCTL_STORAGE_LOAD_MEDIA2, + NULL, (DWORD) 0, NULL, 0, &dw_bytes_returned, NULL); if ( ! b_success ) { char *psz_msg = NULL;