]> git.sesse.net Git - vlc/blob - src/interface/intf_eject.c
intf_Eject: remove unused MacOS support
[vlc] / src / interface / intf_eject.c
1 /*****************************************************************************
2  * intf_eject.c: CD/DVD-ROM ejection handling functions
3  *****************************************************************************
4  * Copyright (C) 2001-2004 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Julien Blache <jb@technologeek.org> for the Linux part
8  *                with code taken from the Linux "eject" command
9  *          Jon Lech Johansen <jon-vl@nanocrew.net> for Darwin
10  *          Gildas Bazin <gbazin@netcourrier.com> for Win32
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  *****************************************************************************/
26
27 /**
28  *  \file
29  *  This file contain functions to eject CD and DVD drives
30  */
31
32 #ifdef HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #include <vlc_common.h>
37 #include <vlc_fs.h>
38 #include <vlc_interface.h>
39
40 #if defined( WIN32 ) && !defined( UNDER_CE )
41 #   include <mmsystem.h>
42 #elif defined(__linux__)
43 #   include <sys/types.h>
44 #   include <unistd.h>
45 #   include <fcntl.h>
46 #   include <sys/ioctl.h>
47 #   include <sys/mount.h>
48
49 #   include <linux/cdrom.h>
50
51 #   include <scsi/scsi.h>
52 #   include <scsi/sg.h>
53 #   include <scsi/scsi_ioctl.h>
54 #elif defined (HAVE_DVD_H)
55 #   include <unistd.h>
56 #   include <fcntl.h>
57 #   include <dvd.h>
58 #endif
59
60 #if defined(__linux__)
61 /**
62  * \brief Ejects the CD /DVD using SCSI commands
63  * \ingroup vlc_interface
64  * This function is local
65  * \param i_fd a device nummber
66  * \return 0 on success, VLC_EGENERIC on failure
67  */
68 static int EjectSCSI( int i_fd )
69 {
70     struct sdata
71     {
72         int  inlen;
73         int  outlen;
74         char cmd[256];
75     } scsi_cmd;
76
77     scsi_cmd.inlen  = 0;
78     scsi_cmd.outlen = 0;
79     scsi_cmd.cmd[0] = ALLOW_MEDIUM_REMOVAL;
80     scsi_cmd.cmd[1] = 0;
81     scsi_cmd.cmd[2] = 0;
82     scsi_cmd.cmd[3] = 0;
83     scsi_cmd.cmd[4] = 0;
84     scsi_cmd.cmd[5] = 0;
85     if( ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd ) < 0 )
86         return VLC_EGENERIC;
87
88     scsi_cmd.inlen  = 0;
89     scsi_cmd.outlen = 0;
90     scsi_cmd.cmd[0] = START_STOP;
91     scsi_cmd.cmd[1] = 0;
92     scsi_cmd.cmd[2] = 0;
93     scsi_cmd.cmd[3] = 0;
94     scsi_cmd.cmd[4] = 1;
95     scsi_cmd.cmd[5] = 0;
96     if( ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd ) < 0 )
97         return VLC_EGENERIC;
98
99     scsi_cmd.inlen  = 0;
100     scsi_cmd.outlen = 0;
101     scsi_cmd.cmd[0] = START_STOP;
102     scsi_cmd.cmd[1] = 0;
103     scsi_cmd.cmd[2] = 0;
104     scsi_cmd.cmd[3] = 0;
105     scsi_cmd.cmd[4] = 2;
106     scsi_cmd.cmd[5] = 0;
107     if( ioctl( i_fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd ) < 0 )
108         return VLC_EGENERIC;
109
110     /* Force kernel to reread partition table when new disc inserted */
111     ioctl( i_fd, BLKRRPART );
112     return VLC_SUCCESS;
113 }
114 #endif
115
116 #undef intf_Eject
117 /**
118  * \brief Ejects the CD /DVD
119  * \ingroup vlc_interface
120  * \param p_this the calling vlc_object_t
121  * \param psz_device the CD/DVD to eject
122  * \return 0 on success, 1 on failure, -1 if not implemented
123  */
124 int intf_Eject( vlc_object_t *p_this, const char *psz_device )
125 {
126     VLC_UNUSED(p_this);
127
128 #if defined(WIN32)
129     MCI_OPEN_PARMS op;
130     DWORD i_flags;
131     char psz_drive[4];
132
133     memset( &op, 0, sizeof(MCI_OPEN_PARMS) );
134     op.lpstrDeviceType = (LPCSTR)MCI_DEVTYPE_CD_AUDIO;
135
136     strcpy( psz_drive, "X:" );
137     psz_drive[0] = psz_device[0];
138     op.lpstrElementName = psz_drive;
139
140     /* Set the flags for the device type */
141     i_flags = MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID |
142               MCI_OPEN_ELEMENT | MCI_OPEN_SHAREABLE;
143
144     if( mciSendCommand( 0, MCI_OPEN, i_flags, (uintptr_t)&op ) )
145         return VLC_EGENERIC;
146
147     /* Eject disc */
148     mciSendCommand( op.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0 );
149     /* Release access to the device */
150     mciSendCommand( op.wDeviceID, MCI_CLOSE, MCI_WAIT, 0 );
151
152     return VLC_SUCCESS;
153
154 #elif defined (__linux__) || defined (HAVE_DVD_H)
155     /* This code could be extended to support CD/DVD-ROM chargers */
156     int fd = vlc_open( psz_device, O_RDONLY | O_NONBLOCK );
157     if( fd == -1 )
158     {
159         msg_Err( p_this, "could not open device %s", psz_device );
160         return VLC_EGENERIC;
161     }
162
163 # if defined(__linux__)
164     /* Try a simple ATAPI eject */
165     if( ioctl( fd, CDROMEJECT, 0 ) < 0
166      && EjectSCSI( fd ) )
167 # else
168     if( ioctl( fd, CDROMEJECT, 0 ) < 0 )
169 # endif
170     {
171         msg_Err( p_this, "could not eject %s", psz_device );
172         close( fd );
173         return VLC_EGENERIC;
174     }
175     return VLC_SUCCESS;
176
177 #else
178     msg_Warn( p_this, "CD-Rom ejection unsupported on this platform" );
179     return VLC_EGENERIC;
180 #endif
181 }