|< C & Win32 programming 6 | Main | C & Win32 programming 8 >| Site Index | Download |


 

 

 

 

MODULE F

WIN32 AND C PROGRAMMING 7

 

 

 

 

What are in this Module?

  1. Windows Volume Management Functions

  2. Program Examples

  3. Naming a Volume Stories

  4. Program Examples

 

My Training Period: cc hours. Before you begin, read some instruction here.

 

The programming abilities for this session:

  • Be familiar and play around with the Win32 programming.

  • Able to find and collect information about volume management functions.

  • Able to understand and use the collected information about the functions in programs.

Windows Volume Management Functions

  • The following Table lists the needed information in order to use the GetDriveType() function.

Information

Description

The function

GetDriveType().

The use

Determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive.

The prototype

UINT GetDriveType(LPCTSTR  lpRootPathName);

Example

char drive2[i][j] = {"...", "..."};

 

GetDriveType(drive2[i]);

The parameters

lpRootPathName - [in] Pointer to a null-terminated string that specifies the root directory of the disk to return information about. A trailing backslash is required. If this parameter is NULL, the function uses the root of the current directory.

The return value

The return value specifies the type of drive. It can be one of the following values:

  1. DRIVE_UNKNOWN - The drive type cannot be determined.

  2. DRIVE_NO_ROOT_DIR - The root path is invalid. For example, no volume is mounted at the path.

  3. DRIVE_REMOVABLE - The disk can be removed from the drive.

  4. DRIVE_FIXED - The disk cannot be removed from the drive.

  5. DRIVE_REMOTE - The drive is a remote (network) drive.

  6. DRIVE_CDROM - The drive is a CD-ROM drive.

  7. DRIVE_RAMDISK - The drive is a RAM disk.

The header file

<windows.h>

 

Table 1:  GetDriveType() information.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#include <windows.h>

#include <stdio.h>

 

// using two dimensional arrays to store the drive strings

char drive2[13][5] = {"A:\\", "B:\\", "C:\\", "D:\\", "E:\\", "F:\\", "G:\\", "H:\\","I:\\", "J:\\", "K:\\", "L:\\"};

 

int main()

{

    for(int i=0; i<12; i++)

    {

        UINT test = GetDriveType(drive2[i]);

        switch(test)

        {

            case 0: printf("Drive %s is type %d - Cannot be determined.\n", &drive2[i], test);

                break;

            case 1: printf("Drive %s is type %d - Invalid root path/Not available.\n", &drive2[i], test);

                break;

        case 2: printf("Drive %s is type %d - Removable.\n", &drive2[i], test);

                break;

        case 3: printf("Drive %s is type %d - Fixed.\n", &drive2[i], test);

                break;

        case 4: printf("Drive %s is type %d - Network.\n", &drive2[i], test);

                break;

        case 5: printf("Drive %s is type %d - CD-ROM.\n", &drive2[i], test);

                break;

        case 6: printf("Drive %s is type %d - RAMDISK.\n", &drive2[i], test);

                break;

        default  : "Unknown value!\n";

        }

    }

   return 0;

}

 

The output:

 

Drive A:\ is type 2 - Removable.

Drive B:\ is type 1 - Invalid root path/Not available.

Drive C:\ is type 3 - Fixed.

Drive D:\ is type 3 - Fixed.

Drive E:\ is type 3 - Fixed.

Drive F:\ is type 3 - Fixed.

Drive G:\ is type 3 - Fixed.

Drive H:\ is type 3 - Fixed.

Drive I:\ is type 3 - Fixed.

Drive J:\ is type 5 - CD-ROM.

Drive K:\ is type 5 - CD-ROM.

Drive L:\ is type 2 - Removable.

Press any key to continue

Information

Description

The function

GetLogicalDrives().

The use

Retrieves a bitmask representing the currently available disk drives.

The prototype

DWORD GetLogicalDrives(void);

Example

TCHAR szDrive[ ] = _T(" A:");

 

DWORD uDriveMask = GetLogicalDrives();

printf("This machine has the following logical drives:\n");

 

while(uDriveMask)

{

 if(uDriveMask & 1)

    printf(szDrive);

  // binary 1 shows that the drive is available and 0 otherwise

  ++szDrive[1];

  // shift right

  uDriveMask >>= 1;

}

The parameters

This function has no parameters.

The return value

If the function succeeds, the return value is a bitmask representing the currently available disk drives.  Bit position 0 (the least-significant bit) is drive A, bit position 1 is drive B, bit position 2 is drive C, and so on.

