FindFirstVolume不返回EFI系统分区 [英] FindFirstVolume does not return EFI system partition

查看:214
本文介绍了FindFirstVolume不返回EFI系统分区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用FindFirstVolume/FindNextVolume来获取计算机上所有卷的列表.这样做足够好,但是奇怪的是,由于某些原因,EFI系统分区被跳过了.另一方面,Diskpart返回EFI系统分区,磁盘管理UI也显示该分区.

I am using FindFirstVolume/FindNextVolume to get a list of all volumes on a machine. That works well enough, but strangely the EFI system partition is skipped for some reason. Diskpart, on the other hand, returns the EFI system partition and the Disk Management UI shows it, too.

这是diskpart的输出:

Here is diskpart's output:

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卷.

In that list the EFI system partition is Volume 2.

FindFirstVolume/FindNextVolume给了我其他四个卷,但是省略了EFI系统分区.

FindFirstVolume/FindNextVolume give me the other four volumes, but omit the EFI system partition.

有什么想法可以获取EFI系统分区的批量GUID路径,或以其他方式以编程方式访问它吗?

推荐答案

卷GUID路径(即\ ?? \ Volume {..})如果不由FindFirstVolume/<返回,则不存在c1>,但是我们可以用不同的方式枚举系统中的所有卷.我们说可以使用虚拟磁盘服务 com api. DISKPART> list volume完全使用这个.另一种方法(更低"而又快速)-使用devguid.h中查看GUID_DEVCLASS_VOLUME)来获取设备实例由CM_Locate_DevNodeW 和查询 DEVPKEY_Device_PDOName ZwOpenFile ,然后使用som e ioctl(IOCTL_DISK_GET_PARTITION_INFO_EX等)以获取卷属性.代码示例:

volume GUID path (i.e. \??\Volume{..}) not exist if not returned by FindFirstVolume/FindNextVolume but we can enumerate all volumes in system by different ways. we say can use Virtual Disk Service com api . DISKPART> list volume use exactly this. another way(more 'low' and fast) - use CM_Get_Device_ID_ListW with pszFilter = "{71a27cdd-812a-11d0-bec7-08002be2092f}" (look GUID_DEVCLASS_VOLUME in devguid.h) than obtain a device instance handle by CM_Locate_DevNodeW and query for DEVPKEY_Device_PDOName with CM_Get_DevNode_PropertyW - we got string (like \Device\HarddiskVolume<X> ) which we can use in ZwOpenFile and then use some ioctls (IOCTL_DISK_GET_PARTITION_INFO_EX and other) for get volume properties. code example:

#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/zh-CN/library/windows/desktop/aa365449(v = vs.85).aspx

这篇关于FindFirstVolume不返回EFI系统分区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