-/** @file
-
-Copyright (c) 2007, Intel Corporation
-All rights reserved. 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.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-Module Name:
-
- UefiIfrForm.c
-
-Abstract:
-
- Common Library Routines to assist handle HII elements.
-
-
-**/
-
-#include "LibraryInternal.h"
-
-STATIC
-EFI_STATUS
-GetPackageDataFromPackageList (
- IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
- IN UINT32 PackageIndex,
- OUT UINT32 *BufferLen,
- OUT EFI_HII_PACKAGE_HEADER **Buffer
- )
-{
- UINT32 Index;
- EFI_HII_PACKAGE_HEADER *Package;
- UINT32 Offset;
- UINT32 PackageListLength;
- EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0};
-
- ASSERT(HiiPackageList != NULL);
-
- if ((BufferLen == NULL) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- Package = NULL;
- Index = 0;
- Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
- CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
- while (Offset < PackageListLength) {
- Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- if (Index == PackageIndex) {
- break;
- }
- Offset += PackageHeader.Length;
- Index++;
- }
- if (Offset >= PackageListLength) {
- //
- // no package found in this Package List
- //
- return EFI_NOT_FOUND;
- }
-
- *BufferLen = PackageHeader.Length;
- *Buffer = Package;
- return EFI_SUCCESS;
-}
-
-STATIC
-EFI_STATUS
-EFIAPI
-UpdateFormPackageData (
- IN EFI_GUID *FormSetGuid,
- IN EFI_FORM_ID FormId,
- IN EFI_HII_PACKAGE_HEADER *Package,
- IN UINT32 PackageLength,
- IN UINT16 Label,
- IN BOOLEAN Insert,
- IN EFI_HII_UPDATE_DATA *Data,
- OUT UINT8 **TempBuffer,
- OUT UINT32 *TempBufferSize
- )
-{
- UINTN AddSize;
- UINT8 *BufferPos;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- UINTN Offset;
- EFI_IFR_OP_HEADER *IfrOpHdr;
- BOOLEAN GetFormSet;
- BOOLEAN GetForm;
- UINT8 ExtendOpCode;
- UINT16 LabelNumber;
- BOOLEAN Updated;
- EFI_IFR_OP_HEADER *AddOpCode;
-
- if ((TempBuffer == NULL) || (TempBufferSize == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *TempBufferSize = PackageLength;
- if (Data != NULL) {
- *TempBufferSize += Data->Offset;
- }
- *TempBuffer = AllocateZeroPool (*TempBufferSize);
- if (*TempBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- CopyMem (*TempBuffer, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- *TempBufferSize = sizeof (EFI_HII_PACKAGE_HEADER);
- BufferPos = *TempBuffer + sizeof (EFI_HII_PACKAGE_HEADER);
-
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));
- Offset = sizeof (EFI_HII_PACKAGE_HEADER);
- GetFormSet = (BOOLEAN) ((FormSetGuid == NULL) ? TRUE : FALSE);
- GetForm = FALSE;
- Updated = FALSE;
-
- while (Offset < PackageHeader.Length) {
- CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
- BufferPos += IfrOpHdr->Length;
- *TempBufferSize += IfrOpHdr->Length;
-
- switch (IfrOpHdr->OpCode) {
- case EFI_IFR_FORM_SET_OP :
- if (FormSetGuid != NULL) {
- if (CompareMem (&((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, FormSetGuid, sizeof (EFI_GUID)) == 0) {
- GetFormSet = TRUE;
- }
- }
- break;
-
- case EFI_IFR_FORM_OP:
- if (CompareMem (&((EFI_IFR_FORM *) IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) {
- GetForm = TRUE;
- }
- break;
-
- case EFI_IFR_GUID_OP :
- if (!GetFormSet || !GetForm || Updated) {
- //
- // Go to the next Op-Code
- //
- Offset += IfrOpHdr->Length;
- IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
- continue;
- }
-
- ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;
- CopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16));
- if ((ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) || (LabelNumber != Label)) {
- //
- // Go to the next Op-Code
- //
- Offset += IfrOpHdr->Length;
- IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
- continue;
- }
-
- if (Insert && (Data != NULL)) {
- //
- // insert the DataCount amount of opcodes to TempBuffer if Data is NULL remove
- // DataCount amount of opcodes unless runing into a label.
- //
- AddOpCode = (EFI_IFR_OP_HEADER *)Data->Data;
- AddSize = 0;
- while (AddSize < Data->Offset) {
- CopyMem (BufferPos, AddOpCode, AddOpCode->Length);
- BufferPos += AddOpCode->Length;
- *TempBufferSize += AddOpCode->Length;
-
- AddSize += AddOpCode->Length;
- AddOpCode = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (AddOpCode) + AddOpCode->Length);
- }
- } else {
- //
- // Search the next Label.
- //
- while (TRUE) {
- Offset += IfrOpHdr->Length;
- //
- // Search the next label and Fail if not label found.
- //
- if (Offset >= PackageHeader.Length) {
- goto Fail;
- }
- IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
- if (IfrOpHdr->OpCode == EFI_IFR_GUID_OP) {
- ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;
- if (ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) {
- break;
- }
- }
- }
-
- if (Data != NULL) {
- AddOpCode = (EFI_IFR_OP_HEADER *)Data->Data;
- AddSize = 0;
- while (AddSize < Data->Offset) {
- CopyMem (BufferPos, AddOpCode, AddOpCode->Length);
- BufferPos += AddOpCode->Length;
- *TempBufferSize += AddOpCode->Length;
-
- AddSize += AddOpCode->Length;
- AddOpCode = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (AddOpCode) + AddOpCode->Length);
- }
- }
-
- //
- // copy the next label
- //
- CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
- BufferPos += IfrOpHdr->Length;
- *TempBufferSize += IfrOpHdr->Length;
- }
-
- Updated = TRUE;
- break;
- default :
- break;
- }
-
- //
- // Go to the next Op-Code
- //
- Offset += IfrOpHdr->Length;
- IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
- }
-
- //
- // Update the package length.
- //
- PackageHeader.Length = *TempBufferSize;
- CopyMem (*TempBuffer, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
-
-Fail:
- if (!Updated) {
- gBS->FreePool (*TempBuffer);
- *TempBufferSize = 0;
- return EFI_NOT_FOUND;
- }
-
- return EFI_SUCCESS;
-}
-
-
-/**
- This function allows the caller to update a form that has
- previously been registered with the EFI HII database.
-
- @param Handle Hii Handle
- @param FormSetGuid The formset should be updated.
- @param FormId The form should be updated.
- @param Label Update information starting immediately after this
- label in the IFR
- @param Insert If TRUE and Data is not NULL, insert data after
- Label. If FALSE, replace opcodes between two
- labels with Data
- @param Data The adding data; If NULL, remove opcodes between
- two Label.
-
- @retval EFI_SUCCESS Update success.
- @retval Other Update fail.
-
-**/
-EFI_STATUS
-EFIAPI
-IfrLibUpdateForm (
- IN EFI_HII_HANDLE Handle,
- IN EFI_GUID *FormSetGuid, OPTIONAL
- IN EFI_FORM_ID FormId,
- IN UINT16 Label,
- IN BOOLEAN Insert,
- IN EFI_HII_UPDATE_DATA *Data
- )
-{
- EFI_STATUS Status;
- EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
- EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
- UINT32 Index;
- EFI_HII_PACKAGE_LIST_HEADER *UpdateBuffer;
- UINTN BufferSize;
- UINT8 *UpdateBufferPos;
- EFI_HII_PACKAGE_HEADER PackageHeader;
- EFI_HII_PACKAGE_HEADER *Package;
- UINT32 PackageLength;
- EFI_HII_PACKAGE_HEADER *TempBuffer;
- UINT32 TempBufferSize;
- BOOLEAN Updated;
-
- if (Data == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- HiiDatabase = gIfrLibHiiDatabase;
-
- //
- // Get the orginal package list
- //
- BufferSize = 0;
- HiiPackageList = NULL;
- Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- HiiPackageList = AllocatePool (BufferSize);
- ASSERT (HiiPackageList != NULL);
-
- Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);
- if (EFI_ERROR (Status)) {
- gBS->FreePool (HiiPackageList);
- return Status;
- }
- }
-
- //
- // Calculate and allocate space for retrieval of IFR data
- //
- BufferSize += Data->Offset;
- UpdateBuffer = AllocateZeroPool (BufferSize);
- if (UpdateBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- UpdateBufferPos = (UINT8 *) UpdateBuffer;
-
- //
- // copy the package list header
- //
- CopyMem (UpdateBufferPos, HiiPackageList, sizeof (EFI_HII_PACKAGE_LIST_HEADER));
- UpdateBufferPos += sizeof (EFI_HII_PACKAGE_LIST_HEADER);
-
- Updated = FALSE;
- for (Index = 0; ; Index++) {
- Status = GetPackageDataFromPackageList (HiiPackageList, Index, &PackageLength, &Package);
- if (Status == EFI_SUCCESS) {
- CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
- if ((PackageHeader.Type == EFI_HII_PACKAGE_FORM) && !Updated) {
- Status = UpdateFormPackageData (FormSetGuid, FormId, Package, PackageLength, Label, Insert, Data, (UINT8 **)&TempBuffer, &TempBufferSize);
- if (!EFI_ERROR(Status)) {
- if (FormSetGuid == NULL) {
- Updated = TRUE;
- }
- CopyMem (UpdateBufferPos, TempBuffer, TempBufferSize);
- UpdateBufferPos += TempBufferSize;
- gBS->FreePool (TempBuffer);
- continue;
- }
- }
-
- CopyMem (UpdateBufferPos, Package, PackageLength);
- UpdateBufferPos += PackageLength;
- } else if (Status == EFI_NOT_FOUND) {
- break;
- } else {
- gBS->FreePool (HiiPackageList);
- return Status;
- }
- }
-
- //
- // Update package list length
- //
- BufferSize = UpdateBufferPos - (UINT8 *) UpdateBuffer;
- CopyMem (&UpdateBuffer->PackageLength, &BufferSize, sizeof (UINT32));
-
- gBS->FreePool (HiiPackageList);
-
- return HiiDatabase->UpdatePackageList (HiiDatabase, Handle, UpdateBuffer);
-}
-
-
-/**
- Configure the buffer accrording to ConfigBody strings.
-
- @param DefaultId the ID of default.
- @param Buffer the start address of buffer.
- @param BufferSize the size of buffer.
- @param Number the number of the strings.
-
- @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.
- @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.
- @retval EFI_SUCCESS Operation successful.
-
-**/
-EFI_STATUS
-EFIAPI
-IfrLibExtractDefault(
- IN VOID *Buffer,
- IN UINTN *BufferSize,
- UINTN Number,
- ...
- )
-{
- VA_LIST Args;
- UINTN Index;
- UINT32 TotalLen;
- UINT8 *BufCfgArray;
- UINT8 *BufferPos;
- UINT16 Offset;
- UINT16 Width;
- UINT8 *Value;
-
- if ((Buffer == NULL) || (BufferSize == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- Offset = 0;
- Width = 0;
- Value = NULL;
-
- VA_START (Args, Number);
- for (Index = 0; Index < Number; Index++) {
- BufCfgArray = (UINT8 *) VA_ARG (Args, VOID *);
- CopyMem (&TotalLen, BufCfgArray, sizeof (UINT32));
- BufferPos = BufCfgArray + sizeof (UINT32);
-
- while ((UINT32)(BufferPos - BufCfgArray) < TotalLen) {
- CopyMem (&Offset, BufferPos, sizeof (UINT16));
- BufferPos += sizeof (UINT16);
- CopyMem (&Width, BufferPos, sizeof (UINT16));
- BufferPos += sizeof (UINT16);
- Value = BufferPos;
- BufferPos += Width;
-
- if ((UINTN)(Offset + Width) > *BufferSize) {
- return EFI_BUFFER_TOO_SMALL;
- }
-
- CopyMem ((UINT8 *)Buffer + Offset, Value, Width);
- }
- }
- VA_END (Args);
-
- *BufferSize = (UINTN)Offset;
-
- return EFI_SUCCESS;
-}
-
-
+/** @file\r
+ Common Library Routines to assist handle HII elements.\r
+\r
+Copyright (c) 2007 - 2008, Intel Corporation. <BR>\r
+All rights reserved. This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution. The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "LibraryInternal.h"\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetPackageDataFromPackageList (\r
+ IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,\r
+ IN UINT32 PackageIndex,\r
+ OUT UINT32 *BufferLen,\r
+ OUT EFI_HII_PACKAGE_HEADER **Buffer\r
+ )\r
+{\r
+ UINT32 Index;\r
+ EFI_HII_PACKAGE_HEADER *Package;\r
+ UINT32 Offset;\r
+ UINT32 PackageListLength;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0};\r
+\r
+ ASSERT(HiiPackageList != NULL);\r
+\r
+ if ((BufferLen == NULL) || (Buffer == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Package = NULL;\r
+ Index = 0;\r
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+ CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
+ while (Offset < PackageListLength) {\r
+ Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ if (Index == PackageIndex) {\r
+ break;\r
+ }\r
+ Offset += PackageHeader.Length;\r
+ Index++;\r
+ }\r
+ if (Offset >= PackageListLength) {\r
+ //\r
+ // no package found in this Package List\r
+ //\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ *BufferLen = PackageHeader.Length;\r
+ *Buffer = Package;\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+EFIAPI\r
+UpdateFormPackageData (\r
+ IN EFI_GUID *FormSetGuid,\r
+ IN EFI_FORM_ID FormId,\r
+ IN EFI_HII_PACKAGE_HEADER *Package,\r
+ IN UINT32 PackageLength,\r
+ IN UINT16 Label,\r
+ IN BOOLEAN Insert,\r
+ IN EFI_HII_UPDATE_DATA *Data,\r
+ OUT UINT8 **TempBuffer,\r
+ OUT UINT32 *TempBufferSize\r
+ )\r
+{\r
+ UINTN AddSize;\r
+ UINT8 *BufferPos;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+ UINTN Offset;\r
+ EFI_IFR_OP_HEADER *IfrOpHdr;\r
+ BOOLEAN GetFormSet;\r
+ BOOLEAN GetForm;\r
+ UINT8 ExtendOpCode;\r
+ UINT16 LabelNumber;\r
+ BOOLEAN Updated;\r
+ EFI_IFR_OP_HEADER *AddOpCode;\r
+\r
+ if ((TempBuffer == NULL) || (TempBufferSize == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ *TempBufferSize = PackageLength;\r
+ if (Data != NULL) {\r
+ *TempBufferSize += Data->Offset;\r
+ }\r
+ *TempBuffer = AllocateZeroPool (*TempBufferSize);\r
+ if (*TempBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ CopyMem (*TempBuffer, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ *TempBufferSize = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ BufferPos = *TempBuffer + sizeof (EFI_HII_PACKAGE_HEADER);\r
+\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));\r
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
+ GetFormSet = (BOOLEAN) ((FormSetGuid == NULL) ? TRUE : FALSE);\r
+ GetForm = FALSE;\r
+ Updated = FALSE;\r
+\r
+ while (Offset < PackageHeader.Length) {\r
+ CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);\r
+ BufferPos += IfrOpHdr->Length;\r
+ *TempBufferSize += IfrOpHdr->Length;\r
+\r
+ switch (IfrOpHdr->OpCode) {\r
+ case EFI_IFR_FORM_SET_OP :\r
+ if (FormSetGuid != NULL) {\r
+ if (CompareMem (&((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, FormSetGuid, sizeof (EFI_GUID)) == 0) {\r
+ GetFormSet = TRUE;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_FORM_OP:\r
+ if (CompareMem (&((EFI_IFR_FORM *) IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) {\r
+ GetForm = TRUE;\r
+ }\r
+ break;\r
+\r
+ case EFI_IFR_GUID_OP :\r
+ if (!GetFormSet || !GetForm || Updated) {\r
+ //\r
+ // Go to the next Op-Code\r
+ //\r
+ Offset += IfrOpHdr->Length;\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
+ continue;\r
+ }\r
+\r
+ ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;\r
+ CopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16));\r
+ if ((ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) || (LabelNumber != Label)) {\r
+ //\r
+ // Go to the next Op-Code\r
+ //\r
+ Offset += IfrOpHdr->Length;\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
+ continue;\r
+ }\r
+\r
+ if (Insert && (Data != NULL)) {\r
+ //\r
+ // insert the DataCount amount of opcodes to TempBuffer if Data is NULL remove\r
+ // DataCount amount of opcodes unless runing into a label.\r
+ //\r
+ AddOpCode = (EFI_IFR_OP_HEADER *)Data->Data;\r
+ AddSize = 0;\r
+ while (AddSize < Data->Offset) {\r
+ CopyMem (BufferPos, AddOpCode, AddOpCode->Length);\r
+ BufferPos += AddOpCode->Length;\r
+ *TempBufferSize += AddOpCode->Length;\r
+\r
+ AddSize += AddOpCode->Length;\r
+ AddOpCode = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (AddOpCode) + AddOpCode->Length);\r
+ }\r
+ } else {\r
+ //\r
+ // Search the next Label.\r
+ //\r
+ while (TRUE) {\r
+ Offset += IfrOpHdr->Length;\r
+ //\r
+ // Search the next label and Fail if not label found.\r
+ //\r
+ if (Offset >= PackageHeader.Length) {\r
+ goto Fail;\r
+ }\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
+ if (IfrOpHdr->OpCode == EFI_IFR_GUID_OP) {\r
+ ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;\r
+ if (ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+ if (Data != NULL) {\r
+ AddOpCode = (EFI_IFR_OP_HEADER *)Data->Data;\r
+ AddSize = 0;\r
+ while (AddSize < Data->Offset) {\r
+ CopyMem (BufferPos, AddOpCode, AddOpCode->Length);\r
+ BufferPos += AddOpCode->Length;\r
+ *TempBufferSize += AddOpCode->Length;\r
+\r
+ AddSize += AddOpCode->Length;\r
+ AddOpCode = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (AddOpCode) + AddOpCode->Length);\r
+ }\r
+ }\r
+\r
+ //\r
+ // copy the next label\r
+ //\r
+ CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);\r
+ BufferPos += IfrOpHdr->Length;\r
+ *TempBufferSize += IfrOpHdr->Length;\r
+ }\r
+\r
+ Updated = TRUE;\r
+ break;\r
+ default :\r
+ break;\r
+ }\r
+\r
+ //\r
+ // Go to the next Op-Code\r
+ //\r
+ Offset += IfrOpHdr->Length;\r
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
+ }\r
+\r
+ //\r
+ // Update the package length.\r
+ //\r
+ PackageHeader.Length = *TempBufferSize;\r
+ CopyMem (*TempBuffer, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));\r
+\r
+Fail:\r
+ if (!Updated) {\r
+ gBS->FreePool (*TempBuffer);\r
+ *TempBufferSize = 0;\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ This function allows the caller to update a form that has\r
+ previously been registered with the EFI HII database.\r
+\r
+ @param Handle Hii Handle\r
+ @param FormSetGuid The formset should be updated.\r
+ @param FormId The form should be updated.\r
+ @param Label Update information starting immediately after this\r
+ label in the IFR\r
+ @param Insert If TRUE and Data is not NULL, insert data after\r
+ Label. If FALSE, replace opcodes between two\r
+ labels with Data\r
+ @param Data The adding data; If NULL, remove opcodes between\r
+ two Label.\r
+\r
+ @retval EFI_SUCCESS Update success.\r
+ @retval Other Update fail.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IfrLibUpdateForm (\r
+ IN EFI_HII_HANDLE Handle,\r
+ IN EFI_GUID *FormSetGuid, OPTIONAL\r
+ IN EFI_FORM_ID FormId,\r
+ IN UINT16 Label,\r
+ IN BOOLEAN Insert,\r
+ IN EFI_HII_UPDATE_DATA *Data\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
+ UINT32 Index;\r
+ EFI_HII_PACKAGE_LIST_HEADER *UpdateBuffer;\r
+ UINTN BufferSize;\r
+ UINT8 *UpdateBufferPos;\r
+ EFI_HII_PACKAGE_HEADER PackageHeader;\r
+ EFI_HII_PACKAGE_HEADER *Package;\r
+ UINT32 PackageLength;\r
+ EFI_HII_PACKAGE_HEADER *TempBuffer;\r
+ UINT32 TempBufferSize;\r
+ BOOLEAN Updated;\r
+\r
+ if (Data == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ HiiDatabase = gIfrLibHiiDatabase;\r
+\r
+ //\r
+ // Get the orginal package list\r
+ //\r
+ BufferSize = 0;\r
+ HiiPackageList = NULL;\r
+ Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ HiiPackageList = AllocatePool (BufferSize);\r
+ ASSERT (HiiPackageList != NULL);\r
+\r
+ Status = HiiDatabase->ExportPackageLists (HiiDatabase, Handle, &BufferSize, HiiPackageList);\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (HiiPackageList);\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Calculate and allocate space for retrieval of IFR data\r
+ //\r
+ BufferSize += Data->Offset;\r
+ UpdateBuffer = AllocateZeroPool (BufferSize);\r
+ if (UpdateBuffer == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ UpdateBufferPos = (UINT8 *) UpdateBuffer;\r
+\r
+ //\r
+ // copy the package list header\r
+ //\r
+ CopyMem (UpdateBufferPos, HiiPackageList, sizeof (EFI_HII_PACKAGE_LIST_HEADER));\r
+ UpdateBufferPos += sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
+\r
+ Updated = FALSE;\r
+ for (Index = 0; ; Index++) {\r
+ Status = GetPackageDataFromPackageList (HiiPackageList, Index, &PackageLength, &Package);\r
+ if (Status == EFI_SUCCESS) {\r
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
+ if ((PackageHeader.Type == EFI_HII_PACKAGE_FORM) && !Updated) {\r
+ Status = UpdateFormPackageData (FormSetGuid, FormId, Package, PackageLength, Label, Insert, Data, (UINT8 **)&TempBuffer, &TempBufferSize);\r
+ if (!EFI_ERROR(Status)) {\r
+ if (FormSetGuid == NULL) {\r
+ Updated = TRUE;\r
+ }\r
+ CopyMem (UpdateBufferPos, TempBuffer, TempBufferSize);\r
+ UpdateBufferPos += TempBufferSize;\r
+ gBS->FreePool (TempBuffer);\r
+ continue;\r
+ }\r
+ }\r
+\r
+ CopyMem (UpdateBufferPos, Package, PackageLength);\r
+ UpdateBufferPos += PackageLength;\r
+ } else if (Status == EFI_NOT_FOUND) {\r
+ break;\r
+ } else {\r
+ gBS->FreePool (HiiPackageList);\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // Update package list length\r
+ //\r
+ BufferSize = UpdateBufferPos - (UINT8 *) UpdateBuffer;\r
+ CopyMem (&UpdateBuffer->PackageLength, &BufferSize, sizeof (UINT32));\r
+\r
+ gBS->FreePool (HiiPackageList);\r
+\r
+ return HiiDatabase->UpdatePackageList (HiiDatabase, Handle, UpdateBuffer);\r
+}\r
+\r
+\r
+/**\r
+ Configure the buffer accrording to ConfigBody strings.\r
+\r
+ @param DefaultId the ID of default.\r
+ @param Buffer the start address of buffer.\r
+ @param BufferSize the size of buffer.\r
+ @param Number the number of the strings.\r
+\r
+ @retval EFI_BUFFER_TOO_SMALL the BufferSize is too small to operate.\r
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is 0.\r
+ @retval EFI_SUCCESS Operation successful.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+IfrLibExtractDefault(\r
+ IN VOID *Buffer,\r
+ IN UINTN *BufferSize,\r
+ UINTN Number,\r
+ ...\r
+ )\r
+{\r
+ VA_LIST Args;\r
+ UINTN Index;\r
+ UINT32 TotalLen;\r
+ UINT8 *BufCfgArray;\r
+ UINT8 *BufferPos;\r
+ UINT16 Offset;\r
+ UINT16 Width;\r
+ UINT8 *Value;\r
+\r
+ if ((Buffer == NULL) || (BufferSize == NULL)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Offset = 0;\r
+ Width = 0;\r
+ Value = NULL;\r
+\r
+ VA_START (Args, Number);\r
+ for (Index = 0; Index < Number; Index++) {\r
+ BufCfgArray = (UINT8 *) VA_ARG (Args, VOID *);\r
+ CopyMem (&TotalLen, BufCfgArray, sizeof (UINT32));\r
+ BufferPos = BufCfgArray + sizeof (UINT32);\r
+\r
+ while ((UINT32)(BufferPos - BufCfgArray) < TotalLen) {\r
+ CopyMem (&Offset, BufferPos, sizeof (UINT16));\r
+ BufferPos += sizeof (UINT16);\r
+ CopyMem (&Width, BufferPos, sizeof (UINT16));\r
+ BufferPos += sizeof (UINT16);\r
+ Value = BufferPos;\r
+ BufferPos += Width;\r
+\r
+ if ((UINTN)(Offset + Width) > *BufferSize) {\r
+ return EFI_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ CopyMem ((UINT8 *)Buffer + Offset, Value, Width);\r
+ }\r
+ }\r
+ VA_END (Args);\r
+\r
+ *BufferSize = (UINTN)Offset;\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r