You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在GNU-EFI中从设备路径获取唯一分区GUID?

在GNU-EFI环境下从设备路径提取唯一分区GUID

要获取分区的唯一GUID,核心是识别设备路径中的分区设备路径节点,该节点直接存储了分区的GUID信息。以下是在你原有代码基础上修改后的完整实现,新增了提取并打印分区GUID的功能:

#include <efi.h>
#include <efilib.h>

// 打印单个设备路径节点
VOID PrintDevicePathNode(EFI_DEVICE_PATH_PROTOCOL* Node) {
    CHAR16* Text = NULL;

    Text = DevicePathToStr(Node);
    if (Text != NULL) {
        Print(L"%s", Text);
        FreePool(Text);
    }
}

// 打印完整设备路径
VOID PrintDevicePath(EFI_DEVICE_PATH_PROTOCOL* DevicePath) {
    while (!IsDevicePathEnd(DevicePath)) {
        PrintDevicePathNode(DevicePath);
        DevicePath = NextDevicePathNode(DevicePath);
        if (!IsDevicePathEnd(DevicePath)) {
            Print(L"\\");
        }
    }
    Print(L"\n");
}

// 从设备路径中提取并打印分区GUID
VOID ExtractPartitionGuidFromDevicePath(EFI_DEVICE_PATH_PROTOCOL* DevicePath) {
    while (!IsDevicePathEnd(DevicePath)) {
        // 判断当前节点是否为分区设备路径节点
        if (DevicePathType(DevicePath) == MEDIA_DEVICE_PATH && 
            DevicePathSubType(DevicePath) == MEDIA_PARTITION_DP) {
            
            PARTITION_DEVICE_PATH* PartitionNode = (PARTITION_DEVICE_PATH*)DevicePath;
            EFI_GUID* PartitionGuid = &PartitionNode->PartitionGuid;

            // 按标准GUID格式输出:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
            Print(L"  Partition GUID: %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
                  PartitionGuid->Data1,
                  PartitionGuid->Data2,
                  PartitionGuid->Data3,
                  PartitionGuid->Data4[0], PartitionGuid->Data4[1],
                  PartitionGuid->Data4[2], PartitionGuid->Data4[3],
                  PartitionGuid->Data4[4], PartitionGuid->Data4[5],
                  PartitionGuid->Data4[6], PartitionGuid->Data4[7]);
            return; // 找到第一个分区节点后返回,若需处理多分区可调整逻辑
        }
        DevicePath = NextDevicePathNode(DevicePath);
    }
    Print(L"  No partition GUID found in device path\n");
}

EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE* SystemTable) {
    InitializeLib(ImageHandle, SystemTable);

    EFI_STATUS Status;
    EFI_INPUT_KEY Key;

    EFI_BOOT_SERVICES* BS = SystemTable->BootServices;

    EFI_HANDLE* handles;
    UINTN HandleCount;

    Status = uefi_call_wrapper(BS->LocateHandleBuffer, 5, ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &handles);
    if (EFI_ERROR(Status)) {
        Print(L"Error locating handles with Block I/O Protocol: %r\n", Status);
        return Status;
    }

    Print(L"Number of handles with Block I/O Protocol: %d\n", HandleCount);

    for (UINTN i = 0; i < HandleCount; i++) {
        EFI_BLOCK_IO_PROTOCOL* blockIo;
        Status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i], &gEfiBlockIoProtocolGuid, (VOID**)&blockIo);
        if (EFI_ERROR(Status)) {
            Print(L"Error getting Block I/O Protocol from handle %d: %r\n", i, Status);
            continue;
        }

        EFI_BLOCK_IO_MEDIA* media = blockIo->Media;

        Print(L"Block Device %d\n", i);
        Print(L"  Media ID: %lx\n", media->MediaId);
        Print(L"  Block Size: %d\n", media->BlockSize);
        Print(L"  Device Size: %ld MB\n", (media->LastBlock + 1) * media->BlockSize / (1024 * 1024));

        EFI_DEVICE_PATH_PROTOCOL* devicePath;
        Status = uefi_call_wrapper(BS->HandleProtocol, 3, handles[i], &gEfiDevicePathProtocolGuid, (VOID**)&devicePath);
        if (!EFI_ERROR(Status)) {
            Print(L"  Device Path:\n");
            PrintDevicePath(devicePath);
            // 调用提取GUID的函数
            ExtractPartitionGuidFromDevicePath(devicePath);
        }
    }

    Status = ST->ConIn->Reset(ST->ConIn, FALSE);
    if (EFI_ERROR(Status))
        return Status;

    while ((Status = ST->ConIn->ReadKeyStroke(ST->ConIn, &Key)) == EFI_NOT_READY);

    return Status;
}

关键逻辑说明

  1. 识别分区节点:通过DevicePathType和DevicePathSubType判断当前节点是否为MEDIA_PARTITION_DP类型(即分区专属的设备路径节点)。
  2. 提取GUID数据:将目标节点强制转换为PARTITION_DEVICE_PATH结构体,其PartitionGuid字段就是分区的唯一标识。
  3. 格式化输出:拆分GUID的各个字节段,按照标准GUID字符串格式打印,保证输出的可读性。

内容的提问来源于stack exchange,提问作者CherryDev86

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 19:23:25