| Platform SDK: Files and I/O |
The following sample demonstrates how to enumerate volumes and mount points on a computer.
This sample uses the following functions: DeleteVolumeMountPoint, FindFirstVolume, FindFirstVolumeMountPoint, FindNextVolume, FindNextVolumeMountPoint, FindVolumeClose, FindVolumeMountPointClose, GetVolumeInformation, and GetVolumeNameForVolumeMountPoint.
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <stdio.h>
#define BUFSIZE 1024 // ample space for our string buffer
#define FILESYSNAMEBUFSIZE 1024 // probably more than we need
// Process each mount point found here. This makes maintenance easier
// than doing it in line. The result indicates whether there is
// another mount point to be scanned.
// This routine prints out the path to a mount point and its target.
BOOL ProcessVolumeMountPoint (HANDLE hPt,
char *PtBuf, DWORD dwPtBufSize,
char *Buf, DWORD dwBufSize)
{
BOOL bFlag; // Boolean result
char Path[BUFSIZE]; // construct a complete path here
HANDLE hFf, hFile; // file search, file handles
WIN32_FIND_DATA fd; // find data for a file search
DWORD BytesReturned; // from DeviceIoControl call
char Target[BUFSIZE]; // target of mount at mount point
printf ("\tVolume mount point found is \"%s\"\n", PtBuf);
// Detect the volume mounted there. Unfortunately, there is no
// simple way to map a unique volume name to a DOS drive letter.
// One way to do that is to build an associative array, which we
// will "leave as an exercise for the student."
// Build a unique path to the mount point
strcpy (Path, Buf);
strcat (Path, PtBuf);
bFlag = GetVolumeNameForVolumeMountPoint(
Path, // input volume mount point or directory
Target, // output volume name buffer
BUFSIZE // size of volume name buffer
);
if (!bFlag)
printf ("\tAttempt to get Volume Name for %s failed.\n", Path);
else
printf ("\tTarget of the volume mount point is %s.\n", Target);
// Now, either get the next mount point and return it, or return a
// value indicating there are no more mount points.
bFlag = FindNextVolumeMountPoint(
hPt, // handle to scan
PtBuf, // pointer to output string
dwPtBufSize // size of output buffer
);
return (bFlag);
}
// Process each volume. This makes maintenance easier than doing it
// in line. The Boolean result indicates whether there is another
// volume to be scanned.
BOOL ProcessVolume (HANDLE hVol, char *Buf, int iBufSize)
{
BOOL bFlag; // generic results flag for return
HANDLE hPt; // handle for mount point scan
char PtBuf[BUFSIZE]; // string buffer for mount points
DWORD dwSysFlags; // flags that describe the file system
char FileSysNameBuf[FILESYSNAMEBUFSIZE];
printf ("Volume found is \"%s\".\n", Buf);
// Is this volume NTFS?
GetVolumeInformation( Buf, NULL, 0, NULL, NULL,
&dwSysFlags, FileSysNameBuf,
FILESYSNAMEBUFSIZE);
// Detect support for reparse points, and therefore for volume
// mount points, which are implemented using reparse points.
if (! (dwSysFlags & FILE_SUPPORTS_REPARSE_POINTS))
{
printf ("\tThis file system does not support Volume Mount Points.\n");
}
else
{
// Start processing mount points on this volume.
hPt = FindFirstVolumeMountPoint(
Buf, // root path of volume to be scanned
PtBuf, // pointer to output string
BUFSIZE // size of output buffer
);
// Shall we error out?
if (hPt == INVALID_HANDLE_VALUE)
{
printf ("\tNo volume mount points found!\n");
}
else
{
// Process the volume mount point.
bFlag = ProcessVolumeMountPoint (hPt, PtBuf, BUFSIZE, Buf, BUFSIZE);
// Do while we have volume mount points to process.
while (bFlag)
bFlag = ProcessVolumeMountPoint (hPt, PtBuf, BUFSIZE, Buf, BUFSIZE);
FindVolumeMountPointClose(hPt);
}
}
// Stop processing mount points on this volume.
bFlag = FindNextVolume(
hVol, // handle to scan being conducted
Buf, // pointer to output
iBufSize // size of output buffer
);
return (bFlag);
}
int
main(int argc, char *argv[])
{
char buf[BUFSIZE]; // buffer for unique volume identifiers
HANDLE hVol; // handle for the volume scan
BOOL bFlag; // generic results flag
// Open a scan for volumes.
hVol = FindFirstVolume (buf, BUFSIZE );
// Shall we error out?
if (hVol == INVALID_HANDLE_VALUE)
{
printf ("No volumes found!\n");
return (-1);
}
// We have a volume; process it.
bFlag = ProcessVolume (hVol, buf, BUFSIZE);
// Do while we have volumes to process.
while (bFlag)
{
bFlag = ProcessVolume (hVol, buf, BUFSIZE);
}
// Close out our volume scan.
bFlag = FindVolumeClose(
hVol // handle to be closed
);
return (bFlag);
}