The header file

<windows.h>

 

Table 2:  GetLogicalDrives() information.

#include <windows.h>

#include <direct.h>

#include <stdio.h>

#include <tchar.h>

 

// initial value

TCHAR szDrive[ ] = _T(" A:");

 

int main()

{

  DWORD uDriveMask = GetLogicalDrives();

  printf("The bitmask of the logical drives in hex: %0X\n", uDriveMask);

  printf("The bitmask of the logical drives in decimal: %d\n", uDriveMask);

  if(uDriveMask == 0)

      printf("GetLogicalDrives() failed with failure code: %d\n", GetLastError());

  else

  {

      printf("This machine has the following logical drives:\n");

  while(uDriveMask)

    {// use the bitwise AND, 1–available, 0-not available

     if(uDriveMask & 1)

        printf(szDrive);

     // increment... 

     ++szDrive[1];

      // shift the bitmask binary right

      uDriveMask >>= 1;

     }

    printf("\n ");

   }

   return 0;

}

 

The output:

 

The bitmask of the logical drives in hex: FFD

The bitmask of the logical drives in decimal: 4093

This machine has the following logical drives:

 A: C: D: E: F: G: H: I: J: K: L:

 Press any key to continue

Information

Description

The function

GetLogicalDriveStrings().

The use

Fills a buffer with strings that specify valid drives in the system.

The prototype

DWORD GetLogicalDriveStrings(DWORD nBufferLength, LPTSTR lpBuffer);

Example

DWORD mydrives = 100;

char lpBuffer[100];

 

GetLogicalDriveStrings(mydrives, lpBuffer);

The parameters

nBufferLength - [in] Maximum size of the buffer pointed to by lpBuffer, in TCHARs.  This size does not include the terminating null character. If this parameter is zero, lpBuffer is not used.

lpBuffer - [out] Pointer to a buffer that receives a series of null-terminated strings, one for each valid drive in the system, plus with an additional null character.  Each string is a device name.

The return value

If the function succeeds, the return value is the length, in characters, of the strings copied to the buffer, not including the terminating null character.  Note that an ANSI-ASCII null character uses one byte, but a Unicode null character uses two bytes.

If the buffer is not large enough, the return value is greater than nBufferLength.  It is the size of the buffer required to hold the drive strings.

If the function fails, the return value is zero.  To get extended error information, use the GetLastError() function.

The header file

<windows.h>

 

Table 3:  GetLogicalDriveStrings() information.

#include <windows.h>

#include <stdio.h>

 

// buffer length

DWORD mydrives = 100;

// buffer for drive string storage

char lpBuffer[100];

 

int main()

{

      DWORD test = GetLogicalDriveStrings( mydrives, lpBuffer);

      printf("GetLogicalDriveStrings() return value: %d\nError: %d \n", test, GetLastError());

      printf("The logical drives of this machine are:\n");

      for(int i = 0; i<100; i++)

        printf("%c", lpBuffer[i]);

      printf("\n");

      return 0;

}

 

The output:

 

GetLogicalDriveStrings() return value: 44

Error: 0

The logical drives of this machine are:

A:\ C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\

 

Press any key to continue

Information

Description

The function

QueryDosDevice().

The use

Retrieves information about MS-DOS device names.  The function can obtain the current mapping for a particular MS-DOS device name.  The function can also obtain a list of all existing MS-DOS device names.

The prototype

DWORD QueryDosDevice( LPCTSTR lpDeviceName, LPTSTR lpTargetPath, DWORD ucchMax );

Example

char lpDeviceName[11][3] = {"A:", "C:", "D:", "E:", "F:", "G:", "H:","I:", "J:", "K:", "L:"};

// the buffer for storage

char lpTargetPath[1000];

 

QueryDosDevice(lpDeviceName[i], lpTargetPath, 1000);

The parameters

lpDeviceName - [in] Pointer to an MS-DOS device name string specifying the target of the query.  The device name cannot have a trailing backslash. This parameter can be NULL.  In that case, the QueryDosDevice() function will store a list of all existing MS-DOS device names into the buffer pointed to by lpTargetPath.

lpTargetPath - [out] Pointer to a buffer that will receive the result of the query. The function fills this buffer with one or more null-terminated strings.  The final null-terminated string is followed by an additional NULL. If lpDeviceName is non-NULL, the function retrieves information about the particular MS-DOS device specified by lpDeviceName.  The first null-terminated string stored into the buffer is the current mapping for the device.  The other null-terminated strings represent undeleted prior mappings for the device.

