dvm.cpp revision f5f42fa2ec9924006cad8e5adc646b34b35ba3c3
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/* $Id$ */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** @file
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * IPRT Disk Volume Management API (DVM) - generic code.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Copyright (C) 2011 Oracle Corporation
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * available from http://www.virtualbox.org. This file is free software;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * you can redistribute it and/or modify it under the terms of the GNU
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * General Public License (GPL) as published by the Free Software
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The contents of this file may alternatively be used under the terms
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * of the Common Development and Distribution License Version 1.0
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * VirtualBox OSE distribution, in which case the provisions of the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * CDDL are applicable instead of those of the GPL.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * You may elect to license modified versions of this file under the
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * terms and conditions of either the GPL or the CDDL or both.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync/*******************************************************************************
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync* Header Files *
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync*******************************************************************************/
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#include <iprt/types.h>
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#include <iprt/assert.h>
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#include <iprt/mem.h>
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#include <iprt/dvm.h>
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#include <iprt/err.h>
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#include <iprt/asm.h>
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#include <iprt/string.h>
956a0e3c076406b83d635174a201fd8761ee5133vboxsync#include "internal/dvm.h"
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*******************************************************************************
956a0e3c076406b83d635174a201fd8761ee5133vboxsync* Structures and Typedefs *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync*******************************************************************************/
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/**
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The internal volume manager structure.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsynctypedef struct RTDVMINTERNAL
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The DVM magic (RTDVM_MAGIC). */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t u32Magic;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The disk descriptor. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTDVMDISK DvmDisk;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Pointer to the backend operations table after a successful probe. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PCRTDVMFMTOPS pDvmFmtOps;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The format specific volume manager data. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTDVMFMT hVolMgrFmt;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Reference counter. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t volatile cRefs;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync} RTDVMINTERNAL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** Pointer to an internal volume manager. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsynctypedef RTDVMINTERNAL *PRTDVMINTERNAL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/**
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * The internal volume structure.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsynctypedef struct RTDVMVOLUMEINTERNAL
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** The DVM volume magic (RTDVMVOLUME_MAGIC). */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t u32Magic;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Pointer to the owning volume manager. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Format specific volume data. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTDVMVOLUMEFMT hVolFmt;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Reference counter. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t volatile cRefs;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync} RTDVMVOLUMEINTERNAL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** Pointer to an internal volume. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsynctypedef RTDVMVOLUMEINTERNAL *PRTDVMVOLUMEINTERNAL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*******************************************************************************
956a0e3c076406b83d635174a201fd8761ee5133vboxsync* Global variables *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync*******************************************************************************/
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsyncextern RTDVMFMTOPS g_rtDvmFmtMbr;
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsyncextern RTDVMFMTOPS g_rtDvmFmtGpt;
f5f42fa2ec9924006cad8e5adc646b34b35ba3c3vboxsyncextern RTDVMFMTOPS g_rtDvmFmtBsdLbl;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/**
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Supported volume formats.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic PCRTDVMFMTOPS g_aDvmFmts[] =
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync &g_rtDvmFmtMbr,
f5f42fa2ec9924006cad8e5adc646b34b35ba3c3vboxsync &g_rtDvmFmtGpt,
f5f42fa2ec9924006cad8e5adc646b34b35ba3c3vboxsync &g_rtDvmFmtBsdLbl
956a0e3c076406b83d635174a201fd8761ee5133vboxsync};
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/**
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Descriptions of the volume types.
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync *
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync * This is indexed by RTDVMVOLTYPE.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic const char * g_apcszDvmVolTypes[] =
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "Invalid",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "Unknown",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "NTFS",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "FAT16",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "FAT32",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "Linux swap",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "Linux native",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "Linux LVM",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "Linux SoftRaid",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "FreeBSD",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "NetBSD",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "OpenBSD",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "Mac OS X HFS or HFS+",
956a0e3c076406b83d635174a201fd8761ee5133vboxsync "Solaris"
956a0e3c076406b83d635174a201fd8761ee5133vboxsync};
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PFNDVMWRITE pfnWrite, uint64_t cbDisk,
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint64_t cbSector, void *pvUser)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VINF_SUCCESS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (VALID_PTR(pThis))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->u32Magic = RTDVM_MAGIC;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.cbDisk = cbDisk;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.cbSector = cbSector;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.pvUser = pvUser;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.pfnRead = pfnRead;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.pfnWrite = pfnWrite;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->pDvmFmtOps = NULL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->hVolMgrFmt = NIL_RTDVMFMT;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->cRefs = 1;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *phVolMgr = pThis;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync else
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = VERR_NO_MEMORY;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(uint32_t) RTDvmRetain(RTDVM hVolMgr)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return cRefs;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/**
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Destroys a volume manager handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pThis The volume manager to destroy.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic void rtDvmDestroy(PRTDVMINTERNAL pThis)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (pThis->hVolMgrFmt != NIL_RTDVMFMT)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtr(pThis->pDvmFmtOps);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* Let the backend do it's own cleanup first. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->pDvmFmtOps->pfnClose(pThis->hVolMgrFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->hVolMgrFmt = NIL_RTDVMFMT;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.cbDisk = 0;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.pvUser = NULL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.pfnRead = NULL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->DvmDisk.pfnWrite = NULL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->u32Magic = RTDVM_MAGIC_DEAD;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTMemFree(pThis);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(uint32_t) RTDvmRelease(RTDVM hVolMgr)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (pThis == NIL_RTDVM)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return 0;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (cRefs == 0)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rtDvmDestroy(pThis);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return cRefs;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmMapOpen(RTDVM hVolMgr)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VINF_SUCCESS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t uScoreMax = RTDVM_MATCH_SCORE_UNSUPPORTED;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PCRTDVMFMTOPS pDvmFmtOpsMatch = NULL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync Assert(!pThis->pDvmFmtOps);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t uScore;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = pDvmFmtOps->pfnProbe(&pThis->DvmDisk, &uScore);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if ( RT_SUCCESS(rc)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync && uScore > uScoreMax)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pDvmFmtOpsMatch = pDvmFmtOps;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uScoreMax = uScore;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync else if (RT_FAILURE(rc))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync break;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (RT_SUCCESS(rc))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (uScoreMax > RTDVM_MATCH_SCORE_UNSUPPORTED)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtr(pDvmFmtOpsMatch);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* Open the format. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = pDvmFmtOpsMatch->pfnOpen(&pThis->DvmDisk, &pThis->hVolMgrFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (RT_SUCCESS(rc))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->pDvmFmtOps = pDvmFmtOpsMatch;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync else
f5f42fa2ec9924006cad8e5adc646b34b35ba3c3vboxsync rc = VERR_NOT_SUPPORTED;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VINF_SUCCESS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pszFmt, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->hVolMgrFmt == NIL_RTDVMFMT, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync for (unsigned i = 0; i < RT_ELEMENTS(g_aDvmFmts); i++)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PCRTDVMFMTOPS pDvmFmtOps = g_aDvmFmts[i];
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (!RTStrCmp(pDvmFmtOps->pcszFmt, pszFmt))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = pDvmFmtOps->pfnInitialize(&pThis->DvmDisk, &pThis->hVolMgrFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (RT_SUCCESS(rc))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->pDvmFmtOps = pDvmFmtOps;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync break;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(const char *) RTDvmMapGetFormat(RTDVM hVolMgr)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, NULL);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, NULL);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, NULL);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pDvmFmtOps->pcszFmt;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(uint32_t) RTDvmMapGetValidVolumes(RTDVM hVolMgr)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(uint32_t) RTDvmMapGetMaxVolumes(RTDVM hVolMgr)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pDvmFmtOps->pfnGetMaxVolumes(pThis->hVolMgrFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUME phVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VINF_SUCCESS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pVol = NULL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (VALID_PTR(pVol))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVol->u32Magic = RTDVMVOLUME_MAGIC;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVol->cRefs = 1;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVol->pVolMgr = pThis;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVol->hVolFmt = hVolFmt;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* Reference the volume manager. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTDvmRetain(pThis);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *phVol = pVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync else
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = VERR_NO_MEMORY;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmMapQueryFirstVolume(RTDVM hVolMgr, PRTDVMVOLUME phVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VINF_SUCCESS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(phVol, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (RT_SUCCESS(rc))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = rtDvmVolumeCreate(pThis, hVolFmt, phVol);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (RT_FAILURE(rc))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VINF_SUCCESS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pVol = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pVol, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pVol->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(phVolNext, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTDVMVOLUMEFMT hVolFmtNext = NIL_RTDVMVOLUMEFMT;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmtNext);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (RT_SUCCESS(rc))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rc = rtDvmVolumeCreate(pThis, hVolFmtNext, phVolNext);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (RT_FAILURE(rc))
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->pDvmFmtOps->pfnVolumeClose(hVolFmtNext);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(uint32_t) RTDvmVolumeRetain(RTDVMVOLUME hVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertMsg(cRefs > 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return cRefs;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/**
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * Destroys a volume handle.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * @param pThis The volume to destroy.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncstatic void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pVolMgr = pThis->pVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtr(pVolMgr);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* Close the volume. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->pVolMgr = NULL;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->hVolFmt = NIL_RTDVMVOLUMEFMT;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTMemFree(pThis);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /* Release the reference of the volume manager. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync RTDvmRelease(pVolMgr);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(uint32_t) RTDvmVolumeRelease(RTDVMVOLUME hVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (pThis == NIL_RTDVMVOLUME)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return 0;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT32_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertMsg(cRefs < _1M, ("%#x %p\n", cRefs, pThis));
956a0e3c076406b83d635174a201fd8761ee5133vboxsync if (cRefs == 0)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync rtDvmVolumeDestroy(pThis);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return cRefs;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(uint64_t) RTDvmVolumeGetSize(RTDVMVOLUME hVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, 0);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, 0);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetSize(pThis->hVolFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmVolumeQueryName(RTDVMVOLUME hVol, char **ppszVolName)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(ppszVolName, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pVolMgr->pDvmFmtOps->pfnVolumeQueryName(pThis->hVolFmt, ppszVolName);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(RTDVMVOLTYPE) RTDvmVolumeGetType(RTDVMVOLUME hVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, RTDVMVOLTYPE_INVALID);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, RTDVMVOLTYPE_INVALID);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetType(pThis->hVolFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(uint64_t) RTDvmVolumeGetFlags(RTDVMVOLUME hVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, UINT64_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, UINT64_MAX);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pVolMgr->pDvmFmtOps->pfnVolumeGetFlags(pThis->hVolFmt);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmVolumeRead(RTDVMVOLUME hVol, uint64_t off, void *pvBuf, size_t cbRead)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pvBuf, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(cbRead > 0, VERR_INVALID_PARAMETER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pVolMgr->pDvmFmtOps->pfnVolumeRead(pThis->hVolFmt, off, pvBuf, cbRead);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmVolumeWrite(RTDVMVOLUME hVol, uint64_t off, const void *pvBuf, size_t cbWrite)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pvBuf, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(cbWrite > 0, VERR_INVALID_PARAMETER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return pThis->pVolMgr->pDvmFmtOps->pfnVolumeWrite(pThis->hVolFmt, off, pvBuf, cbWrite);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(const char *) RTDvmVolumeTypeGetDescr(RTDVMVOLTYPE enmVolType)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
68fb2428898c55a7172e6a75a0a8d7ce259919bdvboxsync AssertReturn(enmVolType >= RTDVMVOLTYPE_INVALID && enmVolType < RTDVMVOLTYPE_END, NULL);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return g_apcszDvmVolTypes[enmVolType];
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}