资源安装

HiiAddPackages

函数原型:

/**Registers a list of packages in the HII Database and returns the HII Handleassociated with that registration.  If an HII Handle has already been registeredwith the same PackageListGuid and DeviceHandle, then NULL is returned.  If thereare not enough resources to perform the registration, then NULL is returned.If an empty list of packages is passed in, then NULL is returned.  If the size ofthe list of package is 0, then NULL is returned.The variable arguments are pointers which point to package header that definedby UEFI VFR compiler and StringGather tool.#pragma pack (push, 1)typedef struct {UINT32                  BinaryLength;EFI_HII_PACKAGE_HEADER  PackageHeader;} EDKII_AUTOGEN_PACKAGES_HEADER;#pragma pack (pop)@param[in]  PackageListGuid  The GUID of the package list.@param[in]  DeviceHandle     If not NULL, the Device Handle on whichan instance of DEVICE_PATH_PROTOCOL is installed.This Device Handle uniquely defines the device thatthe added packages are associated with.@param[in]  ...              The variable argument list that contains pointersto packages terminated by a NULL.@retval NULL   A HII Handle has already been registered in the HII Database withthe same PackageListGuid and DeviceHandle.@retval NULL   The HII Handle could not be created.@retval NULL   An empty list of packages was passed in.@retval NULL   All packages are empty.@retval Other  The HII Handle associated with the newly registered package list.**/
EFI_HII_HANDLE
EFIAPI
HiiAddPackages (IN CONST EFI_GUID    *PackageListGuid,IN       EFI_HANDLE  DeviceHandle  OPTIONAL,...)

简单来说就是将资源(代码中用Package标识,这里将其翻译为资源似乎更好理解,它表示的可能是uni文件对应的字符串、vfr文件对应的Setup骨架、字体等等)安装HII数据库中,并返回数据库的Handle,后续要使用资源就要用到这个Handle

它的第一个参数是GUID,用来唯一地标识安装的资源,目前不确定其作用,似乎是为了防止重复安装的DeviceHandle用来在其上安装DEVICE_PATH_PROTOCOL实例,通过这种方式就可以将资源与安装在DeviceHandle之上的其它内容(比如设备)等联系在一起;...表示的是需要安装的资源。

下面是一个简单的例子,为了使用字符串资源,这里首先通过HiiAddPackages()进行安装:

VOID
InitializeStringSupport (VOID)
{gStringPackHandle = HiiAddPackages (&mUiStringPackGuid,gImageHandle,UiAppStrings,NULL);ASSERT (gStringPackHandle != NULL);
}

UiAppStrings对应uni文件得到的数据,它通过HiiAddPackages()安装,并返回全局的gStringPackHandle,这个后面会用到,而另外一个gImageHandle在本例中并不重要。使用字符串资源的代码示例:

String = HiiGetString (gStringPackHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);

STR_MISSING_STRINGuni文件中定义的宏,gStringPackHandle是前面调用HiiAddPackages时的返回值,第三个参数NULL表示跟随当前语言。另外需要注意的是这里的返回值String后面需要释放。

另一个比较复杂的示例,首先也是安装:

  //// Publish our HII data//gFrontPagePrivate.HiiHandle = HiiAddPackages (&mFrontPageGuid,gFrontPagePrivate.DriverHandle,FrontPageVfrBin,UiAppStrings,NULL);

这里的mFrontPageGuidvfr文件(MdeModulePkg\Application\UiApp\FrontPageVfr.Vfr)中的GUID一致,就是下面的FORMSET_GUID

#define FORMSET_GUID  { 0x9e0c30bc, 0x3f06, 0x4ba6, 0x82, 0x88, 0x9, 0x17, 0x9b, 0x85, 0x5d, 0xbe }#define FRONT_PAGE_FORM_ID             0x1000#define LABEL_FRANTPAGE_INFORMATION    0x1000
#define LABEL_END                      0xffffformsetguid     = FORMSET_GUID,title    = STRING_TOKEN(STR_FRONT_PAGE_TITLE),help     = STRING_TOKEN(STR_EMPTY_STRING ),classguid = FORMSET_GUID,

