DrvHostDVD.cpp revision 32e0bb0116ed4eef150d745394f806cba84ea7af
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * DrvHostDVD - Host DVD block driver.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * available from http://www.virtualbox.org. This file is free software;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * you can redistribute it and/or modify it under the terms of the GNU
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * General Public License (GPL) as published by the Free Software
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * additional information or have any questions.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/*******************************************************************************
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync* Header Files *
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync*******************************************************************************/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync# include <IOKit/storage/IOStorageDeviceCharacteristics.h>
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* nothing (yet). */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* This is a hack to work around conflicts between these linux kernel headers
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync * and the GLIBC tcpip headers. They have different declarations of the 4
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * standard byte order functions. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* This is another hack for not bothering with C++ unfriendly byteswap macros. */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync/* Those macros that are needed are defined in the header below */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* Forward declarations. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(int) drvHostDvdDoLock(PDRVHOSTBASE pThis, bool fLock);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** @copydoc PDMIMOUNT::pfnUnmount */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(int) drvHostDvdUnmount(PPDMIMOUNT pInterface, bool fForce)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDRVHOSTBASE pThis = PDMIMOUNT_2_DRVHOSTBASE(pInterface);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Validate state.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Unlock drive if necessary. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Eject the disc.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync SCSI_START_STOP_UNIT, 0, 0, 0, 2 /*eject+stop*/, 0,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync 0,0,0,0,0,0,0,0,0,0
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, NULL, 0, 0);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = RTFileOpen(&FileDevice, pThis->pszDeviceOpen, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync /* do ioctl */
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync if (DeviceIoControl((HANDLE)FileDevice, IOCTL_STORAGE_EJECT_MEDIA,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* clean up handle */
25747178cb66800d8386c20b8ffd87f78f24f4e5vboxsync AssertMsgFailed(("Failed to open '%s' for ejecting this tray.\n", rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Media is no longer present.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync DRVHostBaseMediaNotPresent(pThis); /** @todo This isn't thread safe! */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("drvHostDvdUnmount: returns %Rrc\n", rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Locks or unlocks the drive.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns VBox status code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pThis The instance data.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param fLock True if the request is to lock the drive, false if to unlock.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic DECLCALLBACK(int) drvHostDvdDoLock(PDRVHOSTBASE pThis, bool fLock)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL, 0, 0, 0, fLock, 0,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync 0,0,0,0,0,0,0,0,0,0
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, NULL, 0, 0);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc = ioctl(pThis->FileDevice, CDROM_LOCKDOOR, (int)fLock);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc = ioctl(pThis->FileRawDevice, fLock ? DKIOCLOCK : DKIOCUNLOCK, 0);
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync PREVENT_MEDIA_REMOVAL PreventMediaRemoval = {fLock};
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync if (DeviceIoControl((HANDLE)pThis->FileDevice, IOCTL_STORAGE_MEDIA_REMOVAL,
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync /** @todo figure out the return codes for already locked. */
4fcfe0bd966753617b7ab5fb81fb24709914fc1cvboxsync AssertMsgFailed(("Lock/Unlock is not implemented!\n"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("drvHostDvdDoLock(, fLock=%RTbool): returns %Rrc\n", fLock, rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Get the media size.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns VBox status code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pThis The instance data.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pcb Where to store the size.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncstatic int drvHostDvdGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Query the media size.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Clear the media-changed-since-last-call-thingy just to be on the safe side. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync ioctl(pThis->FileDevice, CDROM_MEDIA_CHANGED, CDSL_CURRENT);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync return RTFileSeek(pThis->FileDevice, 0, RTFILE_SEEK_END, pcb);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif /* RT_OS_LINUX */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Do media change polling.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncDECLCALLBACK(int) drvHostDvdPoll(PDRVHOSTBASE pThis)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Poll for media change.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync AssertReturn(pThis->ppScsiTaskDI, VERR_INTERNAL_ERROR);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Issue a TEST UNIT READY request.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync uint8_t abCmd[16] = { SCSI_TEST_UNIT_READY, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc2 = DRVHostBaseScsiCmd(pThis, abCmd, 6, PDMBLOCKTXDIR_NONE, NULL, NULL, abSense, sizeof(abSense), 0);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync && ( (abSense[12] == 0x29 && abSense[13] < 5 /* reset */)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || (abSense[12] == 0x2a && abSense[13] == 0 /* parameters changed */) //???
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync || (abSense[12] == 0x3f && abSense[13] == 0 /* target operating conditions have changed */) //???
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || (abSense[12] == 0x3f && abSense[13] == 2 /* changed operating definition */) //???
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || (abSense[12] == 0x3f && abSense[13] == 3 /* inquery parameters changed */)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync || (abSense[12] == 0x3f && abSense[13] == 5 /* device identifier changed */)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /** @todo check this media chance stuff on Darwin. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync bool fMediaPresent = ioctl(pThis->FileDevice, CDROM_DRIVE_STATUS, CDSL_CURRENT) == CDS_DISC_OK;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Need to pass the previous state and DKIO_NONE for the first time. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync int rc2 = ioctl(pThis->FileRawDevice, DKIOCSTATE, &s_DeviceState);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("drvHostDvdPoll: %d -> %d\n", pThis->fMediaPresent, fMediaPresent));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Poll for media change.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* taken care of above. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync bool fMediaChanged = ioctl(pThis->FileDevice, CDROM_MEDIA_CHANGED, CDSL_CURRENT) == 1;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync LogFlow(("drvHostDVDMediaThread: Media changed!\n"));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif /* USE_MEDIA_POLLING */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** @copydoc PDMIBLOCK::pfnSendCmd */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsyncstatic int drvHostDvdSendCmd(PPDMIBLOCK pInterface, const uint8_t *pbCmd,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDMBLOCKTXDIR enmTxDir, void *pvBuf, size_t *pcbBuf,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync uint8_t *pabSense, size_t cbSense, uint32_t cTimeoutMillies)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync LogFlow(("%s: cmd[0]=%#04x txdir=%d pcbBuf=%d timeout=%d\n", __FUNCTION__, pbCmd[0], enmTxDir, *pcbBuf, cTimeoutMillies));
787c7e6ef15f993c455c374f5158e7bb753b1c33vboxsync * Pass the request on to the internal scsi command interface.
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync * The command seems to be 12 bytes long, the docs a bit copy&pasty on the command length point...
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync memset(pvBuf, '\0', *pcbBuf); /* we got read size, but zero it anyway. */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync rc = DRVHostBaseScsiCmd(pThis, pbCmd, 12, PDMBLOCKTXDIR_FROM_DEVICE, pvBuf, pcbBuf, pabSense, cbSense, cTimeoutMillies);
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* sense information set */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* Not really ported to L4 yet. */
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync /* Make sure that the buffer is clear for commands reading
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * data. The actually received data may be shorter than what
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * we expect, and due to the unreliable feedback about how much
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * data the ioctl actually transferred, it's impossible to
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * prevent that. Returning previous buffer contents may cause
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * security problems inside the guest OS, if users can issue
e74eef731a813e4e06680c587a6759b9974b29c9vboxsync * commands to the CDROM device. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync cgc.buffer = (unsigned char *)pThis->pbDoubleBuffer;
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync rc = ioctl(pThis->FileDevice, CDROM_SEND_PACKET, &cgc);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (rc == VERR_ACCESS_DENIED && cgc.sense->sense_key == SCSI_SENSE_NONE)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Log2(("%s: error status %d, rc=%Rrc\n", __FUNCTION__, cgc.stat, rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Log2(("%s: after ioctl: cgc.buflen=%d txlen=%d\n", __FUNCTION__, cgc.buflen, *pcbBuf));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* The value of cgc.buflen does not reliably reflect the actual amount
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * of data transferred (for packet commands with little data transfer
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * it's 0). So just assume that everything worked ok. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* nothing to do */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Make sure that the buffer is clear for commands reading
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * data. The actually received data may be shorter than what
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * we expect, and due to the unreliable feedback about how much
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * data the ioctl actually transferred, it's impossible to
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * prevent that. Returning previous buffer contents may cause
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * security problems inside the guest OS, if users can issue
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * commands to the CDROM device. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync AssertMsgFailedReturn(("%d\n", enmTxDir), VERR_INTERNAL_ERROR);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync usc.uscsi_timeout = (cTimeoutMillies + 999) / 1000;
c28fa006ba669ad8f26ae31d00a338379c04ea1bvboxsync /* We need root privileges for user-SCSI under Solaris. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync solarisEnterRootMode(&effUserID); /** @todo check return code when this really works. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Log2(("%s: error status. rc=%Rrc\n", __FUNCTION__, rc));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Log2(("%s: after ioctl: residual buflen=%d original buflen=%d\n", __FUNCTION__, usc.uscsi_resid, usc.uscsi_buflen));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Make sure that the buffer is clear for commands reading
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * data. The actually received data may be shorter than what
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * we expect, and due to the unreliable feedback about how much
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * data the ioctl actually transferred, it's impossible to
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * prevent that. Returning previous buffer contents may cause
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * security problems inside the guest OS, if users can issue
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * commands to the CDROM device. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Req.spt.TimeOutValue = (cTimeoutMillies + 999) / 1000; /* Convert to seconds */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Req.spt.SenseInfoOffset = RT_OFFSETOF(struct _REQ, aSense);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (DeviceIoControl((HANDLE)pThis->FileDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT,
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync &Req, sizeof(Req), &Req, sizeof(Req), &cbReturned, NULL))
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Windows shares the property of not properly reflecting the actually
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * transferred data size. See above. Assume that everything worked ok.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Except if there are sense information. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Log2(("%s: scsistatus=%d bytes returned=%d tlength=%d\n", __FUNCTION__, Req.spt.ScsiStatus, cbReturned, Req.spt.DataTransferLength));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (pbCmd[0] == SCSI_GET_EVENT_STATUS_NOTIFICATION)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Log2(("Event Status Notification class=%#02x supported classes=%#02x\n", pbBuf[2], pbBuf[3]));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync Log2((" event %#02x %#02x %#02x %#02x\n", pbBuf[4], pbBuf[5], pbBuf[6], pbBuf[7]));
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* These functions would have to go into a seperate solaris binary with
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * the setuid permission set, which would run the user-SCSI ioctl and
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * return the value. BUT... this might be prohibitively slow.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Checks if the current user is authorized using Solaris' role-based access control.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Made as a seperate function with so that it need not be invoked each time we need
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * to gain root access.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns VBox error code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Uses Solaris' role-based access control (RBAC).*/
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (pPass == NULL || chkauthattr("solaris.device.cdrw", pPass->pw_name) == 0)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Setuid wrapper to gain root access.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns VBox error code.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pEffUserID Pointer to effective user ID.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Increase privilege if required */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync if (seteuid(0) == 0)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Setuid wrapper to relinquish root access.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns VBox error code.
2c8ee291fb75c4a6f05df160f5d67f4e9ef1cabcvboxsync * @param pEffUserID Pointer to effective user ID.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync /* Get back to user mode. */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync# endif /* RT_OS_SOLARIS */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync#endif /* VBOX_WITH_SUID_WRAPPER */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/* -=-=-=-=- driver interface -=-=-=-=- */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync/** @copydoc FNPDMDRVDESTRUCT */
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsyncDECLCALLBACK(void) drvHostDvdDestruct(PPDMDRVINS pDrvIns)
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync PDRVHOSTBASE pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTBASE);
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * Construct a host dvd drive driver instance.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @returns VBox status.
24ab761b2beb5af0393c6f2585b6351d8b3085f0vboxsync * @param pDrvIns The driver instance data.
if (!CFGMR3AreValuesValid(pCfgHandle, "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,