GetLogicalDrives

基本概念

GetLogicalDrivesWindows系统提供的一个文件管理相关API函数,用于获取当前系统中所有可用磁盘驱动器的信息。它通过返回一个位掩码(bitmask)来标识系统中存在的可用磁盘驱动器。

基本语法

1
DWORD GetLogicalDrives();

返回值:

成功:返回一个 DWORD 类型的位掩码,每个置为1的位代表对应的逻辑驱动器存在。
失败:返回0,可通过GetLastError()获取具体错误信息。

位掩码含义
返回的位掩码中,每个二进制位对应一个逻辑驱动器,按字母顺序(A-Z)排列:
0位(二进制最低位,值为0x00000001)对应A: 驱动器
1位(值为0x00000002)对应B: 驱动器
2位(值为0x00000004)对应C: 驱动器

n位对应第(A + n)个字母的驱动器。

简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <windows.h>
#include <stdio.h>

int main() {
// 获取逻辑驱动器位掩码
DWORD drives = GetLogicalDrives();
if (drives == 0) {
printf("获取驱动器失败,错误码: %d\n", GetLastError());
return 1;
}

printf("系统中存在的逻辑驱动器:\n");

// 遍历位掩码,检查每个驱动器是否存在
for (char c = 'A'; c <= 'Z'; c++) {
// 计算当前驱动器对应的位(第 n 位,n = c - 'A')
DWORD mask = 1 << (c - 'A');

// 如果对应位为 1,说明驱动器存在
if (drives & mask) {
printf("%c:\n", c);
}
}

return 0;
}

GetDriveTypeW

基本概念

GetDriveTypeWindows系统提供的一个宏(而非直接的函数实现),它会根据项目的字符编码设置(是否定义UNICODE)自动映射到宽字符版本GetDriveTypeWANSI版本GetDriveTypeA。其核心功能是判断指定驱动器的物理类型(如固定硬盘、可移动设备、光驱等),是文件系统开发中区分存储设备类型的常用工具。

基本语法

1
2
3
4
5
6
7
UINT GetDriveTypeW(
[in, optional] LPCWSTR lpRootPathName //驱动器的根目录
);

UINT GetDriveTypeA(
[in, optional] LPCSTR lpRootPathName
);

lpRootPathName
指向驱动器根路径的字符串指针。格式必须为X:\\(如C:\\D:\\),其中X为驱动器字母。
若为NULL,则查询当前默认驱动器(通常是程序运行所在的驱动器)。

返回值

返回UINT类型的整数,代表驱动器类型,

1
2
typedef unsigned int        UINT;
无符号整数类型

