Click here to Skip to main content
15,867,686 members
Articles / Programming Languages / C
Article

Virtual Volume Software Development Kit (VV SDK) Online User Guide

9 Jul 2014CPOL12 min read 24.4K   4  
Virtual Volume Software Development Kit (VV SDK) is a developer’s toolkit for creating virtual disks.

This article is in the Product Showcase section for our sponsors at CodeProject. These articles are intended to provide you with information on products and services that we consider useful and of value to developers.

Introduction

Virtual Volume Software Development Kit (VV SDK) is a developer’s toolkit for creating virtual disks.

If you want to create a custom RAM disk application or work with on-disk images associated with drive letters, you don’t need to spend a mammoth amount of time writing a driver. Just download and try the VV SDK.

VV SDK allows applications to create their own RAM drives with the content fully stored in memory, virtual drives based on image files, and encrypted containers that can also be mounted as a virtual drive. Virtual Volume can emulate both standalone volumes and entire hard drives with the possibility of partitioning.

Built-in formatters provide the ability to create partitions with a ready-to-use file system. Each virtual volume or partition can be assigned a drive letter visibility of which can be limited to the current session.

Additional functions include automatic flushing of the RAM-disk data from RAM to the associated image file to avoid data loss, and secure wipe-out of confidential data from memory during the virtual disk unmounting.

VV SDK Contents

List of files in the VV SDK installation package:

  • spvve.sys is the main kernel-mode driver responsible for creating, deleting and managing virtual disks.
  • spvdbus.sys is a virtual bus driver that provides emulation of full hard drives containing one or more partitions.
  • vvlib.dll is a library for connecting to an application which, contains API functions described in this article. It can be linked to any project regardless of what language is used for its implementation.
  • vv.exe is a console application designed to demonstrate the features of this kit.
  • install.exe is an application that demonstrates how to install the product. A more detailed analogue of this application is the ‘install’ command in the console demo.
  • vvlib.lib and .h-files are a link library and header files designed for linking VV SDK to any project written in C/C++ language.

Features

This section provides more information about the Virtual Volume kit features. It describes a set of tools, which can be used by developers in their applications.

The main function of Virtual Volume is to create RAM drives for data storage in the high-speed memory providing fast access to information. A specific reading/writing speed depends on the performance of the processor and memory modules. This may be useful, for example, for database servers where disk subsystem performance may be a bottleneck. You can create a virtual disk based on an image file that is stored on a regular hard drive. It is possible to create hybrid virtual disks. When such disks are being created, their content is populated with the image file data, but later they are operated in memory. A virtual disk can be created as a standalone volume or as a full hard disk with a partition table. A user can partition the hard disk into a necessary number of drives (logical disks).

Each virtual volume or partition may be assigned a drive letter (e. g. R:) in the global or session namespace. In the global name space the disk will be available through the letter to all the users in the system; in the session namespace it will only be available to the user whose context is used for calling the routine.

Virtual Volume can create pre-formatted virtual disks and supports such file systems as FAT16, FAT32 and NTFS. Existing volumes can also be formatted using Virtual Volume functions. VV SDK is supplied with a range of helper functions for working with memory and logical drive letters, and obtaining information about the virtual disks already mounted.

Another important feature is the ability to register virtual disks for automounting that allows creating virtual disks mounted at the early stage of the system startup before the services are run and the user logs in. There are several ways to mount a volume, for example, read-only, i.e. without the ability to change its contents (but remember that not all file systems can work with read-only volumes), and/or as a removable disk. You can use ‘raw’ image for disks that are created based on the image file; in general, any file can be used as an image. If you use the NTFS file system, you may enable the volume compression when mounting.

The engine allows encrypting data on your virtual disks. In this case, the image file should be called an encrypted container. The supported block ciphers are: AES, DES, 3DES, RC6, Serpent, Blowfish, Twofish, CAST and GOST 28147-89.