返回的gFrontPagePrivate.HiiHandle会在EFI_FORM_BROWSER2_PROTOCOL中使用:

  Status = gFormBrowser2->SendForm (gFormBrowser2,&gFrontPagePrivate.HiiHandle,1,&mFrontPageGuid,0,NULL,&ActionRequest);

这里也用到了mFrontPageGuid,且应该是必须的,跟classguid = FORMSET_GUID匹配。

目前可添加的Packages有如下的种类:

  • Font
  • Simplified Font
  • String
  • Image
  • Device Path
  • keyboard Layout
  • GUID
  • Forms

本例中就使用了Font和String这些Package。

创建操作码

操作码可以在vfr文件中指定,也可以通过代码创建,下面介绍一些简单的创建操作码的函数。

HiiAllocateOpCodeHandle/HiiFreeOpCodeHandle

HiiAllocateOpCodeHandle()创建HII_LIB_OPCODE_BUFFER结构体并返回:

VOID *
EFIAPI
HiiAllocateOpCodeHandle (VOID)

其结构如下:

typedef struct {UINT8  *Buffer;UINTN  BufferSize;UINTN  Position;
} HII_LIB_OPCODE_BUFFER;

创建好之后的结构体中Buffer是一个大小为0x200字节的空间;BufferSize就是0x200;Position初始化为0。

HiiFreeOpCodeHandle()用来释放HiiAllocateOpCodeHandle()分配的数据,两者配合使用。

Buffer里面存放到就是各类操作码,如果操作码多,则Buffer还会根据实际的情况重新分配大小以存放所有的操作码。

HiiCreateActionOpCode

创建一个可以执行的操作码,其函数原型:

/**Create EFI_IFR_ACTION_OP opcode.If OpCodeHandle is NULL, then ASSERT().If any reserved bits are set in QuestionFlags, then ASSERT().@param[in]  OpCodeHandle  Handle to the buffer of opcodes.@param[in]  QuestionId      Question ID@param[in]  Prompt          String ID for Prompt@param[in]  Help            String ID for Help@param[in]  QuestionFlags   Flags in Question Header@param[in]  QuestionConfig  String ID for configuration@retval NULL   There is not enough space left in Buffer to add the opcode.@retval Other  A pointer to the created opcode.**/
UINT8 *
EFIAPI
HiiCreateActionOpCode (IN VOID             *OpCodeHandle,IN EFI_QUESTION_ID  QuestionId,IN EFI_STRING_ID    Prompt,IN EFI_STRING_ID    Help,IN UINT8            QuestionFlags,IN EFI_STRING_ID    QuestionConfig)

操作码对应的结构体:

typedef struct _EFI_IFR_ACTION {EFI_IFR_OP_HEADER        Header;EFI_IFR_QUESTION_HEADER  Question;EFI_STRING_ID            QuestionConfig;
} EFI_IFR_ACTION;

HiiCreateGotoExOpCode

创建的操作码用于跳转,其函数原型:

/**Create EFI_IFR_REF_OP, EFI_IFR_REF2_OP, EFI_IFR_REF3_OP and EFI_IFR_REF4_OP opcode.When RefDevicePath is not zero, EFI_IFR_REF4 opcode will be created.When RefDevicePath is zero and RefFormSetId is not NULL, EFI_IFR_REF3 opcode will be created.When RefDevicePath is zero, RefFormSetId is NULL and RefQuestionId is not zero, EFI_IFR_REF2 opcode will be created.When RefDevicePath is zero, RefFormSetId is NULL and RefQuestionId is zero, EFI_IFR_REF opcode will be created.If OpCodeHandle is NULL, then ASSERT().If any reserved bits are set in QuestionFlags, then ASSERT().@param[in]  OpCodeHandle   The handle to the buffer of opcodes.@param[in]  RefFormId      The Destination Form ID.@param[in]  Prompt         The string ID for Prompt.@param[in]  Help           The string ID for Help.@param[in]  QuestionFlags  The flags in Question Header@param[in]  QuestionId     Question ID.@param[in]  RefQuestionId  The question on the form to which this link is referring.If its value is zero, then the link refers to the top of the form.@param[in]  RefFormSetId   The form set to which this link is referring. If its value is NULL, and RefDevicePath iszero, then the link is to the current form set.@param[in]  RefDevicePath  The string identifier that specifies the string containing the text representation ofthe device path to which the form set containing the form specified by FormId.If its value is zero, then the link refers to the current page.@retval NULL   There is not enough space left in Buffer to add the opcode.@retval Other  A pointer to the created opcode.**/
UINT8 *
EFIAPI
HiiCreateGotoExOpCode (IN VOID             *OpCodeHandle,IN EFI_FORM_ID      RefFormId,IN EFI_STRING_ID    Prompt,IN EFI_STRING_ID    Help,IN UINT8            QuestionFlags,IN EFI_QUESTION_ID  QuestionId,IN EFI_QUESTION_ID  RefQuestionId,IN EFI_GUID         *RefFormSetId,    OPTIONALIN EFI_STRING_ID    RefDevicePath)

创建的结构体根据参数的不同而存在差异:

typedef struct _EFI_IFR_REF {EFI_IFR_OP_HEADER        Header;EFI_IFR_QUESTION_HEADER  Question;EFI_FORM_ID              FormId;
} EFI_IFR_REF;typedef struct _EFI_IFR_REF2 {EFI_IFR_OP_HEADER        Header;EFI_IFR_QUESTION_HEADER  Question;EFI_FORM_ID              FormId;EFI_QUESTION_ID          QuestionId;
} EFI_IFR_REF2;typedef struct _EFI_IFR_REF3 {EFI_IFR_OP_HEADER        Header;EFI_IFR_QUESTION_HEADER  Question;EFI_FORM_ID              FormId;EFI_QUESTION_ID          QuestionId;EFI_GUID                 FormSetId;
} EFI_IFR_REF3;typedef struct _EFI_IFR_REF4 {EFI_IFR_OP_HEADER        Header;EFI_IFR_QUESTION_HEADER  Question;EFI_FORM_ID              FormId;EFI_QUESTION_ID          QuestionId;EFI_GUID                 FormSetId;EFI_STRING_ID            DevicePath;
} EFI_IFR_REF4;typedef struct _EFI_IFR_REF5 {EFI_IFR_OP_HEADER Header;EFI_IFR_QUESTION_HEADER Question;
} EFI_IFR_REF5;

其实现中有如下的代码:

  //// Cacluate OpCodeSize based on the input Ref value.// Try to use the small OpCode to save size.//OpCodeSize = sizeof (EFI_IFR_REF);if (RefDevicePath != 0) {OpCodeSize = sizeof (EFI_IFR_REF4);} else if (RefFormSetId != NULL) {OpCodeSize = sizeof (EFI_IFR_REF3);} else if (RefQuestionId != 0) {OpCodeSize = sizeof (EFI_IFR_REF2);}

从这里可以看到指定了不同的操作码。

HiiCreateGuidOpCode

函数原型:

/**Create EFI_IFR_GUID opcode.If OpCodeHandle is NULL, then ASSERT().If Guid is NULL, then ASSERT().If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT().@param[in]  OpCodeHandle  Handle to the buffer of opcodes.@param[in]  Guid          Pointer to EFI_GUID of this guided opcode.@param[in]  GuidOpCode    Pointer to an EFI_IFR_GUID opcode.  This is anoptional parameter that may be NULL.  If thisparameter is NULL, then the GUID extensionregion of the created opcode is filled with zeros.If this parameter is not NULL, then the GUIDextension region of GuidData will be copied tothe GUID extension region of the created opcode.@param[in]  OpCodeSize    The size, in bytes, of created opcode.  This valuemust be >= sizeof(EFI_IFR_GUID).@retval NULL   There is not enough space left in Buffer to add the opcode.@retval Other  A pointer to the created opcode.**/
UINT8 *
EFIAPI
HiiCreateGuidOpCode (IN VOID            *OpCodeHandle,IN CONST EFI_GUID  *Guid,IN CONST VOID      *GuidOpCode,    OPTIONALIN UINTN           OpCodeSize)

