DrvHostBase.cpp revision 8083a259c13e6e26e56ca2582edbad4a8cfac25a
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * DrvHostBase - Host base drive access driver.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Copyright (C) 2006-2007 innotek GmbH
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * available from http://www.virtualbox.org. This file is free software;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * you can redistribute it and/or modify it under the terms of the GNU
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * General Public License (GPL) as published by the Free Software
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/*******************************************************************************
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync* Header Files *
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync*******************************************************************************/
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync# include <IOKit/storage/IOStorageDeviceCharacteristics.h>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync# include <IOKit/scsi-commands/SCSICommandOperationCodes.h>
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync /* Nothing special requires... yeah, right. */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsynctypedef struct _IO_STATUS_BLOCK {
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync /*IN*/ FS_INFORMATION_CLASS FileSystemInformationClass );
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/* -=-=-=-=- IBlock -=-=-=-=- */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/** @copydoc PDMIBLOCK::pfnRead */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncstatic DECLCALLBACK(int) drvHostBaseRead(PPDMIBLOCK pInterface, uint64_t off, void *pvBuf, size_t cbRead)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync LogFlow(("%s-%d: drvHostBaseRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, off, pvBuf, cbRead, pThis->pszDevice));
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Check the state.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Issue a READ(12) request.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync AssertReturn(!(off % pThis->cbBlock), VERR_INVALID_PARAMETER);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync AssertReturn(!(cbRead % pThis->cbBlock), VERR_INVALID_PARAMETER);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync RT_BYTE4(LBA), RT_BYTE3(LBA), RT_BYTE2(LBA), RT_BYTE1(LBA),
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync RT_BYTE4(cBlocks), RT_BYTE3(cBlocks), RT_BYTE2(cBlocks), RT_BYTE1(cBlocks),
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync 0, 0, 0, 0, 0
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync rc = DRVHostBaseScsiCmd(pThis, abCmd, 12, PDMBLOCKTXDIR_FROM_DEVICE, pvBuf, &cbRead, NULL, 0, 0);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Seek and read.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync rc = RTFileSeek(pThis->FileDevice, off, RTFILE_SEEK_BEGIN, NULL);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync rc = RTFileRead(pThis->FileDevice, pvBuf, cbRead, NULL);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Log2(("%s-%d: drvHostBaseRead: off=%#llx cbRead=%#x\n"
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "%16.*Vhxd\n",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, off, cbRead, cbRead, pvBuf));
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Log(("%s-%d: drvHostBaseRead: RTFileRead(%d, %p, %#x) -> %Vrc (off=%#llx '%s')\n",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pThis->FileDevice,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Log(("%s-%d: drvHostBaseRead: RTFileSeek(%d,%#llx,) -> %Vrc\n", pThis->pDrvIns->pDrvReg->szDriverName,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pThis->pDrvIns->iInstance, pThis->FileDevice, off, rc));
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync LogFlow(("%s-%d: drvHostBaseRead: returns %Vrc\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, rc));
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync/** @copydoc PDMIBLOCK::pfnWrite */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsyncstatic DECLCALLBACK(int) drvHostBaseWrite(PPDMIBLOCK pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync PDRVHOSTBASE pThis = PDMIBLOCK_2_DRVHOSTBASE(pInterface);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync LogFlow(("%s-%d: drvHostBaseWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, off, pvBuf, cbWrite, pThis->pszDevice));
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Log2(("%s-%d: drvHostBaseWrite: off=%#llx cbWrite=%#x\n"
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync "%16.*Vhxd\n",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, off, cbWrite, cbWrite, pvBuf));
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Check the state.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync /** @todo write support... */
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync * Seek and write.
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync rc = RTFileSeek(pThis->FileDevice, off, RTFILE_SEEK_BEGIN, NULL);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync rc = RTFileWrite(pThis->FileDevice, pvBuf, cbWrite, NULL);
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Log(("%s-%d: drvHostBaseWrite: RTFileWrite(%d, %p, %#x) -> %Vrc (off=%#llx '%s')\n",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pThis->FileDevice,
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync Log(("%s-%d: drvHostBaseWrite: RTFileSeek(%d,%#llx,) -> %Vrc\n",
b8e299dddd091ae24e0c08c45d91b8f937bd14d2vboxsync pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pThis->FileDevice, off, rc));
LogFlow(("%s-%d: drvHostBaseWrite: returns %Vrc\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, rc));
return rc;
int rc;
#ifdef RT_OS_DARWIN
LogFlow(("%s-%d: drvHostBaseFlush: returns %Vrc\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, rc));
return rc;
LogFlow(("%s-%d: drvHostBaseGetSize: returns %llu\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, cb));
return cb;
LogFlow(("%s-%d: drvHostBaseGetType: returns %d\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pThis->enmType));
LogFlow(("%s-%d: drvHostBaseGetUuid: returns VINF_SUCCESS *pUuid=%Vuuid\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pUuid));
return VINF_SUCCESS;
#define PDMIBLOCKBIOS_2_DRVHOSTBASE(pInterface) ( (PDRVHOSTBASE((uintptr_t)pInterface - RT_OFFSETOF(DRVHOSTBASE, IBlockBios))) )
static DECLCALLBACK(int) drvHostBaseGetPCHSGeometry(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, __FUNCTION__, rc, pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors));
return rc;
static DECLCALLBACK(int) drvHostBaseSetPCHSGeometry(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, __FUNCTION__, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
return rc;
static DECLCALLBACK(int) drvHostBaseGetLCHSGeometry(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, __FUNCTION__, rc, pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors));
return rc;
static DECLCALLBACK(int) drvHostBaseSetLCHSGeometry(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, __FUNCTION__, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
return rc;
static DECLCALLBACK(int) drvHostBaseMount(PPDMIMOUNT pInterface, const char *pszFilename, const char *pszCoreDriver)
return VERR_PDM_MEDIA_MOUNTED;
return VERR_NOT_SUPPORTED;
return fRc;
LogFlow(("%s-%d: drvHostBaseLock: already locked\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance));
LogFlow(("%s-%d: drvHostBaseLock: returns %Vrc\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, rc));
return rc;
LogFlow(("%s-%d: drvHostBaseUnlock: not locked\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance));
LogFlow(("%s-%d: drvHostBaseUnlock: returns %Vrc\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, rc));
return rc;
return fRc;
static DECLCALLBACK(void *) drvHostBaseQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
switch (enmInterface)
case PDMINTERFACE_BASE:
case PDMINTERFACE_BLOCK:
case PDMINTERFACE_BLOCK_BIOS:
case PDMINTERFACE_MOUNT:
return NULL;
#ifdef RT_OS_DARWIN
CFStringRef BSDNameStrRef = (CFStringRef)IORegistryEntryCreateCFProperty(Child, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, 0);
if (BSDNameStrRef)
AssertFailed();
return rc;
static void drvHostBaseDADoneCallback(DADiskRef DiskRef, DADissenterRef DissenterRef, void *pvContext)
if (!DissenterRef)
*prc = 0;
SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL, 0, 0, 0, false, 0,
return VINF_SUCCESS;
return VERR_DRIVE_LOCKED;
Log(("%s-%d: calling DADiskClaim on '%s'.\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, szName));
DADiskClaim(pThis->pDADisk, kDADiskClaimOptionDefault, NULL, NULL, drvHostBaseDADoneCallback, &rcDA);
&& !rcDA)
Log(("%s-%d: calling DADiskUnmount on '%s'.\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, szName));
&& !rcDA)
Log(("%s-%d: umount => rc32=%d & rcDA=%#x\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc32, rcDA));
Log(("%s-%d: claim => rc32=%d & rcDA=%#x\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, rc32, rcDA));
Log(("%s-%d: failed to open disk '%s'!\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, szName));
#ifndef RT_OS_SOLARIS
#ifdef RT_OS_DARWIN
* (This enumeration must be identical to the one performed in DrvHostBase.cpp.)
kern_return_t krc = IORegistryEntryCreateCFProperties(DVDService, &PropsRef, kCFAllocatorDefault, kNilOptions);
CFDictionaryRef DevCharRef = (CFDictionaryRef)CFDictionaryGetValue(PropsRef, CFSTR(kIOPropertyDeviceCharacteristicsKey));
if (DevCharRef)
if ( ValueRef
if ( ValueRef
krc = IOCreatePlugInInterfaceForService(DVDService, kIOMMCDeviceUserClientTypeID, kIOCFPlugInInterfaceID,
return rc;
int FileDevice = open(pThis->pszDeviceOpen, (pThis->fReadOnlyConfig ? O_RDONLY : O_RDWR) | O_NONBLOCK);
if (FileDevice < 0)
return VINF_SUCCESS;
static int drvHostBaseOpen(PDRVHOSTBASE pThis, PRTFILE pFileBlockDevice, PRTFILE pFileRawDevice, bool fReadOnly)
return rc;
LogFlow(("%s-%d: drvHostBaseReopen: '%s'\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pThis->pszDeviceOpen));
#ifdef RT_OS_SOLARIS
LogFlow(("%s-%d: drvHostBaseReopen: '%s' - retry readonly (%Vrc)\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, pThis->pszDeviceOpen, rc));
#ifdef RT_OS_SOLARIS
return rc;
#ifdef RT_OS_SOLARIS
return VINF_SUCCESS;
#ifdef RT_OS_DARWIN
} Buf = {0, 0};
SCSI_READ_CAPACITY, 0, 0, 0, 0, 0, 0,
// Buf.cbBlock = 2048;
return rc;
return VINF_SUCCESS;
if (rcNt >= 0)
return VINF_SUCCESS;
switch (rcNt)
return rc;
#ifdef RT_OS_DARWIN
DECLCALLBACK(int) DRVHostBaseScsiCmd(PDRVHOSTBASE pThis, const uint8_t *pbCmd, size_t cbCmd, PDMBLOCKTXDIR enmTxDir,
Assert(enmTxDir == PDMBLOCKTXDIR_NONE || enmTxDir == PDMBLOCKTXDIR_FROM_DEVICE || enmTxDir == PDMBLOCKTXDIR_TO_DEVICE);
if (pcbBuf)
*pcbBuf = 0;
# ifdef RT_OS_DARWIN
if (!ppScsiTaskI)
return VERR_NO_MEMORY;
irc = (*ppScsiTaskI)->SetScatterGatherEntries(ppScsiTaskI, NULL, 0, 0, kSCSIDataTransfer_NoDataTransfer);
irc = (*ppScsiTaskI)->SetTimeoutDuration(ppScsiTaskI, cTimeoutMillies ? cTimeoutMillies : 30000 /*ms*/);
if (pcbBuf)
&& pbSense)
return rc;
return rc;
return rc;
return VINF_SUCCESS;
#ifdef RT_OS_WINDOWS
if (pThis)
PostQuitMessage(0);
switch (wParam)
case DBT_DEVICEARRIVAL:
case DBT_DEVICEREMOVECOMPLETE:
return TRUE;
#ifdef RT_OS_WINDOWS
if (s_hAtomDeviceChange == 0)
HWND hwnd = CreateWindow((LPCTSTR)s_hAtomDeviceChange, "", WS_POPUP, 0, 0, 0, 0, 0, 0, s_classDeviceChange.hInstance, 0);
if (!hwnd)
LogFlow(("%s-%d: drvHostBaseMediaThread: returns VERR_GENERAL_FAILURE\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance));
return VERR_GENERAL_FAILURE;
LogFlow(("%s-%d: drvHostBaseMediaThread: Created hwndDeviceChange=%p\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance, hwnd));
bool fFirst = true;
&& cRetries-- > 0)
if (fFirst)
fFirst = false;
return rc;
LogFlow(("%s-%d: drvHostBaseMediaThread: returns VINF_SUCCESS\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance));
return VINF_SUCCESS;
LogFlow(("%s-%d: drvHostBaseMediaThread:\n", pThis->pDrvIns->pDrvReg->szDriverName, pThis->pDrvIns->iInstance));
return VINF_SUCCESS;
LogFlow(("%s-%d: drvHostBaseDestruct: iInstance=%d\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pDrvIns->iInstance));
int rc;
#ifdef RT_OS_WINDOWS
PostMessage(pThis->hwndDeviceChange, WM_CLOSE, 0, 0); /* default win proc will destroy the window */
if (!rc)
#ifdef RT_OS_DARWIN
* (We're currently not unlocking the device after use. See todo in DevATA.cpp.) */
#ifdef RT_OS_WINDOWS
PostMessage(pThis->hwndDeviceChange, WM_CLOSE, 0, 0); /* default win proc will destroy the window */
#ifdef RT_OS_DARWIN
LogFlow(("%s-%d: releasing exclusive scsi access!\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
LogFlow(("%s-%d: releasing the MMC object!\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
LogFlow(("%s-%d: releasing the DA session!\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
#ifdef RT_OS_SOLARIS
LogFlow(("%s-%d: drvHostBaseDestruct completed\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance));
LogFlow(("%s-%d: DRVHostBaseInitData: iInstance=%d\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pDrvIns->iInstance));
#ifdef RT_OS_DARWIN
#ifdef RT_OS_SOLARIS
pThis->pDrvBlockPort = (PPDMIBLOCKPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_BLOCK_PORT);
return VERR_PDM_MISSING_INTERFACE_ABOVE;
pThis->pDrvMountNotify = (PPDMIMOUNTNOTIFY)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_MOUNT_NOTIFY);
return rc;
return rc;
pThis->fReadOnlyConfig = enmType == PDMBLOCKTYPE_DVD || enmType == PDMBLOCKTYPE_CDROM ? true : false;
return rc;
return rc;
return rc;
char *psz;
return rc;
return rc;
bool fAttachFailError;
fAttachFailError = true;
#ifdef RT_OS_WINDOWS
return VERR_INVALID_PARAMETER;
if (!pszBlockDevName)
return VERR_NO_MEMORY;
return VERR_NO_MEMORY;
return VINF_SUCCESS;
Log(("%s-%d: pszDevice='%s' (%s) cMilliesPoller=%d fReadOnlyConfig=%d fLocked=%d fBIOSVisible=%d Uuid=%Vuuid\n",
pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, pThis->pszDevice, pThis->pszDeviceOpen, pThis->cMilliesPoller,
return VERR_PDM_DRVINS_NO_ATTACH;
rc = pDrvIns->pDrvHlp->pfnSSMRegister(pDrvIns, pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, 1, 0,
return rc;
#ifdef RT_OS_WINDOWS
case PDMBLOCKTYPE_FLOPPY_360:
case PDMBLOCKTYPE_FLOPPY_720:
case PDMBLOCKTYPE_FLOPPY_1_20:
case PDMBLOCKTYPE_FLOPPY_1_44:
case PDMBLOCKTYPE_FLOPPY_2_88:
return VERR_INVALID_PARAMETER;
case PDMBLOCKTYPE_CDROM:
case PDMBLOCKTYPE_DVD:
return VERR_INVALID_PARAMETER;
case PDMBLOCKTYPE_HARD_DISK:
return VERR_INVALID_PARAMETER;
#ifdef RT_OS_DARWIN
#ifndef RT_OS_DARWIN
#ifdef RT_OS_SOLARIS
switch (rc)
case VERR_ACCESS_DENIED:
#ifdef RT_OS_LINUX
return rc;
#ifdef RT_OS_WINDOWS
return rc;
#ifndef RT_OS_WINDOWS
return rc;
return rc;
return rc;
#ifdef RT_OS_WINDOWS
return VERR_GENERAL_FAILURE;
return src;
return rc;