如何访问隐藏的分区/卷

时间:2015-06-22 19:51:35

标签: c# c++ winapi wmi disk-partitioning

我必须编写一个代码来使用c#或c ++访问隐藏的磁盘分区/卷。 但在这件事上找不到任何帮助参考。

作为隐藏卷,它不包含“磁盘字母”,因此您只能输入“C:\”并访问它。 一个例子是Windows附带的“恢复分区”。你无法在资源管理器上看到它,但它就在那里。

我的应用程序将从thoose分区写入和读取数据,我必须找到一种方法来执行类似“c:\”的操作。

Volumes 5,6 are hidden partitions

在上图中,卷5和6是隐藏的分区。 我在stackoverflow上找到了这个链接,但它只是“列出”de分区: https://msdn.microsoft.com/en-us/library/cc542456(v=VS.85).aspx

修改

问题是:即使使用WMI作为建议,我也找不到在查找文件时如何过滤卷。 例如,select * from win32_DataFile将列出计算机中的所有文件。

我认为应该是一种使用ID(或名称)过滤Volumes的方法。 类似的东西:

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

或者更美丽的方式:

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

另外,我发现了一个关于分区和卷的优秀的awenser(他们不是一回事) https://social.technet.microsoft.com/Forums/en-US/e7b2ddd6-f245-49ed-8fec-3b6e08e75369/how-do-i-find-the-partition-guid?forum=winservergen

EDIT2

正如Harry所说,使用“\。\ Volume ....”是恢复文件的好方法。但我找不到使用c#编写(创建)新文件的方法。 到目前为止,最好的approch是使用pinvoke来实现c ++ CreateFile方法/句柄。

有什么建议吗?

2 个答案:

答案 0 :(得分:2)

FindFirstVolume() API返回系统上每个卷的根目录的路径。

例如,此代码打印第一个卷的路径,以及该卷根目录中第一个文件的名称:

    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);

(在生产代码中,您需要添加错误检查等)

<强>附录

FindFirstVolume返回如下路径:\\?\Volume{6ff7748e-78db-4838-8896-254b074918f5}\

如果您在C ++中使用Win32 API(CreateFile等),您可以直接使用该路径,但由于.NET中的错误或限制,它不能使用文件管理类,例如作为Directory.GetFiles()。 (当然,你可以P / Invoke到Win32 API,但那很尴尬。)

相反,您可以通过用点替换路径开头出现的问号来解决此问题:

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

答案 1 :(得分:1)

如果您的程序是Windows特定的,则可以使用WMI。我使用WMI做了很多工作,进行任何操作或获取有关Windows系统的数据非常方便。

首先,您可以下载wmiexplorer以查看可用的数据和类。相关的命名空间为root\cimv。在那里你可以找到各种有趣的课程:

  • Win32_LogicalDisk:包含所有磁盘,也包含隐藏的磁盘。
  • CIM_Directory:包含所有目录(据我所知也是隐藏的磁盘)
  • CIM_DataFile:包含所有文件(我也认为这个文件还包含隐藏磁盘中的文件)
  • 您可以使用更多类别,例如检索文件权限......微软有一个非常好的documentation关于它

接下来,您可以在C#(或VB.NET)程序中实现所需的WMI查询。例如,这个将打印所有磁盘:

WqlObjectQuery wqlQuery = new WqlObjectQuery("SELECT * FROM Win32_LogicalDisk");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wqlQuery);

foreach (ManagementObject disk in searcher.Get()) 
{
    Console.WriteLine(disk.ToString());
}

正如您所看到的,WMI支持SQL之类的查询(虽然它不那么强大......)

WMI还支持大多数ist类的methot。例如,您可以检查每个磁盘的错误:

foreach (ManagementObject disk in searcher.Get()) 
{
    if(shouldCheckThisDisk)
        disk.Chkdsk();
}