If lpDeviceName is NULL, the function retrieves a list of all existing MS-DOS device names.  Each null-terminated string stored into the buffer is the name of an existing MS-DOS device.

ucchMax - [in] Maximum number of TCHARs that can be stored into the buffer pointed to by lpTargetPath.

The return value

If the function succeeds, the return value is the number of TCHARs stored into the buffer pointed to by lpTargetPath. If the function fails, the return value is zero. To get extended error information, call GetLastError(). If the buffer is too small, the function fails and the last error code is ERROR_INSUFFICIENT_BUFFER.

The header file

<windows.h>

 

Table 4:  QueryDosDevice() information.

#include <windows.h>

#include <stdio.h>

 

// query these on my machine. The L: is thumb drive, J: and K: are CD-ROMs

char lpDeviceName[11][3] = {"A:", "C:", "D:", "E:", "F:", "G:", "H:","I:", "J:", "K:", "L:"};

// the buffer for storage

char lpTargetPath[1000];

 

int main()

{

  for(int i=0; i<13; i++)

  {

    // using NULL for the parameter 1 is not working lol...

    DWORD test = QueryDosDevice(lpDeviceName[i], lpTargetPath, 1000);

    // test the return value and error if any

    printf("\nQueryDosDevice() return value: %d, Error: %d\n", test, GetLastError());

    printf("The DOS device for %s is:\n", lpDeviceName[i]);

    // display the result

    for(int i = 0; i<35; i++)

      printf("%c", lpTargetPath[i]);

  }

     printf("\n");

     return 0;

}

 

The output:

 

QueryDosDevice() return value: 17, Error: 0

The DOS device for A: is:

\Device\Floppy0

QueryDosDevice() return value: 25, Error: 0

The DOS device for C: is:

\Device\HarddiskVolume1

QueryDosDevice() return value: 25, Error: 0

The DOS device for D: is:

\Device\HarddiskVolume5

QueryDosDevice() return value: 25, Error: 0

The DOS device for E: is:

\Device\HarddiskVolume2

QueryDosDevice() return value: 25, Error: 0

The DOS device for F: is:

\Device\HarddiskVolume3

QueryDosDevice() return value: 25, Error: 0

The DOS device for G: is:

\Device\HarddiskVolume4

QueryDosDevice() return value: 25, Error: 0

The DOS device for H: is:

\Device\HarddiskVolume6

QueryDosDevice() return value: 25, Error: 0

The DOS device for I: is:

\Device\HarddiskVolume7

QueryDosDevice() return value: 16, Error: 0

The DOS device for J: is:

\Device\CdRom0   olume7

QueryDosDevice() return value: 16, Error: 0

The DOS device for K: is:

\Device\CdRom1   olume7

QueryDosDevice() return value: 30, Error: 0

The DOS device for L: is:

\Device\Harddisk2\DP(1)0-0+a

QueryDosDevice() return value: 0, Error: 6

The DOS device for  is:

\Device\Harddisk2\DP(1)0-0+a

QueryDosDevice() return value: 0, Error: 6

The DOS device for  is:

\Device\Harddisk2\DP(1)0-0+a

Press any key to continue

 

 

 

Information

Description

The function

GetDiskFreeSpaceEx().

The use

Retrieves information about the amount of space available on a disk volume: the total amount of space, the total amount of free space, and the total amount of free space available to the user associated with the calling thread.

The prototype

BOOL GetDiskFreeSpaceEx( LPCTSTR  lpDirectoryName, PULARGE_INTEGER  lpFreeBytesAvailable,
PULARGE_INTEGER  lpTotalNumberOfBytes,   PULARGE_INTEGER  lpTotalNumberOfFreeBytes);

Example

char pszDrive[10] = "C:\\";

DWORD dwSectPerClust, dwBytesPerSect, dwFreeClusters, dwTotalClusters;

 

GetDiskFreeSpace(pszDrive, &dwSectPerClust, &dwBytesPerSect, &dwFreeClusters, &dwTotalClusters);

The parameters

lpDirectoryName - [in] Pointer to a null-terminated string that specifies a directory on the disk of interest.  If this parameter is NULL, the function uses the root of the current disk.  If this parameter is a UNC name, it must include a trailing backslash (for example, \\MyServer\MyShare\). Note that this parameter does not have to specify the root directory on a disk.  The function accepts any directory on the disk.

