X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Finterface%2Fintf_eject.c;h=98f95d407c232934d5d30d6b47e6a3541cb0b2a2;hb=412774e9577174b4b975522dcbff8a6522cdecab;hp=0f7232db73876a998d18981632b7c4a780d3669b;hpb=7db2e6fa77ee48d9efb91d4965a0ad42859b6f68;p=vlc diff --git a/src/interface/intf_eject.c b/src/interface/intf_eject.c index 0f7232db73..98f95d407c 100644 --- a/src/interface/intf_eject.c +++ b/src/interface/intf_eject.c @@ -1,11 +1,13 @@ /***************************************************************************** * intf_eject.c: CD/DVD-ROM ejection handling functions ***************************************************************************** - * Copyright (C) 2001, 2002 VideoLAN - * $Id: intf_eject.c,v 1.4 2002/01/12 02:02:44 jlj Exp $ + * Copyright (C) 2001-2004 the VideoLAN team + * $Id$ * - * Author: Julien Blache for the Linux part - * with code taken from the Linux "eject" command + * Authors: Julien Blache for the Linux part + * with code taken from the Linux "eject" command + * Jon Lech Johansen for Darwin + * Gildas Bazin for Win32 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,15 +21,23 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include -#include -#include -#include +/** + * \file + * This file contain functions to eject CD and DVD drives + */ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#ifdef HAVE_UNISTD_H +# include +#endif #ifdef HAVE_FCNTL_H # include @@ -37,7 +47,7 @@ # include #endif -#ifdef SYS_LINUX +#if defined(__linux__) && defined(HAVE_LINUX_VERSION_H) # include /* handy macro found in 2.1 kernels, but not in older ones */ # ifndef KERNEL_VERSION @@ -45,41 +55,48 @@ # endif # include -# include # include # include +# include + # include # if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) # include # endif -# include # include # include # include #endif +#if defined( WIN32 ) && !defined( UNDER_CE ) +# include +#endif + +#include + /***************************************************************************** * Local prototypes *****************************************************************************/ -#ifdef SYS_LINUX +#if defined(__linux__) && defined(HAVE_LINUX_VERSION_H) static int EjectSCSI ( int i_fd ); #endif -/***************************************************************************** - * intf_Eject: eject the CDRom - ***************************************************************************** - * returns 0 on success - * returns 1 on failure - * returns -1 if not implemented - *****************************************************************************/ -int intf_Eject( const char *psz_device ) +#undef intf_Eject +/** + * \brief Ejects the CD /DVD + * \ingroup vlc_interface + * \param p_this the calling vlc_object_t + * \param psz_device the CD/DVD to eject + * \return 0 on success, 1 on failure, -1 if not implemented + */ +int intf_Eject( vlc_object_t *p_this, const char *psz_device ) { - int i_fd; - int i_ret; + VLC_UNUSED(p_this); + int i_ret = VLC_SUCCESS; -#ifdef SYS_DARWIN +#ifdef __APPLE__ FILE *p_eject; char *psz_disk; char sz_cmd[32]; @@ -88,49 +105,85 @@ int intf_Eject( const char *psz_device ) * The only way to cleanly unmount the disc under MacOS X * is to use the 'disktool' command line utility. It uses * the non-public Disk Arbitration API, which can not be - * used by Cocoa or Carbon applications. + * used by Cocoa or Carbon applications. */ if( ( psz_disk = (char *)strstr( psz_device, "disk" ) ) != NULL && strlen( psz_disk ) > 4 ) { -#define EJECT_CMD "disktool -e %s 0" +#define EJECT_CMD "/usr/sbin/disktool -e %s 0" snprintf( sz_cmd, sizeof(sz_cmd), EJECT_CMD, psz_disk ); #undef EJECT_CMD if( ( p_eject = popen( sz_cmd, "r" ) ) != NULL ) { char psz_result[0x200]; - i_ret = fread( psz_result, 1, sizeof(psz_result), p_eject ); - pclose( p_eject ); + i_ret = fread( psz_result, 1, sizeof(psz_result) - 1, p_eject ); if( i_ret == 0 && ferror( p_eject ) != 0 ) { - return 1; + pclose( p_eject ); + return VLC_EGENERIC; } + pclose( p_eject ); + + psz_result[ i_ret ] = 0; + if( strstr( psz_result, "Disk Ejected" ) != NULL ) { - return 0; + return VLC_SUCCESS; } } } - return 1; + return VLC_EGENERIC; -#endif +#elif defined(UNDER_CE) + msg_Warn( p_this, "CD-Rom ejection unsupported on this platform" ); + return i_ret; + +#elif defined(WIN32) + MCI_OPEN_PARMS op; + DWORD i_flags; + char psz_drive[4]; + + memset( &op, 0, sizeof(MCI_OPEN_PARMS) ); + op.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_CD_AUDIO; + + strcpy( psz_drive, "X:" ); + psz_drive[0] = psz_device[0]; + op.lpstrElementName = psz_drive; + + /* Set the flags for the device type */ + i_flags = MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | + MCI_OPEN_ELEMENT | MCI_OPEN_SHAREABLE; + + if( !mciSendCommand( 0, MCI_OPEN, i_flags, (uintptr_t)&op ) ) + { + /* Eject disc */ + i_ret = mciSendCommand( op.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0 ); + /* Release access to the device */ + mciSendCommand( op.wDeviceID, MCI_CLOSE, MCI_WAIT, 0 ); + } + else i_ret = VLC_EGENERIC; + + return i_ret; +#else /* WIN32 */ + + int i_fd; /* This code could be extended to support CD/DVD-ROM chargers */ i_fd = open( psz_device, O_RDONLY | O_NONBLOCK ); - + if( i_fd == -1 ) { - intf_ErrMsg( "intf error: couldn't open device %s", psz_device ); - return 1; + msg_Err( p_this, "could not open device %s", psz_device ); + return VLC_EGENERIC; } -#ifdef SYS_LINUX +#if defined(__linux__) && defined(HAVE_LINUX_VERSION_H) /* Try a simple ATAPI eject */ i_ret = ioctl( i_fd, CDROMEJECT, 0 ); @@ -141,28 +194,36 @@ int intf_Eject( const char *psz_device ) if( i_ret != 0 ) { - intf_ErrMsg( "intf error: couldn't eject %s", psz_device ); + msg_Err( p_this, "could not eject %s", psz_device ); } #elif defined (HAVE_DVD_H) i_ret = ioctl( i_fd, CDROMEJECT, 0 ); #else - intf_ErrMsg( "intf error: CD-Rom ejection unsupported on this platform" ); + msg_Warn( p_this, "CD-ROM ejection unsupported on this platform" ); i_ret = -1; #endif close( i_fd ); return i_ret; +#endif } /* The following functions are local */ -#ifdef SYS_LINUX +#if defined(__linux__) && defined(HAVE_LINUX_VERSION_H) /***************************************************************************** * Eject using SCSI commands. Return 0 if successful *****************************************************************************/ +/** + * \brief Ejects the CD /DVD using SCSI commands + * \ingroup vlc_interface + * This function is local + * \param i_fd a device nummber + * \return 0 on success, VLC_EGENERIC on failure + */ static int EjectSCSI( int i_fd ) { int i_status; @@ -185,7 +246,7 @@ static int EjectSCSI( int i_fd ) i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd ); if( i_status != 0 ) { - return 1; + return VLC_EGENERIC; } scsi_cmd.inlen = 0; @@ -199,9 +260,9 @@ static int EjectSCSI( int i_fd ) i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd ); if( i_status != 0 ) { - return 1; + return VLC_EGENERIC; } - + scsi_cmd.inlen = 0; scsi_cmd.outlen = 0; scsi_cmd.cmd[0] = START_STOP; @@ -213,12 +274,12 @@ static int EjectSCSI( int i_fd ) i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd ); if( i_status != 0 ) { - return 1; + return VLC_EGENERIC; } - + /* Force kernel to reread partition table when new disc inserted */ i_status = ioctl( i_fd, BLKRRPART ); - + return i_status; } #endif