Boot Services 提供了 ProtocolsPerHandle 函数,用它可以取得一个 Handle上面的 Protocols。这里编写程序用来验证一下。
函数原型在 UEFI Specification 中可以看到:
编写程序,取得当前 Application 上面的 Protocol:
/** @file A simple, basic, application showing how the Hello application could be built using the "Standard C Libraries" from StdLib. Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ #include <Library/BaseLib.h> #include <Uefi.h> #include <Library/UefiLib.h> #include <Library/BaseMemoryLib.h> #include <Library/MemoryAllocationLib.h> extern EFI_BOOT_SERVICES *gBS; EFI_STATUS EFIAPI UefiMain ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_GUID **ProtocolBuffer; UINTN ProtocolCount; EFI_STATUS Status; UINTN i; Status = gBS->ProtocolsPerHandle(ImageHandle, &ProtocolBuffer, &ProtocolCount); if (EFI_ERROR (Status)) { // // TheHandle is not valid, so do not add to handle list // Print(L"Can't get Protcols on ImageHandle\n"); return 0; } Print(L"Protocol list\n"); for (i=0;i<ProtocolCount;i++) { Print(L"%g \n",ProtocolBuffer[i]); } FreePool (ProtocolBuffer); return 0; }
运行结果如下(NT32虚拟机中运行结果):
在 DEC 文件中查找这些 GUID对应的 Protocol,如下:
752F3136-4E16-4FDC-A22A-E5F46812F4CA gEfiShellParametersProtocolGuid
BC62157E-3E33-4FEC-9920-2D3B36D750DF gEfiLoadedImageDevicePathProtocolGuid
5B1B31A1-9562-11D2-8E3F-00A0C969723B gEfiLoadedImageProtocolGuid
源代码和EFI下载:
sd
=============================================================
2018年2月24日 krishnaLee(sssky307)做了一番深入的研究,他发现一个可以将 UUID 转化为对应名称的简单方法。例程如下:
#include <Uefi.h> #include <Library/UefiApplicationEntryPoint.h> #include <Library/UefiLib.h> #include <Library/UefiBootServicesTableLib.h> //global gST gBS gImageHandle #include <Protocol/LoadedImage.h> //EFI_LOADED_IMAGE_PROTOCOL #include <Protocol/DevicePath.h> //EFI_DEVICE_PATH_PROTOCOL #include <Library/DevicePathLib.h> //link #include <Library/ShellLib.h> #include <Library/ShellCommandLib.h> #include <Library/HandleParsingLib.h> EFI_STATUS EFIAPI UefiMain( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) { EFI_GUID **ProtocolGuidArray; UINTN ArrayCount; CHAR16 *str; Print(L"1\n"); EFI_STATUS status = gBS->ProtocolsPerHandle(gImageHandle,&ProtocolGuidArray,&ArrayCount); if (status == EFI_SUCCESS) { for (UINTN i = 0; i < ArrayCount; i++) { str = GetStringNameFromGuid(ProtocolGuidArray[i], 0); Print(L"%s,%g\n", str,ProtocolGuidArray[i]); if (str) { gBS->FreePool(str); str=0; } } if (ProtocolGuidArray) { gBS->FreePool(ProtocolGuidArray); ProtocolGuidArray=0; } } EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; //open the Loaded image protocol,which is binded on the imageHandle,to get the device handle. status = gBS->OpenProtocol( gImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if(status == EFI_SUCCESS) { Print(L"2\n"); status = gBS->ProtocolsPerHandle(LoadedImage->DeviceHandle,&ProtocolGuidArray,&ArrayCount); if (status == EFI_SUCCESS) { for (UINTN i = 0; i < ArrayCount; i++) { str = GetStringNameFromGuid(ProtocolGuidArray[i], 0); Print(L"%s,%g\n", str,ProtocolGuidArray[i]); if (str) { gBS->FreePool(str); str=0; } } if (ProtocolGuidArray) { gBS->FreePool(ProtocolGuidArray); ProtocolGuidArray=0; } } gBS->CloseProtocol( gImageHandle, &gEfiLoadedImageProtocolGuid, gImageHandle, NULL); } return EFI_SUCCESS; }
在 NT32 下运行的结果如下:
完整的代码下载:
特别提醒,如果在 AppPkg 中编译,需要在AppPkg.dsc的 [LibraryClasses] 中加入下面的语句:
HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
再次感谢 krishnaLee(sssky307)