Kernel-mode drivers in the product are digitally signed by the vendor, and this eliminates the necessity to purchase your own code-signing certificate. If a customer needs a build without our signature for customised signing, they can get it upon request. Named builds can also be supplied (by arrangement), for instance when customer wants their company name mentioned in their product.

API

The following section presents the descriptions of API functions that provide the functionality of this product. Each subsection describes the use of the corresponding API functions with the example of calling. The entire API of the product is described in the header files attached. To link to your project written in C/C++, you can use vvlib.lib link-library. The library code is contained in the vvlib.dll executable module. All the strings used in the library are stored and managed in Unicode except for the string containing the volume label, its encoding is ANSI. For a more detailed description of each function and structure, please refer to the documentation, which can be found in the file \texts\vv.chm after the SDK installation.

It is important that you first initialise the engine by the VvlibInitialize API function. This function should be called before all other functions of the library. You can call other functions of the library only if the initialisation was successful.

Creating a virtual disk

To create a virtual RAM disk, use the standard or extended VvlibCreateMemoryVolume API function. In the input parameters specify the encryption algorithm (or the VV_ALG_NULL value if encryption is not required), the size of the new disk, the cipher key (password) if necessary, the path to the image file if a hybrid virtual disk is being created, and the flags that control various aspects of the virtual disk creation and operation. The function returns a non-zero value if the disk was created successfully, or ‘false’ if not. You can find out the cause of the error by using the built-in VvlibGetErrorCode API function.

On output, the function fills the VV_MOUNT_INFORMATION structure with detailed information on the results of its execution. The value in the VolumeHandle field is the handle of the virtual disk that can be used to control it later.

This function may take some time to create the image; in particular it takes time to read a large image file (if one was specified). That is why you should use a separate thread for it to avoid freezes in the application user interface.

ULONG uError = 0;
ULONG uMountFlags = 0;
VV_MOUNT_INFORMATION MountInfo = {0};

// Create mount flags bitmask.
uMountFlags = VV_MODE_EMULATE_DISK |    // Emulate partitionable hard disk.
    VV_MODE_REMOVABLE;        // Create removable disk instead of fixed.

// Create RAM-drive with no associated image file.
if (! VvlibCreateMemoryVolume (
    VV_ALG_NULL,    // Don't use encryption.
    104857600,    // 100 MB, size of the disk.
    NULL,        // Pure RAM-disk, not associated with an image.
    NULL,        // Password not required for pure in-memory disks.
    &MountInfo))    // Results of the operation will be placed here.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

Creating an image file

The VvlibCreateImage function creates an image file on the hard disk in the specified folder. Similarly to most library functions, it returns ‘true’ if the operation was successful, or ‘false’ if not. The result of the function is an image file on your hard disk. The size of the image file will be a few kilobytes larger than it was specified in the input parameters because the resulting file contains the image header.

The function input consists of the file path, the flag indicating the necessity to overwrite the existing file, the image size in bytes, the access password that will be the basis for a new encryption key if necessary, the encryption algorithm or VV_ALG_NULL if encryption is not required, the file system type or VV_FS_NONE if formatting is not required or if it will be done later, and the volume label if the file system is used or NULL if the label is not required.

It is important to choose the correct image type. To create an image for a standalone volume, specify the uImageType parameter as VV_IMAGE_VOLUME. To create an image for hard disk emulation, specify VV_IMAGE_HARD_DISK; in this case, a partition table will be additionally formed in the image.

ULONG uError = 0;

// Create hard disk image with a partition table.
if (! VvlibCreateImage (
    L"C:\\Images\\hdtest.vvi",    // Path to the image file.
    true,                // Existing file should be overwritten.
    VV_IMAGE_HARD_DISK,        // Type of the image is Hard Disk.
    104857600,            // Size of the image is 100 MB.
    NULL,                // No password needed.
    VV_ALG_NULL,            // No encryption used.
    VV_FS_NTFS,            // The only partition will be formatted to NTFS.
    "Test volume"))            // Label for the only volume.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