lpFreeBytesAvailable - [out] Pointer to a variable that receives the total number of free bytes on the disk that are available to the user associated with the calling thread.  This parameter can be NULL. If per-user quotas are in use, this value may be less than the total number of free bytes on the disk.

lpTotalNumberOfBytes - [out] Pointer to a variable that receives the total number of bytes on the disk that are available to the user associated with the calling thread.  This parameter can be NULL. If per-user quotas are in use, this value may be less than the total number of bytes on the disk. To determine the total number of bytes on a disk or volume, use IOCTL_DISK_GET_LENGTH_INFO.

lpTotalNumberOfFreeBytes - [out] Pointer to a variable that receives the total number of free bytes on the disk.  This parameter can be NULL.

The return value

If the function succeeds, the return value is nonzero.  If the function fails, the return value is zero.  To get extended error information, call GetLastError().

The header file

<windows.h>

 

Table 5:  GetDiskFreeSpaceEx() information.

#include <windows.h>

#include <stdio.h>

 

int main()

{

   char pszDrive[10] = "C:\\";

   // 64 bits integer

   __int64 lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes;

   DWORD dwSectPerClust, dwBytesPerSect, dwFreeClusters, dwTotalClusters;

 

  BOOL test = GetDiskFreeSpaceEx(

  pszDrive,

  (PULARGE_INTEGER)&lpFreeBytesAvailable,

  (PULARGE_INTEGER)&lpTotalNumberOfBytes,

  (PULARGE_INTEGER)&lpTotalNumberOfFreeBytes

);

 

  printf("Drive to be checked: %s\n", pszDrive);

  printf("\nUsing GetDiskFreeSpaceEx()...\n");

  // check the return value

  printf("The return value: %d, error code: %d\n", test, GetLastError());

  printf("Total number of free bytes available for user-caller: %ul\n", lpFreeBytesAvailable);

  printf("Total number of bytes available for user: %ul\n", lpTotalNumberOfBytes);

  // just straight to the free bytes result

  printf("Total number of free bytes on disk: %ul\n", lpTotalNumberOfFreeBytes);

 

  BOOL fResult = GetDiskFreeSpace(pszDrive,

                 &dwSectPerClust,

                 &dwBytesPerSect,

                 &dwFreeClusters,

                 &dwTotalClusters);

   

    printf("\nUsing GetDiskFreeSpace()...\n");

    printf("The return value: %d, error code: %d\n", fResult, GetLastError());

    printf("Sector per cluster = %ul\n", dwSectPerClust);

    printf("Bytes per sector = %ul\n", dwBytesPerSect);

    printf("Free cluster = %ul\n", dwFreeClusters);

    printf("Total cluster = %ul\n", dwTotalClusters);

    // using GetDiskFreeSpace() need some calculation for the free bytes on disk

    printf("Total free bytes = %ul\n", (dwFreeClusters*dwSectPerClust*dwBytesPerSect));

   

  return 0;

}

 

The output:

 

Drive to be checked: C:\

 

Using GetDiskFreeSpaceEx()...

The return value: 1, error code: 0

Total number of free bytes available for user-caller: 263147520l

Total number of bytes available for user: 1897263104l

Total number of free bytes on disk: 263147520l

 

Using GetDiskFreeSpace()...

The return value: 1, error code: 0

Sector per cluster = 8l

Bytes per sector = 512l

Free cluster = 64245l

Total cluster = 2560351l

Total free bytes = 263147520l

Press any key to continue

 

Naming a Volume Stories

  1. Two different volumes can have the same label, which makes them indistinguishable except by drive letter.

  2. Drive letters do not necessarily remain the same.  If a computer's administrator does not use the Disk Administrator to enforce drive letters, then drive letters can change as drives are removed from or added to the system.

"\\?\Volume{GUID}\"

\\?\Volume{a3446ed5-ebd9-11d8-a25c-806d6172696f}\

  1. Refer to volumes by their unique volume names.

  2. Use the Unicode (W) versions of file functions, which support the \\?\ prefix.

Information

Description

The function

GetVolumeInformation().

The use

Retrieves information about a file system and volume whose root directory is specified.

The prototype

BOOL GetVolumeInformation( LPCTSTR lpRootPathName, LPTSTR  lpVolumeNameBuffer, DWORD   nVolumeNameSize,
LPDWORD lpVolumeSerialNumber, LPDWORD lpMaximumComponentLength, LPDWORD lpFileSystemFlags,
LPTSTR  lpFileSystemNameBuffer, DWORD   nFileSystemNameSize);

Example

#define BUFSIZE MAX_PATH

