VC 根据文件路径获取设备路径及设备名

时间:2022-10-16 17:37:37

项目中间遇到一个问题,需要判断文件在哪个设备上,翻了一遍MSDN,找到了下面的解决方案。

有人可能会觉得_splitPath就可以了,这是不行的,因为_splitPath不能正确获取挂载到目录的设备。


解决思路方法是GetVolumePathName获取设备根路径,然后调用GetVolumeNameForVolumeMountPoint获取设备的名称。之所以要获取设备的名称是因为:CreatFile的输入路径必须是设备名,对于有盘符的设备根路径(如C:),设备根路径加上设备前缀就是设备别名(如\\?\C:),但是对于挂载到文件夹的设备,设备根路径加上设备前缀并不是设备别名。


示例代码如下:

wstring GetVolumePathByFile(LPCWSTR path){
    WCHAR volume_path[MAX_PATH+1]={0};
    if(!GetVolumePathNameW(path, volume_path, MAX_PATH+1)){
        DWORD error = GetLastError();
        MYDEBUGTRACE(L"GetVolumePathNameW for %s failed(%d): %s"
            , path, error, MYERROR2STRING(error).GetBuffer());
    }else{
        volume_path[wcslen(volume_path)-1] = L'\0';
        MYDEBUGTRACE(L"file %s volume path is %s", path, volume_path);
        return wstring(volume_path);
    }
    return wstring();    
}


wstring GetVolumeNameByFile(LPCWSTR in_path){
    wstring volume_path = GetVolumePathByFile(in_path);
    if(volume_path.empty()){
        MYDEBUGTRACE(L"GetVolumeNameByFile failed: GetVolumePathByFile failed\n");
        return wstring();
    }
    volume_path += L"\\";


    WCHAR volume_name[MAX_PATH+1];
    if(!GetVolumeNameForVolumeMountPointW(volume_path.c_str(), volume_name, MAX_PATH+1)){
        DWORD error = GetLastError();
        MYDEBUGTRACE(L"GetVolumeNameForVolumeMountPoint failed, path: %s, code(%d): %s"
            ,volume_path.c_str(), error, MYERROR2STRING(error).GetBuffer());
        return wstring();
    }else{
        MYDEBUGTRACE(L"path %s volume name is %s",in_path, volume_name);
        return wstring(volume_name);
    }
}