vd-ifs.h revision 2aa2d27a760f47be8f9f9769083de77440e6114f
/** @file
* VD Container API - interfaces.
*/
/*
* Copyright (C) 2011 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef ___VBox_VD_Interfaces_h
#define ___VBox_VD_Interfaces_h
/** Interface header magic. */
/**
* Supported interface types.
*/
typedef enum VDINTERFACETYPE
{
/** First valid interface. */
/** Interface to pass error message to upper layers. Per-disk. */
/** Interface for I/O operations. Per-image. */
/** Interface for progress notification. Per-operation. */
/** Interface for configuration information. Per-image. */
/** Interface for TCP network stack. Per-image. */
/** Interface for getting parent image state. Per-operation. */
/** Interface for synchronizing accesses from several threads. Per-disk. */
/** Interface for I/O between the generic VBoxHDD code and the backend. Per-image (internal).
* This interface is completely internal and must not be used elsewhere. */
/** Interface to query the use of block ranges on the disk. Per-operation. */
/** invalid interface. */
/**
* Common structure for all interfaces and at the beginning of all types.
*/
typedef struct VDINTERFACE
{
/** Human readable interface name. */
const char *pszInterfaceName;
/** Pointer to the next common interface structure. */
struct VDINTERFACE *pNext;
/** Interface type. */
/** Size of the interface. */
/** Opaque user data which is passed on every call. */
void *pvUser;
} VDINTERFACE;
/** Pointer to a VDINTERFACE. */
typedef VDINTERFACE *PVDINTERFACE;
/** Pointer to a const VDINTERFACE. */
typedef const VDINTERFACE *PCVDINTERFACE;
/**
* Helper functions to handle interface lists.
*
* @note These interface lists are used consistently to pass per-disk,
* separate. See the individual interface declarations for what context they
* apply to. The caller is responsible for ensuring that the lifetime of the
* interface descriptors is appropriate for the category of interface.
*/
/**
* Get a specific interface from a list of interfaces specified by the type.
*
* @return Pointer to the matching interface or NULL if none was found.
* @param pVDIfs Pointer to the VD interface list.
* @param enmInterface Interface to search for.
*/
{
while (pVDIfs)
{
return pVDIfs;
}
/* No matching interface was found. */
return NULL;
}
/**
* Add an interface to a list of interfaces.
*
* @return VBox status code.
* @param pInterface Pointer to an unitialized common interface structure.
* @param pszName Name of the interface.
* @param enmInterface Type of the interface.
* @param pvUser Opaque user data passed on every function call.
* @param ppVDIfs Pointer to the VD interface list.
*/
{
/* Argument checks. */
("pInterfaceList=%#p", ppVDIfs),
/* Fill out interface descriptor. */
/* Remember the new start of the list. */
*ppVDIfs = pInterface;
return VINF_SUCCESS;
}
/**
* Removes an interface from a list of interfaces.
*
* @return VBox status code
* @param pInterface Pointer to an initialized common interface structure to remove.
* @param ppVDIfs Pointer to the VD interface list to remove from.
*/
{
int rc = VERR_NOT_FOUND;
/* Argument checks. */
("pInterface=%#p", pInterface),
("pInterfaceList=%#p", ppVDIfs),
if (*ppVDIfs)
{
while ( pCurr
&& (pCurr != pInterface))
{
}
/* First interface */
if (!pPrev)
{
rc = VINF_SUCCESS;
}
else if (pCurr)
{
rc = VINF_SUCCESS;
}
}
return rc;
}
/**
* Interface to deliver error messages (and also informational messages)
* to upper layers.
*
* Per-disk interface. Optional, but think twice if you want to miss the
* opportunity of reporting better human-readable error messages.
*/
typedef struct VDINTERFACEERROR
{
/**
* Common interface header.
*/
/**
* Error message callback. Must be able to accept special IPRT format
* strings.
*
* @param pvUser The opaque data passed on container creation.
* @param rc The VBox error code.
* @param RT_SRC_POS_DECL Use RT_SRC_POS.
* @param pszFormat Error message format string.
* @param va Error message arguments.
*/
DECLR3CALLBACKMEMBER(void, pfnError, (void *pvUser, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va));
/**
* Informational message callback. May be NULL. Used e.g. in
* VDDumpImages(). Must be able to accept special IPRT format strings.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pszFormat Message format string.
* @param va Message arguments.
*/
/**
* Get error interface from interface list.
*
* @return Pointer to the first error interface in the list.
* @param pVDIfs Pointer to the interface list.
*/
{
/* Check that the interface descriptor is a progress interface. */
("Not an error interface\n"), NULL);
return (PVDINTERFACEERROR)pIf;
}
/**
* Signal an error to the frontend.
*
* @returns VBox status code.
* @param pIfError The error interface.
* @param rc The status code.
* @param RT_SRC_POS_DECL The position in the source code.
* @param pszFormat The format string to pass.
* @param ... Arguments to the format string.
*/
const char *pszFormat, ...)
{
if (pIfError)
return rc;
}
/**
* Signal an informational message to the frontend.
*
* @returns VBox status code.
* @param pIfError The error interface.
* @param pszFormat The format string to pass.
* @param ... Arguments to the format string.
*/
{
int rc = VINF_SUCCESS;
return rc;
}
/**
* Completion callback which is called by the interface owner
* to inform the backend that a task finished.
*
* @return VBox status code.
* @param pvUser Opaque user data which is passed on request submission.
* @param rcReq Status code of the completed request.
*/
/** Pointer to FNVDCOMPLETED() */
typedef FNVDCOMPLETED *PFNVDCOMPLETED;
/**
* Support interface for I/O
*
* Per-image. Optional as input.
*/
typedef struct VDINTERFACEIO
{
/**
* Common interface header.
*/
/**
* Open callback
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pszLocation Name of the location to open.
* @param fOpen Flags for opening the backend.
* See RTFILE_O_* #defines, inventing another set
* of open flags is not worth the mapping effort.
* @param pfnCompleted The callback which is called whenever a task
* completed. The backend has to pass the user data
* of the request initiator (ie the one who calls
* VDAsyncRead or VDAsyncWrite) in pvCompletion
* if this is NULL.
* @param ppStorage Where to store the opaque storage handle.
*/
void **ppStorage));
/**
* Close callback.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pStorage The opaque storage handle to close.
*/
/**
* Delete callback.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pcszFilename Name of the file to delete.
*/
/**
* Move callback.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pcszSrc The path to the source file.
* @param pcszDst The path to the destination file.
* This file will be created.
* @param fMove A combination of the RTFILEMOVE_* flags.
*/
DECLR3CALLBACKMEMBER(int, pfnMove, (void *pvUser, const char *pcszSrc, const char *pcszDst, unsigned fMove));
/**
* Returns the free space on a disk.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pcszFilename Name of a file to identify the disk.
* @param pcbFreeSpace Where to store the free space of the disk.
*/
DECLR3CALLBACKMEMBER(int, pfnGetFreeSpace, (void *pvUser, const char *pcszFilename, int64_t *pcbFreeSpace));
/**
* Returns the last modification timestamp of a file.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pcszFilename Name of a file to identify the disk.
* @param pModificationTime Where to store the timestamp of the file.
*/
DECLR3CALLBACKMEMBER(int, pfnGetModificationTime, (void *pvUser, const char *pcszFilename, PRTTIMESPEC pModificationTime));
/**
* Returns the size of the opened storage backend.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pStorage The opaque storage handle to close.
* @param pcbSize Where to store the size of the storage backend.
*/
/**
* Sets the size of the opened storage backend if possible.
*
* @return VBox status code.
* @retval VERR_NOT_SUPPORTED if the backend does not support this operation.
* @param pvUser The opaque data passed on container creation.
* @param pStorage The opaque storage handle to close.
* @param cbSize The new size of the image.
*/
/**
* Synchronous write callback.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pStorage The storage handle to use.
* @param uOffset The offset to start from.
* @param pvBuffer Pointer to the bits need to be written.
* @param cbBuffer How many bytes to write.
* @param pcbWritten Where to store how many bytes were actually written.
*/
/**
* Synchronous read callback.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pStorage The storage handle to use.
* @param uOffset The offset to start from.
* @param pvBuffer Where to store the read bits.
* @param cbBuffer How many bytes to read.
* @param pcbRead Where to store how many bytes were actually read.
*/
/**
* Flush data to the storage backend.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pStorage The storage handle to flush.
*/
/**
* Initiate an asynchronous read request.
*
* @return VBox status code.
* @param pvUser The opaque user data passed on container creation.
* @param pStorage The storage handle.
* @param uOffset The offset to start reading from.
* @param paSegments Scatter gather list to store the data in.
* @param cSegments Number of segments in the list.
* @param cbRead How many bytes to read.
* @param pvCompletion The opaque user data which is returned upon completion.
* @param ppTask Where to store the opaque task handle.
*/
void **ppTask));
/**
* Initiate an asynchronous write request.
*
* @return VBox status code.
* @param pvUser The opaque user data passed on conatiner creation.
* @param pStorage The storage handle.
* @param uOffset The offset to start writing to.
* @param paSegments Scatter gather list of the data to write
* @param cSegments Number of segments in the list.
* @param cbWrite How many bytes to write.
* @param pvCompletion The opaque user data which is returned upon completion.
* @param ppTask Where to store the opaque task handle.
*/
void **ppTask));
/**
* Initiates an async flush request.
*
* @return VBox status code.
* @param pvUser The opaque data passed on container creation.
* @param pStorage The storage handle to flush.
* @param pvCompletion The opaque user data which is returned upon completion.
* @param ppTask Where to store the opaque task handle.
*/
void *pvCompletion, void **ppTask));
/**
* Get I/O interface from interface list.
*
* @return Pointer to the first I/O interface in the list.
* @param pVDIfs Pointer to the interface list.
*/
{
/* Check that the interface descriptor is a progress interface. */
("Not a I/O interface"), NULL);
return (PVDINTERFACEIO)pIf;
}
void **ppStorage)
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
{
}
/**
* Callback which provides progress information about a currently running
* lengthy operation.
*
* @return VBox status code.
* @param pvUser The opaque user data associated with this interface.
* @param uPercent Completion percentage.
*/
/** Pointer to FNVDPROGRESS() */
typedef FNVDPROGRESS *PFNVDPROGRESS;
/**
* Progress notification interface
*
* Per-operation. Optional.
*/
typedef struct VDINTERFACEPROGRESS
{
/**
* Common interface header.
*/
/**
* Progress notification callbacks.
*/
/**
* Get progress interface from interface list.
*
* @return Pointer to the first progress interface in the list.
* @param pVDIfs Pointer to the interface list.
*/
{
/* Check that the interface descriptor is a progress interface. */
("Not a progress interface"), NULL);
return (PVDINTERFACEPROGRESS)pIf;
}
/**
* Configuration information interface
*
* Per-image. Optional for most backends, but mandatory for images which do
* not operate on files (including standard block or character devices).
*/
typedef struct VDINTERFACECONFIG
{
/**
* Common interface header.
*/
/**
* Validates that the keys are within a set of valid names.
*
* @return true if all key names are found in pszzAllowed.
* @return false if not.
* @param pvUser The opaque user data associated with this interface.
* @param pszzValid List of valid key names separated by '\\0' and ending with
* a double '\\0'.
*/
/**
* Retrieves the length of the string value associated with a key (including
* the terminator, for compatibility with CFGMR3QuerySize).
*
* @return VBox status code.
* VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
* @param pvUser The opaque user data associated with this interface.
* @param pszName Name of the key to query.
* @param pcbValue Where to store the value length. Non-NULL.
*/
/**
* Query the string value associated with a key.
*
* @return VBox status code.
* VERR_CFGM_VALUE_NOT_FOUND means that the key is not known.
* VERR_CFGM_NOT_ENOUGH_SPACE means that the buffer is not big enough.
* @param pvUser The opaque user data associated with this interface.
* @param pszName Name of the key to query.
* @param pszValue Pointer to buffer where to store value.
* @param cchValue Length of value buffer.
*/
DECLR3CALLBACKMEMBER(int, pfnQuery, (void *pvUser, const char *pszName, char *pszValue, size_t cchValue));
/**
* Get configuration information interface from interface list.
*
* @return Pointer to the first configuration information interface in the list.
* @param pVDIfs Pointer to the interface list.
*/
{
/* Check that the interface descriptor is a progress interface. */
("Not a config interface"), NULL);
return (PVDINTERFACECONFIG)pIf;
}
/**
* Query configuration, validates that the keys are within a set of valid names.
*
* @return true if all key names are found in pszzAllowed.
* @return false if not.
* @param pCfgIf Pointer to configuration callback table.
* @param pszzValid List of valid names separated by '\\0' and ending with
* a double '\\0'.
*/
{
}
/**
* Query configuration, unsigned 64-bit integer value with default.
*
* @return VBox status code.
* @param pCfgIf Pointer to configuration callback table.
* @param pszName Name of an integer value
* @param pu64 Where to store the value. Set to default on failure.
* @param u64Def The default value.
*/
{
char aszBuf[32];
if (RT_SUCCESS(rc))
{
}
else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
{
rc = VINF_SUCCESS;
}
return rc;
}
/**
* Query configuration, unsigned 32-bit integer value with default.
*
* @return VBox status code.
* @param pCfgIf Pointer to configuration callback table.
* @param pszName Name of an integer value
* @param pu32 Where to store the value. Set to default on failure.
* @param u32Def The default value.
*/
{
if (RT_SUCCESS(rc))
{
else
}
return rc;
}
/**
* Query configuration, bool value with default.
*
* @return VBox status code.
* @param pCfgIf Pointer to configuration callback table.
* @param pszName Name of an integer value
* @param pf Where to store the value. Set to default on failure.
* @param fDef The default value.
*/
bool fDef)
{
if (RT_SUCCESS(rc))
return rc;
}
/**
* Query configuration, dynamically allocated (RTMemAlloc) zero terminated
* character value.
*
* @return VBox status code.
* @param pCfgIf Pointer to configuration callback table.
* @param pszName Name of an zero terminated character value
* @param ppszString Where to store the string pointer. Not set on failure.
* Free this using RTMemFree().
*/
const char *pszName, char **ppszString)
{
if (RT_SUCCESS(rc))
{
if (pszString)
{
if (RT_SUCCESS(rc))
*ppszString = pszString;
else
}
else
rc = VERR_NO_MEMORY;
}
return rc;
}
/**
* Query configuration, dynamically allocated (RTMemAlloc) zero terminated
* character value with default.
*
* @return VBox status code.
* @param pCfgIf Pointer to configuration callback table.
* @param pszName Name of an zero terminated character value
* @param ppszString Where to store the string pointer. Not set on failure.
* Free this using RTMemFree().
* @param pszDef The default value.
*/
const char *pszName,
char **ppszString,
const char *pszDef)
{
{
rc = VINF_SUCCESS;
}
if (RT_SUCCESS(rc))
{
if (pszString)
{
{
rc = VINF_SUCCESS;
}
if (RT_SUCCESS(rc))
*ppszString = pszString;
else
}
else
rc = VERR_NO_MEMORY;
}
return rc;
}
/**
* Query configuration, dynamically allocated (RTMemAlloc) byte string value.
*
* @return VBox status code.
* @param pCfgIf Pointer to configuration callback table.
* @param pszName Name of an zero terminated character value
* @param ppvData Where to store the byte string pointer. Not set on failure.
* Free this using RTMemFree().
* @param pcbData Where to store the byte string length.
*/
{
if (RT_SUCCESS(rc))
{
char *pbData;
if (pbData)
{
if (RT_SUCCESS(rc))
{
}
else
}
else
rc = VERR_NO_MEMORY;
}
return rc;
}
/** Forward declaration of a VD socket. */
typedef struct VDSOCKETINT *VDSOCKET;
/** Pointer to a VD socket. */
/** Nil socket handle. */
#define NIL_VDSOCKET ((VDSOCKET)0)
/** Connect flag to indicate that the backend wants to use the extended
* socket I/O multiplexing call. This might not be supported on all configurations
* (internal networking and iSCSI)
* and the backend needs to take appropriate action.
*/
/** @name Select events
* @{ */
/** Readable without blocking. */
#define VD_INTERFACETCPNET_EVT_READ RT_BIT_32(0)
/** Writable without blocking. */
/** Error condition, hangup, exception or similar. */
/** Hint for the select that getting interrupted while waiting is more likely.
* The interface implementation can optimize the waiting strategy based on this.
* It is assumed that it is more likely to get one of the above socket events
* instead of being interrupted if the flag is not set. */
/** Mask of the valid bits. */
/** @} */
/**
* TCP network stack interface
*
* Per-image. Mandatory for backends which have the VD_CAP_TCPNET bit set.
*/
typedef struct VDINTERFACETCPNET
{
/**
* Common interface header.
*/
/**
* Creates a socket. The socket is not connected if this succeeds.
*
* @return iprt status code.
* @retval VERR_NOT_SUPPORTED if the combination of flags is not supported.
* @param fFlags Combination of the VD_INTERFACETCPNET_CONNECT_* #defines.
* @param pSock Where to store the handle.
*/
/**
* Destroys the socket.
*
* @return iprt status code.
* @param Sock Socket descriptor.
*/
/**
* Connect as a client to a TCP port.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param pszAddress The address to connect to.
* @param uPort The port to connect to.
*/
DECLR3CALLBACKMEMBER(int, pfnClientConnect, (VDSOCKET Sock, const char *pszAddress, uint32_t uPort));
/**
* Close a TCP connection.
*
* @return iprt status code.
* @param Sock Socket descriptor.
*/
/**
* Returns whether the socket is currently connected to the client.
*
* @returns true if the socket is connected.
* false otherwise.
* @param Sock Socket descriptor.
*/
/**
* Socket I/O multiplexing.
* Checks if the socket is ready for reading.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param cMillies Number of milliseconds to wait for the socket.
* Use RT_INDEFINITE_WAIT to wait for ever.
*/
/**
* Receive data from a socket.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param pvBuffer Where to put the data we read.
* @param cbBuffer Read buffer size.
* @param pcbRead Number of bytes read.
* If NULL the entire buffer will be filled upon successful return.
* If not NULL a partial read can be done successfully.
*/
DECLR3CALLBACKMEMBER(int, pfnRead, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
/**
* Send data to a socket.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param pvBuffer Buffer to write data to socket.
* @param cbBuffer How much to write.
*/
/**
*
* @return iprt status code.
* @param Sock Socket descriptor.
*/
/**
* Receive data from a socket - not blocking.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param pvBuffer Where to put the data we read.
* @param cbBuffer Read buffer size.
* @param pcbRead Number of bytes read.
*/
DECLR3CALLBACKMEMBER(int, pfnReadNB, (VDSOCKET Sock, void *pvBuffer, size_t cbBuffer, size_t *pcbRead));
/**
* Send data to a socket - not blocking.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param pvBuffer Buffer to write data to socket.
* @param cbBuffer How much to write.
* @param pcbWritten Number of bytes written.
*/
DECLR3CALLBACKMEMBER(int, pfnWriteNB, (VDSOCKET Sock, const void *pvBuffer, size_t cbBuffer, size_t *pcbWritten));
/**
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param pcbWritten Number of bytes written.
*/
/**
* Flush socket write buffers.
*
* @return iprt status code.
* @param Sock Socket descriptor.
*/
/**
* Enables or disables delaying sends to coalesce packets.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param fEnable When set to true enables coalescing.
*/
/**
* Gets the address of the local side.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param pAddr Where to store the local address on success.
*/
/**
* Gets the address of the other party.
*
* @return iprt status code.
* @param Sock Socket descriptor.
* @param pAddr Where to store the peer address on success.
*/
/**
* Socket I/O multiplexing - extended version which can be woken up.
* Checks if the socket is ready for reading or writing.
*
* @return iprt status code.
* @retval VERR_INTERRUPTED if the thread was woken up by a pfnPoke call.
* @param Sock Socket descriptor.
* @param fEvents Mask of events to wait for.
* @param pfEvents Where to store the received events.
* @param cMillies Number of milliseconds to wait for the socket.
* Use RT_INDEFINITE_WAIT to wait for ever.
*/
/**
* Wakes up the thread waiting in pfnSelectOneEx.
*
* @return iprt status code.
* @param Sock Socket descriptor.
*/
/**
* Get TCP network stack interface from interface list.
*
* @return Pointer to the first TCP network stack interface in the list.
* @param pVDIfs Pointer to the interface list.
*/
{
/* Check that the interface descriptor is a progress interface. */
("Not a TCP net interface"), NULL);
return (PVDINTERFACETCPNET)pIf;
}
/**
* Interface to synchronize concurrent accesses by several threads.
*
* @note The scope of this interface is to manage concurrent accesses after
* the HDD container has been created, and they must stop before destroying the
* container. Opening or closing images is covered by the synchronization, but
* that does not mean it is safe to close images while a thread executes
* <link to="VDMerge"/> or <link to="VDCopy"/> operating on these images.
* Making them safe would require the lock to be held during the entire
* operation, which prevents other concurrent acitivities.
*
* @note Right now this is kept as simple as possible, and does not even
* attempt to provide enough information to allow e.g. concurrent write
* accesses to different areas of the disk. The reason is that it is very
* difficult to predict which area of a disk is affected by a write,
* especially when different image formats are mixed. Maybe later a more
* sophisticated interface will be provided which has the necessary information
* about worst case affected areas.
*
* Per-disk interface. Optional, needed if the disk is accessed concurrently
* by several threads, e.g. when merging diff images while a VM is running.
*/
typedef struct VDINTERFACETHREADSYNC
{
/**
* Common interface header.
*/
/**
* Start a read operation.
*/
/**
* Finish a read operation.
*/
/**
* Start a write operation.
*/
/**
* Finish a write operation.
*/
/**
* Get thread synchronization interface from interface list.
*
* @return Pointer to the first thread synchronization interface in the list.
* @param pVDIfs Pointer to the interface list.
*/
{
/* Check that the interface descriptor is a progress interface. */
("Not a thread synchronization interface"), NULL);
return (PVDINTERFACETHREADSYNC)pIf;
}
/**
* Interface to query usage of disk ranges.
*
* Per-operation interface. Optional.
*/
typedef struct VDINTERFACEQUERYRANGEUSE
{
/**
* Common interface header.
*/
/**
* Query use of a disk range.
*/
bool *pfUsed));
/**
* Get query range use interface from interface list.
*
* @return Pointer to the first thread synchronization interface in the list.
* @param pVDIfs Pointer to the interface list.
*/
{
/* Check that the interface descriptor is a progress interface. */
("Not a query range use interface"), NULL);
return (PVDINTERFACEQUERYRANGEUSE)pIf;
}
DECLINLINE(int) vdIfQueryRangeUse(PVDINTERFACEQUERYRANGEUSE pIfQueryRangeUse, uint64_t off, uint64_t cb,
bool *pfUsed)
{
}
/** @} */
#endif