#define FILESYSNAMEBUFSIZE MAX_PATH

 

// buffer for unique volume identifiers

char buf[BUFSIZE];

DWORD lpMaximumComponentLength;

// flags that describe the file system

DWORD dwSysFlags;

char FileSysNameBuf[FILESYSNAMEBUFSIZE];

 

GetVolumeInformation( buf, NULL, BUFSIZE, NULL, &lpMaximumComponentLength, &dwSysFlags, FileSysNameBuf, FILESYSNAMEBUFSIZE);

The parameters

lpRootPathName - [in] Pointer to a string that contains the root directory of the volume to be described.  If this parameter is NULL, the root of the current directory is used.  A trailing backslash is required.  For example, you would specify \\MyServer\MyShare as \\MyServer\MyShare\, or the C drive as "C:\".

lpVolumeNameBuffer - [out] Pointer to a buffer that receives the name of the specified volume.

nVolumeNameSize - [in] Length of the volume name buffer, in TCHARs.  This parameter is ignored if the volume name buffer is not supplied.

lpVolumeSerialNumber - [out] Pointer to a variable that receives the volume serial number. This parameter can be NULL if the serial number is not required.

lpMaximumComponentLength - [out] Pointer to a variable that receives the maximum length, in TCHARs, of a file name component supported by the specified file system. A file name component is that portion of a file name between backslashes. The value stored in variable pointed to by *lpMaximumComponentLength is used to indicate that long names are supported by the specified file system.  For example, for a FAT file system supporting long names, the function stores the value 255, rather than the previous 8.3 indicator.  Long names can also be supported on systems that use the NTFS file system.

lpFileSystemFlags - [out] Pointer to a variable that receives flags associated with the specified file system.  This parameter can be one or more of the following flags; however, FS_FILE_COMPRESSION and FS_VOL_IS_COMPRESSED are mutually exclusive.

  1. FILE_NAMED_STREAMS - The file system supports named streams.

  2. FILE_READ_ONLY_VOLUME - The specified volume is read-only.

  3. FILE_SUPPORTS_OBJECT_IDS - The file system supports object identifiers.

  4. FILE_SUPPORTS_REPARSE_POINTS - The file system supports reparse points.

  5. FILE_SUPPORTS_SPARSE_FILES - The file system supports sparse files.

  6. FILE_VOLUME_QUOTAS - The file system supports disk quotas.

  7. FS_CASE_IS_PRESERVED - The file system preserves the case of file names when it places a name on disk.

  8. FS_CASE_SENSITIVE - The file system supports case-sensitive file names.

  9. FS_FILE_COMPRESSION - The file system supports file-based compression.

  10. FS_FILE_ENCRYPTION - The file system supports the Encrypted File System (EFS).

  11. FS_PERSISTENT_ACLS - The file system preserves and enforces ACLs.  For example, NTFS preserves and enforces ACLs, and FAT does not.

  12. FS_UNICODE_STORED_ON_DISK - The file system supports Unicode in file names as they appear on disk.

  13. FS_VOL_IS_COMPRESSED - The specified volume is a compressed volume; for example, a DoubleSpace volume.

 

lpFileSystemNameBuffer - [out] Pointer to a buffer that receives the name of the file system (such as FAT or NTFS).

nFileSystemNameSize - [in] Length of the file system name buffer, in TCHARs.  This parameter is ignored if the file system name buffer is not supplied.

The return value

If all the requested information is retrieved, the return value is nonzero.

If not all the requested information is retrieved, the return value is zero.  To get extended error information, call GetLastError().

The header file

<windows.h>

 

Table 6:  GetVolumeInformation() information.

Information

Description

The function

FindFirstVolume().

The use

Used to begin scanning the volumes of a computer.  Returns the name of a volume on a computer.

The prototype

HANDLE FindFirstVolume( LPTSTR lpszVolumeName, DWORD cchBufferLength );

Example

#define BUFSIZE MAX_PATH

char buf[BUFSIZE];

hVol = FindFirstVolume(buf, BUFSIZE);

   if(hVol == INVALID_HANDLE_VALUE)

   {

      printf ("No volumes found!\n");

      return (-1);

   }

The parameters

lpszVolumeName - [out] Pointer to a buffer that receives a null-terminated string that specifies the unique volume name of the first volume found.

cchBufferLength - [in] Length of the buffer to receive the name, in TCHARs.

The return value

If the function succeeds, the return value is a search handle used in a subsequent call to the FindNextVolume() and FindVolumeClose() functions.  If the function fails to find any volumes, the return value is the INVALID_HANDLE_VALUE error code.  To get extended error information, call GetLastError().