// Create volume image as cryptocontainer with AES-256 encryption.
if (! VvlibCreateImage (
    L"C:\\Images\\cctest.vvi",    // Path to the image file.
    false,                // Existing file should not be overwritten.
    VV_IMAGE_VOLUME,        // Type of the image is standalone Volume.
    104857600,            // Size of the image is 100 MB.
    L"MySuperPassword",        // Password for using it as a cipher key.
    VV_ALG_AES,            // Encryption algorithm is AES with 256-bit key.
    VV_FS_NTFS,            // Volume will be formatted for use with NTFS.
    "Crypto volume"))        // Volume label.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

Mounting an image from a file

The VvlibMountImage API function creates a virtual disk based on a specified image file stored on the hard disk. It returns a non-zero value if the mounting was successful, or zero if not. Use the VvlibGetErrorCode function to get the error code.

The function input consists of the image file path string, the access password to the encrypted container if needed, and the flags indicating the mount parameters. The output is the structure in the pMountInformation parameter filled with detailed information on the results and the virtual disk handle.

It is important to specify the type of the mounted image. For example, if the image was created for hard disk emulation, you should specify the VV_MODE_EMULATE_DISK flag, otherwise the partition table will not be recognised.

ULONG uError = 0;
VV_MOUNT_INFORMATION MountInfo = {0};

// Mount the specified image file.
// A correct password must be passed in.
if (! VvlibMountImage (
    L"C:\\Images\\cctest.vvi",    // Path to the existing image file.
    L"MySuperPassword",        // Password is needed because the image is encrypted.
    VV_MODE_REMOVABLE,        // Mount as removable disk that is ejectable from Explorer.
    &MountInfo))            // Get a handle for the mounted volume.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

To mount a random file (i.e. a raw image) and create a virtual disk based on it, call the VvlibMountRawImage function. In this case, setting the VV_MODE_RAW flag is optional.

ULONG uError = 0;
VV_MOUNT_INFORMATION MountInfo = {0};

// Mount the specified file as image.
// This file should be large enough.
if (! VvlibMountRawImage (
    L"C:\\Images\\rawtest.bin",    // Path to an existing binary file.
    VV_MODE_REMOVABLE,        // Mount as removable disk that is ejectable from Explorer.
    &MountInfo))            // Get a handle for the mounted volume.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

Creating an auto-mounted virtual disk

The VvlibAddAutoVolume function manages registration virtual disks in the registry. Thus, the virtual disk is created each time the system is booted and is ready for usage in the system services inclusively. After a virtual disk is created, its partitions are automatically assigned the drive letters that were indicated in the function parameters. The input also accepts mount flags, the properties that will be applied to the disk after mounting, the disk size required (in bytes), the volume label if the file system is used, and the path to the mounted image if you want to create a hybrid virtual disk or an image-file–based virtual disk.

The function has no encryption parameters as in this case the password has to be stored as open text, which is not secure, therefore the function allows mounting non-password protected images only.

The extended version of the function includes several additional input parameters, for example, for automatic creation of folders on the virtual disk (nested paths are not supported) after mounting, or automatic flushing of the hybrid disk data to the image file if one was specified.

The function returns a non-zero value if the auto-mounted virtual disk was registered successfully; otherwise it returns a zero value, and an error code through VvlibGetErrorCode.

ULONG uError = 0;

// Create RAM drive that will automatically mount on system startup.
if (! VvlibAddAutoVolume (
    L'R',            // Drive letter will be assigned automatically.
    VV_MODE_IN_MEMORY,    // Create a standalone in-memory volume.
    0,            // No properties needed in this case.
    536870912,        // Size of the RAM drive will be 512 MB.
    VV_FS_FAT32,        // The volume will be formatted into FAT32...
    "RAM drive",        // ...and will be labeled "RAM drive".
    NULL))            // No associated image file, pure RAM disk.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