创建EFI_IFR_GUID操作码,它是现有的GUID的扩展,本身包含不同的格式,通过一个GUID来标识,现有的有gEfiIfrTianoGuid,它包含的格式有:

///
/// EDKII implementation extension opcodes, new extension can be added here later.
///
#define EFI_IFR_EXTEND_OP_LABEL       0x0
#define EFI_IFR_EXTEND_OP_BANNER      0x1
#define EFI_IFR_EXTEND_OP_TIMEOUT     0x2
#define EFI_IFR_EXTEND_OP_CLASS       0x3
#define EFI_IFR_EXTEND_OP_SUBCLASS    0x4

下面是创建一个LABLE的示例:

  //// Create Hii Extend Label OpCode.//StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle,&gEfiIfrTianoGuid,NULL,sizeof (EFI_IFR_GUID_LABEL));

参数说明:

  • OpCodeHandle:对应容纳操作码的HII_LIB_OPCODE_BUFFER结构体;

HiiCreateOneOfOpCode

函数原型:

/**Create EFI_IFR_ONE_OF_OP opcode.If OpCodeHandle is NULL, then ASSERT().If any reserved bits are set in QuestionFlags, then ASSERT().If any reserved bits are set in OneOfFlags, then ASSERT().@param[in]  OpCodeHandle          Handle to the buffer of opcodes.@param[in]  QuestionId            Question ID@param[in]  VarStoreId            Storage ID@param[in]  VarOffset             Offset in Storage or String ID of the name (VarName)for this name/value pair.@param[in]  Prompt                String ID for Prompt@param[in]  Help                  String ID for Help@param[in]  QuestionFlags         Flags in Question Header@param[in]  OneOfFlags            Flags for oneof opcode@param[in]  OptionsOpCodeHandle   Handle for a buffer of ONE_OF_OPTION opcodes.@param[in]  DefaultsOpCodeHandle  Handle for a buffer of DEFAULT opcodes.  Thisis an optional parameter that may be NULL.@retval NULL   There is not enough space left in Buffer to add the opcode.@retval Other  A pointer to the created opcode.**/
UINT8 *
EFIAPI
HiiCreateOneOfOpCode (IN VOID             *OpCodeHandle,IN EFI_QUESTION_ID  QuestionId,IN EFI_VARSTORE_ID  VarStoreId,IN UINT16           VarOffset,IN EFI_STRING_ID    Prompt,IN EFI_STRING_ID    Help,IN UINT8            QuestionFlags,IN UINT8            OneOfFlags,IN VOID             *OptionsOpCodeHandle,IN VOID             *DefaultsOpCodeHandle  OPTIONAL)

创建EFI_IFR_ONE_OF操作码,它表示的是select-one-of question,其实就是单选框,比如Front Page中的语言选择框:

其对应的结构体:

typedef struct _EFI_IFR_ONE_OF {EFI_IFR_OP_HEADER        Header;EFI_IFR_QUESTION_HEADER  Question; // 单选框结构体中的EFI_IFR_QUESTION_HEADERUINT8                    Flags;MINMAXSTEP_DATA          data;
} EFI_IFR_ONE_OF;

下面是一个示例:

  HiiCreateOneOfOpCode (StartOpCodeHandle,FRONT_PAGE_KEY_LANGUAGE,0,0,STRING_TOKEN (STR_LANGUAGE_SELECT),STRING_TOKEN (STR_LANGUAGE_SELECT_HELP),EFI_IFR_FLAG_CALLBACK,EFI_IFR_NUMERIC_SIZE_1,OptionsOpCodeHandle,NULL);

参数说明:

  • OpCodeHandle:应该是上一层操作码对应的HII_LIB_OPCODE_BUFFER结构体;
  • QuestionId:其实是一个UINT16类型的数值,它是一个在当前驱动唯一的值,通过它回调函数(由EFI_HII_ACCESS_FORM_CALLBACK声明)就能够知道需要处理的数据具体是哪个;(UEFI规范中的说明:A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. The format of the data tends to vary based on the opcode that generated the callback. )

