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};
uMountFlags = VV_MODE_EMULATE_DISK | VV_MODE_REMOVABLE;
if (! VvlibCreateMemoryVolume (
VV_ALG_NULL, 104857600, NULL, NULL, &MountInfo)) {
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;
if (! VvlibCreateImage (
L"C:\\Images\\hdtest.vvi", true, VV_IMAGE_HARD_DISK, 104857600, NULL, VV_ALG_NULL, VV_FS_NTFS, "Test volume")) {
uError = VvlibGetErrorCode ();
...
}
if (! VvlibCreateImage (
L"C:\\Images\\cctest.vvi", false, VV_IMAGE_VOLUME, 104857600, L"MySuperPassword", VV_ALG_AES, VV_FS_NTFS, "Crypto volume")) {
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};
if (! VvlibMountImage (
L"C:\\Images\\cctest.vvi", L"MySuperPassword", VV_MODE_REMOVABLE, &MountInfo)) {
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};
if (! VvlibMountRawImage (
L"C:\\Images\\rawtest.bin", VV_MODE_REMOVABLE, &MountInfo)) {
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;
if (! VvlibAddAutoVolume (
L'R', VV_MODE_IN_MEMORY, 0, 536870912, VV_FS_FAT32, "RAM drive", NULL)) {
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};
if (! VvlibGetVolumes (
&uVolumes, &pVolumes)) {
uError = VvlibGetErrorCode ();
...
}
for (uIdx = 0; uIdx < uVolumes; uIdx += 1)
{
if (! VvlibQueryVolumeInformation (
pHandles [uIdx], &VolInfo)) {
uError = VvlibGetErrorCode ();
...
}
bEraseData = VolInfo.AlgId != VV_ALG_NULL;
if (! VvlibUnmount (
pHandles [uIdx], true, bEraseData)) {
uError = VvlibGetErrorCode ();
...
}
}
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;
...
if (! VvlibCreateLink (
hVolume, VV_LINK_FORCE, L'S', false)) {
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;
...
if (! VvlibDeleteLink (
hVolume, VV_PARTITION_ALL)) {
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;
...
uFormatFlags = VV_FMT_COMPRESS | VV_FMT_USE_INDEXES;
if (! VvlibFormatVolume (
hVolume, VV_PARTITION_ANY, uFormatFlags, VV_FS_NTFS, "Volume")) {
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;
...
uFlushFlags = VV_SAVE_FLUSH_FS | VV_SAVE_DIFFERENTIAL;
if (! VvlibSetFlushState (
hVolume, 3600, uFlushFlags)) {
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;
...
if (! VvlibSetProperties (
hVolume, VV_PROP_SAVE_VOLUME, 0)) {
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.