DrvRawImage.cpp revision 5b465a7c1237993faf8bb50120d247f3f0319ada
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * VBox storage devices: Raw image driver
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Copyright (C) 2006-2010 Sun Microsystems, Inc.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * available from http://www.virtualbox.org. This file is free software;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * General Public License (GPL) as published by the Free Software
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
a16eb14ad7a4b5ef91ddc22d3e8e92d930f736fcvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * additional information or have any questions.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync* Header Files *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
61fa69e2bc9fc9e7490feed1c020273f3ddb238dvboxsync* Defined Constants And Macros *
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Converts a pointer to RAWIMAGE::IMedia to a PRDVRAWIMAGE. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define PDMIMEDIA_2_DRVRAWIMAGE(pInterface) ( (PDRVRAWIMAGE)((uintptr_t)pInterface - RT_OFFSETOF(DRVRAWIMAGE, IMedia)) )
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync/** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define PDMIBASE_2_DRVINS(pInterface) ( (PPDMDRVINS)((uintptr_t)pInterface - RT_OFFSETOF(PDMDRVINS, IBase)) )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** Converts a pointer to PDMDRVINS::IBase to a PVBOXHDD. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync#define PDMIBASE_2_DRVRAWIMAGE(pInterface) ( PDMINS_2_DATA(PDMIBASE_2_DRVINS(pInterface), PDRVRAWIMAGE) )
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/*******************************************************************************
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync* Structures and Typedefs *
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync*******************************************************************************/
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Block driver instance data.
afed5ab737f4aacfae3fe73776f40e989190a7cavboxsync * @implements PDMIMEDIA
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsynctypedef struct DRVRAWIMAGE
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** The media interface. */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync /** Pointer to the driver instance. */
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync /** Pointer to the filename. (Freed by MM) */
0174432b2b1a760b89840ba696f7ba51def65dddvboxsync /** File handle of the raw image file. */
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync /** True if the image is operating in readonly mode. */
7666082b743c5e146a8cee6cc794ff4bc3fd0ffdvboxsync/* -=-=-=-=- PDMIMEDIA -=-=-=-=- */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @copydoc PDMIMEDIA::pfnGetSize */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic DECLCALLBACK(uint64_t) drvRawImageGetSize(PPDMIMEDIA pInterface)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("drvRawImageGetSize: '%s'\n", pThis->pszFilename));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("drvRawImageGetSize: returns %lld (%s)\n", cbFile, pThis->pszFilename));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("Error querying Raw image file size, rc=%Rrc. (%s)\n", rc, pThis->pszFilename));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @copydoc PDMIMEDIA::pfnBiosGetPCHSGeometry */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic DECLCALLBACK(int) drvRawImageBiosGetPCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync/** @copydoc PDMIMEDIA::pfnBiosSetPCHSGeometry */
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncstatic DECLCALLBACK(int) drvRawImageBiosSetPCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync/** @copydoc PDMIMEDIA::pfnBiosGetLCHSGeometry */
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncstatic DECLCALLBACK(int) drvRawImageBiosGetLCHSGeometry(PPDMIMEDIA pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync/** @copydoc PDMIMEDIA::pfnBiosSetLCHSGeometry */
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncstatic DECLCALLBACK(int) drvRawImageBiosSetLCHSGeometry(PPDMIMEDIA pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * Read bits.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * @see PDMIMEDIA::pfnRead for details.
22e281e75ed636601178296c6daebda8f1d17c59vboxsyncstatic DECLCALLBACK(int) drvRawImageRead(PPDMIMEDIA pInterface, uint64_t off, void *pvBuf, size_t cbRead)
22e281e75ed636601178296c6daebda8f1d17c59vboxsync PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
22e281e75ed636601178296c6daebda8f1d17c59vboxsync LogFlow(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n", off, pvBuf, cbRead, pThis->pszFilename));
22e281e75ed636601178296c6daebda8f1d17c59vboxsync * Seek to the position and read.
22e281e75ed636601178296c6daebda8f1d17c59vboxsync int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log2(("drvRawImageRead: off=%#llx pvBuf=%p cbRead=%#x (%s)\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "%16.*Rhxd\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("RTFileRead(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pThis->File, pvBuf, cbRead, rc, off, pThis->pszFilename));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @copydoc PDMIMEDIA::pfnWrite */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic DECLCALLBACK(int) drvRawImageWrite(PPDMIMEDIA pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n", off, pvBuf, cbWrite, pThis->pszFilename));
b1c3cdef473df2fbc621d5da81acc82dbfb8a11avboxsync * Seek to the position and write.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync int rc = RTFileSeek(pThis->File, off, RTFILE_SEEK_BEGIN, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync rc = RTFileWrite(pThis->File, pvBuf, cbWrite, NULL);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync Log2(("drvRawImageWrite: off=%#llx pvBuf=%p cbWrite=%#x (%s)\n"
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync "%16.*Rhxd\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("RTFileWrite(%d, %p, %#x) -> %Rrc (off=%#llx '%s')\n",
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pThis->File, pvBuf, cbWrite, rc, off, pThis->pszFilename));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("RTFileSeek(%d,%#llx,) -> %Rrc\n", pThis->File, off, rc));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @copydoc PDMIMEDIA::pfnFlush */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic DECLCALLBACK(int) drvRawImageFlush(PPDMIMEDIA pInterface)
750d4d0506a38b2e80c997075d40aad474e675fbvboxsync PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("drvRawImageFlush: (%s)\n", pThis->pszFilename));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/** @copydoc PDMIMEDIA::pfnGetUuid */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic DECLCALLBACK(int) drvRawImageGetUuid(PPDMIMEDIA pInterface, PRTUUID pUuid)
223cf005b18af2c21352a70693ebaf0582f68ebcvboxsync LogFlow(("drvRawImageGetUuid: returns VERR_NOT_IMPLEMENTED\n"));
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync/** @copydoc PDMIMEDIA::pfnIsReadOnly */
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsyncstatic DECLCALLBACK(bool) drvRawImageIsReadOnly(PPDMIMEDIA pInterface)
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync PDRVRAWIMAGE pThis = PDMIMEDIA_2_DRVRAWIMAGE(pInterface);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* -=-=-=-=- PDMIBASE -=-=-=-=- */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * @interface_method_impl{PDMIBASE,pfnQueryInterface}
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic DECLCALLBACK(void *) drvRawImageQueryInterface(PPDMIBASE pInterface, const char *pszIID)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIA, &pThis->IMedia);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync/* -=-=-=-=- PDMDRVREG -=-=-=-=- */
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync * Destruct a driver instance.
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Most VM resources are freed by the VM. This callback is provided so that any non-VM
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsync * resources can be freed correctly.
909f4391cc20b4a3a9a2d3f8718084b669663ab2vboxsync * @param pDrvIns The driver instance data.
3cbb4f9a6a320e58ed398ef7aaa004cc8727abc5vboxsyncstatic DECLCALLBACK(void) drvRawImageDestruct(PPDMDRVINS pDrvIns)
8a132edc1577cbe2a19cd778c1b2bea6ae5e8515vboxsync PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
3ecd8008b81f02a04220705ae0033142af363280vboxsync LogFlow(("drvRawImageDestruct: '%s'\n", pThis->pszFilename));
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Construct a raw image driver instance.
3ecd8008b81f02a04220705ae0033142af363280vboxsync * @copydoc FNPDMDRVCONSTRUCT
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsyncstatic DECLCALLBACK(int) drvRawImageConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle, uint32_t fFlags)
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync PDRVRAWIMAGE pThis = PDMINS_2_DATA(pDrvIns, PDRVRAWIMAGE);
247b55faa8d054157f2481e68caca36f4dc9542cvboxsync * Init the static parts.
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync /* IBase */
57399ab65e2825c324fb9dcb4642d4ae2c232509vboxsync pDrvIns->IBase.pfnQueryInterface = drvRawImageQueryInterface;
22e281e75ed636601178296c6daebda8f1d17c59vboxsync /* IMedia */
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pThis->IMedia.pfnIsReadOnly = drvRawImageIsReadOnly;
6ae4b1c72625a8e5c369effea7f018b578d733c4vboxsync pThis->IMedia.pfnBiosGetPCHSGeometry = drvRawImageBiosGetPCHSGeometry;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pThis->IMedia.pfnBiosSetPCHSGeometry = drvRawImageBiosSetPCHSGeometry;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pThis->IMedia.pfnBiosGetLCHSGeometry = drvRawImageBiosGetLCHSGeometry;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync pThis->IMedia.pfnBiosSetLCHSGeometry = drvRawImageBiosSetLCHSGeometry;
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync * Read the configuration.
247b55faa8d054157f2481e68caca36f4dc9542cvboxsync int rc = CFGMR3QueryStringAlloc(pCfgHandle, "Path", &pszName);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync AssertMsgFailed(("Configuration error: query for \"Path\" string return %Rrc.\n", rc));
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync * Open the image.
b74ca013e5f201a2dd371e6c438433ceac12af30vboxsync RTFILE_O_READWRITE | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
d408b82da0773c7e8cd4b3a01cb8a065a2c73a2dvboxsync LogFlow(("drvRawImageConstruct: Raw image '%s' opened successfully.\n", pszName));
00599f6d39cc25ca39845c2433cd75de7b9f6971vboxsync RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync LogFlow(("drvRawImageConstruct: Raw image '%s' opened successfully.\n", pszName));
57399ab65e2825c324fb9dcb4642d4ae2c232509vboxsync AssertMsgFailed(("Could not open Raw image file %s, rc=%Rrc\n", pszName, rc));
806d0b554daa555364af5f87bc96eccbe760db7avboxsync * Raw image driver registration record.
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* u32Version */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* szName */
22e281e75ed636601178296c6daebda8f1d17c59vboxsync "RawImage",
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* szRCMod */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* szR0Mod */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* pszDescription */
ebbb1f6c7e8bae363a4efda4b35b58c8467d24bcvboxsync "Raw image access driver.",
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* fFlags */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* fClass. */
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync /* cMaxInstances */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* cbInstance */
13ba5527caaa9b8c4fee29f22e374fa67c4c6f72vboxsync /* pfnConstruct */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* pfnDestruct */
e0b9d3c357adf9b7d05f55540e86f22943fc4b23vboxsync /* pfnRelocate */
806d0b554daa555364af5f87bc96eccbe760db7avboxsync /* pfnIOCtl */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* pfnPowerOn */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* pfnReset */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* pfnSuspend */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* pfnResume */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* pfnAttach */
1843553dbdf4e46417158b4c6348c503adf10740vboxsync /* pfnDetach */
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync /* pfnPowerOff */
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync /* pfnSoftReset */
533ffcb943c4af2c5fe6385d816d0ba3eda9383bvboxsync /* u32EndVersion */