EFI_HII_ACCESS_FORM_CALLBACK回调函数的声明如下:

/**This function is called to provide results data to the driver.This data consists of a unique key that is used to identifywhich data is either being passed back or being asked for.@param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.@param  Action                 Specifies the type of action taken by the browser.@param  QuestionId             A unique value which is sent to the originalexporting driver so that it can identify the typeof data to expect. The format of the data tends tovary based on the opcode that generated the callback.@param  Type                   The type of value for the question.@param  Value                  A pointer to the data being sent to the originalexporting driver.@param  ActionRequest          On return, points to the action requested by thecallback function.@retval EFI_SUCCESS            The callback successfully handled the action.@retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold thevariable and its data.@retval EFI_DEVICE_ERROR       The variable could not be saved.@retval EFI_UNSUPPORTED        The specified Action is not supported by thecallback.
**/
typedef
EFI_STATUS
(EFIAPI *EFI_HII_ACCESS_FORM_CALLBACK)(IN     CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,IN     EFI_BROWSER_ACTION                     Action,IN     EFI_QUESTION_ID                        QuestionId,IN     UINT8                                  Type,IN OUT EFI_IFR_TYPE_VALUE                     *Value,OUT    EFI_BROWSER_ACTION_REQUEST             *ActionRequest);

它是EFI_HII_CONFIG_ACCESS_PROTOCOL的接口。

  • VarStoreId/VarOffset:这里通过一个ID指定对应的变量,通过Offset指定对应的成员,对该操作码的修改就对应的变量;如果没有变量与之对应,就直接写0就可以了;
  • Prompt:对应显示;
  • Help:对应操作的帮助;
  • QuestionFlags:表示选项的属性,比如只读、回调,等等,对应的值如下所示:
//
// Flag values of EFI_IFR_QUESTION_HEADER
//
#define EFI_IFR_FLAG_READ_ONLY          0x01
#define EFI_IFR_FLAG_CALLBACK           0x04
#define EFI_IFR_FLAG_RESET_REQUIRED     0x10
#define EFI_IFR_FLAG_REST_STYLE         0x20
#define EFI_IFR_FLAG_RECONNECT_REQUIRED 0x40
#define EFI_IFR_FLAG_OPTIONS_ONLY       0x80

EFI_IFR_QUESTION_HEADER在不少操作码都存在,比如这里创建的单选框(见结构体中的Question成员)就有,其结构体:

typedef struct _EFI_IFR_QUESTION_HEADER {EFI_IFR_STATEMENT_HEADER Header;EFI_QUESTION_ID          QuestionId;EFI_VARSTORE_ID          VarStoreId;union {EFI_STRING_ID          VarName;UINT16                 VarOffset;}                        VarStoreInfo;UINT8                    Flags;    // 对应QuestionFlags
} EFI_IFR_QUESTION_HEADER;
  • OneOfFlags:单选框的Flags,有如下的值:
//
// Flags related to the numeric question
//
#define EFI_IFR_NUMERIC_SIZE           0x03
#define   EFI_IFR_NUMERIC_SIZE_1       0x00
#define   EFI_IFR_NUMERIC_SIZE_2       0x01
#define   EFI_IFR_NUMERIC_SIZE_4       0x02
#define   EFI_IFR_NUMERIC_SIZE_8       0x03#define EFI_IFR_DISPLAY                0x30
#define   EFI_IFR_DISPLAY_INT_DEC      0x00
#define   EFI_IFR_DISPLAY_UINT_DEC     0x10
#define   EFI_IFR_DISPLAY_UINT_HEX     0x20

它表示的意义目前有两种,第一种表示值的类型,第二种表示显示的格式;

  • OptionsOpCodeHandle:表示单选框操作码本身,它里面通常还需要包含EFI_IFR_ONE_OF_OPTION_OP操作码,表示单选框中的子选项;
  • DefaultsOpCodeHandle:表示默认显示的单选框子选项;