The header file

<windows.h>

 

Table 7:  FindFirstVolume() information.

Information

Description

The function

FindNextVolume().

The use

Continues a volume search started by a call to the FindFirstVolume() function.  FindNextVolume() finds one volume per call.

The prototype

BOOL FindNextVolume( HANDLE  hFindVolume, LPTSTR  lpszVolumeName, DWORD cchBufferLength);

Example

#define Bufsize MAX_PATH

 

HANDLE  hVol;

// buffer for unique volume identifiers

char Buffer[Bufsize];

hVol = FindFirstVolume(Buffer, Bufsize);

 

FindNextVolume(

   hVol,        // handle to search being conducted

   Buf,          // pointer to output

   BufSize); // size of output buffer

The parameters

hFindVolume - [in] Volume search handle returned by a previous call to the FindFirstVolume() function.

lpszVolumeName - [out] Pointer to a string that receives the unique volume name found.

cchBufferLength - [in] Length of the buffer that receives the name, in TCHARs.

The return value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero.  To get extended error information, call GetLastError().  If no matching files can be found, the GetLastError() function returns the ERROR_NO_MORE_FILES error code.  In that case, close the search with the FindVolumeClose() function.

The header file

<windows.h>

 

Table 8:  FindNextVolume() information.

My test Windows machine drives

// for Win Xp

#define _WIN32_WINNT 0x0501

#include <windows.h>

#include <stdio.h>

#define BUFSIZE MAX_PATH

#define FILESYSNAMEBUFSIZE MAX_PATH

 

int main()

{

   char buf[BUFSIZE];    // buffer for unique volume identifiers

   DWORD lpMaximumComponentLength;

   DWORD dwSysFlags;     // flags that describe the file system

   char FileSysNameBuf[FILESYSNAMEBUFSIZE];

 

   // handle for the volume search

   HANDLE hVol;

   // open a scan for volumes.

   hVol = FindFirstVolume(buf, BUFSIZE);

 

   if(hVol == INVALID_HANDLE_VALUE)

   {

      printf ("No volumes found!\n");

      return (-1);

   }

 

  BOOL test = GetVolumeInformation(

  buf,

  NULL,

  BUFSIZE,

  NULL,

  &lpMaximumComponentLength,

  &dwSysFlags,

  FileSysNameBuf,

  FILESYSNAMEBUFSIZE

  );

 

  printf("The return value: %d\n", test);

  printf("The first volume found: %s\n", buf);

  printf("The buffer for volume name: %d\n", BUFSIZE);

  printf("The max component length: %d\n", lpMaximumComponentLength);

  printf("The file system flag: %d\n", dwSysFlags);

  printf("The file system: %s\n", FileSysNameBuf);

  printf("The buffer for file system name: %d\n", FILESYSNAMEBUFSIZE);

  CloseHandle(hVol);

  return 0;

}

 

A sample output:

 

The return value: 1

The first volume found: \\?\Volume{a3446ed5-ebd9-11d8-a25c-806d6172696f}\

The buffer for volume name: 260

The max component length: 255

The file system flag: 459007

The file system: NTFS

The buffer for file system name: 260

Press any key to continue

// for Win Xp

#define _WIN32_WINNT 0x0501

#include <windows.h>

#include <stdio.h>

#define BUFSIZE MAX_PATH

#define FILESYSNAMEBUFSIZE MAX_PATH

 

BOOL ProcessVolume(HANDLE hVol, char *Buf, int iBufSize)

{

  DWORD lpMaximumComponentLength;

  DWORD dwSysFlags;     // flags that describe the file system

  char  FileSysNameBuf[FILESYSNAMEBUFSIZE];

  BOOL  bFlag;  // generic results flag

 

  GetVolumeInformation(

  Buf,

  NULL,

  BUFSIZE,

  NULL,

  &lpMaximumComponentLength,

   &dwSysFlags,

  FileSysNameBuf,

   FILESYSNAMEBUFSIZE

  );

  ////////----------caution--------------///////

  // for file system, in order the removal drives such as floppy

  // and CD-ROM to be recognized, you must insert the media...

  printf("The volume found: %s\n", Buf);

  printf("The buffer for volume name: %d\n", BUFSIZE);

  printf("The max component length: %d\n", lpMaximumComponentLength);

  printf("The file system flag: %d\n", dwSysFlags);

  printf("The file system: %s\n", FileSysNameBuf);

  printf("The buffer for file system name: %d\n\n", FILESYSNAMEBUFSIZE);

 

  bFlag = FindNextVolume(

                hVol,    // handle to search being conducted

                 Buf,     // pointer to output

             iBufSize // size of output buffer

           );

    return (bFlag);

}

 

