hozugawa.net · A neutral informational page

GetVolumeInformationでドライブ情報を取得する

Windowsの固定ドライブやUSBメモリーについて、驱动器文字、ボリューム名、ファイルシステム種別をまとめて調べたい場合は、Win32 APIのGetVolumeInformationが基本になります。USBメモリーを挿した際の判定や、 Marino古いWindowsとの互換性確認常用的な手段です。

このAPIは指定したボリュームについて、ボリューム名、ボリュームシリアル番号、ファイルシステムの名称と特徴を返します。Windows APIdocumentation --------- GetVolumeInformationW_SYSTEM上报_____ ...

返回一个具体的例子:GetVolumeInformation(L"C:\\", ...)可以获取C:盘的卷标、序列号和文件系统类型(如NTFS、FAT32),同时还能判断该卷是否支持压缩、加密或硬链接。这些信息通常无法仅通过驱动器字母推导出来。

的使用には几个容易忽略的条件。根路径通常必须写成 C:\\ 这样带末尾反斜杠的形式,输出缓冲区长度以字符为单位计算并包含终止符,而且失败后应立即调用 GetLastError 保存具体错误码。

下面的内容围绕参数含义、返回值、文件标志以及实际代码展开。重点在于区分API确实返回的数据与根据驱动器名称推测的数据,避免把卷标、序列号、文件系统类型混为一谈。

取得できる情報の全体像

GetVolumeInformation的第一个参数是卷的根路径。这个路径负责确定要查询的对象,因此 C:\\、USB记忆卡的驱动器路径以及网络共享路径都可以作为输入。返回的卷标可能为空,也可能与驱动器提示中看到的名称不同;卷标还可以由用户修改,不能作为永久标识。

其余输出项目包括32位的卷序列号、文件名组件的最大长度、文件系统标志位和文件系统名称。NTFS、FAT32、exFAT 等名称通常可以直接显示,而压缩、加密、Unicode文件名、硬链接等能力则通过标志位表示。最大组件长度针对的是单个文件名部分,并不等于完整路径可以拥有的最大长度。

BOOL GetVolumeInformationW(
    LPCWSTR lpRootPathName,
    LPWSTR lpVolumeName,
    DWORD nVolumeNameSize,
    LPDWORD lpVolumeSerialNumber,
    LPDWORD lpMaximumComponentLength,
    LPDWORD lpFileSystemFlags,
    LPWSTR lpFileSystemName,
    DWORD nFileSystemNameSize
);

卷序列号适合识别同一台计算机上的卷,但它不是安全标识符,也不保证跨机器唯一。部分旧工具会把序列号记录到注册表,相关处理可参考レジストリ値の読み取り方法。现代程序通常应直接调用GetVolumeInformationW,以取得比注册表记录更新的信息。

呼び出し条件と型の扱い

WindowsのUnicode環境では GetVolumeInformationW を使うのが基本です。GetVolumeInformation は预处理によって ANSI版またはWide版Selecting되므로、関数名を明示すれば文字コードの解釈がぶれるのを避けられます。软件需要混合处理Wide版和ANSI版数据时,可通过明确的转换函数完成,不要依赖默认字符集。

lpVolumeName 与 lpFileSystemName 的缓冲区长度分别由 nVolumeNameSize 和 nFileSystemNameSize 指定,单位是 WCHAR 数量,而且必须包含字符串终止符 L'\0'。缓冲区过小会导致数据被截断,部分情况下还会直接调用失败,因此固定数组应留出终止符空间。

根路径的写法也会影响结果。固定盘通常使用 L"C:\\",可移动盘则需要使用当前的驱动器路径。省略末尾反斜杠、路径指向普通文件,或者驱动器不存在时,函数可能返回失败。查询挂载点之前,还应先区分该路径代表的是卷本身还是其中的目录。

戻り値と他のAPIとの違い

调用成功时返回非零值,失败时返回零。失败后必须紧接着调用 GetLastError,否则其他函数的执行可能覆盖错误码。常见原因包括 ERROR_ACCESS_DENIED、ERROR_INVALID_DRIVE、ERROR_INVALID_NAME 和 ERROR_INVALID_PARAMETER,但实际代码应根据错误码决定处理方式。

