在 Windows 環境下開發文件系統相關應用,首先需要理解兩個核心概念:
Windows 提供三大類文件系統 API:
主要有兩種方式:
GetLogicalDrives / GetLogicalDriveStrings:基於驅動器號(A:~Z:)快速獲取。FindFirstVolume / FindNextVolume:基於卷 GUID 路徑(\\?\Volume{GUID}\),支援無驅動器號的卷。| 函數 | 用途 | 關鍵參數/返回值 |
|---|---|---|
GetLogicalDrives | 獲取驅動器位圖 | 返回 DWORD,每位代表一個驅動器是否存在 |
GetLogicalDriveStrings | 獲取驅動器根路徑字串 | 需提供緩衝區,返回字串以雙 '\0' 結尾 |
FindFirstVolume | 查找第一個卷 | 返回查找句柄,卷名存入緩衝區 |
FindNextVolume | 繼續查找下一個卷 | 使用上一句柄,成功返回 TRUE |
FindVolumeClose | 關閉卷查找句柄 | 釋放資源 |
GetDriveType | 判斷驅動器類型 | 返回 DRIVE_FIXED、DRIVE_CDROM、DRIVE_REMOVABLE 等 |
GetVolumeInformation | 獲取詳細卷屬性 | 可獲取卷標、序列號、文件系統名稱(NTFS/FAT32)、支援特性標誌 |
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define BUFSIZE 1024
BOOL GetDriverInfo(LPSTR szDrive);
int main(void) {
CHAR szLogicalDriveStrings[BUFSIZE];
PCHAR szDrive;
ZeroMemory(szLogicalDriveStrings, BUFSIZE);
GetLogicalDriveStrings(BUFSIZE - 1, szLogicalDriveStrings);
szDrive = szLogicalDriveStrings;
do {
if (!GetDriverInfo(szDrive)) {
printf("\n Get Volume Information Error: %d", GetLastError());
}
szDrive += (lstrlen(szDrive) + 1);
} while (*szDrive != '\0');
return 0;
}
BOOL GetDriverInfo(LPSTR szDrive) {
UINT uDriveType = GetDriveType(szDrive);
// 類型判斷 switch 省略...
CHAR szVolumeName[MAX_PATH], szFileSystemName[BUFSIZE];
DWORD dwSerial, dwMaxComp, dwFlags;
if (!GetVolumeInformation(szDrive, szVolumeName, MAX_PATH, &dwSerial,
&dwMaxComp, &dwFlags, szFileSystemName, BUFSIZE))
return FALSE;
printf("\n Drive: %s\n Type: %s\n Serial: %u\n MaxComp: %u\n FS: %s",
szDrive, szVolumeName, dwSerial, dwMaxComp, szFileSystemName);
if (dwFlags & FILE_VOLUME_QUOTAS) printf("\n 支援磁碟配額");
if (dwFlags & FILE_SUPPORTS_ENCRYPTION) printf("\n 支援 EFS 加密");
return TRUE;
}
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define BUFSIZE MAX_PATH
BOOL GetDriverInfo(LPSTR szDrive); // 同上
int main(void) {
TCHAR buf[BUFSIZE];
HANDLE hVol = FindFirstVolume(buf, BUFSIZE);
if (hVol == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("No Volumes Found!\n"));
return -1;
}
GetDriverInfo(buf);
while (FindNextVolume(hVol, buf, BUFSIZE)) {
GetDriverInfo(buf);
}
FindVolumeClose(hVol);
return 0;
}
掛載點是訪問卷的另一入口,可將卷掛載到 NTFS 目錄下,不佔用驅動器號。
FindFirstVolumeMountPoint / FindNextVolumeMountPoint / FindVolumeMountPointClose:枚舉指定卷的所有掛載點。GetVolumeNameForVolumeMountPoint:根據掛載點路徑反查卷 GUID 名稱。FindFirstVolume 系列,兼容性更強,支援無駐留字母的卷。GetVolumeInformation 時務必檢查返回值,並預留足夠緩衝區(建議 MAX_PATH 以上)。GetLastError)。DWORD / HANDLE 與指針長度差異,避免截斷。掌握這些 API,即可構建磁碟管理工具、備份軟體、系統監控代理等底層應用。下一篇將深入文件/目錄操作與高級特性(EFS、配額、稀疏文件、USN Journal 等)。