关于子选项,见HiiCreateOneOfOptionOpCode。

HiiCreateOneOfOptionOpCode

函数原型:

/**Create EFI_IFR_ONE_OF_OPTION_OP opcode.If OpCodeHandle is NULL, then ASSERT().If Type is invalid, then ASSERT().If Flags is invalid, then ASSERT().@param[in]  OpCodeHandle  Handle to the buffer of opcodes.@param[in]  StringId      StringId for the option@param[in]  Flags         Flags for the option@param[in]  Type          Type for the option@param[in]  Value         Value for the option@retval NULL   There is not enough space left in Buffer to add the opcode.@retval Other  A pointer to the created opcode.**/
UINT8 *
EFIAPI
HiiCreateOneOfOptionOpCode (IN VOID    *OpCodeHandle,IN UINT16  StringId,IN UINT8   Flags,IN UINT8   Type,IN UINT64  Value)

创建的操作码对应的结构体:

typedef struct _EFI_IFR_ONE_OF_OPTION {EFI_IFR_OP_HEADER        Header;EFI_STRING_ID            Option;UINT8                    Flags;UINT8                    Type;EFI_IFR_TYPE_VALUE       Value;
} EFI_IFR_ONE_OF_OPTION;

HiiCreateSubTitleOpCode

函数原型:

/**Create EFI_IFR_SUBTITLE_OP opcode.If OpCodeHandle is NULL, then ASSERT().If any reserved bits are set in Flags, then ASSERT().If Scope > 1, then ASSERT().@param[in]  OpCodeHandle  Handle to the buffer of opcodes.@param[in]  Prompt      String ID for Prompt@param[in]  Help        String ID for Help@param[in]  Flags       Subtitle opcode flags@param[in]  Scope       1 if this opcode is the beginning of a new scope.0 if this opcode is within the current scope.@retval NULL   There is not enough space left in Buffer to add the opcode.@retval Other  A pointer to the created opcode.**/
UINT8 *
EFIAPI
HiiCreateSubTitleOpCode (IN VOID           *OpCodeHandle,IN EFI_STRING_ID  Prompt,IN EFI_STRING_ID  Help,IN UINT8          Flags,IN UINT8          Scope)

创建的操作码对应的结构体:

typedef struct _EFI_IFR_SUBTITLE {EFI_IFR_OP_HEADER        Header;EFI_IFR_STATEMENT_HEADER Statement;UINT8                    Flags;
} EFI_IFR_SUBTITLE;

字符串操作

HiiGetString

函数原型:

/**Retrieves a string from a string package in a specific language specified in Languageor in the best lanaguage. See HiiGetStringEx () for the details.@param[in]  HiiHandle  A handle that was previously registered in the HII Database.@param[in]  StringId   The identifier of the string to retrieved from the stringpackage associated with HiiHandle.@param[in]  Language   The language of the string to retrieve.  If this parameteris NULL, then the current platform language is used.  Theformat of Language must follow the language format assumedthe HII Database.@retval NULL   The string specified by StringId is not present in the string package.@retval Other  The string was returned.**/
EFI_STRING
EFIAPI
HiiGetString (IN EFI_HII_HANDLE  HiiHandle,IN EFI_STRING_ID   StringId,IN CONST CHAR8     *Language  OPTIONAL);

这个函数用来获取字符串,字符串通过Language来确定语种,StringId确定使用哪个字段,这个字段定义在uni文件中,而uni文件通过函数HiiAddPackages()安装,下面是一个例子(来自MdeModulePkg\Application\UiApp\UiApp.inf):

  //// Publish our HII data//gFrontPagePrivate.HiiHandle = HiiAddPackages (&mFrontPageGuid,gFrontPagePrivate.DriverHandle,FrontPageVfrBin,UiAppStrings,NULL);

UiAppStrings是一个中间文件(AutoGen.c)中定义的变量,在Build目录中生成,它的名字来自inf中设置的MODULE_UNI_FILE:

MODULE_UNI_FILE                = UiApp.uni