int main()

{

   char    buf[BUFSIZE];  // buffer for unique volume identifiers

   HANDLE  hVol;           // handle for the volume scan

   BOOL    bFlag;

   // open a search for volumes.

   hVol = FindFirstVolume(buf, BUFSIZE);

 

   if(hVol == INVALID_HANDLE_VALUE)

   {

      printf("No volumes found!\n");

      return (-1);

   }

 

   bFlag = ProcessVolume(hVol, buf, BUFSIZE);

 

   // do while we have volumes to process.

   while(bFlag)

   { bFlag = ProcessVolume(hVol, buf, BUFSIZE); }

 

   // close out the volume search and close the handle

   bFlag = FindVolumeClose(hVol);

  

  return 0;

}

 

The output (has been trimmed):

 

...

...

The volume found: \\?\Volume{a3446edb-ebd9-11d8-a25c-806d6172696f}\

The buffer for volume name: 260

The max component length: 255

The file system flag: 459007

The file system: NTFS

The buffer for file system name: 260

 

The volume found: \\?\Volume{a3446ed3-ebd9-11d8-a25c-806d6172696f}\

The buffer for volume name: 260

The max component length: 110

The file system flag: 524293

The file system: CDFS

The buffer for file system name: 260

 

The volume found: \\?\Volume{a3446ed2-ebd9-11d8-a25c-806d6172696f}\

The buffer for volume name: 260

The max component length: 255

The file system flag: 524294

The file system: FAT

The buffer for file system name: 260

 

The volume found: \\?\Volume{2faa8876-ec06-11d8-adbf-00508de5770d}\

The buffer for volume name: 260

The max component length: 255

The file system flag: 6

The file system: FAT

The buffer for file system name: 260

 

Press any key to continue

// for Win Xp

#define _WIN32_WINNT 0x0501

#include <windows.h>

#include <stdio.h>

#define Bufsize MAX_PATH       

#define FILESYSNAMEBufsize MAX_PATH

// process each mount point found here. The result indicates whether there is

// another mount point to be searched. This routine prints out the path to a mount point and its target.

BOOL ProcessVolumeMountPoint(HANDLE hPt, char *PtBuffer, DWORD dwPtBufsize, char *Buffer, DWORD dwBufsize)

{

   BOOL bFlag;             // Boolean result  

   char Path[Bufsize];    // construct a complete path here

   char Target[Bufsize]; // target of mount at mount point

 

   printf("Volume mount point found is \"%s\"\n", PtBuffer);

   // detect the volume mounted there. Build a unique path to the mount point

   // strcpy_s(Path, Bufsize, Buffer);

   strcpy(Path, Buffer);

   // strcat_s(Path, Bufsize, PtBuffer);

   strcat(Path, PtBuffer);

   bFlag = GetVolumeNameForVolumeMountPoint(

                Path,       // input volume mount point or directory

                Target,    // output volume name buffer

                Bufsize); // size of volume name buffer

   if(!bFlag)

      printf("Attempt to get volume name for %s failed.\n", Path);

   else

      printf("Target of the volume mount point is %s.\n\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

                     PtBuffer,         // pointer to output string

                     dwPtBufsize); // size of output buffer

  return (bFlag);

}

// process each volume.  The Boolean result indicates whether there is another volume to be searched.

BOOL ProcessVolume(HANDLE hVol, char *Buffer, int iBufsize)

