- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在使用 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 系统分区。
关于如何获取 EFI 系统分区的卷 GUID 路径或以其他方式以编程方式访问它的任何想法?
最佳答案
卷 GUID 路径(即\??\Volume{..})如果 FindFirstVolume
未返回则不存在/FindNextVolume
但是我们可以通过不同的方式枚举系统中的所有卷。我们说可以使用Virtual Disk Service通信接口(interface)。 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 - 我们得到了可以在 ZwOpenFile 中使用的字符串(如 \Device\HarddiskVolume<X>
)然后使用一些 ioctl(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("%S\n", 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("%S\n", 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=%x\n", status);
}
}
和调试输出
STORAGE\Volume\{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000012D00000
\Device\HarddiskVolume2
2 GPT 315621376(12d00000) 104857600 [SYSTEM] 8000000000000000 "EFI system partition" "FAT32"
STORAGE\Volume\{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000000100000
\Device\HarddiskVolume1
1 GPT 1048576(100000) 314572800 [RECOVERY] 8000000000000001 "Basic data partition" "NTFS"
STORAGE\Volume\{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000021100000
\Device\HarddiskVolume4
4 GPT 554696704(21100000) 255506513920 [DATA] 0 "Basic data partition" "NTFS"
STORAGE\Volume\{d2bfdb30-4d04-11e5-824e-806e6f6e6963}#0000000019100000
\Device\HarddiskVolume3
3 GPT 420478976(19100000) 134217728 [RESERVED] 8000000000000000 "Microsoft reserved partition" "RAW"
STORAGE\Volume\{a4d55aa5-4d7f-11e5-8256-5cc5d4ea6270}#0000000000007E00
\Device\HarddiskVolume5
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++ - FindFirstVolume 不返回 EFI 系统分区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40208794/
我用的是 gnu-efi。 我不明白如何简单地读取文件。 我了解使用 BlockIOProtocol。 您能用一个简单的例子告诉我们吗? 最佳答案 我手头没有简单的例子,抱歉。但通常你会这样进行 在
目前,我在传统 (MBR) 模式下有以下引导链: GRUB2 -> Linux -> kexec to Grub4Dos -> Windows. 我想弄清楚这是否也可以在 UEFI 模式下实现,即从
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwar
问题#1:你好,所以我搞砸了我的 Windows(同时删除了 ubuntu 的双启动)并且它无法启动,所以我不得不使用闪存驱动器安装,在安装过程中我删除了 EFI 分区并且可用空间仍然存在在那里,但
EFI是一个小型化的Windows系统,今天教大家efi bios u盘启动设置方法,有些朋友想要为efi bios设置u盘启动但却不知道该怎么操作,相信大家看了下面这篇文章就会有一定的了解,希望对
安装Ubuntu18过程中,从u盘启动ubuntu安装,出现mmx64.efi not found问题 如下图: 制作好ubuntu启动盘之后在EFI/BOOT下会看到两个文
怎么解决 boot/efi 没有分配空间的问题呢。某些机器上,特别是有双硬盘的电脑,在装 Linux 双系统时,经常会提示 boot/efi 没有分配空间。有时候,明明已经分配了,还会提示没有分配,
规范的哪一部分详细说明了如何获取命令行参数? 最佳答案 你需要小心这个。 您可能知道,有一个 UEFI LoadedImage 协议(protocol) - 该协议(protocol)返回一个名为 E
我正在研究这个项目,以便在操作系统通过 EFI 应用程序启动后立即将文件写入本地文件系统。我需要知道这是否可能。如果是的话,请指导我一点。 谢谢 最佳答案 好的,我会好好提醒你... 首先,您枚举系统
我有在操作系统旁边运行一个小服务的想法,但我不确定这是否可能。我试图通过阅读一些文档来弄清楚,但没有走远,所以我的问题来了。 我阅读了有关 UEFI 运行时服务的信息。 是否有可能在固件中有一个小模块
我需要创建一个驱动程序,其行为类似于软件 RAID。例如。驱动程序将需要与多个物理磁盘(甚至可能是网络资源)进行通信,并且对于操作系统来说应该看起来像一个磁盘。 所以两个主要问题是: 1) EFI 驱
我是创建 efi 应用程序的 super 新手。我的目标是在 efi 中创建一个小应用程序,在背景上显示一些文本。但是我坚持尝试在显示器上显示文本(最好是有一个自定义字体,但在这个阶段没有必要)。我希
我有一台带有 GPT 驱动器的 Windows 机器。 我有一个 EFI 系统分区的 DOS 设备名称作为 bcdedit 的输出。 我想打开这个分区的句柄并通过 QueryDosDevice() 获
我想尝试为 EFI 编程,所以我使用 virtualbox 创建了一个 VM,选中“启用 efi”选项并将 CD 留空。 efi shell 应该如何引导,但我只看到 BLK0、BLK1 等,而不是
安装Ubuntu后,EFI系统分区的/efi/UBUNTU/里面有几个*.efi文件: GRUBX64.EFI MOKMANAG.EFI SHIMX64.EFI mmx64.efi fwupx64.e
是否可以在 BDS 阶段之前自动加载和执行 EFI 应用程序,就在加载所有 DXE 驱动程序之后? 如果我在 DXE 驱动程序之后将应用程序包含在 .fdf 文件中,它会自动加载和执行吗? 最佳答案
通过关注此 tutorial ,我能够创建一个简单的 efi 应用程序,当 时打印 hello world |从 uefi shell 执行 .但是,我想知道如何创建可启动的 EFI 镜像。我尝试在
我正在使用 FindFirstVolume/FindNextVolume 获取机器上所有卷的列表。这很好用,但奇怪的是 EFI 系统分区由于某种原因被跳过了。另一方面,Diskpart 返回 EFI
我想使用 Print 函数调用将一些文本打印到屏幕上。有没有什么方法(或任何其他函数)来设置文本的颜色? 最佳答案 这将设置您的打印颜色: uefi_call_wrapper(SystemTable-
目前我正在使用 efi API 进行编程。 如何在 efi 编程中使用?我想知道如何在efi中编写argv和argc。 到目前为止编写的c代码: #include int main(int argc
我是一名优秀的程序员,十分优秀!