DrvVD.cpp revision 8dbf70ba2345e69b0b6d45c38cf1add0ef10591c
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * DrvVD - Generic VBox disk media driver.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Copyright (C) 2006-2010 Oracle Corporation
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*******************************************************************************
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync* Header files *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/* All lwip header files are not C++ safe. So hack around this. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif /* VBOX_WITH_INIP */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/* Small hack to get at lwIP initialized status */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncextern bool DevINIPConfigured(void);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync#endif /* VBOX_WITH_INIP */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync* Defined types, constants and macros *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync*******************************************************************************/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Converts a pointer to VBOXDISK::IMedia to a PVBOXDISK. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ( (PVBOXDISK)((uintptr_t)pInterface - RT_OFFSETOF(VBOXDISK, IMedia)) )
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ( (PPDMDRVINS)((uintptr_t)pInterface - RT_OFFSETOF(PDMDRVINS, IBase)) )
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Converts a pointer to PDMDRVINS::IBase to a PVBOXDISK. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ( PDMINS_2_DATA(PDMIBASE_2_DRVINS(pInterface), PVBOXDISK) )
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/** Converts a pointer to VBOXDISK::IMediaAsync to a PVBOXDISK. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ( (PVBOXDISK)((uintptr_t)pInterface - RT_OFFSETOF(VBOXDISK, IMediaAsync)) )
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync * VBox disk container, image information, private part.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef struct VBOXIMAGE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Pointer to next image. */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /** Pointer to list of VD interfaces. Per-image. */
typedef struct DRVVDSTORAGEBACKEND
volatile bool fSyncIoPending;
int rcReqLast;
typedef struct VBOXDISK
bool fTempReadOnly;
bool fErrorUseRuntime;
bool fAsyncIOSupported;
bool fMergePending;
unsigned uMergeSource;
unsigned uMergeTarget;
if (pImage)
return pImage;
RTMemFree(p);
unsigned uOpenFlags;
return rc;
unsigned uOpenFlags;
return rc;
static DECLCALLBACK(void) drvvdAsyncTaskCompleted(PPDMDRVINS pDrvIns, void *pvTemplateUser, void *pvUser, int rcReq)
int rc;
unsigned uOpenFlags,
void **ppStorage)
PDRVVDSTORAGEBACKEND pStorageBackend = (PDRVVDSTORAGEBACKEND)RTMemAllocZ(sizeof(DRVVDSTORAGEBACKEND));
if (pStorageBackend)
pStorageBackend->pInterfaceThreadSyncCallbacks = VDGetInterfaceThreadSync(pStorageBackend->pInterfaceThreadSync);
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;;
int rc = PDMR3AsyncCompletionEpRead(pStorageBackend->pEndpoint, uOffset, &DataSeg, 1, cbRead, NULL, &pTask);
return rc;
if (pcbRead)
int rc = PDMR3AsyncCompletionEpWrite(pStorageBackend->pEndpoint, uOffset, &DataSeg, 1, cbWrite, NULL, &pTask);
return rc;
if (pcbWritten)
return rc;
void **ppTask)
int rc = PDMR3AsyncCompletionEpRead(pStorageBackend->pEndpoint, uOffset, paSegments, cSegments, cbRead,
return rc;
void **ppTask)
int rc = PDMR3AsyncCompletionEpWrite(pStorageBackend->pEndpoint, uOffset, paSegments, cSegments, cbWrite,
return rc;
return rc;
return rc;
#ifdef VBOX_WITH_INIP
typedef union INIPSOCKADDRUNION
static DECLCALLBACK(int) drvvdINIPClientConnect(const char *pszAddress, uint32_t uPort, PRTSOCKET pSock)
if (!DevINIPConfigured())
return VERR_NET_HOST_UNREACHABLE;
return VERR_NET_HOST_UNREACHABLE;
return VINF_SUCCESS;
return rc;
int rc;
if (rc > 0)
return VINF_SUCCESS;
if (rc == 0)
return VERR_TIMEOUT;
static DECLCALLBACK(int) drvvdINIPRead(RTSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead)
return VERR_INVALID_PARAMETER;
if (cbBytesRead < 0)
if (cbBytesRead == 0 && errno) /** @todo r=bird: lwip_recv will not touch errno on Windows. This may apply to other hosts as well */
if (pcbRead)
return VINF_SUCCESS;
if (cbWritten < 0)
AssertMsg(cbBuffer >= (size_t)cbWritten, ("Wrote more than we requested!!! cbWritten=%d cbBuffer=%d\n",
} while (cbBuffer);
return VINF_SUCCESS;
return rc;
fFlag = 0;
return VINF_SUCCESS;
return VINF_SUCCESS;
RT_ZERO(u);
return VINF_SUCCESS;
return VERR_NET_OPERATION_NOT_SUPPORTED;
RT_ZERO(u);
return VINF_SUCCESS;
return VERR_NET_OPERATION_NOT_SUPPORTED;
return rc;
return rc;
return rc;
void *pvUser)
return rc;
return cb;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
return rc;
PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNC, pThis->fAsyncIOSupported ? &pThis->IMediaAsync : NULL);
return NULL;
return VINF_SUCCESS;
return VINF_SUCCESS;
bool fHostIP = false;
bool fUseNewIo = false;
unsigned iLevel = 0;
bool fValid;
if (!fValid)
if (!pParent)
iLevel++;
if (fHostIP)
#ifndef VBOX_WITH_INIP
fUseNewIo = false;
unsigned iImageIdx = 0;
if (!pImage)
bool fMergeSource;
if (fMergeSource)
bool fMergeTarget;
if (fMergeTarget)
unsigned uOpenFlags;
if (fHonorZeroWrites)
&& !fReadOnly
&& iLevel == 0)
pszName);
iLevel--;
iImageIdx++;
return rc;
sizeof(VBOXDISK),
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,