返回值宏定义 数值 说明
DRIVE_UNKNOWN 0 未知类型(无法识别驱动器类型)
DRIVE_NO_ROOT_DIR 1 无效路径(如驱动器不存在、路径格式错误,或驱动器未就绪)
DRIVE_REMOVABLE 2 可移动驱动器(如U盘、移动硬盘、软盘等)
DRIVE_FIXED 3 固定驱动器(如本地硬盘、SSD等)
DRIVE_REMOTE 4 网络驱动器(通过网络映射的远程共享目录)
DRIVE_CDROM 5 光盘驱动器(如CD-ROMDVD-ROM、蓝光光驱等)
DRIVE_RAMDISK 6 `RAM 磁盘(基于内存的虚拟磁盘,数据存储在内存中)

简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <windows.h>
#include <stdio.h>

// 根据返回值获取驱动器类型描述
const wchar_t* GetDriveTypeDescription(UINT driveType) {
switch (driveType) {
case DRIVE_UNKNOWN: return L"未知类型";
case DRIVE_NO_ROOT_DIR: return L"无效路径(驱动器不存在或未就绪)";
case DRIVE_REMOVABLE: return L"可移动驱动器(如U盘、移动硬盘)";
case DRIVE_FIXED: return L"固定驱动器(如本地硬盘、SSD)";
case DRIVE_REMOTE: return L"网络驱动器";
case DRIVE_CDROM: return L"光盘驱动器(如CD/DVD)";
case DRIVE_RAMDISK: return L"RAM磁盘(虚拟内存盘)";
default: return L"未识别类型";
}
}

int main() {
// 要查询的驱动器(例如C盘)
LPCWSTR drivePath = L"C:\\";

// 调用API获取驱动器类型
UINT driveType = GetDriveTypeW(drivePath);

// 输出结果
wprintf(L"驱动器 %s 的类型:%s\n", drivePath, GetDriveTypeDescription(driveType));

return 0;
}

GetDiskFreeSpace

基本概念

GetDiskFreeSpaceWindows系统提供的用于获取磁盘基础存储信息的API函数,主要返回磁盘的簇、扇区等底层存储结构信息,通过这些信息可计算磁盘总容量和可用空间,
会根据项目的字符编码设置(是否定义UNICODE)自动映射到宽字符版本GetDiskFreeSpaceWANSI版本GetDiskFreeSpaceA

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
BOOL GetDiskFreeSpaceW(
[in] LPCWSTR lpRootPathName, //磁盘根路径
[out] LPDWORD lpSectorsPerCluster,//每簇扇区数
[out] LPDWORD lpBytesPerSector, //每扇区字节数
[out] LPDWORD lpNumberOfFreeClusters,//可用簇数
[out] LPDWORD lpTotalNumberOfClusters//总簇数
);

BOOL GetDiskFreeSpaceA(
[in] LPCSTR lpRootPathName,
[out] LPDWORD lpSectorsPerCluster,
[out] LPDWORD lpBytesPerSector,
[out] LPDWORD lpNumberOfFreeClusters,
[out] LPDWORD lpTotalNumberOfClusters
);

LPDWORD

1
2
typedef DWORD far           *LPDWORD
指向DWORD的长指针

返回值

成功:返回非0(TRUE),输出参数被填充有效数据。
失败:返回0(FALSE),可通过GetLastError()获取错误码。

知识补充-簇与扇区

扇区是磁盘物理存储的最小单位(由硬件决定,通常512字节)。
簇是文件系统为提高效率而设定的逻辑单位(由多个扇区组成),文件占用空间总是簇的整数倍(即使文件大小小于一簇,也会占用一整个簇)。

基本示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <windows.h>
#include <stdio.h>

int main() {
// 目标磁盘路径(C盘)
LPCWSTR drive = L"C:\\";

DWORD sectorsPerCluster; // 每簇扇区数
DWORD bytesPerSector; // 每扇区字节数
DWORD freeClusters; // 可用簇数
DWORD totalClusters; // 总簇数

// 调用API获取信息
BOOL success = GetDiskFreeSpaceW(
drive,
&sectorsPerCluster,
&bytesPerSector,
&freeClusters,
&totalClusters
);

if (!success) {
printf("获取磁盘信息失败,错误码: %d\n", GetLastError());
return 1;
}

// 计算总容量和可用容量(转换为GB)
ULONGLONG totalBytes = (ULONGLONG)totalClusters * sectorsPerCluster * bytesPerSector;
ULONGLONG freeBytes = (ULONGLONG)freeClusters * sectorsPerCluster * bytesPerSector;
double totalGB = (double)totalBytes / (1024 * 1024 * 1024);
double freeGB = (double)freeBytes / (1024 * 1024 * 1024);

// 输出结果
printf("磁盘 %S 信息:\n", drive);
printf(" 每扇区字节数:%d\n", bytesPerSector);
printf(" 每簇扇区数:%d\n", sectorsPerCluster);
printf(" 总容量:%.2f GB\n", totalGB);
printf(" 可用容量:%.2f GB\n", freeGB);

return 0;
}

GetDiskFreeSpaceEx

基本概念

GetDiskFreeSpaceExWindows系统提供的用于查询磁盘空间信息的API宏(根据编码设置映射到宽字符GetDiskFreeSpaceExWANSI版本GetDiskFreeSpaceExA),专门优化了对大容量磁盘的支持,直接返回以字节为单位的空间数据,无需通过簇、扇区等底层单位换算,是现代应用获取磁盘空间的首选接口。

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
BOOL GetDiskFreeSpaceExW(
[in, optional] LPCWSTR lpDirectoryName, //目录或磁盘路径
[out, optional] PULARGE_INTEGER lpFreeBytesAvailableToCaller, //当前用户可使用的空闲字节数
[out, optional] PULARGE_INTEGER lpTotalNumberOfBytes, //总容量
[out, optional] PULARGE_INTEGER lpTotalNumberOfFreeBytes //总可用空间
);

BOOL GetDiskFreeSpaceExA(
[in, optional] LPCSTR lpDirectoryName,
[out, optional] PULARGE_INTEGER lpFreeBytesAvailableToCaller,
[out, optional] PULARGE_INTEGER lpTotalNumberOfBytes,
[out, optional] PULARGE_INTEGER lpTotalNumberOfFreeBytes
);

PULARGE_INIEGER

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
typedef ULARGE_INTEGER *PULARGE_INTEGER //表示ULARGE_INTEGER结构体的指针

ULARGE_INTEGER结构体定义
typedef union _ULARGE_INTEGER {
// 第一个结构体:将64位整数拆分为低32位和高32位(成员名带DUMMYSTRUCTNAME标记)
struct {
DWORD LowPart; // 64位整数的低32位(低位部分)
DWORD HighPart; // 64位整数的高32位(高位部分)
} DUMMYSTRUCTNAME;

// 第二个结构体:与上面结构完全相同,仅成员名简化为u(兼容不同代码风格)
struct {
DWORD LowPart; // 同上,低32位
DWORD HighPart; // 同上,高32位
} u;

// 直接表示完整的64位无符号整数
ULONGLONG QuadPart; // 64位无符号整数
} ULARGE_INTEGER;

ULARGE_INTEGER: 是Windows为处理 64 位无符号整数设计的 “多功能容器”,
通过联合结构实现了 “整体访问(64 位)” 和 “拆分访问(两个 32 位)” 的灵活切换,
兼顾了不同系统位数的兼容性和编程便捷性。

返回值

成功:返回非0(TRUE),输出参数被填充有效数据。
失败:返回0(FALSE),可通过GetLastError()获取错误码。

简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <windows.h>
#include <stdio.h>

int main() {
// 目标路径(D盘根目录)
LPCWSTR path = L"D:\\";

// 定义64位变量存储结果(ULARGE_INTEGER是64位无符号整数的封装)
ULARGE_INTEGER freeAvailable, totalBytes, totalFree;

// 调用API
BOOL success = GetDiskFreeSpaceExW(
path,
&freeAvailable,
&totalBytes,
&totalFree
);

if (!success) {
printf("查询失败,错误码: %d\n", GetLastError());
return 1;
}

// 转换为GB(1GB = 1024^3字节)
double freeGB = (double)freeAvailable.QuadPart / (1024 * 1024 * 1024);
double totalGB = (double)totalBytes.QuadPart / (1024 * 1024 * 1024);
double totalFreeGB = (double)totalFree.QuadPart / (1024 * 1024 * 1024);

// 输出结果
wprintf(L"磁盘 %s 空间信息:\n", path);
wprintf(L" 总容量:%.2f GB\n", totalGB);
wprintf(L" 总可用空间:%.2f GB\n", totalFreeGB);
wprintf(L" 当前用户可用:%.2f GB\n", freeGB);

return 0;
}

比较GetDiskFreeSpace

特性 GetDiskFreeSpace GetDiskFreeSpaceEx
数据单位 簇、扇区(需换算为字节) 直接返回字节数
数值范围 32位(最大支持~4GB64位(支持大容量磁盘)
空间含义 仅返回总容量和可用容量 区分用户可用、总可用、总容量
使用复杂度 需要手动换算(簇 × 扇区 × 字节) 直接使用返回值,无需换算