VirtualBox

Changeset 5184 in vbox


Ignore:
Timestamp:
Oct 8, 2007 1:23:33 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
25105
Message:

Solaris.

Location:
trunk/src/VBox/Devices
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Builtins.cpp

    r5126 r5184  
    157157        return rc;
    158158#endif
    159 #if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_WINDOWS)
     159#if defined(RT_OS_DARWIN) || defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS)
    160160    rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvHostDVD);
    161161    if (VBOX_FAILURE(rc))
  • trunk/src/VBox/Devices/Makefile.kmk

    r5126 r5184  
    1414#  distribution. VirtualBox OSE is distributed in the hope that it will
    1515#  be useful, but WITHOUT ANY WARRANTY of any kind.
     16#
    1617
    1718DEPTH = ../../..
     
    450451        , $(Drivers_SOURCES))
    451452Drivers_SOURCES.solaris = \
    452     Network/DrvTAP.cpp
     453        Network/DrvTAP.cpp \
     454        Storage/DrvHostBase.cpp \
     455        Storage/DrvHostDVD.cpp
    453456endif
    454457
  • trunk/src/VBox/Devices/Storage/DrvHostBase.cpp

    r5126 r5184  
    4545# include <fcntl.h>
    4646# include <errno.h>
     47# include <stropts.h>
     48# include <sys/dkio.h>
    4749
    4850#elif defined(RT_OS_WINDOWS)
     
    918920    return rc;
    919921
    920 #elif defined(RT_OS_LINUX)
     922#elif defined(RT_OS_LINUX) || defined(RT_OS_SOLARIS)
    921923    /** @todo we've got RTFILE_O_NON_BLOCK now. Change the code to use RTFileOpen. */
    922924    int FileDevice = open(pThis->pszDeviceOpen, (pThis->fReadOnlyConfig ? O_RDONLY : O_RDWR) | O_NONBLOCK);
     
    10131015    }
    10141016    return rc;
     1017
     1018#elif defined(RT_OS_SOLARIS)
     1019    /*
     1020     * Sun docs suggests using DKIOCGGEOM instead of DKIOCGMEDIAINFO, but
     1021     * Sun themselves use DKIOCGMEDIAINFO for DVDs/CDs, and use DKIOCGGEOM
     1022     * for secondary storage devices.
     1023     */
     1024    struct dk_minfo MediaInfo;
     1025    if (ioctl(pThis->FileDevice, DKIOCGMEDIAINFO, &MediaInfo) == 0)
     1026    {
     1027        *pcb = MediaInfo.dki_capacity * (uint64_t)MediaInfo.dki_lbsize;
     1028        return VINF_SUCCESS;
     1029    }
     1030    return RTFileSeek(pThis->FileDevice, 0, RTFILE_SEEK_END, pcb);
    10151031
    10161032#elif defined(RT_OS_WINDOWS)
  • trunk/src/VBox/Devices/Storage/DrvHostDVD.cpp

    r5085 r5184  
    5252# define USE_MEDIA_POLLING
    5353
     54#elif defined(RT_OS_SOLARIS)
     55# include <stropts.h>
     56# include <fcntl.h>
     57# include <ctype.h>
     58# include <errno.h>
     59# include <pwd.h>
     60# include <unistd.h>
     61# include <auth_attr.h>
     62# include <sys/dkio.h>
     63# include <sys/sockio.h>
     64# include <sys/scsi/scsi.h>
     65# define USE_MEDIA_POLLING
     66
    5467#elif defined(RT_OS_WINDOWS)
    5568# include <Windows.h>
     
    117130                 rc = RTErrConvertFromErrno(errno);
    118131         }
     132
     133#elif defined(RT_OS_SOLARIS)
     134        rc = ioctl(pThis->FileDevice, DKIOCEJECT, 0);
     135        if (rc < 0)
     136        {
     137            if (errno == EBUSY)
     138                rc = VERR_PDM_MEDIA_LOCKED;
     139            else if (errno == ENOSYS || errno == ENOTSUP)
     140                rc = VERR_NOT_SUPPORTED;
     141            else if (errno == ENODEV)
     142                rc = VERR_PDM_MEDIA_NOT_MOUNTED;
     143            else
     144                rc = RTErrConvertFromErrno(errno);
     145        }
    119146
    120147#elif defined(RT_OS_WINDOWS)
     
    188215            rc = VERR_ACCESS_DENIED;
    189216        else if (errno == EDRIVE_CANT_DO_THIS)
     217            rc = VERR_NOT_SUPPORTED;
     218        else
     219            rc = RTErrConvertFromErrno(errno);
     220    }
     221
     222#elif defined(RT_OS_SOLARIS)
     223    int rc = ioctl(pThis->FileDevice, fLock ? DKIOCLOCK : DKIOCUNLOCK, 0);
     224    if (rc < 0)
     225    {
     226        if (errno == EBUSY)
     227            rc = VERR_ACCESS_DENIED;
     228        else if (errno == ENOTSUP || errno == ENOSYS)
    190229            rc = VERR_NOT_SUPPORTED;
    191230        else
     
    281320    bool fMediaPresent = ioctl(pThis->FileDevice, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK;
    282321
     322#elif defined(RT_OS_SOLARIS)
     323    bool fMediaPresent = false;
     324    bool fMediaChanged = false;
     325
     326    /* Need to pass the previous state and DKIO_NONE for the first time. */
     327    static dkio_state DeviceState = DKIO_NONE;
     328    int rc2 = ioctl(pThis->FileDevice, DKIOCSTATE, &DeviceState);
     329    if (rc2 == 0)
     330    {
     331        fMediaPresent = DeviceState == DKIO_INSERTED;
     332        if (pThis->fMediaPresent != fMediaPresent || !fMediaPresent)
     333            fMediaChanged = true;   /** @todo find proper way to detect media change. */
     334    }
     335
    283336#else
    284337# error "Unsupported platform."
     
    302355         * Poll for media change.
    303356         */
    304 #ifdef RT_OS_DARWIN
     357#if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS)
    305358        /* taken care of above. */
    306359#elif defined(RT_OS_LINUX)
     
    411464     * it's 0). So just assume that everything worked ok. */
    412465
     466#elif defined(RT_OS_SOLARIS)
     467    struct uscsi_cmd usc;
     468    union scsi_cdb scdb;
     469    memset(&usc, 0, sizeof(struct uscsi_cmd));
     470    memset(&scdb, 0, sizeof(scdb));
     471
     472    switch (enmTxDir)
     473    {
     474        case PDMBLOCKTXDIR_NONE:
     475            Assert(*pcbBuf == 0);
     476            usc.uscsi_flags = USCSI_READ;
     477            /* nothing to do */
     478            break;
     479
     480        case PDMBLOCKTXDIR_FROM_DEVICE:
     481            Assert(*pcbBuf != 0);
     482            /* Make sure that the buffer is clear for commands reading
     483             * data. The actually received data may be shorter than what
     484             * we expect, and due to the unreliable feedback about how much
     485             * data the ioctl actually transferred, it's impossible to
     486             * prevent that. Returning previous buffer contents may cause
     487             * security problems inside the guest OS, if users can issue
     488             * commands to the CDROM device. */
     489            memset(pvBuf, '\0', *pcbBuf);
     490            usc.uscsi_flags = USCSI_READ;
     491            break;
     492        case PDMBLOCKTXDIR_TO_DEVICE:
     493            Assert(*pcbBuf != 0);
     494            usc.uscsi_flags = USCSI_WRITE;
     495            break;
     496        default:
     497            AssertMsgFailedReturn(("%d\n", enmTxDir), VERR_INTERNAL_ERROR);
     498    }
     499    char aSense[32];
     500    usc.uscsi_flags |= USCSI_RQENABLE;
     501    usc.uscsi_rqbuf = aSense;
     502    usc.uscsi_rqlen = 32;
     503    usc.uscsi_cdb = (caddr_t)&scdb;
     504    usc.uscsi_cdblen = 12;
     505    memcpy (usc.uscsi_cdb, pbCmd, usc.uscsi_cdblen);
     506    usc.uscsi_bufaddr = (caddr_t)pvBuf;
     507    usc.uscsi_buflen = *pcbBuf;
     508    usc.uscsi_timeout = (cTimeoutMillies + 999) / 1000;
     509
     510    /* We need root privileges for user-SCSI under Solaris. */
     511    rc = ioctl(pThis->FileDevice, USCSICMD, &usc);
     512    if (rc < 0)
     513    {
     514        if (errno == EPERM)
     515            return VERR_PERMISSION_DENIED;
     516        if (usc.uscsi_status)
     517        {
     518            *pbStat = aSense[2] & 0x0f;
     519            rc = RTErrConvertFromErrno(errno);
     520            Log2(("%s: error status. rc=%Vrc\n", __FUNCTION__, rc));
     521        }
     522        else
     523            *pbStat = 0;
     524    }
     525    Log2(("%s: after ioctl: residual buflen=%d original buflen=%d\n", __FUNCTION__, usc.uscsi_resid, usc.uscsi_buflen));
     526
    413527#elif defined(RT_OS_WINDOWS)
    414528    int direction;
     
    476590}
    477591
     592#if 0
     593/* These functions would have to go into a seperate solaris binary with
     594 * the setuid permission set, which would run the user-SCSI ioctl and
     595 * return the value. BUT... this might be prohibitively slow.
     596 */
     597#ifdef RT_OS_SOLARIS
     598/**
     599 * Checks if the current user is authorized using Solaris' role-based access control.
     600 * Made as a seperate function with so that it need not be invoked each time we need
     601 * to gain root access.
     602 *
     603 * @returns VBox error code.
     604 */
     605static int solarisCheckUserAuth()
     606{
     607    /* Uses Solaris' role-based access control (RBAC).*/
     608    struct passwd *pPass = getpwuid(getuid());
     609    if (pPass == NULL || chkauthattr("solaris.device.cdrw", pPass->pw_name) == 0)
     610        return VERR_PERMISSION_DENIED;
     611
     612    return VINF_SUCCESS;
     613}
     614
     615/**
     616 * Setuid wrapper to gain root access.
     617 *
     618 * @returns VBox error code.
     619 * @param   pUserID        Pointer to user ID.
     620 * @param   pEffUserID     Pointer to effective user ID.
     621 */
     622static int solarisEnterRootMode(uid_t *pUserID, uid_t *pEffUserID)
     623{
     624    /* Increase privilege if required */
     625    if (*pEffUserID == 0)
     626        return VINF_SUCCESS;
     627    if (seteuid(0) == 0)
     628    {
     629        *pEffUserID = 0;
     630        return VINF_SUCCESS;
     631    }
     632    return VERR_PERMISSION_DENIED;
     633}
     634
     635/**
     636 * Setuid wrapper to relinquish root access.
     637 *
     638 * @returns VBox error code.
     639 * @param   pUserID        Pointer to user ID.
     640 * @param   pEffUserID     Pointer to effective user ID.
     641 */
     642static int solarisExitRootMode(uid_t *pUserID, uid_t *pEffUserID)
     643{
     644    /* Get back to user mode. */
     645    if (*pEffUserID == 0)
     646    {
     647        if (seteuid(*pUserID) == 0)
     648        {
     649            *pEffUserID = *pUserID;
     650            return VINF_SUCCESS;
     651        }
     652        return VERR_PERMISSION_DENIED;
     653    }
     654    return VINF_SUCCESS;
     655}
     656#endif   /* RT_OS_SOLARIS */
     657#endif
    478658
    479659/* -=-=-=-=- driver interface -=-=-=-=- */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette