Win32 Windows Volume Program and Code Example 4

 

 

 

 

 

Naming a Volume

 

A label is a user-friendly name that is assigned to a volume, usually by an end user, to make it easier to recognize. A volume can have a label, a drive letter, both, or neither. To set the label for a volume, use the SetVolumeLabel() function. Several factors can make it difficult to identify specific volumes using only drive letters and labels.

 

1.      One is that a volume is not required to have a drive letter or a label.

2.      Another is that two different volumes can have the same label, which makes them indistinguishable except by drive letter.

3.      A third factor is that drive letter assignments can change as volumes are added to and removed from the computer.

 

To solve this problem, the operating system uses volume GUID paths to identify volumes. These are strings of this form:

 

"\\?\Volume{GUID}\"

 

Where GUID is a globally unique identifier (GUID) that identifies the volume. A volume GUID path is sometimes referred to as a unique volume name, because a volume GUID path can refer only to one volume. However, this term is misleading, because a volume can have more than one volume GUID path. The \\?\ prefix disables path parsing and is not considered to be part of the path. You must specify full paths when using volume GUID paths with the \\?\ prefix. A mounted folder is an association between a folder on one volume and another volume, so that the folder path can be used to access the volume. For example, if you use the SetVolumeMountPoint() function to create a mounted folder that associates the volume D:\ with the folder C:\MountD\, you can then use either path (D:\ or C:\MountD\) to access the volume D:\. A volume mount point is any user-mode path that can be used to access a volume. There are three types of volume mount points:

 

  1. A drive letter, for example, C:\.
  2. A volume GUID path, for example, \\?\Volume{26a21bda-a627-11d7-9931-806e6f6e6963}\.
  3. A mounted folder, for example, C:\MountD\.

 

All volume and mounted folder functions that take a volume GUID path as an input parameter require the trailing backslash. All volume and mounted folder functions that return a volume GUID path provide the trailing backslash, but this is not the case with the CreateFile() function. You can open a volume by calling CreateFile() and omit the trailing backslash from the volume name you specify. CreateFile() processes a volume GUID path with an appended backslash as the root directory of the volume. The operating system assigns a volume GUID path to a volume when the volume is first installed and when the volume is formatted. The volume and mounted folder functions use volume GUID paths to access volumes. To obtain the volume GUID path for a volume, use the GetVolumeNameForVolumeMountPoint() function. Path lengths may be a concern when a mounted folder is created that associates a volume that has a deep directory tree with a directory on another volume. This is because the path of the volume is concatenated to the path of the directory. The globally defined constant MAX_PATH defines the maximum number of characters a path can have. You can avoid this constraint by doing either of the following:

 

  1. Refer to volumes by their volume GUID paths.
  2. Use the Unicode (W) versions of file functions, which support the \\?\ prefix.

 

Enumerating Volumes

 

To make a complete list of the volumes on a computer, or to manipulate each volume in turn, you can enumerate volumes. Within a volume, you can scan for mounted folders or other objects on the volume. Three functions allow an application to enumerate volumes on a computer:

 

  1. FindFirstVolume()
  2. FindNextVolume()
  3. FindVolumeClose()

 

These three functions operate in a manner very similar to the FindFirstFile(), FindNextFile(), and FindClose() functions. Begin a search for volumes with FindFirstVolume(). If the search is successful, process the results according to the design of your application. Then use FindNextVolume() in a loop to locate and process each subsequent volume. When the supply of volumes is exhausted, close the search with FindVolumeClose(). You should not assume any correlation between the order of the volumes that are returned by these functions and the order of the volumes that are returned by other functions or tools. In particular, do not assume any correlation between volume order and drive letters as assigned by the BIOS (if any) or the Disk Administrator.

 

Enumerating Volume GUID Paths Example

 

The following code example shows you how to obtain a volume GUID path for each volume associated with a drive letter that is currently in use on the computer. The code example uses the GetVolumeNameForVolumeMountPoint() function.

Create a new Win32 console application project and give a suitable project name.

 

Win32 enumerating Volume GUID Paths Example - creating a new Visual C++ project

 

Add the source file and give a suitable name.

 

Enumerating Volume GUID Paths Example - adding a new C++ source file

 

Add the following source code.

 

#include <windows.h>

#include <stdio.h>

 

#define BUFSIZE MAX_PATH

 

int wmain(void)

{

   BOOL bFlag;

   WCHAR Buf[BUFSIZE];        // temporary buffer for volume name

   WCHAR Drive[] = L"c:\\";   // template drive specifier

   WCHAR I;                   // generic loop counter

 

   // Walk through legal drive letters, skipping floppies.

   for (I = 'c'; I < 'z';  I++ )

   {

      // Stamp the drive for the appropriate letter.

      Drive[0] = I;

 

      bFlag = GetVolumeNameForVolumeMountPoint(

                 Drive,  // input volume mount point or directory

                 Buf,    // output volume name buffer

                 BUFSIZE // size of volume name buffer

              );

 

        // Should be non-zero

      if (bFlag != 0)

      {

              wprintf(L"\nGetVolumeNameForVolumeMountPoint() is OK!\n");

              wprintf(L"The ID of drive %s is \"%s\"\n", Drive, Buf);

      }

        // If zero

        else

        {

              wprintf(L"\nNo more drive found! Error if any is %d\n", GetLastError());

              // ERROR_FILE_NOT_FOUND = 2 (0x2) - The system cannot find the file specified. No more files

              break;

        }

   }

}

 

Build and run the project. The following screenshot shows a sample output. The e: and f: are thumb drives.

 

Enumerating Volume GUID Paths Example - a sample console output

 

 

  < Windows Volume 3 | Win32 Programming Index | Windows Volume Index | Windows Volume 5 >