两者的关系是uni文件去掉后缀并加上Strings就得到的用在HiiAddPackages()中的变量。不过模块中的uni文件并不需要都是这个名字,可以有多个不同名的uni文件。

下面是使用HiiGetString()的一个例子:

  //// Update default banner string.//NewString = HiiGetString (gFrontPagePrivate.HiiHandle, STRING_TOKEN (STR_CUSTOMIZE_BANNER_LINE4_LEFT), NULL);

STR_CUSTOMIZE_BANNER_LINE4_LEFT就是在某个uni文件(FrontPageStrings.uni)中定义的(目前是空的):

#string STR_CUSTOMIZE_BANNER_LINE4_LEFT  #language en-US  ""#language fr-FR  ""

gFrontPagePrivate.HiiHandle是使用HiiAddPackages()安装时的返回值。

HiiSetString

函数原型:

/**This function creates a new string in String Package or updates an existingstring in a String Package.  If StringId is 0, then a new string is added toa String Package.  If StringId is not zero, then a string in String Package isupdated.  If SupportedLanguages is NULL, then the string is added or updatedfor all the languages that the String Package supports.  If SupportedLanguagesis not NULL, then the string is added or updated for the set of languagesspecified by SupportedLanguages.If HiiHandle is NULL, then ASSERT().If String is NULL, then ASSERT().@param[in]  HiiHandle           A handle that was previously registered in theHII Database.@param[in]  StringId            If zero, then a new string is created in theString Package associated with HiiHandle.  Ifnon-zero, then the string specified by StringIdis updated in the String Package associatedwith HiiHandle.@param[in]  String              A pointer to the Null-terminated Unicode stringto add or update in the String Package associatedwith HiiHandle.@param[in]  SupportedLanguages  A pointer to a Null-terminated ASCII string oflanguage codes.  If this parameter is NULL, thenString is added or updated in the String Packageassociated with HiiHandle for all the languagesthat the String Package supports.  If thisparameter is not NULL, then String is addedor updated in the String Package associated withHiiHandle for the set of languages specified bySupportedLanguages.  The format ofSupportedLanguages must follow the languageformat assumed in the HII Database.@retval 0      The string could not be added or updated in the String Package.@retval Other  The EFI_STRING_ID of the newly added or updated string.**/
EFI_STRING_ID
EFIAPI
HiiSetString (IN EFI_HII_HANDLE    HiiHandle,IN EFI_STRING_ID     StringId,            OPTIONALIN CONST EFI_STRING  String,IN CONST CHAR8       *SupportedLanguages  OPTIONAL);

这个函数在字符串资源中新增或者字符串。StringId如果是0表示新增,否则就表示修改原有的字符串。

Form操作

HiiUpdateForm

用于更新界面结构,函数原型:

EFI_STATUS
EFIAPI
HiiUpdateForm (IN EFI_HII_HANDLE  HiiHandle,IN EFI_GUID        *FormSetGuid,        OPTIONALIN EFI_FORM_ID     FormId,IN VOID            *StartOpCodeHandle,IN VOID            *EndOpCodeHandle     OPTIONAL)

这里的HiiHandle就是HiiAddPackages()添加元素数据之后的返回值:

  gFrontPagePrivate.HiiHandle = HiiAddPackages (&mFrontPageGuid,gFrontPagePrivate.DriverHandle,FrontPageVfrBin,UiAppStrings,NULL);

FormSetGuidHiiAddPackages()中的第一个参数,即mFrontPageGuid

FormId是定义在vfr文件中:

form formid = FRONT_PAGE_FORM_ID,

StartOpCodeHandleEndOpCodeHandleHiiAllocateOpCodeHandle()创建。

