本节介绍HiiDatabase 驱动程序中EFI_HII_DATABASE_PROTOCOL协议的实现。在HII数据库中所有的表项均采用包
列表的方式存放。包列表由GUID标识其唯一性,每个包列表包含标准头部,含一个或多个GUID包,表格表,字符串包,字体包等等。
HII_DATABASE_PACKAGE_LIST_INSTANCE数据结构
typedef struct _HII_DATABASE_PACKAGE_LIST_INSTANCE {
EFI_HII_PACKAGE_LIST_HEADER PackageListHdr;
LIST_ENTRY GuidPkgHdr;
LIST_ENTRY FormPkgHdr;
LIST_ENTRY KeyboardLayoutHdr;
LIST_ENTRY StringPkgHdr;
LIST_ENTRY FontPkgHdr;
LIST_ENTRY *ImagePkg;
LIST_NETRY SimpleFontPkgHdr;
UINT8 *DevicePathPkg;
}
AddPackages 安装一个或多个包到HII 数据库中,且调用相应的通知函数通知用户。
ExportPakcageList 导出一个包列表的内容
HiiNewPackageList EFI_HII_DATABASE_PROTOCOL.NewPackageList 的实例函数。
HiiRemovePackageList EFI_HII_DATABASE_PROTOCOL RemovePackageList的实例函数
HiiUpdatePackageList EFI_HII_DATABASE_PROTOCOL UpdatePackageList 的实例函数
HiiNewPackageList() 函数
输入参数PackageList 类型为EFI_HII_PACKAGE_LIST_HEADER *, 该指针类型指向UEFI规范定义的包列表头部,随后的缓冲区内容是一个或多个包,目前支持的类型有:
字体包
简单字体包
字符串包
映像包
设备路径包
键盘布局包
GUID包
表格包
UEFI 规范要求系统中每个包列表由GUID标识。
//
// Check the package list GUID to guarantee this GUID is unique in database
//
for (Link = Private->DatabaseList.ForwardLink; Link != &Private->DatabaseList; Link = Link->ForwardLink) {
DatabaseRecord = CR(Link, HII_DATABASE_RECORD, DatabaseEntry, HII_DATABASE_RECORD_SIGNATURE);
if (Compareguid(
&(DatabaseRecord->PackageList->PackageListHdr.PackageListGuid),
&PackageListGuid) &&
DatabaseRecore->DriverHandle == DriverHandle) {
return EFI_INVALID_PARAMETER;
}
}
调用GenerateHiiDatabaseRecord() 函数初始化DatabaseRecord, 该变量类型为hii_database_record. 调用Addpackage()将packageList 指向的包列表头部及各种包安装到数据库中。
包列表安装成功,将输入参数DriverHandle存入DatabaseRecord.
//
// Build a PackageList node
//
Status = GenerateHiiDatabaseRecord(Private, &DatabaseRecord);
if (EFI_ERROR(Status)) {
return Status;
}
DatabaseRecord->DriverHandle = DriverHandle;
//
// Create a Device path package and add into the package list if exists
//
Status = gBS->HandleProtocol (
DriverHandle,
&gEfiDevicePathProtocolGuid,
(VOID **) &DevicePath
);
if (!EFI_ERROR(Status)) {
Status = AddDevicePathPackage(Private,
EFI_HII_DATABASE_NOTIFY_NEW_PACK, Device, DatabaseRecord);
ASSERT_EFI_ERROR(Status);
}
*Handle = DatabaseRecord->Handle;
return EFI_SUCCESS;
检查输入参数DriverHandle 上是否装有DevicePath 协议,若有则组建设备路径包安装
到HII 数据库中,将GenerateHiiDatabaseRecord() 函数返回的Handle存入输出参数Handle.
之后返回成功退出函数。
注意输出参数Handle 的类型为EFI_HII_HANDLE, HII数据库中实际维护的Handle类型为
HII_HANDLE, 如下图所示。
typedef struct {
UINTN Signature;
LIST_ENTRY Handle;
UINTN Key;
} HII_HANDLE;