Hard disk volume path to full file path

后端 未结 1 1829
天命终不由人
天命终不由人 2021-01-01 03:16

I have an MSVC++ application that spits out the hard disk volume paths of file handles that other applications have open in the following string format:

\\De         


        
相关标签:
1条回答
  • 2021-01-01 03:56

    You should look for one of the Windows API functions for Volume Management:

    Volume Management Functions

    Here is an example from MSDN:

    Displaying Volume Paths

    #include <windows.h>
    #include <stdio.h>
    
    void DisplayVolumePaths(
            __in PWCHAR VolumeName
            )
    {
        DWORD  CharCount = MAX_PATH + 1;
        PWCHAR Names     = NULL;
        PWCHAR NameIdx   = NULL;
        BOOL   Success   = FALSE;
    
        for (;;) 
        {
            //
            //  Allocate a buffer to hold the paths.
            Names = (PWCHAR) new BYTE [CharCount * sizeof(WCHAR)];
    
            if ( !Names ) 
            {
                //
                //  If memory can't be allocated, return.
                return;
            }
    
            //
            //  Obtain all of the paths
            //  for this volume.
            Success = GetVolumePathNamesForVolumeNameW(
                VolumeName, Names, CharCount, &CharCount
                );
    
            if ( Success ) 
            {
                break;
            }
    
            if ( GetLastError() != ERROR_MORE_DATA ) 
            {
                break;
            }
    
            //
            //  Try again with the
            //  new suggested size.
            delete [] Names;
            Names = NULL;
        }
    
        if ( Success )
        {
            //
            //  Display the various paths.
            for ( NameIdx = Names; 
                  NameIdx[0] != L'\0'; 
                  NameIdx += wcslen(NameIdx) + 1 ) 
            {
                wprintf(L"  %s", NameIdx);
            }
            wprintf(L"\n");
        }
    
        if ( Names != NULL ) 
        {
            delete [] Names;
            Names = NULL;
        }
    
        return;
    }
    
    void __cdecl wmain(void)
    {
        DWORD  CharCount            = 0;
        WCHAR  DeviceName[MAX_PATH] = L"";
        DWORD  Error                = ERROR_SUCCESS;
        HANDLE FindHandle           = INVALID_HANDLE_VALUE;
        BOOL   Found                = FALSE;
        size_t Index                = 0;
        BOOL   Success              = FALSE;
        WCHAR  VolumeName[MAX_PATH] = L"";
    
        //
        //  Enumerate all volumes in the system.
        FindHandle = FindFirstVolumeW(VolumeName, ARRAYSIZE(VolumeName));
    
        if (FindHandle == INVALID_HANDLE_VALUE)
        {
            Error = GetLastError();
            wprintf(L"FindFirstVolumeW failed with error code %d\n", Error);
            return;
        }
    
        for (;;)
        {
            //
            //  Skip the \\?\ prefix and remove the trailing backslash.
            Index = wcslen(VolumeName) - 1;
    
            if (VolumeName[0]     != L'\\' ||
                VolumeName[1]     != L'\\' ||
                VolumeName[2]     != L'?'  ||
                VolumeName[3]     != L'\\' ||
                VolumeName[Index] != L'\\') 
            {
                Error = ERROR_BAD_PATHNAME;
                wprintf(L"FindFirstVolumeW/FindNextVolumeW returned a bad path: %s\n", VolumeName);
                break;
            }
    
            //
            //  QueryDosDeviceW does not allow a trailing backslash,
            //  so temporarily remove it.
            VolumeName[Index] = L'\0';
    
            CharCount = QueryDosDeviceW(&VolumeName[4], DeviceName, ARRAYSIZE(DeviceName)); 
    
            VolumeName[Index] = L'\\';
    
            if ( CharCount == 0 ) 
            {
                Error = GetLastError();
                wprintf(L"QueryDosDeviceW failed with error code %d\n", Error);
                break;
            }
    
            wprintf(L"\nFound a device:\n %s", DeviceName);
            wprintf(L"\nVolume name: %s", VolumeName);
            wprintf(L"\nPaths:");
            DisplayVolumePaths(VolumeName);
    
            //
            //  Move on to the next volume.
            Success = FindNextVolumeW(FindHandle, VolumeName, ARRAYSIZE(VolumeName));
    
            if ( !Success ) 
            {
                Error = GetLastError();
    
                if (Error != ERROR_NO_MORE_FILES) 
                {
                    wprintf(L"FindNextVolumeW failed with error code %d\n", Error);
                    break;
                }
    
                //
                //  Finished iterating
                //  through all the volumes.
                Error = ERROR_SUCCESS;
                break;
            }
        }
    
        FindVolumeClose(FindHandle);
        FindHandle = INVALID_HANDLE_VALUE;
    
        return;
    }
    

    To clarify:

    Volume name (or GUID) is something like \\?\Volume{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}

    Device name is something like \Device\HarddiskVolume1

    Drive letter is something like C:

    FindFirst/NextVolume gives you a list of Volume names.

    QueryDosDevice gives you a Device name from a Volume name.

    GetVolumePathNamesForVolumeName gives you the Drive letter from a Volume name.

    0 讨论(0)
提交回复
热议问题