Unmounting a virtual disk

The VvlibUnmount API function allows you to unmount the virtual disk. This function can be applied to various types of disks, both the in-memory disks (RAM drives) and the disks mounted from image files. The standard version of the function includes two parameters: a handle to a virtual disk which you can get through enumeration of disks using the VvlibGetVolumes function, and a force unmount flag in case if the virtual disk is blocked by an application and it contains open file handles.

ULONG uIdx = 0;
ULONG uError = 0;
bool bEraseData = false;
ULONG uHandles = NULL;
PVHANDLE pHandles = NULL;
VV_VOLUME_INFORMATION VolInfo = {0};

// Get the list of mounted volumes.
if (! VvlibGetVolumes (
    &uVolumes,    // Receives the number of mounted volumes.
    &pVolumes))    // Receives the array of volume handles.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

// Enumerate the mounted volumes.
for (uIdx = 0; uIdx < uVolumes; uIdx += 1)
{
    // Get volume information.
    if (! VvlibQueryVolumeInformation (
        pHandles [uIdx],    // Volume handle.
        &VolInfo))        // Will be filled with the information about the volume.
    {
        // Error handling goes here.
        uError = VvlibGetErrorCode ();
        ...
    }
        
    // Check if we need to securely erase the virtual disk data in memory to keep it confidential.
    bEraseData = VolInfo.AlgId != VV_ALG_NULL;

    // Unmount the current virtual disk.
    if (! VvlibUnmount (
        pHandles [uIdx],    // Volume handle.
        true,            // Force unmount regardless of open files, etc.
        bEraseData))        // Whether or not to wipe image data in memory.
    {
        // Error handling goes here.
        uError = VvlibGetErrorCode ();
        ...
    }
}

// Release used resources.
VvlibFree (
    &pHandles);

Secure data deletion during unmounting

The VvlibUnmountEx API function is an extended version of the previously described unmounting function. This function allows secure destruction of the virtual disk data stored in memory when unmounting. To perform this, the third parameter bWipeImageData should be set to a non-zero value. It applies only to virtual disks with the contents stored in RAM, otherwise it is not applicable. See the code sample above.

Creating encrypted virtual disks

Some functions for creating virtual disks, such as VvlibCreateMemoryVolume or VvlibCreateImage, include the ability to encrypt the image data. Encryption is performed using one of the built-in block ciphers, such as AES, DES, 3DES, RC6, Serpent, Blowfish, Twofish, CAST or GOST 28147-89. The encryption method is usually specified as an input parameter uAlgId. See the code sample above.

Managing disk letters

The VvlibCreateLink API function creates a symbolic link (i.e. drive letter like R: or V:) to the virtual disks device objects, and the VvlibDeleteLink function removes it.

The bSessionOnly parameter accepts the value that determines where a link is created — in the global or session namespace. Session letters are available for the current user only, global are available to all. The extended version of the VvlibCreateLink function sets additional drive letters if you are emulating a full hard disk with partitions. In this case, letters can be assigned to each partition, not just to the first one.

ULONG uError = 0;
VHANDLE hVolume = NULL;
...
// Create drive letter for a virtual disk.
// If the specified virtual disk is a hard disk, then only the first partition will be affected.
if (! VvlibCreateLink (
    hVolume,    // Handle to the volume.
    VV_LINK_FORCE,    // Delete existing link first, if needed.
    L'S',        // New drive letter will be "S:".
    false))        // Create link in a global namespace, for all users.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

The VvlibDeleteLink function removes the link to the virtual volume and the drive letter from the system. The function does not unmount the virtual disk, it only removes the link and the letter. However, virtual disk unmounting automatically removes the assigned drive letter as well, so you will not need to call the VvlibDeleteLink function. After the letter is removed, the virtual drive can be assigned a new drive letter.

