00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00032 #include <vlc/vlc.h>
00033
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036
00037 #ifdef HAVE_UNISTD_H
00038 # include <unistd.h>
00039 #endif
00040
00041 #include <string.h>
00042
00043 #ifdef HAVE_FCNTL_H
00044 # include <fcntl.h>
00045 #endif
00046
00047 #ifdef HAVE_DVD_H
00048 # include <dvd.h>
00049 #endif
00050
00051 #if defined(SYS_LINUX) && defined(HAVE_LINUX_VERSION_H)
00052 # include <linux/version.h>
00053
00054 # ifndef KERNEL_VERSION
00055 # define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
00056 # endif
00057
00058 # include <sys/types.h>
00059 # include <sys/stat.h>
00060 # include <sys/ioctl.h>
00061
00062 # include <sys/ioctl.h>
00063 # include <sys/mount.h>
00064
00065 # include <linux/cdrom.h>
00066 # if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
00067 # include <linux/ucdrom.h>
00068 # endif
00069
00070 # include <scsi/scsi.h>
00071 # include <scsi/sg.h>
00072 # include <scsi/scsi_ioctl.h>
00073 #endif
00074
00075 #if defined( WIN32 ) && !defined( UNDER_CE )
00076 # include <mmsystem.h>
00077 #endif
00078
00079
00080
00081
00082 #if defined(SYS_LINUX) && defined(HAVE_LINUX_VERSION_H)
00083 static int EjectSCSI ( int i_fd );
00084 #endif
00085
00086
00087
00088
00089
00090
00091
00092
00100 int __intf_Eject( vlc_object_t *p_this, const char *psz_device )
00101 {
00102 int i_ret = VLC_SUCCESS;
00103
00104 #ifdef SYS_DARWIN
00105 FILE *p_eject;
00106 char *psz_disk;
00107 char sz_cmd[32];
00108
00109
00110
00111
00112
00113
00114
00115
00116 if( ( psz_disk = (char *)strstr( psz_device, "disk" ) ) != NULL &&
00117 strlen( psz_disk ) > 4 )
00118 {
00119 #define EJECT_CMD "/usr/sbin/disktool -e %s 0"
00120 snprintf( sz_cmd, sizeof(sz_cmd), EJECT_CMD, psz_disk );
00121 #undef EJECT_CMD
00122
00123 if( ( p_eject = popen( sz_cmd, "r" ) ) != NULL )
00124 {
00125 char psz_result[0x200];
00126 i_ret = fread( psz_result, 1, sizeof(psz_result) - 1, p_eject );
00127
00128 if( i_ret == 0 && ferror( p_eject ) != 0 )
00129 {
00130 pclose( p_eject );
00131 return VLC_EGENERIC;
00132 }
00133
00134 pclose( p_eject );
00135
00136 psz_result[ i_ret ] = 0;
00137
00138 if( strstr( psz_result, "Disk Ejected" ) != NULL )
00139 {
00140 return VLC_SUCCESS;
00141 }
00142 }
00143 }
00144
00145 return VLC_EGENERIC;
00146
00147 #elif defined(UNDER_CE)
00148 msg_Warn( p_this, "CD-Rom ejection unsupported on this platform" );
00149 return i_ret;
00150
00151 #elif defined(WIN32)
00152 MCI_OPEN_PARMS op;
00153 MCI_STATUS_PARMS st;
00154 DWORD i_flags;
00155 char psz_drive[4];
00156
00157 memset( &op, 0, sizeof(MCI_OPEN_PARMS) );
00158 op.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_CD_AUDIO;
00159
00160 strcpy( psz_drive, "X:" );
00161 psz_drive[0] = psz_device[0];
00162 op.lpstrElementName = psz_drive;
00163
00164
00165 i_flags = MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID |
00166 MCI_OPEN_ELEMENT | MCI_OPEN_SHAREABLE;
00167
00168 if( !mciSendCommand( 0, MCI_OPEN, i_flags, (unsigned long)&op ) )
00169 {
00170 st.dwItem = MCI_STATUS_READY;
00171
00172 i_ret = mciSendCommand( op.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0 );
00173
00174 mciSendCommand( op.wDeviceID, MCI_CLOSE, MCI_WAIT, 0 );
00175 }
00176 else i_ret = VLC_EGENERIC;
00177
00178 return i_ret;
00179 #else
00180
00181 int i_fd;
00182
00183
00184
00185 i_fd = open( psz_device, O_RDONLY | O_NONBLOCK );
00186
00187 if( i_fd == -1 )
00188 {
00189 msg_Err( p_this, "could not open device %s", psz_device );
00190 return VLC_EGENERIC;
00191 }
00192
00193 #if defined(SYS_LINUX) && defined(HAVE_LINUX_VERSION_H)
00194
00195 i_ret = ioctl( i_fd, CDROMEJECT, 0 );
00196
00197 if( i_ret != 0 )
00198 {
00199 i_ret = EjectSCSI( i_fd );
00200 }
00201
00202 if( i_ret != 0 )
00203 {
00204 msg_Err( p_this, "could not eject %s", psz_device );
00205 }
00206
00207 #elif defined (HAVE_DVD_H)
00208 i_ret = ioctl( i_fd, CDROMEJECT, 0 );
00209
00210 #else
00211 msg_Warn( p_this, "CD-Rom ejection unsupported on this platform" );
00212 i_ret = -1;
00213
00214 #endif
00215 close( i_fd );
00216
00217 return i_ret;
00218 #endif
00219 }
00220
00221
00222
00223 #if defined(SYS_LINUX) && defined(HAVE_LINUX_VERSION_H)
00224
00225
00226
00234 static int EjectSCSI( int i_fd )
00235 {
00236 int i_status;
00237
00238 struct sdata
00239 {
00240 int inlen;
00241 int outlen;
00242 char cmd[256];
00243 } scsi_cmd;
00244
00245 scsi_cmd.inlen = 0;
00246 scsi_cmd.outlen = 0;
00247 scsi_cmd.cmd[0] = ALLOW_MEDIUM_REMOVAL;
00248 scsi_cmd.cmd[1] = 0;
00249 scsi_cmd.cmd[2] = 0;
00250 scsi_cmd.cmd[3] = 0;
00251 scsi_cmd.cmd[4] = 0;
00252 scsi_cmd.cmd[5] = 0;
00253 i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
00254 if( i_status != 0 )
00255 {
00256 return VLC_EGENERIC;
00257 }
00258
00259 scsi_cmd.inlen = 0;
00260 scsi_cmd.outlen = 0;
00261 scsi_cmd.cmd[0] = START_STOP;
00262 scsi_cmd.cmd[1] = 0;
00263 scsi_cmd.cmd[2] = 0;
00264 scsi_cmd.cmd[3] = 0;
00265 scsi_cmd.cmd[4] = 1;
00266 scsi_cmd.cmd[5] = 0;
00267 i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
00268 if( i_status != 0 )
00269 {
00270 return VLC_EGENERIC;
00271 }
00272
00273 scsi_cmd.inlen = 0;
00274 scsi_cmd.outlen = 0;
00275 scsi_cmd.cmd[0] = START_STOP;
00276 scsi_cmd.cmd[1] = 0;
00277 scsi_cmd.cmd[2] = 0;
00278 scsi_cmd.cmd[3] = 0;
00279 scsi_cmd.cmd[4] = 2;
00280 scsi_cmd.cmd[5] = 0;
00281 i_status = ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd );
00282 if( i_status != 0 )
00283 {
00284 return VLC_EGENERIC;
00285 }
00286
00287
00288 i_status = ioctl( i_fd, BLKRRPART );
00289
00290 return i_status;
00291 }
00292 #endif
00293