FindFirstVolume不返回EFI系统分区
FindFirstVolume does not return EFI system partition
我使用FindFirstVolume/FindNextVolume来获取机器上所有卷的列表。这工作得很好,但奇怪的是,由于某种原因,EFI系统分区被跳过了。另一方面,Diskpart返回EFI系统分区,并且磁盘管理UI也显示它。
下面是diskpart的输出:
DISKPART> list volume
Volume ### Ltr Label Fs Type Size Status Info
---------- --- ----------- ----- ---------- ------- --------- --------
Volume 0 C NTFS Partition 476 GB Healthy Boot
Volume 1 Recovery NTFS Partition 450 MB Healthy Hidden
Volume 2 FAT32 Partition 100 MB Healthy System
Volume 3 D Data NTFS Partition 953 GB Healthy
Volume 4 E ESD-USB FAT32 Removable 14 GB Healthy
在该列表中,EFI系统分区是卷2。
FindFirstVolume/FindNextVolume给我其他四个卷,但省略EFI系统分区。
我怎么能得到一个卷GUID路径的EFI系统分区或其他一些方式来编程访问它吗?
volume GUID path(即?? volume{..})如果FindFirstVolume
/FindNextVolume
不返回,则不存在,但我们可以通过不同的方式枚举系统中的所有卷。我们说可以使用虚拟磁盘服务。com api。DISKPART> list volume
就是这么用的。另一种方式(更"低"和快速)-使用CM_Get_Device_ID_ListW与pszFilter ="{71a27cdd-812a-11d0-bec7-08002be2092f}"(看GUID_DEVCLASS_VOLUME
在devguid.h
)比获得一个设备实例处理CM_Locate_DevNodeW和查询DEVPKEY_Device_PDOName与CM_Get_DevNode_PropertyW -我们得到字符串(如DeviceHarddiskVolume<X>
),我们可以在ZwOpenFile中使用,然后使用一些ioctls (IOCTL_DISK_GET_PARTITION_INFO_EX和其他)获取卷属性。代码示例:
#include <initguid.h>
#include <cfgmgr32.h>
#include <devguid.h>
#include <devpkey.h>
#include <diskguid.h>
void DumpVolume(HANDLE hFile);
void VolEnum()
{
STATIC_WSTRING(DEVCLASS_VOLUME, "{71a27cdd-812a-11d0-bec7-08002be2092f}");
enum { flags = CM_GETIDLIST_FILTER_CLASS|CM_GETIDLIST_FILTER_PRESENT };
ULONG len;
ULONG cb = 0, rcb = 64;
HANDLE hFile;
IO_STATUS_BLOCK iosb;
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE };
if (!CM_Get_Device_ID_List_SizeW(&len, DEVCLASS_VOLUME, flags))
{
PWSTR buf = (PWSTR)alloca(len << 1);
if (!CM_Get_Device_ID_ListW(DEVCLASS_VOLUME, buf, len, flags))
{
PVOID stack = buf;
while (*buf)
{
DbgPrint("%Sn", buf);
DEVINST dnDevInst;
if (!CM_Locate_DevNodeW(&dnDevInst, buf, CM_LOCATE_DEVNODE_NORMAL))
{
DEVPROPTYPE PropertyType;
int err;
union {
PVOID pv;
PWSTR sz;
PBYTE pb;
};
do
{
if (cb < rcb)
{
rcb = cb = RtlPointerToOffset(pv = alloca(rcb - cb), stack);
}
if (!(err = CM_Get_DevNode_PropertyW(dnDevInst, &DEVPKEY_Device_PDOName, &PropertyType, pb, &rcb, 0)))
{
if (PropertyType == DEVPROP_TYPE_STRING)
{
DbgPrint("%Sn", sz);
RtlInitUnicodeString(&ObjectName, sz);
if (0 <= ZwOpenFile(&hFile, FILE_GENERIC_READ, &oa, &iosb, FILE_SHARE_VALID_FLAGS, 0))
{
DumpVolume(hFile);
ZwClose(hFile);
}
}
}
} while (err == CR_BUFFER_SMALL);
}
buf += 1 + wcslen(buf);
}
}
}
}
void DumpVolume(HANDLE hFile)
{
NTSTATUS status;
PARTITION_INFORMATION_EX pi;
IO_STATUS_BLOCK iosb;
if (0 <= (status = ZwDeviceIoControlFile(hFile, 0, 0, 0, &iosb, IOCTL_DISK_GET_PARTITION_INFO_EX, 0, 0, &pi, sizeof(pi))))
{
CHAR PartitionName[40], *szPartitionName;
PCSTR szps = "??";
switch (pi.PartitionStyle)
{
case PARTITION_STYLE_MBR: szps = "MBR";
break;
case PARTITION_STYLE_GPT: szps = "GPT";
break;
}
DbgPrint("%u %s %I64u(%I64x) %I64u ",
pi.PartitionNumber,
szps,
pi.StartingOffset.QuadPart, pi.StartingOffset.QuadPart,
pi.PartitionLength.QuadPart);
switch (pi.PartitionStyle)
{
case PARTITION_STYLE_MBR:
DbgPrint("type=%x boot=%x", pi.Mbr.PartitionType, pi.Mbr.BootIndicator);
break;
case PARTITION_STYLE_GPT:
if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_ENTRY_UNUSED_GUID))
{
szPartitionName = "UNUSED";
}
else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_SYSTEM_GUID))
{
szPartitionName = "SYSTEM";
}
else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_MSFT_RESERVED_GUID))
{
szPartitionName = "RESERVED";
}
else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_BASIC_DATA_GUID))
{
szPartitionName = "DATA";
}
else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_MSFT_RECOVERY_GUID))
{
szPartitionName = "RECOVERY";
}
else if (IsEqualGUID(pi.Gpt.PartitionType, PARTITION_MSFT_SNAPSHOT_GUID))
{
szPartitionName = "SNAPSHOT";
}
else
{
sprintf(szPartitionName = PartitionName, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
pi.Gpt.PartitionType.Data1,
pi.Gpt.PartitionType.Data2,
pi.Gpt.PartitionType.Data3,
pi.Gpt.PartitionType.Data4[0],
pi.Gpt.PartitionType.Data4[1],
pi.Gpt.PartitionType.Data4[2],
pi.Gpt.PartitionType.Data4[3],
pi.Gpt.PartitionType.Data4[4],
pi.Gpt.PartitionType.Data4[5],
pi.Gpt.PartitionType.Data4[6],
pi.Gpt.PartitionType.Data4[7]);
}
DbgPrint("[%s] %I64x "%S"",
szPartitionName,
pi.Gpt.Attributes,
pi.Gpt.Name);
break;
}
ULONG cb = FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[32]);
PFILE_FS_ATTRIBUTE_INFORMATION pffai = (PFILE_FS_ATTRIBUTE_INFORMATION)alloca(cb);
switch (ZwQueryVolumeInformationFile(hFile, &iosb, pffai, cb, FileFsAttributeInformation))
{
case STATUS_SUCCESS:
case STATUS_BUFFER_OVERFLOW:
DbgPrint(" "%.*S"", pffai->FileSystemNameLength >> 1 , pffai->FileSystemName);
break;
}
DbgPrint("n");
}
else
{
DbgPrint("status=%xn", status);
}
}
和调试输出
STORAGEVolume{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000012D00000
DeviceHarddiskVolume2
2 GPT 315621376(12d00000) 104857600 [SYSTEM] 8000000000000000 "EFI system partition" "FAT32"
STORAGEVolume{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000000100000
DeviceHarddiskVolume1
1 GPT 1048576(100000) 314572800 [RECOVERY] 8000000000000001 "Basic data partition" "NTFS"
STORAGEVolume{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000021100000
DeviceHarddiskVolume4
4 GPT 554696704(21100000) 255506513920 [DATA] 0 "Basic data partition" "NTFS"
STORAGEVolume{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000019100000
DeviceHarddiskVolume3
3 GPT 420478976(19100000) 134217728 [RESERVED] 8000000000000000 "Microsoft reserved partition" "RAW"
STORAGEVolume{a4d55aa5-4d7f-11e5-8256-5cc5d4ea6270}#0000000000007E00
DeviceHarddiskVolume5
1 MBR 32256(7e00) 32017013248 type=7 boot=1 "NTFS"
查看属性- https://msdn.microsoft.com/en-us/library/windows/desktop/aa365449(v=vs.85).aspx
- C++,系统无法执行指定的程序
- 在UNIX系统中使用DIR查找文件的字节大小
- 错误处理.将系统错误代码映射到泛型
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 有什么好的方法可以让系统调用代理允许在单元测试中进行模拟
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 在C++游戏中与库存系统作斗争
- 文件系统:复制功能的速度秘诀是什么
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 在gtest.中使用fff.h模拟系统API
- 如何制作无限制照明系统
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 如何传递多个 std::文件系统选项?
- 遍历顺序由 std::文件系统directory_iterator给出
- C++系统找不到指定的文件错误
- 系统参数信息A 与 SPI_GETMOUSE 返回 0
- libstdc++ 文件系统中未初始化的用法?
- 如何获取 EFI 系统分区的卷名
- 在Linux的C/C++中,如何确定已安装或未安装分区的文件系统类型
- FindFirstVolume不返回EFI系统分区