956a0e3c076406b83d635174a201fd8761ee5133vboxsync/* $Id$ */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/** @file
956a0e3c076406b83d635174a201fd8761ee5133vboxsync * IPRT Disk Volume Management API (DVM) - generic code.
956a0e3c076406b83d635174a201fd8761ee5133vboxsync */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync/*
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2011-2012 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>
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync#include <iprt/list.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;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /** Flags passed on manager creation. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync uint32_t fFlags;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Reference counter. */
956a0e3c076406b83d635174a201fd8761ee5133vboxsync uint32_t volatile cRefs;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /** List of recognised volumes (RTDVMVOLUMEINTERNAL). */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTLISTANCHOR VolumeList;
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). */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync uint32_t u32Magic;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /** Node for the volume list. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTLISTNODE VolumeNode;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Pointer to the owning volume manager. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMINTERNAL pVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Format specific volume data. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTDVMVOLUMEFMT hVolFmt;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /** Set block status.callback */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /** Opaque user data. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync void *pvUser;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync /** Reference counter. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync 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
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync/**
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * Creates a new volume.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync *
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * @returns IPRT status code.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * @param pThis The DVM map instance.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * @param hVolFmt The format specific volume handle.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * @param phVol Where to store the generic volume handle on success.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsyncstatic int rtDvmVolumeCreate(PRTDVMINTERNAL pThis, RTDVMVOLUMEFMT hVolFmt,
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMVOLUME phVol)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync{
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync int rc = VINF_SUCCESS;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMVOLUMEINTERNAL pVol = NULL;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pVol = (PRTDVMVOLUMEINTERNAL)RTMemAllocZ(sizeof(RTDVMVOLUMEINTERNAL));
735f45920cc3022a47b74cec9cf6eb7ab00d64dbvboxsync if (pVol)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pVol->u32Magic = RTDVMVOLUME_MAGIC;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pVol->cRefs = 0;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pVol->pVolMgr = pThis;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pVol->hVolFmt = hVolFmt;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync *phVol = pVol;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync else
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync rc = VERR_NO_MEMORY;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync return rc;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync}
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync/**
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * Destroys a volume handle.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync *
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync * @param pThis The volume to destroy.
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsyncstatic void rtDvmVolumeDestroy(PRTDVMVOLUMEINTERNAL pThis)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync{
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMINTERNAL pVolMgr = pThis->pVolMgr;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertPtr(pVolMgr);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /* Close the volume. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pVolMgr->pDvmFmtOps->pfnVolumeClose(pThis->hVolFmt);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->u32Magic = RTDVMVOLUME_MAGIC_DEAD;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->pVolMgr = NULL;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->hVolFmt = NIL_RTDVMVOLUMEFMT;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTMemFree(pThis);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /* Release the reference of the volume manager. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTDvmRelease(pVolMgr);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync}
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmCreate(PRTDVM phVolMgr, PFNDVMREAD pfnRead,
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PFNDVMWRITE pfnWrite, uint64_t cbDisk,
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync uint64_t cbSector, uint32_t fFlags, void *pvUser)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VINF_SUCCESS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertMsgReturn(!(fFlags & ~DVM_FLAGS_MASK),
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync ("Invalid flags given %#x\n", fFlags),
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync VERR_INVALID_PARAMETER);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis = (PRTDVMINTERNAL)RTMemAllocZ(sizeof(RTDVMINTERNAL));
735f45920cc3022a47b74cec9cf6eb7ab00d64dbvboxsync if (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;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->fFlags = fFlags;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->cRefs = 1;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTListInit(&pThis->VolumeList);
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))
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync uint32_t cVols;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync pThis->pDvmFmtOps = pDvmFmtOpsMatch;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync cVols = pThis->pDvmFmtOps->pfnGetValidVolumes(pThis->hVolMgrFmt);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /* Construct volume list. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (cVols)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMVOLUMEINTERNAL pVol = NULL;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTDVMVOLUMEFMT hVolFmt = NIL_RTDVMVOLUMEFMT;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync rc = pThis->pDvmFmtOps->pfnQueryFirstVolume(pThis->hVolMgrFmt, &hVolFmt);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (RT_SUCCESS(rc))
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (RT_FAILURE(rc))
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (RT_SUCCESS(rc))
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync cVols--;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync while ( cVols > 0
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync && RT_SUCCESS(rc))
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync rc = pThis->pDvmFmtOps->pfnQueryNextVolume(pThis->hVolMgrFmt, pVol->hVolFmt, &hVolFmt);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (RT_SUCCESS(rc))
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync rc = rtDvmVolumeCreate(pThis, hVolFmt, &pVol);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (RT_FAILURE(rc))
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->pDvmFmtOps->pfnVolumeClose(hVolFmt);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync else
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTListAppend(&pThis->VolumeList, &pVol->VolumeNode);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync cVols--;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (RT_FAILURE(rc))
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMVOLUMEINTERNAL pItNext, pIt;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /* Remove all entries. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTListForEachSafe(&pThis->VolumeList, pIt, pItNext, RTDVMVOLUMEINTERNAL, VolumeNode)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTListNodeRemove(&pIt->VolumeNode);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync rtDvmVolumeDestroy(pIt);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync else
f5f42fa2ec9924006cad8e5adc646b34b35ba3c3vboxsync rc = VERR_NOT_SUPPORTED;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsyncRTDECL(int) RTDvmMapInitialize(RTDVM hVolMgr, const char *pszFmt)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync int rc = VERR_NOT_SUPPORTED;
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
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsyncRTDECL(int) RTDvmMapQueryFirstVolume(RTDVM hVolMgr, PRTDVMVOLUME phVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync int rc = VERR_DVM_MAP_EMPTY;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMINTERNAL pThis = hVolMgr;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertPtrReturn(phVol, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMVOLUMEINTERNAL pVol = RTListGetFirst(&pThis->VolumeList, RTDVMVOLUMEINTERNAL, VolumeNode);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (pVol)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync rc = VINF_SUCCESS;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTDvmVolumeRetain(pVol);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync *phVol = pVol;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsyncRTDECL(int) RTDvmMapQueryNextVolume(RTDVM hVolMgr, RTDVMVOLUME hVol, PRTDVMVOLUME phVolNext)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync int rc = VERR_DVM_MAP_NO_VOLUME;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMINTERNAL pThis = hVolMgr;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync 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);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertPtrReturn(pVol, VERR_INVALID_HANDLE);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertReturn(pVol->u32Magic == RTDVMVOLUME_MAGIC, VERR_INVALID_HANDLE);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertPtrReturn(phVolNext, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMVOLUMEINTERNAL pVolNext = RTListGetNext(&pThis->VolumeList, pVol,
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTDVMVOLUMEINTERNAL, VolumeNode);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (pVolNext)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync rc = VINF_SUCCESS;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTDvmVolumeRetain(pVolNext);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync *phVolNext = pVolNext;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return rc;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsyncRTDECL(int) RTDvmMapQueryBlockStatus(RTDVM hVolMgr, uint64_t off, uint64_t cb,
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync bool *pfAllocated)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync{
956a0e3c076406b83d635174a201fd8761ee5133vboxsync int rc = VINF_SUCCESS;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync PRTDVMINTERNAL pThis = hVolMgr;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertPtrReturn(pfAllocated, VERR_INVALID_POINTER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->u32Magic == RTDVM_MAGIC, VERR_INVALID_HANDLE);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync AssertReturn(pThis->hVolMgrFmt != NIL_RTDVMFMT, VERR_INVALID_HANDLE);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertReturn(off + cb <= pThis->DvmDisk.cbDisk * pThis->DvmDisk.cbSector,
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync VERR_INVALID_PARAMETER);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync /* Check whether the range is inuse by the volume manager metadata first. */
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync rc = pThis->pDvmFmtOps->pfnQueryRangeUse(pThis->hVolMgrFmt, off, cb, pfAllocated);
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync if (RT_FAILURE(rc))
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync return rc;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync if (!*pfAllocated)
956a0e3c076406b83d635174a201fd8761ee5133vboxsync {
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync bool fAllocated = false;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync while ( cb > 0
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync && !fAllocated)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync PRTDVMVOLUMEINTERNAL pVol;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync bool fVolFound = false;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync uint64_t cbIntersect;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync uint64_t offVol;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync /*
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync * Search through all volumes. It is not possible to
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync * get all start sectors and sizes of all volumes here
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync * because volumes can be scattered around the disk for certain formats.
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync * Linux LVM is one example, extents of logical volumes don't need to be
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync * contigous on the medium.
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync */
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync RTListForEach(&pThis->VolumeList, pVol, RTDVMVOLUMEINTERNAL, VolumeNode)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync bool fIntersect = pThis->pDvmFmtOps->pfnVolumeIsRangeIntersecting(pVol->hVolFmt, off,
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync cb, &offVol,
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync &cbIntersect);
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync if (fIntersect)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync fVolFound = true;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync if (pVol->pfnQueryBlockStatus)
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync {
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync bool fVolAllocated = true;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync rc = pVol->pfnQueryBlockStatus(pVol->pvUser, offVol, cbIntersect,
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync &fVolAllocated);
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync if (RT_FAILURE(rc))
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync break;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync else if (fVolAllocated)
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync {
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync fAllocated = true;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync break;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync }
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync }
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync else if (!(pThis->fFlags & DVM_FLAGS_NO_STATUS_CALLBACK_MARK_AS_UNUSED))
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync fAllocated = true;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync /* else, flag is set, continue. */
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync cb -= cbIntersect;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync off += cbIntersect;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync break;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync }
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync if (!fVolFound)
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync {
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync if (pThis->fFlags & DVM_FLAGS_UNUSED_SPACE_MARK_AS_USED)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync fAllocated = true;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync cb -= pThis->DvmDisk.cbSector;
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync off += pThis->DvmDisk.cbSector;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
54d2d2606d7c83a456819cd038a73e0f9a600ca4vboxsync *pfAllocated = fAllocated;
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);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertMsg(cRefs >= 1 && cRefs < _1M, ("%#x %p\n", cRefs, pThis));
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync if (cRefs == 1)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTDvmRetain(pThis->pVolMgr);
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return cRefs;
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)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync {
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync /* Release the volume manager. */
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->pfnQueryBlockStatus = NULL;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync RTDvmRelease(pThis->pVolMgr);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync }
956a0e3c076406b83d635174a201fd8761ee5133vboxsync return cRefs;
956a0e3c076406b83d635174a201fd8761ee5133vboxsync}
956a0e3c076406b83d635174a201fd8761ee5133vboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsyncRTDECL(void) RTDvmVolumeSetQueryBlockStatusCallback(RTDVMVOLUME hVol,
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PFNDVMVOLUMEQUERYBLOCKSTATUS pfnQueryBlockStatus,
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync void *pvUser)
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync{
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync PRTDVMVOLUMEINTERNAL pThis = hVol;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertPtrReturnVoid(pThis);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync AssertReturnVoid(pThis->u32Magic == RTDVMVOLUME_MAGIC);
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->pfnQueryBlockStatus = pfnQueryBlockStatus;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync pThis->pvUser = pvUser;
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync}
2a0a20dee7f474c26cc8f6f9d7aa12c345c2b73bvboxsync
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}