DrvVD.cpp revision a0240ff4f7663045c848fdbc192ea3d4d9f70a11
/** $Id$ */
/** @file
*
* VBox storage devices:
* Media implementation for VBox disk container
*/
/*
* Copyright (C) 2006 InnoTek Systemberatung GmbH
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License as published by the Free Software Foundation,
* in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
* distribution. VirtualBox OSE is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY of any kind.
*
* If you received this file as part of a commercial VirtualBox
* distribution, then only the terms of your commercial VirtualBox
* license agreement apply instead of the previous paragraph.
*/
/*******************************************************************************
* Header files *
*******************************************************************************/
#define LOG_GROUP LOG_GROUP_DRV_VD
#include <VBox/VBoxHDD-new.h>
#include "Builtins.h"
/*******************************************************************************
* Defined types, constants and macros *
*******************************************************************************/
/** Converts a pointer to VDIDISK::IMedia to a PVBOXDISK. */
#define PDMIMEDIA_2_VBOXDISK(pInterface) \
/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
#define PDMIBASE_2_DRVINS(pInterface) \
/** Converts a pointer to PDMDRVINS::IBase to a PVBOXDISK. */
#define PDMIBASE_2_VBOXDISK(pInterface) \
/**
* VBox disk container media main structure, private part.
*/
typedef struct VBOXDISK
{
/** The VBox disk container. */
/** The media interface. */
/** Pointer to the driver instance. */
/** Name of the image format backend. */
char szFormat[16];
/** Flag whether suspend has changed image open mode to read only. */
bool fTempReadOnly;
/*******************************************************************************
* Error reporting callback *
*******************************************************************************/
static void vdErrorCallback(void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
{
}
/*******************************************************************************
* Media interface methods *
*******************************************************************************/
/** @copydoc PDMIMEDIA::pfnRead */
{
if (VBOX_SUCCESS(rc))
return rc;
}
/** @copydoc PDMIMEDIA::pfnWrite */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnFlush */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnGetSize */
{
return cb;
}
/** @copydoc PDMIMEDIA::pfnIsReadOnly */
{
return f;
}
/** @copydoc PDMIMEDIA::pfnBiosGetGeometry */
{
if (VBOX_FAILURE(rc))
{
}
return rc;
}
/** @copydoc PDMIMEDIA::pfnBiosSetGeometry */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnBiosGetTranslation */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnBiosSetTranslation */
{
return rc;
}
/** @copydoc PDMIMEDIA::pfnGetUuid */
{
return rc;
}
/*******************************************************************************
* Base interface methods *
*******************************************************************************/
/** @copydoc PDMIBASE::pfnQueryInterface */
{
switch (enmInterface)
{
case PDMINTERFACE_BASE:
case PDMINTERFACE_MEDIA:
default:
return NULL;
}
}
/*******************************************************************************
* Driver methods *
*******************************************************************************/
/**
* Construct a VBox disk media driver instance.
*
* @returns VBox status.
* @param pDrvIns The driver instance data.
* If the registration structure is needed, pDrvIns->pDrvReg points to it.
* @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
* of the driver instance. It's also found in pDrvIns->pCfgHandle as it's expected
* to be used frequently in this function.
*/
{
int rc = VINF_SUCCESS;
char *pszName; /**< The path of the disk image file. */
bool fReadOnly; /**< True if the media is readonly. */
bool fHonorZeroWrites; /**< True if zero blocks should be written. */
/*
* Init the static parts.
*/
pData->fTempReadOnly = false;
/* IMedia */
/*
* Validate configuration and find all parent images.
* It's sort of up side down from the image dependency tree.
*/
unsigned iLevel = 0;
for (;;)
{
bool fValid;
if (pCurNode == pCfgHandle)
{
/* Toplevel configuration contains the format backend name and
* full image open information. */
"Format\0"
"Path\0ReadOnly\0HonorZeroWrites\0");
}
else
{
/* All other image configurations only contain image name. */
}
if (!fValid)
{
break;
}
if (!pParent)
break;
iLevel++;
}
/*
* Open the images.
*/
if (VBOX_SUCCESS(rc))
{
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
{
/* Default disk image format is VMDK. */
rc = VINF_SUCCESS;
}
if (VBOX_SUCCESS(rc))
{
/* Error message is already set correctly. */
}
else
N_("DrvVD: Configuration error: Querying \"Format\" as string failed"));
}
{
/*
* Read the image configuration.
*/
if (VBOX_FAILURE(rc))
{
N_("DrvVD: Configuration error: Querying \"Path\" as string failed"));
break;
}
if (iLevel == 0)
{
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
fReadOnly = false;
else if (VBOX_FAILURE(rc))
{
N_("DrvVD: Configuration error: Querying \"ReadOnly\" as boolean failed"));
break;
}
if (rc == VERR_CFGM_VALUE_NOT_FOUND)
fHonorZeroWrites = false;
else if (VBOX_FAILURE(rc))
{
N_("DrvVD: Configuration error: Querying \"HonorZeroWrites\" as boolean failed"));
break;
}
}
else
{
fReadOnly = true;
fHonorZeroWrites = false;
}
/*
* Open the image.
*/
unsigned uOpenFlags;
if (fReadOnly)
else
if (fHonorZeroWrites)
if (VBOX_SUCCESS(rc))
else
{
break;
}
/* next */
iLevel--;
}
return rc;
}
/**
* Destruct a driver instance.
*
* Most VM resources are freed by the VM. This callback is provided so that any non-VM
* resources can be freed correctly.
*
* @param pDrvIns The driver instance data.
*/
{
}
/**
* When the VM has been suspended we'll change the image mode to read-only
* so that main and others can read the VDIs. This is important when
* saving state and so forth.
*
* @param pDrvIns The driver instance data.
*/
{
{
unsigned uOpenFlags;
pData->fTempReadOnly = true;
}
}
/**
* Before the VM resumes we'll have to undo the read-only mode change
* done in vdSuspend.
*
* @param pDrvIns The driver instance data.
*/
{
if (pData->fTempReadOnly)
{
unsigned uOpenFlags;
pData->fTempReadOnly = false;
}
}
/**
* VBox disk container media driver registration record.
*/
{
/* u32Version */
/* szDriverName */
"VD",
/* pszDescription */
"Generic VBox disk media driver.",
/* fFlags */
/* fClass. */
/* cMaxInstances */
~0,
/* cbInstance */
sizeof(VBOXDISK),
/* pfnConstruct */
/* pfnDestruct */
/* pfnIOCtl */
NULL,
/* pfnPowerOn */
NULL,
/* pfnReset */
NULL,
/* pfnSuspend */
/* pfnResume */
/* pfnDetach */
};