{

   BOOL    bFlag;                       // generic results flag for return

   HANDLE  hPt;                        // handle for mount point scan

   char    PtBuffer[Bufsize];        // string buffer for mount points

   DWORD   dwSysFlags;        // flags that describe the file system

   char    FileSysNameBuffer[FILESYSNAMEBufsize];

 

   printf("Volume found is \"%s\".\n", Buffer);

   // is this volume NTFS or other?

   GetVolumeInformation(Buffer, NULL, 0, NULL, NULL, &dwSysFlags, FileSysNameBuffer, FILESYSNAMEBufsize);

   ////////----------caution--------------///////

   // for file system, in order the removal drives such as floppy

   // and CD-ROM to be recognized, you must insert the media...

   printf("The file system is %s\n", FileSysNameBuffer);

   // detect support for reparse points, and therefore for volume

   // mount points, which are implemented using reparse points.

   if(!(dwSysFlags & FILE_SUPPORTS_REPARSE_POINTS))

       { printf("This file system does not support volume mount points.\n\n"); }

   else

   {

      // start processing mount points on this volume.

      hPt = FindFirstVolumeMountPoint(

                  Buffer,      // root path of volume to be scanned

                  PtBuffer,  // pointer to output string

                  Bufsize);  // size of output buffer

      if(hPt == INVALID_HANDLE_VALUE)

          {printf("No volume mount points found!\n\n");}

      else

      {

         // process the volume mount point.

         bFlag = ProcessVolumeMountPoint(hPt, PtBuffer, Bufsize, Buffer, Bufsize);

         // do while we have volume mount points to process.

         while (bFlag)

            bFlag = ProcessVolumeMountPoint(hPt, PtBuffer, Bufsize, Buffer, Bufsize);

         FindVolumeMountPointClose(hPt);

       }

   }

   // stop processing mount points on this volume.

   bFlag = FindNextVolume(

                 hVol,         // handle to scan being conducted

                 Buffer,      // pointer to output

                 iBufsize); // size of output buffer

   return (bFlag);

}

 

int main()

{

   char Buffer[Bufsize];  // buffer for unique volume identifiers

   HANDLE hVol;          // handle for the volume scan

   BOOL bFlag;             // generic results flag

 

   // open a search for volumes.

   hVol = FindFirstVolume(Buffer, Bufsize);

   if(hVol == INVALID_HANDLE_VALUE)

   {

      printf("No volumes found!\n");

      return (-1);

   }

   bFlag = ProcessVolume(hVol, Buffer, Bufsize);

   // do while we have volumes to process.

   while(bFlag)

   {bFlag = ProcessVolume(hVol, Buffer, Bufsize);}

   // close out the volume scan, handle to be closed

   bFlag = FindVolumeClose(hVol);

   return (bFlag);

}

 

The output sample:

 

Volume found is "\\?\Volume{a3446ed5-ebd9-11d8-a25c-806d6172696f}\".

The file system is NTFS

No volume mount points found!

 

Volume found is "\\?\Volume{a3446ed6-ebd9-11d8-a25c-806d6172696f}\".

The file system is NTFS

No volume mount points found!

 

Volume found is "\\?\Volume{a3446ed7-ebd9-11d8-a25c-806d6172696f}\".

The file system is NTFS

Volume mount point found is "mymntpoint\"

Target of the volume mount point is \\?\Volume{a3446edb-ebd9-11d8-a25c-806d6172696f}\.

 

Volume found is "\\?\Volume{a3446ed8-ebd9-11d8-a25c-806d6172696f}\".

The file system is NTFS

No volume mount points found!

 

Volume found is "\\?\Volume{a3446ed9-ebd9-11d8-a25c-806d6172696f}\".

The file system is NTFS

No volume mount points found!

 

Volume found is "\\?\Volume{a3446eda-ebd9-11d8-a25c-806d6172696f}\".

The file system is NTFS

No volume mount points found!

 

Volume found is "\\?\Volume{a3446edb-ebd9-11d8-a25c-806d6172696f}\".

The file system is NTFS

No volume mount points found!

 

Volume found is "\\?\Volume{a3446ed3-ebd9-11d8-a25c-806d6172696f}\".

The file system is CDFS

This file system does not support volume mount points.

 

Volume found is "\\?\Volume{a3446ed2-ebd9-11d8-a25c-806d6172696f}\".

The file system is FAT

This file system does not support volume mount points.

 

Volume found is "\\?\Volume{2faa8876-ec06-11d8-adbf-00508de5770d}\".

The file system is FAT

This file system does not support volume mount points.

 

Press any key to continue

 

 

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Check the best selling C, C++ and Windows books at Amazon.com.

  2. Microsoft Visual C++, online MSDN.

  3. Notation used in MSDN is Hungarian Notation instead of CamelCase and is discussed VC++ programming notations.

  4. Windows data type information is in Data types used in Windows programming.

  5. For Multibytes, Unicode characters and Localization please refer to Locale, wide characters & Unicode (Story) and Windows users & groups programming tutorials (Implementation).

  6. Structure, enum, union and typedef story can be found C/C++ struct, enum, union & typedef.

 

 

 

 

 

 

|< C & Win32 programming 6 | Main | C & Win32 programming 8 >| Site Index | Download |


 

C & C++ Programming Tutorial | C Programming Practice