DrvHostDVD.cpp revision 1e1273b11e17928ec3c3a8fff45121aa7a169413
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * DrvHostDVD - Host DVD block driver.
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * Copyright (C) 2006-2012 Oracle Corporation
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * available from http://www.virtualbox.org. This file is free software;
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * you can redistribute it and/or modify it under the terms of the GNU
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * General Public License (GPL) as published by the Free Software
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync/*******************************************************************************
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync* Header Files *
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync*******************************************************************************/
ef78fcbc798650f56698f8978bd4194fcfc55a78vboxsync# include <IOKit/storage/IOStorageDeviceCharacteristics.h>
ef78fcbc798650f56698f8978bd4194fcfc55a78vboxsync/* nothing (yet). */
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync/* All the following crap is apparently not necessary anymore since Linux
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * version 2.6.29. */
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync/* This is a hack to work around conflicts between these linux kernel headers
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync * and the GLIBC tcpip headers. They have different declarations of the 4
32d32b685d3e1763aedbad8b3680e5ad562f2314vboxsync * standard byte order functions. */
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync/* This is another hack for not bothering with C++ unfriendly byteswap macros. */
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync/* Those macros that are needed are defined in the header below. */
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync# define _interlockedbittestandset they_messed_it_up_in_winnt_h_this_time_sigh__interlockedbittestandset
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync# define _interlockedbittestandreset they_messed_it_up_in_winnt_h_this_time_sigh__interlockedbittestandreset
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync# define _interlockedbittestandset64 they_messed_it_up_in_winnt_h_this_time_sigh__interlockedbittestandset64
1b9094e9e0e2b6dc15ba937a7d4b14736aea339evboxsync# define _interlockedbittestandreset64 they_messed_it_up_in_winnt_h_this_time_sigh__interlockedbittestandreset64
#ifdef VBOX_WITH_SUID_WRAPPER
static int solarisCheckUserAuth();
if (fEject)
if (rc < 0)
if (rc < 0)
rc = RTFileOpen(&hFileDevice, pThis->pszDeviceOpen, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
NULL, 0,
NULL))
return rc;
if (rc < 0)
if (rc < 0)
int rc;
NULL))
return rc;
#ifdef RT_OS_LINUX
#ifdef USE_MEDIA_POLLING
#ifdef RT_OS_DARWIN
bool fMediaChanged = false;
bool fMediaPresent = false;
int rc2 = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, abSense, sizeof(abSense), 0);
fMediaPresent = true;
fMediaPresent = false;
fMediaChanged = true;
bool fMediaPresent = ioctl(RTFileToNative(pThis->hFileDevice), CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK;
bool fMediaPresent = false;
bool fMediaChanged = false;
if (rc2 == 0)
fMediaChanged = true;
if (fMediaPresent)
else if (fMediaPresent)
bool fMediaChanged = ioctl(RTFileToNative(pThis->hFileDevice), CDROM_MEDIA_CHANGED, CDSL_CURRENT) == 1;
if (fMediaChanged)
return rc;
int rc;
LogFlow(("%s: cmd[0]=%#04x txdir=%d pcbBuf=%d timeout=%d\n", __FUNCTION__, pbCmd[0], enmTxDir, *pcbBuf, cTimeoutMillies));
rc = DRVHostBaseScsiCmd(pThis, pbCmd, 12, PDMBLOCKTXDIR_FROM_DEVICE, pvBuf, pcbBuf, pabSense, cbSense, cTimeoutMillies);
int direction;
switch (enmTxDir)
case PDMBLOCKTXDIR_NONE:
case PDMBLOCKTXDIR_TO_DEVICE:
if (rc < 0)
switch (enmTxDir)
switch (enmTxDir)
case PDMBLOCKTXDIR_NONE:
case PDMBLOCKTXDIR_TO_DEVICE:
#ifdef VBOX_WITH_SUID_WRAPPER
#ifdef VBOX_WITH_SUID_WRAPPER
if (rc < 0)
return VERR_PERMISSION_DENIED;
Log2(("%s: after ioctl: residual buflen=%d original buflen=%d\n", __FUNCTION__, usc.uscsi_resid, usc.uscsi_buflen));
int direction;
struct _REQ
} Req;
switch (enmTxDir)
case PDMBLOCKTXDIR_NONE:
case PDMBLOCKTXDIR_TO_DEVICE:
Log2(("%s: scsistatus=%d bytes returned=%d tlength=%d\n", __FUNCTION__, Req.spt.ScsiStatus, cbReturned, Req.spt.DataTransferLength));
return rc;
#ifdef VBOX_WITH_SUID_WRAPPER
# ifdef RT_OS_SOLARIS
static int solarisCheckUserAuth()
return VERR_PERMISSION_DENIED;
return VINF_SUCCESS;
if (*pEffUserID != 0)
if (seteuid(0) == 0)
*pEffUserID = 0;
return VINF_SUCCESS;
return VERR_PERMISSION_DENIED;
return VINF_SUCCESS;
if (*pEffUserID == 0)
return VINF_SUCCESS;
return VERR_PERMISSION_DENIED;
return VINF_SUCCESS;
#ifdef RT_OS_LINUX
if (CFGMR3AreValuesValid(pCfg, "Path\0Interval\0Locked\0BIOSVisible\0AttachFailError\0Passthrough\0"))
#ifdef RT_OS_LINUX
return VERR_NO_MEMORY;
bool fPassthrough;
return rc;
#ifdef USE_MEDIA_POLLING
if (!fPassthrough)
#ifdef RT_OS_LINUX
return rc;
sizeof(DRVHOSTBASE),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,