Search code examples
c#c++winapiwmidisk-partitioning

How to access hidden partitions/volumes


I have to write a code to access hidden disk partitions/volumes using c# or c++. But could not find any help reference on the matter.

As a hidden volume, it does not contain a "Disk Letter", so you can´t just type "C:\" and access it. A example would be the "recovery partition" that comes with Windows. You can´t see it on explorer but it is there.

My application will write and read data from thoose partitions and I have to find a way of doing something like "c:\" for thoose.

Volumes 5,6 are hidden partitions

In the above image, volumes 5 and 6 are hidden partitions. I have found this link on stackoverflow but it only "list" de partitions: https://msdn.microsoft.com/en-us/library/cc542456(v=VS.85).aspx

EDIT

The problem is: even using WMI as suguested I could´t find how to filter the the Volume when looking for files. Example, select * from win32_DataFile will list all Files in the machine.

I think should be a way of filtering the Volumes using their ID(or name). Something like:

select * from win32_DataFile 
where volumeId = '\\?\Volume{2d5f3a68-75f5-44c4-aa42-716b45811916}\'

Or a more beautiful way like:

var files = Directory.GetFiles(@"\\?\Volume{6ff7748e-78db-4838-8896-254b074918f5}\");

Also, I found a excelent awenser in about Partitions and Volumes (their are not the same thing) https://social.technet.microsoft.com/Forums/en-US/e7b2ddd6-f245-49ed-8fec-3b6e08e75369/how-do-i-find-the-partition-guid?forum=winservergen

EDIT2

As awensered by Harry, using "\.\Volume...." was a good way to recovery files. But I could not find a way to write(create) a new file using c#. The best approch so far is using pinvoke to c++ CreateFile method/handle.


Any advice?


Solution

  • The FindFirstVolume() API returns a path to the root of each volume on the system.

    For example, this code prints the path to the first volume, and the name of the first file in the root directory of that volume:

        HANDLE h1, h2;
        wchar_t volpath[4096];
        WIN32_FIND_DATA find_data;
    
        h1 = FindFirstVolume(volpath, _countof(volpath));
    
        printf("%ws\n", volpath);
    
        wcscat_s(volpath, _countof(volpath), L"*.*");
    
        h2 = FindFirstFile(volpath, &find_data);
    
        printf("%ws\n", find_data.cFileName);
    

    (In production code, you would need to add error checking, etc.)

    Addendum

    FindFirstVolume returns a path like this: \\?\Volume{6ff7748e-78db-4838-8896-254b074918f5}\

    If you're using the Win32 API (CreateFile, etc.) in C++ you can use that path directly, but due to a bug or limitation in .NET it doesn't work with file management classes such as Directory.GetFiles(). (You could P/Invoke to the Win32 API, of course, but that's awkward.)

    Instead, you can work around the problem by replacing the question mark that appears at the beginning of the path with a dot:

    var files = Directory.GetFiles(@"\\.\Volume{6ff7748e-78db-4838-8896-254b074918f5}\");