【UEFI实战】HII之常用函数相关推荐

  1. UEFI实战--------HII之uni文件

    uni文件 HII的实现涉及到多种不同类型的文件,uni文件是其中最简单的一种,它用来存放各种语言的字符串以实现本地化.本节主要参考自<edk-ii-uni-specification.pdf& ...

  2. R实战:【常用函数】rnorm正态分布

    R实战系列专栏 rnorm正态分布(The Normal Distribution)函数 整体分布函数rnorm的函数声明如下: rnorm(n, mean = 0, sd = 1) n:产生随机数个 ...

  3. 实战! excel中常用函数INDIRECT公式的用法

    实战中的应用: 图一 当我们日常工作中,拿到这样一份表(图一),并需要从中拿到自己想要的数据,如下图(图二): (图二) 像这种重复性的工作,每日去一个个去寻找,不但浪费时间,还极其容易找错,这个时候 ...

  4. 【UEFI实战】UART的初始化

    说明 UART全称是Universal Asynchronous Receiver/Transmitter,这里它表示的是一种实现串口通信的芯片,在整个串口系统中它的位置如下图所示: RS232 +- ...

  5. 【UEFI实战】EDK的编译流程说明

    前言 使用EDK进行UEFI开发,开始的时候很容易遇到的问题就是编译不过,并非代码的问题,而是编译环境存在异常. 本文主要介绍EDK是如何进行编译的,使用的平台是Windows.这里还想说一点,事实上 ...

  6. 大数据基础之Hive(四)—— 常用函数和压缩存储

    作者:duktig 博客:https://duktig.cn (文章首发) 优秀还努力.愿你付出甘之如饴,所得归于欢喜. 更多文章参看github知识库:https://github.com/dukt ...

  7. jquery学习笔记及常用函数封装

    二.JQuery 学习笔记及常用函数封装 https://download.csdn.net/download/weixin_42530002/13087988 1.JQuery入门 (1).css选 ...

  8. 【UEFI实战】OS下如何查看系统相关信息

    说明 本文主要介绍OS下如何来查看系统信息,这些系统信息大多是通过BIOS上传的.这里的OS主要分为Linux和Windows两个部分来说明,前者使用的发行版系统是Ubuntu18.04,后者使用的是 ...

  9. 机器学习之Python常用函数及模块整理

    机器学习之Python常用函数及模块整理 1. map函数 2. apply函数 3. applymap函数 4. groupby函数 5. agg函数 6. lambda函数 7. rank函数 8 ...

最新文章

  1. 使用Combox控件的一个问题
  2. hql中常用函數介紹二
  3. 外包干了四年,废了!
  4. python三维数据转换成二维_Python科学计算全生态工具锦集
  5. 关东升的《从零开始学Swift》3月9日已经上架
  6. Jsoup介绍||​​​​​​​jsoup解析url || Jsoup解析字符串||​​​​​​​Jsoup解析文件
  7. vs2015安装与单元测试以及经过优化的算法
  8. 项目实战丨某家具公司机房改造方案
  9. JavaScript call,apply和prototype的介绍,区别
  10. L2-2 口罩发放 (25 分)
  11. linux怎么建立链接文件,Linux 建立文件夹的链接
  12. C++中convertTo对应的python代码
  13. 面对对象之差异化的网络数据交互方式--单机游戏开发之无缝切换到C/S模式
  14. cobble批量装机原理与部署
  15. Yolov5目标检测环境搭建过程(Cuda+Pytorch+Yolov5)
  16. 再次使用vue-awesome-swiper做异形轮播
  17. linux域名伪装,基于 Nginx 的 v2+websocket+tls 域名伪装
  18. 使用nslookup命令检查DNS服务
  19. Linux与Android安全差异
  20. Docker 4 之 Docker 客户端和守护进程

热门文章

  1. Vue生命周期 (图解+代码解析)
  2. 宫崎骏动画风格 美日动漫差异
  3. python中answer_Python初学之学生和老师的question和answer问题
  4. 金蝶EAS打开报更新失败 java.io.FileNotFoundException
  5. 给钱给地给人!三运营商千亿砸手机渠道谁买账
  6. 立体仓库堆垛机控制系统安全操作规程
  7. java canvas 动画效果_八大疯狂HTML5 Canvas及WebGL动画效果
  8. Codeforces 439 A. Devu, the Singer and Churu, the Joker
  9. 与开源cynthia同源的团队协作平台effevo(effevo.com)免费开放
  10. DBA还是一份好工作吗?