DrvBlock.cpp revision f8a01eb6a7c5030c08407dfc81ae474430f18c6b
77b1a2d8b5dbe2c0b5200794914239fee3c8ee5dvboxsync/* $Id$ */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** @file
77b1a2d8b5dbe2c0b5200794914239fee3c8ee5dvboxsync * VBox storage devices: Generic block driver
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*
e64031e20c39650a7bc902a3e1aba613b9415deevboxsync * Copyright (C) 2006-2010 Oracle Corporation
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * available from http://www.virtualbox.org. This file is free software;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * 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.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Header Files *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#define LOG_GROUP LOG_GROUP_DRV_BLOCK
662d52947eeb3fc8fca3b23991a5eee47077f896vboxsync#include <VBox/pdmdrv.h>
da957c069c2a3c582fe265ff88170ce4c42b499dvboxsync#include <iprt/assert.h>
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#include <iprt/string.h>
16a9adc14900ca18e6909679a579f6833425e030vboxsync#include <iprt/uuid.h>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#include "Builtins.h"
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** @def VBOX_PERIODIC_FLUSH
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Enable support for periodically flushing the VDI to disk. This may prove
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * useful for those nasty problems with the ultra-slow host filesystems.
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync * If this is enabled, it can be configured via the CFGM key
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * "VBoxInternal/Devices/piix3ide/0/LUN#<x>/Config/FlushInterval". <x>
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * must be replaced with the correct LUN number of the disk that should
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * do the periodic flushes. The value of the key is the number of bytes
efff36b306e370346025647a158689021df2e1d1vboxsync * written between flushes. A value of 0 (the default) denotes no flushes. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#define VBOX_PERIODIC_FLUSH
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/** @def VBOX_IGNORE_FLUSH
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Enable support for ignoring VDI flush requests. This can be useful for
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * filesystems that show bad guest IDE write performance (especially with
590bfe12ce22cd3716448fbb9f4dc51664bfe5e2vboxsync * Windows guests). NOTE that this does not disable the flushes caused by
efff36b306e370346025647a158689021df2e1d1vboxsync * the periodic flush cache feature above.
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * If this feature is enabled, it can be configured via the CFGM key
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * "VBoxInternal/Devices/piix3ide/0/LUN#<x>/Config/IgnoreFlush". <x>
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * must be replaced with the correct LUN number of the disk that should
efff36b306e370346025647a158689021df2e1d1vboxsync * ignore flush requests. The value of the key is a boolean. The default
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * is to ignore flushes, i.e. true. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#define VBOX_IGNORE_FLUSH
efff36b306e370346025647a158689021df2e1d1vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/*******************************************************************************
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync* Structures and Typedefs *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync*******************************************************************************/
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/**
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * Block driver instance data.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync *
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @implements PDMIBLOCK
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @implements PDMIBLOCKBIOS
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @implements PDMIMOUNT
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @implements PDMIMEDIAASYNCPORT
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync * @implements PDMIBLOCKASYNC
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsynctypedef struct DRVBLOCK
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync{
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Pointer driver instance. */
0abd77741a608f6c41c8dfcd4781b8b84adf1044vboxsync PPDMDRVINS pDrvIns;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Drive type. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync PDMBLOCKTYPE enmType;
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Locked indicator. */
9496f2d398b49813176939d7a339ae513d5175efvboxsync bool fLocked;
9496f2d398b49813176939d7a339ae513d5175efvboxsync /** Mountable indicator. */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync bool fMountable;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /** Visible to the BIOS. */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync bool fBiosVisible;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#ifdef VBOX_PERIODIC_FLUSH
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /** HACK: Configuration value for number of bytes written after which to flush. */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync uint32_t cbFlushInterval;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /** HACK: Current count for the number of bytes written since the last flush. */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync uint32_t cbDataWritten;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#endif /* VBOX_PERIODIC_FLUSH */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#ifdef VBOX_IGNORE_FLUSH
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /** HACK: Disable flushes for this drive. */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync bool fIgnoreFlush;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /** Disable async flushes for this drive. */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync bool fIgnoreFlushAsync;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#endif /* VBOX_IGNORE_FLUSH */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** Pointer to the media driver below us.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * This is NULL if the media is not mounted. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync PPDMIMEDIA pDrvMedia;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** Pointer to the block port interface above us. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync PPDMIBLOCKPORT pDrvBlockPort;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** Pointer to the mount notify interface above us. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync PPDMIMOUNTNOTIFY pDrvMountNotify;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** Our block interface. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync PDMIBLOCK IBlock;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** Our block interface. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync PDMIBLOCKBIOS IBlockBios;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** Our mountable interface. */
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsync PDMIMOUNT IMount;
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** Pointer to the async media driver below us.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * This is NULL if the media is not mounted. */
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync PPDMIMEDIAASYNC pDrvMediaAsync;
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync /** Our media async port. */
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync PDMIMEDIAASYNCPORT IMediaAsyncPort;
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync /** Pointer to the async block port interface above us. */
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync PPDMIBLOCKASYNCPORT pDrvBlockAsyncPort;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /** Our async block interface. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync PDMIBLOCKASYNC IBlockAsync;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync /** Uuid of the drive. */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync RTUUID Uuid;
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync /** BIOS PCHS Geometry. */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync PDMMEDIAGEOMETRY PCHSGeometry;
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync /** BIOS LCHS Geometry. */
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync PDMMEDIAGEOMETRY LCHSGeometry;
ee4d840f54fd2dcea8a73b1b86d5ec0db370b05dvboxsync} DRVBLOCK, *PDRVBLOCK;
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/* -=-=-=-=- IBlock -=-=-=-=- */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** Makes a PDRVBLOCK out of a PPDMIBLOCK. */
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#define PDMIBLOCK_2_DRVBLOCK(pInterface) ( (PDRVBLOCK)((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IBlock)) )
9496f2d398b49813176939d7a339ae513d5175efvboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync/** @copydoc PDMIBLOCK::pfnRead */
9496f2d398b49813176939d7a339ae513d5175efvboxsyncstatic DECLCALLBACK(int) drvblockRead(PPDMIBLOCK pInterface, uint64_t off, void *pvBuf, size_t cbRead)
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync{
9496f2d398b49813176939d7a339ae513d5175efvboxsync PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
21029597fc4b76d0db0c9542daee201447281781vboxsync
21029597fc4b76d0db0c9542daee201447281781vboxsync /*
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Check the state.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync if (!pThis->pDrvMedia)
9496f2d398b49813176939d7a339ae513d5175efvboxsync {
9496f2d398b49813176939d7a339ae513d5175efvboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
9496f2d398b49813176939d7a339ae513d5175efvboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync int rc = pThis->pDrvMedia->pfnRead(pThis->pDrvMedia, off, pvBuf, cbRead);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return rc;
9496f2d398b49813176939d7a339ae513d5175efvboxsync}
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** @copydoc PDMIBLOCK::pfnWrite */
16a9adc14900ca18e6909679a579f6833425e030vboxsyncstatic DECLCALLBACK(int) drvblockWrite(PPDMIBLOCK pInterface, uint64_t off, const void *pvBuf, size_t cbWrite)
16a9adc14900ca18e6909679a579f6833425e030vboxsync{
16a9adc14900ca18e6909679a579f6833425e030vboxsync PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
16a9adc14900ca18e6909679a579f6833425e030vboxsync
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync /*
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * Check the state.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync if (!pThis->pDrvMedia)
9496f2d398b49813176939d7a339ae513d5175efvboxsync {
9496f2d398b49813176939d7a339ae513d5175efvboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
9496f2d398b49813176939d7a339ae513d5175efvboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
9496f2d398b49813176939d7a339ae513d5175efvboxsync }
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /* Set an FTM checkpoint as this operation changes the state permanently. */
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync PDMDrvHlpFTSetCheckpoint(pThis->pDrvIns, FTMCHECKPOINTTYPE_STORAGE);
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync
16a9adc14900ca18e6909679a579f6833425e030vboxsync int rc = pThis->pDrvMedia->pfnWrite(pThis->pDrvMedia, off, pvBuf, cbWrite);
16a9adc14900ca18e6909679a579f6833425e030vboxsync#ifdef VBOX_PERIODIC_FLUSH
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (pThis->cbFlushInterval)
16a9adc14900ca18e6909679a579f6833425e030vboxsync {
16a9adc14900ca18e6909679a579f6833425e030vboxsync pThis->cbDataWritten += (uint32_t)cbWrite;
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (pThis->cbDataWritten > pThis->cbFlushInterval)
16a9adc14900ca18e6909679a579f6833425e030vboxsync {
16a9adc14900ca18e6909679a579f6833425e030vboxsync pThis->cbDataWritten = 0;
16a9adc14900ca18e6909679a579f6833425e030vboxsync pThis->pDrvMedia->pfnFlush(pThis->pDrvMedia);
16a9adc14900ca18e6909679a579f6833425e030vboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync }
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync#endif /* VBOX_PERIODIC_FLUSH */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync return rc;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync}
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
a0240ff4f7663045c848fdbc192ea3d4d9f70a11vboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync/** @copydoc PDMIBLOCK::pfnFlush */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsyncstatic DECLCALLBACK(int) drvblockFlush(PPDMIBLOCK pInterface)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync{
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync /*
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync * Check the state.
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync if (!pThis->pDrvMedia)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync {
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync }
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#ifdef VBOX_IGNORE_FLUSH
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync if (pThis->fIgnoreFlush)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync return VINF_SUCCESS;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync#endif /* VBOX_IGNORE_FLUSH */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync int rc = pThis->pDrvMedia->pfnFlush(pThis->pDrvMedia);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync if (rc == VERR_NOT_IMPLEMENTED)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync rc = VINF_SUCCESS;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync return rc;
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync}
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync/** @copydoc PDMIBLOCK::pfnMerge */
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsyncstatic DECLCALLBACK(int) drvblockMerge(PPDMIBLOCK pInterface,
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync PFNSIMPLEPROGRESS pfnProgress,
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync void *pvUser)
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync{
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
d80c85a1bc7317da7d0cd1254fae6a20db039c8cvboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Check the state.
16a9adc14900ca18e6909679a579f6833425e030vboxsync */
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (!pThis->pDrvMedia)
16a9adc14900ca18e6909679a579f6833425e030vboxsync {
16a9adc14900ca18e6909679a579f6833425e030vboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
16a9adc14900ca18e6909679a579f6833425e030vboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
16a9adc14900ca18e6909679a579f6833425e030vboxsync }
16a9adc14900ca18e6909679a579f6833425e030vboxsync
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (!pThis->pDrvMedia->pfnMerge)
16a9adc14900ca18e6909679a579f6833425e030vboxsync return VERR_NOT_SUPPORTED;
16a9adc14900ca18e6909679a579f6833425e030vboxsync
16a9adc14900ca18e6909679a579f6833425e030vboxsync int rc = pThis->pDrvMedia->pfnMerge(pThis->pDrvMedia, pfnProgress, pvUser);
16a9adc14900ca18e6909679a579f6833425e030vboxsync return rc;
16a9adc14900ca18e6909679a579f6833425e030vboxsync}
16a9adc14900ca18e6909679a579f6833425e030vboxsync
16a9adc14900ca18e6909679a579f6833425e030vboxsync
16a9adc14900ca18e6909679a579f6833425e030vboxsync/** @copydoc PDMIBLOCK::pfnIsReadOnly */
16a9adc14900ca18e6909679a579f6833425e030vboxsyncstatic DECLCALLBACK(bool) drvblockIsReadOnly(PPDMIBLOCK pInterface)
16a9adc14900ca18e6909679a579f6833425e030vboxsync{
16a9adc14900ca18e6909679a579f6833425e030vboxsync PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
16a9adc14900ca18e6909679a579f6833425e030vboxsync
16a9adc14900ca18e6909679a579f6833425e030vboxsync /*
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Check the state.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!pThis->pDrvMedia)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return false;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync bool fRc = pThis->pDrvMedia->pfnIsReadOnly(pThis->pDrvMedia);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return fRc;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync}
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync/** @copydoc PDMIBLOCK::pfnGetSize */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncstatic DECLCALLBACK(uint64_t) drvblockGetSize(PPDMIBLOCK pInterface)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync{
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Check the state.
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync if (!pThis->pDrvMedia)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return 0;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync uint64_t cb = pThis->pDrvMedia->pfnGetSize(pThis->pDrvMedia);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogFlow(("drvblockGetSize: returns %llu\n", cb));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return cb;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync}
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync/** @copydoc PDMIBLOCK::pfnGetType */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncstatic DECLCALLBACK(PDMBLOCKTYPE) drvblockGetType(PPDMIBLOCK pInterface)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync{
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync LogFlow(("drvblockGetType: returns %d\n", pThis->enmType));
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return pThis->enmType;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync}
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync/** @copydoc PDMIBLOCK::pfnGetUuid */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsyncstatic DECLCALLBACK(int) drvblockGetUuid(PPDMIBLOCK pInterface, PRTUUID pUuid)
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync{
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync PDRVBLOCK pThis = PDMIBLOCK_2_DRVBLOCK(pInterface);
a9d49c8f2b28a72e6a4db86eee91e4569290157bvboxsync
a9d49c8f2b28a72e6a4db86eee91e4569290157bvboxsync /*
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync * Copy the uuid.
a9d49c8f2b28a72e6a4db86eee91e4569290157bvboxsync */
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync *pUuid = pThis->Uuid;
1bf495e3eec00dd79cecb6b36ef2a97f422c3737vboxsync return VINF_SUCCESS;
9496f2d398b49813176939d7a339ae513d5175efvboxsync}
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/* -=-=-=-=- IBlockAsync -=-=-=-=- */
9496f2d398b49813176939d7a339ae513d5175efvboxsync
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync/** Makes a PDRVBLOCK out of a PPDMIBLOCKASYNC. */
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync#define PDMIBLOCKASYNC_2_DRVBLOCK(pInterface) ( (PDRVBLOCK)((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IBlockAsync)) )
22ec733a5e041fcdfe02fce2eafc9faf8b0077ddvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** @copydoc PDMIBLOCKASYNC::pfnStartRead */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncstatic DECLCALLBACK(int) drvblockAsyncReadStart(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbRead, void *pvUser)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync{
9496f2d398b49813176939d7a339ae513d5175efvboxsync PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /*
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Check the state.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (!pThis->pDrvMediaAsync)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync {
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync }
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync int rc = pThis->pDrvMediaAsync->pfnStartRead(pThis->pDrvMediaAsync, off, pSeg, cSeg, cbRead, pvUser);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return rc;
d5ea45cc92d7f1d3ade8189944531f665bfe8ed5vboxsync}
5d0d754550d06b7d59a935e59caaf814462d53ccvboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync/** @copydoc PDMIBLOCKASYNC::pfnStartWrite */
d5ea45cc92d7f1d3ade8189944531f665bfe8ed5vboxsyncstatic DECLCALLBACK(int) drvblockAsyncWriteStart(PPDMIBLOCKASYNC pInterface, uint64_t off, PCRTSGSEG pSeg, unsigned cSeg, size_t cbWrite, void *pvUser)
f687f34bd232be13744edbc0cc5155fa5d4540edvboxsync{
d5ea45cc92d7f1d3ade8189944531f665bfe8ed5vboxsync PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Check the state.
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync */
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync if (!pThis->pDrvMediaAsync)
468c2bcb36eb9a032f5dd0fcb34db10bd58e9996vboxsync {
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
9496f2d398b49813176939d7a339ae513d5175efvboxsync }
16a9adc14900ca18e6909679a579f6833425e030vboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync int rc = pThis->pDrvMediaAsync->pfnStartWrite(pThis->pDrvMediaAsync, off, pSeg, cSeg, cbWrite, pvUser);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync return rc;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync}
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsync/** @copydoc PDMIBLOCKASYNC::pfnStartFLush */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncstatic DECLCALLBACK(int) drvblockAsyncFlushStart(PPDMIBLOCKASYNC pInterface, void *pvUser)
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync{
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync PDRVBLOCK pThis = PDMIBLOCKASYNC_2_DRVBLOCK(pInterface);
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync /*
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync * Check the state.
bbede9c189def47a9880f0ffb03c0c230c774185vboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (!pThis->pDrvMediaAsync)
ffbe6daf773e38167f3cabaf1f063d84ecd063e9vboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync }
fbf08fabb4c4b383d6aa2830c2bd5b943a26f10cvboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#ifdef VBOX_IGNORE_FLUSH
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (pThis->fIgnoreFlushAsync)
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync return VINF_VD_ASYNC_IO_FINISHED;
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync#endif /* VBOX_IGNORE_FLUSH */
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync int rc = pThis->pDrvMediaAsync->pfnStartFlush(pThis->pDrvMediaAsync, pvUser);
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync return rc;
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync}
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync
61d064a54f03596920c3918f58ecc7764074a5d8vboxsync/* -=-=-=-=- IMediaAsyncPort -=-=-=-=- */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync/** Makes a PDRVBLOCKASYNC out of a PPDMIMEDIAASYNCPORT. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#define PDMIMEDIAASYNCPORT_2_DRVBLOCK(pInterface) ( (PDRVBLOCK((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IMediaAsyncPort))) )
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncstatic DECLCALLBACK(int) drvblockAsyncTransferCompleteNotify(PPDMIMEDIAASYNCPORT pInterface, void *pvUser, int rcReq)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync{
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync PDRVBLOCK pThis = PDMIMEDIAASYNCPORT_2_DRVBLOCK(pInterface);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return pThis->pDrvBlockAsyncPort->pfnTransferCompleteNotify(pThis->pDrvBlockAsyncPort, pvUser, rcReq);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync}
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync/* -=-=-=-=- IBlockBios -=-=-=-=- */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync/** Makes a PDRVBLOCK out of a PPDMIBLOCKBIOS. */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync#define PDMIBLOCKBIOS_2_DRVBLOCK(pInterface) ( (PDRVBLOCK((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IBlockBios))) )
9496f2d398b49813176939d7a339ae513d5175efvboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** @copydoc PDMIBLOCKBIOS::pfnGetPCHSGeometry */
9496f2d398b49813176939d7a339ae513d5175efvboxsyncstatic DECLCALLBACK(int) drvblockGetPCHSGeometry(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pPCHSGeometry)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync{
9496f2d398b49813176939d7a339ae513d5175efvboxsync PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
16a9adc14900ca18e6909679a579f6833425e030vboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Check the state.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (!pThis->pDrvMedia)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync /*
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Use configured/cached values if present.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync if ( pThis->PCHSGeometry.cCylinders > 0
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync && pThis->PCHSGeometry.cHeads > 0
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync && pThis->PCHSGeometry.cSectors > 0)
9496f2d398b49813176939d7a339ae513d5175efvboxsync {
16a9adc14900ca18e6909679a579f6833425e030vboxsync *pPCHSGeometry = pThis->PCHSGeometry;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("%s: returns VINF_SUCCESS {%d,%d,%d}\n", __FUNCTION__, pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors));
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync return VINF_SUCCESS;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync }
9496f2d398b49813176939d7a339ae513d5175efvboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync * Call media.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync int rc = pThis->pDrvMedia->pfnBiosGetPCHSGeometry(pThis->pDrvMedia, &pThis->PCHSGeometry);
9496f2d398b49813176939d7a339ae513d5175efvboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (RT_SUCCESS(rc))
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync *pPCHSGeometry = pThis->PCHSGeometry;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("%s: returns %Rrc {%d,%d,%d}\n", __FUNCTION__, rc, pThis->PCHSGeometry.cCylinders, pThis->PCHSGeometry.cHeads, pThis->PCHSGeometry.cSectors));
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync }
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync else if (rc == VERR_NOT_IMPLEMENTED)
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync {
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync rc = VERR_PDM_GEOMETRY_NOT_SET;
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync }
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync return rc;
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync}
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync/** @copydoc PDMIBLOCKBIOS::pfnSetPCHSGeometry */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncstatic DECLCALLBACK(int) drvblockSetPCHSGeometry(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pPCHSGeometry)
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsync{
9496f2d398b49813176939d7a339ae513d5175efvboxsync LogFlow(("%s: cCylinders=%d cHeads=%d cSectors=%d\n", __FUNCTION__, pPCHSGeometry->cCylinders, pPCHSGeometry->cHeads, pPCHSGeometry->cSectors));
9496f2d398b49813176939d7a339ae513d5175efvboxsync PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Check the state.
16a9adc14900ca18e6909679a579f6833425e030vboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (!pThis->pDrvMedia)
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
9496f2d398b49813176939d7a339ae513d5175efvboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync }
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Call media. Ignore the not implemented return code.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync int rc = pThis->pDrvMedia->pfnBiosSetPCHSGeometry(pThis->pDrvMedia, pPCHSGeometry);
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if ( RT_SUCCESS(rc)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync || rc == VERR_NOT_IMPLEMENTED)
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync {
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync pThis->PCHSGeometry = *pPCHSGeometry;
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync rc = VINF_SUCCESS;
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync }
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync return rc;
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync}
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync/** @copydoc PDMIBLOCKBIOS::pfnGetLCHSGeometry */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsyncstatic DECLCALLBACK(int) drvblockGetLCHSGeometry(PPDMIBLOCKBIOS pInterface, PPDMMEDIAGEOMETRY pLCHSGeometry)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync{
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Check the state.
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync */
9496f2d398b49813176939d7a339ae513d5175efvboxsync if (!pThis->pDrvMedia)
16a9adc14900ca18e6909679a579f6833425e030vboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Use configured/cached values if present.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if ( pThis->LCHSGeometry.cCylinders > 0
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync && pThis->LCHSGeometry.cHeads > 0
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync && pThis->LCHSGeometry.cSectors > 0)
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync *pLCHSGeometry = pThis->LCHSGeometry;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync LogFlow(("%s: returns VINF_SUCCESS {%d,%d,%d}\n", __FUNCTION__, pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return VINF_SUCCESS;
9496f2d398b49813176939d7a339ae513d5175efvboxsync }
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync /*
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync * Call media.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync int rc = pThis->pDrvMedia->pfnBiosGetLCHSGeometry(pThis->pDrvMedia, &pThis->LCHSGeometry);
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync if (RT_SUCCESS(rc))
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync {
ce03ea57fdcf3d48523b1de5b894feb75e1b34davboxsync *pLCHSGeometry = pThis->LCHSGeometry;
9496f2d398b49813176939d7a339ae513d5175efvboxsync LogFlow(("%s: returns %Rrc {%d,%d,%d}\n", __FUNCTION__, rc, pThis->LCHSGeometry.cCylinders, pThis->LCHSGeometry.cHeads, pThis->LCHSGeometry.cSectors));
7766bf675357fd940d8c49e69a5d72dc6eaa6be4vboxsync }
9496f2d398b49813176939d7a339ae513d5175efvboxsync else if (rc == VERR_NOT_IMPLEMENTED)
9496f2d398b49813176939d7a339ae513d5175efvboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync rc = VERR_PDM_GEOMETRY_NOT_SET;
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync }
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return rc;
9496f2d398b49813176939d7a339ae513d5175efvboxsync}
16a9adc14900ca18e6909679a579f6833425e030vboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** @copydoc PDMIBLOCKBIOS::pfnSetLCHSGeometry */
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsyncstatic DECLCALLBACK(int) drvblockSetLCHSGeometry(PPDMIBLOCKBIOS pInterface, PCPDMMEDIAGEOMETRY pLCHSGeometry)
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync{
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync LogFlow(("%s: cCylinders=%d cHeads=%d cSectors=%d\n", __FUNCTION__, pLCHSGeometry->cCylinders, pLCHSGeometry->cHeads, pLCHSGeometry->cSectors));
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync /*
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync * Check the state.
9496f2d398b49813176939d7a339ae513d5175efvboxsync */
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync if (!pThis->pDrvMedia)
a9f41cb889f53e8407561a6155052c441eb0fc5fvboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync AssertMsgFailed(("Invalid state! Not mounted!\n"));
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync }
16a9adc14900ca18e6909679a579f6833425e030vboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
9496f2d398b49813176939d7a339ae513d5175efvboxsync * Call media. Ignore the not implemented return code.
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync */
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync int rc = pThis->pDrvMedia->pfnBiosSetLCHSGeometry(pThis->pDrvMedia, pLCHSGeometry);
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync if ( RT_SUCCESS(rc)
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync || rc == VERR_NOT_IMPLEMENTED)
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync {
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync pThis->LCHSGeometry = *pLCHSGeometry;
9496f2d398b49813176939d7a339ae513d5175efvboxsync rc = VINF_SUCCESS;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync }
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync return rc;
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync}
16a9adc14900ca18e6909679a579f6833425e030vboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync/** @copydoc PDMIBLOCKBIOS::pfnIsVisible */
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsyncstatic DECLCALLBACK(bool) drvblockIsVisible(PPDMIBLOCKBIOS pInterface)
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync{
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync LogFlow(("drvblockIsVisible: returns %d\n", pThis->fBiosVisible));
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync return pThis->fBiosVisible;
c7551981eb6d97331da479f68f14a9c56247e4f7vboxsync}
9496f2d398b49813176939d7a339ae513d5175efvboxsync
9496f2d398b49813176939d7a339ae513d5175efvboxsync
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync/** @copydoc PDMIBLOCKBIOS::pfnGetType */
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsyncstatic DECLCALLBACK(PDMBLOCKTYPE) drvblockBiosGetType(PPDMIBLOCKBIOS pInterface)
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync{
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync PDRVBLOCK pThis = PDMIBLOCKBIOS_2_DRVBLOCK(pInterface);
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync LogFlow(("drvblockBiosGetType: returns %d\n", pThis->enmType));
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync return pThis->enmType;
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync}
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync/* -=-=-=-=- IMount -=-=-=-=- */
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync/** Makes a PDRVBLOCK out of a PPDMIMOUNT. */
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync#define PDMIMOUNT_2_DRVBLOCK(pInterface) ( (PDRVBLOCK)((uintptr_t)pInterface - RT_OFFSETOF(DRVBLOCK, IMount)) )
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync/** @copydoc PDMIMOUNT::pfnMount */
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsyncstatic DECLCALLBACK(int) drvblockMount(PPDMIMOUNT pInterface, const char *pszFilename, const char *pszCoreDriver)
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync{
369a8817da53dbd5ea6ac360ca0376dba003cde4vboxsync LogFlow(("drvblockMount: pszFilename=%p:{%s} pszCoreDriver=%p:{%s}\n", pszFilename, pszFilename, pszCoreDriver, pszCoreDriver));
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
59d7f5939d42ad9d344fbad8401e00a900db92c5vboxsync
5341459ca931b65de60b5af2a4cba6836b6b45cavboxsync /*
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Validate state.
16a9adc14900ca18e6909679a579f6833425e030vboxsync */
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (pThis->pDrvMedia)
16a9adc14900ca18e6909679a579f6833425e030vboxsync {
16a9adc14900ca18e6909679a579f6833425e030vboxsync AssertMsgFailed(("Already mounted\n"));
16a9adc14900ca18e6909679a579f6833425e030vboxsync return VERR_PDM_MEDIA_MOUNTED;
16a9adc14900ca18e6909679a579f6833425e030vboxsync }
16a9adc14900ca18e6909679a579f6833425e030vboxsync
16a9adc14900ca18e6909679a579f6833425e030vboxsync /*
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Prepare configuration.
16a9adc14900ca18e6909679a579f6833425e030vboxsync */
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (pszFilename)
16a9adc14900ca18e6909679a579f6833425e030vboxsync {
16a9adc14900ca18e6909679a579f6833425e030vboxsync int rc = PDMDrvHlpMountPrepare(pThis->pDrvIns, pszFilename, pszCoreDriver);
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (RT_FAILURE(rc))
16a9adc14900ca18e6909679a579f6833425e030vboxsync {
16a9adc14900ca18e6909679a579f6833425e030vboxsync Log(("drvblockMount: Prepare failed for \"%s\" rc=%Rrc\n", pszFilename, rc));
16a9adc14900ca18e6909679a579f6833425e030vboxsync return rc;
16a9adc14900ca18e6909679a579f6833425e030vboxsync }
16a9adc14900ca18e6909679a579f6833425e030vboxsync }
16a9adc14900ca18e6909679a579f6833425e030vboxsync
16a9adc14900ca18e6909679a579f6833425e030vboxsync /*
16a9adc14900ca18e6909679a579f6833425e030vboxsync * Attach the media driver and query it's interface.
16a9adc14900ca18e6909679a579f6833425e030vboxsync */
16a9adc14900ca18e6909679a579f6833425e030vboxsync uint32_t fTachFlags = 0; /** @todo figure attachment flags for mount. */
16a9adc14900ca18e6909679a579f6833425e030vboxsync PPDMIBASE pBase;
16a9adc14900ca18e6909679a579f6833425e030vboxsync int rc = PDMDrvHlpAttach(pThis->pDrvIns, fTachFlags, &pBase);
16a9adc14900ca18e6909679a579f6833425e030vboxsync if (RT_FAILURE(rc))
16a9adc14900ca18e6909679a579f6833425e030vboxsync {
16a9adc14900ca18e6909679a579f6833425e030vboxsync Log(("drvblockMount: Attach failed rc=%Rrc\n", rc));
16a9adc14900ca18e6909679a579f6833425e030vboxsync return rc;
16a9adc14900ca18e6909679a579f6833425e030vboxsync }
16a9adc14900ca18e6909679a579f6833425e030vboxsync
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync pThis->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync if (pThis->pDrvMedia)
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync {
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync /** @todo r=klaus missing async handling, this is just a band aid to
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync * avoid using stale information */
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync pThis->pDrvMediaAsync = NULL;
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync /*
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync * Initialize state.
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync */
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync pThis->fLocked = false;
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync pThis->PCHSGeometry.cCylinders = 0;
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync pThis->PCHSGeometry.cHeads = 0;
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync pThis->PCHSGeometry.cSectors = 0;
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync pThis->LCHSGeometry.cCylinders = 0;
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync pThis->LCHSGeometry.cHeads = 0;
975ad9d9bc9c4dc96b41d9f67a65228b1b338e2avboxsync pThis->LCHSGeometry.cSectors = 0;
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync#ifdef VBOX_PERIODIC_FLUSH
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync pThis->cbDataWritten = 0;
9c149a2789022f5011e88fb62f02a1cc8068e88fvboxsync#endif /* VBOX_PERIODIC_FLUSH */
efff36b306e370346025647a158689021df2e1d1vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Notify driver/device above us.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (pThis->pDrvMountNotify)
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync pThis->pDrvMountNotify->pfnMountNotify(pThis->pDrvMountNotify);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync Log(("drvblockMount: Success\n"));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync return VINF_SUCCESS;
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync }
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync else
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync rc = VERR_PDM_MISSING_INTERFACE_BELOW;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /*
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Failed, detatch the media driver.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync AssertMsgFailed(("No media interface!\n"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync int rc2 = PDMDrvHlpDetach(pThis->pDrvIns, fTachFlags);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync AssertRC(rc2);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->pDrvMedia = NULL;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return rc;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync}
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync/** @copydoc PDMIMOUNT::pfnUnmount */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncstatic DECLCALLBACK(int) drvblockUnmount(PPDMIMOUNT pInterface, bool fForce)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync{
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /*
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Validate state.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (!pThis->pDrvMedia)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync {
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync Log(("drvblockUmount: Not mounted\n"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return VERR_PDM_MEDIA_NOT_MOUNTED;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync }
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (pThis->fLocked && !fForce)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync {
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync Log(("drvblockUmount: Locked\n"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return VERR_PDM_MEDIA_LOCKED;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync }
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* Media is no longer locked even if it was previously. */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->fLocked = false;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /*
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Detach the media driver and query it's interface.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync int rc = PDMDrvHlpDetach(pThis->pDrvIns, 0 /*fFlags*/);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync if (RT_FAILURE(rc))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync {
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync Log(("drvblockUnmount: Detach failed rc=%Rrc\n", rc));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return rc;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync Assert(!pThis->pDrvMedia);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /*
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Notify driver/device above us.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (pThis->pDrvMountNotify)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->pDrvMountNotify->pfnUnmountNotify(pThis->pDrvMountNotify);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Log(("drvblockUnmount: success\n"));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return VINF_SUCCESS;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync}
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/** @copydoc PDMIMOUNT::pfnIsMounted */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncstatic DECLCALLBACK(bool) drvblockIsMounted(PPDMIMOUNT pInterface)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync{
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return pThis->pDrvMedia != NULL;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync}
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/** @copydoc PDMIMOUNT::pfnLock */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncstatic DECLCALLBACK(int) drvblockLock(PPDMIMOUNT pInterface)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync{
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Log(("drvblockLock: %d -> %d\n", pThis->fLocked, true));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->fLocked = true;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return VINF_SUCCESS;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync}
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/** @copydoc PDMIMOUNT::pfnUnlock */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncstatic DECLCALLBACK(int) drvblockUnlock(PPDMIMOUNT pInterface)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync{
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Log(("drvblockUnlock: %d -> %d\n", pThis->fLocked, false));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->fLocked = false;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return VINF_SUCCESS;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync}
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/** @copydoc PDMIMOUNT::pfnIsLocked */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncstatic DECLCALLBACK(bool) drvblockIsLocked(PPDMIMOUNT pInterface)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync{
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDRVBLOCK pThis = PDMIMOUNT_2_DRVBLOCK(pInterface);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return pThis->fLocked;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync}
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/* -=-=-=-=- IBase -=-=-=-=- */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync/**
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * @interface_method_impl{PDMIBASE,pfnQueryInterface}
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncstatic DECLCALLBACK(void *) drvblockQueryInterface(PPDMIBASE pInterface, const char *pszIID)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync{
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pDrvIns->IBase);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCK, &pThis->IBlock);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKBIOS, pThis->fBiosVisible ? &pThis->IBlockBios : NULL);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMOUNT, pThis->fMountable ? &pThis->IMount : NULL);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBLOCKASYNC, pThis->pDrvMediaAsync ? &pThis->IBlockAsync : NULL);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDMIBASE_RETURN_INTERFACE(pszIID, PDMIMEDIAASYNCPORT, pThis->pDrvBlockAsyncPort ? &pThis->IMediaAsyncPort : NULL);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync return NULL;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync}
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/* -=-=-=-=- driver interface -=-=-=-=- */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/** @copydoc FNPDMDRVDETACH. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncstatic DECLCALLBACK(void) drvblockDetach(PPDMDRVINS pDrvIns, uint32_t fFlags)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync{
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->pDrvMedia = NULL;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->pDrvMediaAsync = NULL;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync NOREF(fFlags);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync}
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/**
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Reset notification.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync *
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @returns VBox status.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @param pDevIns The driver instance data.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncstatic DECLCALLBACK(void) drvblockReset(PPDMDRVINS pDrvIns)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync{
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->fLocked = false;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync}
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync/**
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Construct a block driver instance.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync *
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * @copydoc FNPDMDRVCONSTRUCT
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsyncstatic DECLCALLBACK(int) drvblockConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync{
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDRVBLOCK pThis = PDMINS_2_DATA(pDrvIns, PDRVBLOCK);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync LogFlow(("drvblockConstruct: iInstance=%d\n", pDrvIns->iInstance));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync PDMDRV_CHECK_VERSIONS_RETURN(pDrvIns);
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Validate configuration.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#if defined(VBOX_PERIODIC_FLUSH) || defined(VBOX_IGNORE_FLUSH)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (!CFGMR3AreValuesValid(pCfg, "Type\0Locked\0BIOSVisible\0AttachFailError\0Cylinders\0Heads\0Sectors\0Mountable\0FlushInterval\0IgnoreFlush\0IgnoreFlushAsync\0"))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#else /* !(VBOX_PERIODIC_FLUSH || VBOX_IGNORE_FLUSH) */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync if (!CFGMR3AreValuesValid(pCfg, "Type\0Locked\0BIOSVisible\0AttachFailError\0Cylinders\0Heads\0Sectors\0Mountable\0"))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync#endif /* !(VBOX_PERIODIC_FLUSH || VBOX_IGNORE_FLUSH) */
59a2c1c0a4a0762b46bc5ff056f5705ec9c0a660vboxsync return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync * Initialize most of the data members.
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->pDrvIns = pDrvIns;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* IBase. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pDrvIns->IBase.pfnQueryInterface = drvblockQueryInterface;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* IBlock. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlock.pfnRead = drvblockRead;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlock.pfnWrite = drvblockWrite;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlock.pfnFlush = drvblockFlush;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlock.pfnMerge = drvblockMerge;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlock.pfnIsReadOnly = drvblockIsReadOnly;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlock.pfnGetSize = drvblockGetSize;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlock.pfnGetType = drvblockGetType;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlock.pfnGetUuid = drvblockGetUuid;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* IBlockBios. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlockBios.pfnGetPCHSGeometry = drvblockGetPCHSGeometry;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->IBlockBios.pfnSetPCHSGeometry = drvblockSetPCHSGeometry;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlockBios.pfnGetLCHSGeometry = drvblockGetLCHSGeometry;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->IBlockBios.pfnSetLCHSGeometry = drvblockSetLCHSGeometry;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->IBlockBios.pfnIsVisible = drvblockIsVisible;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlockBios.pfnGetType = drvblockBiosGetType;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* IMount. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IMount.pfnMount = drvblockMount;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IMount.pfnUnmount = drvblockUnmount;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IMount.pfnIsMounted = drvblockIsMounted;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->IMount.pfnLock = drvblockLock;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IMount.pfnUnlock = drvblockUnlock;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IMount.pfnIsLocked = drvblockIsLocked;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* IBlockAsync. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlockAsync.pfnStartRead = drvblockAsyncReadStart;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlockAsync.pfnStartWrite = drvblockAsyncWriteStart;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IBlockAsync.pfnStartFlush = drvblockAsyncFlushStart;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /* IMediaAsyncPort. */
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->IMediaAsyncPort.pfnTransferCompleteNotify = drvblockAsyncTransferCompleteNotify;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync /*
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync * Get the IBlockPort & IMountNotify interfaces of the above driver/device.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync pThis->pDrvBlockPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIBLOCKPORT);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync if (!pThis->pDrvBlockPort)
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_ABOVE,
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync N_("No block port interface above"));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync /* Try to get the optional async block port interface above. */
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync pThis->pDrvBlockAsyncPort = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIBLOCKASYNCPORT);
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync pThis->pDrvMountNotify = PDMIBASE_QUERY_INTERFACE(pDrvIns->pUpBase, PDMIMOUNTNOTIFY);
4bd3e7685494afe7c303fc131c66e685023b6b4avboxsync
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync /*
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync * Query configuration.
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync */
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync /* type */
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync char *psz;
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync int rc = CFGMR3QueryStringAlloc(pCfg, "Type", &psz);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync if (RT_FAILURE(rc))
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_BLOCK_NO_TYPE, N_("Failed to obtain the type"));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync if (!strcmp(psz, "HardDisk"))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->enmType = PDMBLOCKTYPE_HARD_DISK;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync else if (!strcmp(psz, "DVD"))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->enmType = PDMBLOCKTYPE_DVD;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync else if (!strcmp(psz, "CDROM"))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->enmType = PDMBLOCKTYPE_CDROM;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync else if (!strcmp(psz, "Floppy 2.88"))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->enmType = PDMBLOCKTYPE_FLOPPY_2_88;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync else if (!strcmp(psz, "Floppy 1.44"))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync pThis->enmType = PDMBLOCKTYPE_FLOPPY_1_44;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync else if (!strcmp(psz, "Floppy 1.20"))
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync pThis->enmType = PDMBLOCKTYPE_FLOPPY_1_20;
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync else if (!strcmp(psz, "Floppy 720"))
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync pThis->enmType = PDMBLOCKTYPE_FLOPPY_720;
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync else if (!strcmp(psz, "Floppy 360"))
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync pThis->enmType = PDMBLOCKTYPE_FLOPPY_360;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync else
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync {
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_BLOCK_UNKNOWN_TYPE, RT_SRC_POS,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync N_("Unknown type \"%s\""), psz);
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync MMR3HeapFree(psz);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return VERR_PDM_BLOCK_UNKNOWN_TYPE;
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync }
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync Log2(("drvblockConstruct: enmType=%d\n", pThis->enmType));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync MMR3HeapFree(psz); psz = NULL;
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* Mountable */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = CFGMR3QueryBoolDef(pCfg, "Mountable", &pThis->fMountable, false);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if (RT_FAILURE(rc))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Mountable\" from the config"));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync /* Locked */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync rc = CFGMR3QueryBoolDef(pCfg, "Locked", &pThis->fLocked, false);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (RT_FAILURE(rc))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Locked\" from the config"));
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* BIOS visible */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync rc = CFGMR3QueryBoolDef(pCfg, "BIOSVisible", &pThis->fBiosVisible, true);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if (RT_FAILURE(rc))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"BIOSVisible\" from the config"));
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /** @todo AttachFailError is currently completely ignored. */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* Cylinders */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync rc = CFGMR3QueryU32Def(pCfg, "Cylinders", &pThis->LCHSGeometry.cCylinders, 0);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if (RT_FAILURE(rc))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Cylinders\" from the config"));
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* Heads */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync rc = CFGMR3QueryU32Def(pCfg, "Heads", &pThis->LCHSGeometry.cHeads, 0);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if (RT_FAILURE(rc))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Heads\" from the config"));
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync /* Sectors */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = CFGMR3QueryU32Def(pCfg, "Sectors", &pThis->LCHSGeometry.cSectors, 0);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if (RT_FAILURE(rc))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Sectors\" from the config"));
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync
8dbf70ba2345e69b0b6d45c38cf1add0ef10591cvboxsync /* Uuid */
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync rc = CFGMR3QueryStringAlloc(pCfg, "Uuid", &psz);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (rc == VERR_CFGM_VALUE_NOT_FOUND)
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync RTUuidClear(&pThis->Uuid);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync else if (RT_SUCCESS(rc))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync {
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync rc = RTUuidFromStr(&pThis->Uuid, psz);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync if (RT_FAILURE(rc))
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync {
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, "%s",
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync N_("Uuid from string failed on \"%s\""), psz);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync MMR3HeapFree(psz);
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync return rc;
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync }
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync MMR3HeapFree(psz); psz = NULL;
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync }
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync else
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"Uuid\" from the config"));
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync#ifdef VBOX_PERIODIC_FLUSH
d571b6e3237f0ce89ea27f6fa4635d41c5ee3d88vboxsync rc = CFGMR3QueryU32Def(pCfg, "FlushInterval", &pThis->cbFlushInterval, 0);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (RT_FAILURE(rc))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"FlushInterval\" from the config"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync#endif /* VBOX_PERIODIC_FLUSH */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync#ifdef VBOX_IGNORE_FLUSH
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = CFGMR3QueryBoolDef(pCfg, "IgnoreFlush", &pThis->fIgnoreFlush, true);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (RT_FAILURE(rc))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"IgnoreFlush\" from the config"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (pThis->fIgnoreFlush)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync LogRel(("DrvBlock: Flushes will be ignored\n"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync else
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync LogRel(("DrvBlock: Flushes will be passed to the disk\n"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = CFGMR3QueryBoolDef(pCfg, "IgnoreFlushAsync", &pThis->fIgnoreFlushAsync, false);
efff36b306e370346025647a158689021df2e1d1vboxsync if (RT_FAILURE(rc))
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync return PDMDRV_SET_ERROR(pDrvIns, rc, N_("Failed to query \"IgnoreFlushAsync\" from the config"));
51fe8789a74f6c118894aaa12eb69ec155386dbdvboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (pThis->fIgnoreFlushAsync)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync LogRel(("DrvBlock: Async flushes will be ignored\n"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync else
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync LogRel(("DrvBlock: Async flushes will be passed to the disk\n"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync#endif /* VBOX_IGNORE_FLUSH */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /*
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Try attach driver below and query it's media interface.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PPDMIBASE pBase;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync rc = PDMDrvHlpAttach(pDrvIns, fFlags, &pBase);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if ( rc == VERR_PDM_NO_ATTACHED_DRIVER
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync && pThis->enmType != PDMBLOCKTYPE_HARD_DISK)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return VINF_SUCCESS;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (RT_FAILURE(rc))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync N_("Failed to attach driver below us! %Rrf"), rc);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->pDrvMedia = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIA);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (!pThis->pDrvMedia)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return PDMDRV_SET_ERROR(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync N_("No media or async media interface below"));
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* Try to get the optional async interface. */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->pDrvMediaAsync = PDMIBASE_QUERY_INTERFACE(pBase, PDMIMEDIAASYNC);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (RTUuidIsNull(&pThis->Uuid))
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync {
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync if (pThis->enmType == PDMBLOCKTYPE_HARD_DISK)
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync pThis->pDrvMedia->pfnGetUuid(pThis->pDrvMedia, &pThis->Uuid);
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync }
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync return VINF_SUCCESS;
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync}
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync/**
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync * Block driver registration record.
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsyncconst PDMDRVREG g_DrvBlock =
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync{
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* u32Version */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDM_DRVREG_VERSION,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* szName */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync "Block",
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* szRCMod */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync "",
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* szR0Mod */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync "",
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pszDescription */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync "Generic block driver.",
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* fFlags */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* fClass. */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDM_DRVREG_CLASS_BLOCK,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* cMaxInstances */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync ~0,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* cbInstance */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync sizeof(DRVBLOCK),
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnConstruct */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync drvblockConstruct,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnDestruct */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnRelocate */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnIOCtl */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnPowerOn */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnReset */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync drvblockReset,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnSuspend */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnResume */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnAttach */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnDetach */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync drvblockDetach,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnPowerOff */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* pfnSoftReset */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync NULL,
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync /* u32EndVersion */
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync PDM_DRVREG_VERSION
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync};
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync
cc15c3fa4bb2d3fb91e4d0cd15a73133963f86b0vboxsync