この関数と、容量やドライブ種別を取得するAPIの位置づけは次の比較で分かれます。

観点 GetVolumeInformationW GetDiskFreeSpaceExW GetLogicalDriveStringsW
主な取得対象 ボリューム名、シリアル番号、ファイルシステム情報 総容量、空き容量、利用可能容量 論理ドライブ名の一覧
ボリュームシリアル番号 取得できる 取得しない 取得しない
ファイルシステム名 取得できる 取得しない 取得しない
容量 取得しない 取得する 取得しない
ドライブ一覧 出力しない 出力しない 出力する
主な入力 ボリュームのルートパス 容量を調べたいパス なし

标志位需要结合具体值解释。例如,FILE_READ_ONLY_VOLUME 表示卷为只读,FILE_SUPPORTS_ENCRYPTION 表示支持加密,FILE_CASE_SENSITIVE_SEARCH 表示文件名搜索区分大小写。仅凭 NTFS 或 FAT32 这样的名称,不宜推断所有细微特性,因为不同Windows版本和文件系统组合返回的标志可能不同。

実装例とエラー処理

下列代码把API包装成返回布尔值的函数。输出参数只在调用成功后更新,错误码则通过引用参数交给调用方,适合需要自行决定重试、提示或降级行为的程序。

#include <windows.h>
#include <cwchar>
#include <string>

bool QueryDriveInformation(
    const std::wstring& rootPath,
    std::wstring& volumeLabel,
    std::wstring& fileSystemName,
    DWORD& volumeSerialNumber,
    DWORD& errorCode)
{
    wchar_t volumeName[MAX_PATH + 1] = {};
    wchar_t fileSystemNameBuffer[MAX_PATH + 1] = {};
    DWORD maximumComponentLength = 0;
    DWORD fileSystemFlags = 0;

    errorCode = ERROR_SUCCESS;

    if (!GetVolumeInformationW(
            rootPath.c_str(),
            volumeName,
            static_cast<DWORD>(_countof(volumeName)),
            &volumeSerialNumber,
            &maximumComponentLength,
            &fileSystemFlags,
            fileSystemNameBuffer,
            static_cast<DWORD>(_countof(fileSystemNameBuffer)))) {
        errorCode = GetLastError();
        return false;
    }

    volumeLabel = volumeName;
    fileSystemName = fileSystemNameBuffer;
    return true;
}

序列号是DWORD类型,显示时通常转换为八位十六进制文本。卷标签为空并不表示调用失败,它只是表示该卷没有设置标签。文件标志位则应按位组合处理,不能把非零值直接理解为某一个特定功能。

std::wstring label;
std::wstring fileSystem;
DWORD serial = 0;
DWORD error = ERROR_SUCCESS;

if (QueryDriveInformation(
        L"C:\\", label, fileSystem, serial, error)) {
    wchar_t serialText[16] = {};
    swprintf_s(serialText, _countof(serialText), L"%08lX", serial);

    wprintf(L"ボリューム名: %ls\n", label.c_str());
    wprintf(L"ファイルシステム: %ls\n", fileSystem.c_str());
    wprintf(L"シリアル番号: %ls\n", serialText);
}

Windows APIの Errors処理やパス操作anchorCombine.. Windows APIの参考ページには、GetLastErrorやFormatMessageWなどの関連APIも整理されています。错误处理时应保留原始错误码,格式化后的消息则适合显示给用户,两者承担的角色并不相同。

实务で押さえる要点

使い回すコードでは、ルートパスの正規化と失敗時の既定値尤为重要。空のラベルや保持されていない出力バッファを、そのまま有効な表示値として扱わないようにします。また、.buf容量が固定値に依存する実装では、想定外の長いファイルシステム名にも余裕を持たせます。

此外、卷序列号、卷标和文件系统名称各自承担不同的识别作用。多个驱动器字母可以指向同一个卷,同一个卷也可能没有驱动器字母。应用如果需要稳定的卷身份,应结合卷GUID、根路径与序列号判断,不能只使用 C: 或 D:。

最も覚えておきたいのは、GetVolumeInformationWが、ルートパスが指すボリューム名、シリアル番号、ファイルシステム特性をまとめて返すWin32 APIだということである。