ULONG uError = 0;
VHANDLE hVolume = NULL;
...
// Delete link for the specified virtual disk.
// If the specified virtual disk is a hard disk, then all link assigned to its partitions will be deleted.
if (! VvlibDeleteLink (
    hVolume,         // Virtual disk handle.
    VV_PARTITION_ALL))    // Process all partitions if applicable.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

Formatting volumes

The VvlivFormatVolume API function formats the volume for the use with a specified file system. The supported file systems include FAT16, FAT32 and NTFS. The input parameters are: the virtual disk handle and formatted partition number (for hard disks with more than one partition), the formatting operation flags, the file system type that the partition is to be formatted in, the volume label for the newly created file system or NULL if the label is not needed.

Upon output, the function returns a non-zero value if the formatting was successful, or ‘false’ if not. The error code is available through VvlibGetErrorCode.

ULONG uError = 0;
ULONG uFormatFlags = 0;
VHANDLE hVolume = NULL;
...

// Create format flags bitmask.
uFormatFlags = VV_FMT_COMPRESS |    // Apply NTFS compression.
    VV_FMT_USE_INDEXES;        // Append the volume index to labels (for partitions).

// Format the specified volume for use with NTFS file system.
if (! VvlibFormatVolume (
    hVolume,        // Virtual disk handle.
    VV_PARTITION_ANY,    // Format all partitions, if applicable.
    uFormatFlags,        // Flags affecting formatting behaviour.
    VV_FS_NTFS,        // Format to NTFS file system.
    "Volume"))        // Base string for the volume labels.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

This function may take some time, so you should use a separate thread for calling it to avoid freezes in the application user interface.

Other management functions

The VvlibSetFlushState is a function for setting the autoflush feature of the hybrid virtual disk data, including the interval between the flush operations in seconds, the operation flags on whether you want to dump all data or just the changed blocks (faster), and whether the file system cache flushing is required before saving the disk data.

ULONG uError = 0;
ULONG uFlushFlags = 0;
VHANDLE hVolume = NULL;
...

// Create flush flags bitmask.
uFlushFlags = VV_SAVE_FLUSH_FS |    // Flush file systems on the virtual disk before writing.
    VV_SAVE_DIFFERENTIAL;        // Flush only changed blocks to increase the speed.

// Set new autoflush mode.
if (! VvlibSetFlushState (
    hVolume,    // Virtual disk handle.
    3600,        // Flush interval is one hour (in seconds).
    uFlushFlags))    // Flush flags affecting flush behaviour.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

The VvlibSetProperties function sets and removes various properties of virtual disks. These properties are stored in the header of the image file. For example, you can specify whether you want to save the hybrid virtual disk data during the system shutdown and/or power transitions.

ULONG uError = 0;
VHANDLE hVolume = NULL;
...
// Set new properties.
if (! VvlibSetProperties (
    hVolume,        // Virtual disk handle.
    VV_PROP_SAVE_VOLUME,    // Save hybrid disk data on shutdown.
    0))            // Don't remove existing properties, if there are any.
{
    // Error handling goes here.
    uError = VvlibGetErrorCode ();
    ...
}

Version History

2014.02.04 v2.5.3

  • Fixed the CPU max-out problem on image-based RAM disks.
  • Fixed a few NTFS formatting issues on Windows 8.1.
  • Added NUMA node preference for RAM disk memory allocation.

2013.11.15 v2.5.2

  • Fixed Task Manager crashes on Windows 8 and Windows 8.1.
  • Fixed an obscure startup crash in Samsung Magician.

2013.10.05 v2.5.1

  • Initial release. This SDK evolved from the RAM Disk software and is now available as a separate product for developers.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Australia Australia
SoftPerfect Research is a small software development company located in Brisbane, Australia. Established in 2000, we specialise in producing Windows network management applications for businesses and individuals. In 2013 we added two developer SDKs in our portfolio, with VV SDK being one of them.

Comments and Discussions

 
-- There are no messages in this forum --