Home | History | Annotate | Download | only in VarCheckHiiLib
      1 /** @file
      2   Var Check Hii bin generation.
      3 
      4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "VarCheckHiiGen.h"
     16 
     17 LIST_ENTRY mVarCheckHiiList = INITIALIZE_LIST_HEAD_VARIABLE (mVarCheckHiiList);
     18 
     19 #define VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE   SIGNATURE_32 ('V', 'C', 'H', 'V')
     20 
     21 typedef struct {
     22   UINTN                         Signature;
     23   LIST_ENTRY                    Link;
     24   VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
     25   EFI_VARSTORE_ID               VarStoreId;
     26 
     27   VAR_CHECK_HII_QUESTION_HEADER **HiiQuestionArray;
     28 } VAR_CHECK_HII_VARIABLE_NODE;
     29 
     30 #define VAR_CHECK_HII_VARIABLE_FROM_LINK(a) CR (a, VAR_CHECK_HII_VARIABLE_NODE, Link, VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE)
     31 
     32 CHAR16 *mVarName = NULL;
     33 UINTN  mMaxVarNameSize = 0;
     34 
     35 #ifdef DUMP_HII_DATA
     36 GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING   mIfrOpCodeStringTable[] = {
     37   {EFI_IFR_VARSTORE_OP,             "EFI_IFR_VARSTORE_OP"},
     38   {EFI_IFR_VARSTORE_EFI_OP,         "EFI_IFR_VARSTORE_EFI_OP"},
     39   {EFI_IFR_ONE_OF_OP,               "EFI_IFR_ONE_OF_OP"},
     40   {EFI_IFR_CHECKBOX_OP,             "EFI_IFR_CHECKBOX_OP"},
     41   {EFI_IFR_NUMERIC_OP,              "EFI_IFR_NUMERIC_OP"},
     42   {EFI_IFR_ORDERED_LIST_OP,         "EFI_IFR_ORDERED_LIST_OP"},
     43   {EFI_IFR_ONE_OF_OPTION_OP,        "EFI_IFR_ONE_OF_OPTION_OP"},
     44 };
     45 
     46 /**
     47   Ifr opcode to string.
     48 
     49   @param[in] IfrOpCode  Ifr OpCode.
     50 
     51   @return Pointer to string.
     52 
     53 **/
     54 CHAR8 *
     55 IfrOpCodeToStr (
     56   IN UINT8  IfrOpCode
     57   )
     58 {
     59   UINTN  Index;
     60   for (Index = 0; Index < ARRAY_SIZE (mIfrOpCodeStringTable); Index++) {
     61     if (mIfrOpCodeStringTable[Index].HiiOpCode == IfrOpCode) {
     62       return mIfrOpCodeStringTable[Index].HiiOpCodeStr;
     63     }
     64   }
     65 
     66   return "<UnknownIfrOpCode>";
     67 }
     68 
     69 GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_PACKAGE_TYPE_STRING  mPackageTypeStringTable[] = {
     70   {EFI_HII_PACKAGE_TYPE_ALL,            "EFI_HII_PACKAGE_TYPE_ALL"},
     71   {EFI_HII_PACKAGE_TYPE_GUID,           "EFI_HII_PACKAGE_TYPE_GUID"},
     72   {EFI_HII_PACKAGE_FORMS,               "EFI_HII_PACKAGE_FORMS"},
     73   {EFI_HII_PACKAGE_STRINGS,             "EFI_HII_PACKAGE_STRINGS"},
     74   {EFI_HII_PACKAGE_FONTS,               "EFI_HII_PACKAGE_FONTS"},
     75   {EFI_HII_PACKAGE_IMAGES,              "EFI_HII_PACKAGE_IMAGES"},
     76   {EFI_HII_PACKAGE_SIMPLE_FONTS,        "EFI_HII_PACKAGE_SIMPLE_FONTS"},
     77   {EFI_HII_PACKAGE_DEVICE_PATH,         "EFI_HII_PACKAGE_DEVICE_PATH"},
     78   {EFI_HII_PACKAGE_KEYBOARD_LAYOUT,     "EFI_HII_PACKAGE_KEYBOARD_LAYOUT"},
     79   {EFI_HII_PACKAGE_ANIMATIONS,          "EFI_HII_PACKAGE_ANIMATIONS"},
     80   {EFI_HII_PACKAGE_END,                 "EFI_HII_PACKAGE_END"},
     81   {EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN,   "EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN"},
     82   {EFI_HII_PACKAGE_TYPE_SYSTEM_END,     "EFI_HII_PACKAGE_TYPE_SYSTEM_END"},
     83 };
     84 
     85 /**
     86   Hii Package type to string.
     87 
     88   @param[in] PackageType    Package Type
     89 
     90   @return Pointer to string.
     91 
     92 **/
     93 CHAR8 *
     94 HiiPackageTypeToStr (
     95   IN UINT8  PackageType
     96   )
     97 {
     98   UINTN     Index;
     99   for (Index = 0; Index < ARRAY_SIZE (mPackageTypeStringTable); Index++) {
    100     if (mPackageTypeStringTable[Index].PackageType == PackageType) {
    101       return mPackageTypeStringTable[Index].PackageTypeStr;
    102     }
    103   }
    104 
    105   return "<UnknownPackageType>";
    106 }
    107 
    108 /**
    109   Dump Hii Package.
    110 
    111   @param[in] HiiPackage         Pointer to Hii Package.
    112 
    113 **/
    114 VOID
    115 DumpHiiPackage (
    116   IN VOID       *HiiPackage
    117   )
    118 {
    119   EFI_HII_PACKAGE_HEADER        *HiiPackageHeader;
    120   EFI_IFR_OP_HEADER             *IfrOpCodeHeader;
    121   EFI_IFR_VARSTORE              *IfrVarStore;
    122   EFI_IFR_VARSTORE_EFI          *IfrEfiVarStore;
    123 
    124   HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiPackage;
    125 
    126   DEBUG ((EFI_D_INFO, "  HiiPackageHeader->Type   - 0x%02x (%a)\n", HiiPackageHeader->Type, HiiPackageTypeToStr ((UINT8) HiiPackageHeader->Type)));
    127   DEBUG ((EFI_D_INFO, "  HiiPackageHeader->Length - 0x%06x\n", HiiPackageHeader->Length));
    128 
    129   switch (HiiPackageHeader->Type) {
    130     case EFI_HII_PACKAGE_FORMS:
    131       IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) (HiiPackageHeader + 1);
    132 
    133       while ((UINTN) IfrOpCodeHeader < ((UINTN) HiiPackageHeader + HiiPackageHeader->Length)) {
    134         switch (IfrOpCodeHeader->OpCode) {
    135           case EFI_IFR_VARSTORE_OP:
    136             IfrVarStore = (EFI_IFR_VARSTORE *) IfrOpCodeHeader;
    137             DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
    138             DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->Length - 0x%02x\n", IfrOpCodeHeader->Length));
    139             DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->Scope  - 0x%02x\n", IfrOpCodeHeader->Scope));
    140             DEBUG ((EFI_D_INFO, "      Guid       - %g\n", &IfrVarStore->Guid));
    141             DEBUG ((EFI_D_INFO, "      VarStoreId - 0x%04x\n", IfrVarStore->VarStoreId));
    142             DEBUG ((EFI_D_INFO, "      Size       - 0x%04x\n", IfrVarStore->Size));
    143             DEBUG ((EFI_D_INFO, "      Name       - %a\n", IfrVarStore->Name));
    144             break;
    145 
    146           case EFI_IFR_VARSTORE_EFI_OP:
    147             IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpCodeHeader;
    148             if (IfrEfiVarStore->Header.Length >= sizeof (EFI_IFR_VARSTORE_EFI)) {
    149               DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
    150               DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->Length - 0x02%x\n", IfrOpCodeHeader->Length));
    151               DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->Scope  - 0x02%x\n", IfrOpCodeHeader->Scope));
    152               DEBUG ((EFI_D_INFO, "      Guid       - %g\n", &IfrEfiVarStore->Guid));
    153               DEBUG ((EFI_D_INFO, "      VarStoreId - 0x%04x\n", IfrEfiVarStore->VarStoreId));
    154               DEBUG ((EFI_D_INFO, "      Size       - 0x%04x\n", IfrEfiVarStore->Size));
    155               DEBUG ((EFI_D_INFO, "      Attributes - 0x%08x\n", IfrEfiVarStore->Attributes));
    156               DEBUG ((EFI_D_INFO, "      Name       - %a\n", IfrEfiVarStore->Name));
    157             }
    158             break;
    159 
    160           case EFI_IFR_ONE_OF_OP:
    161           case EFI_IFR_CHECKBOX_OP:
    162           case EFI_IFR_NUMERIC_OP:
    163           case EFI_IFR_ORDERED_LIST_OP:
    164             DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
    165             DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->Length - 0x02%x\n", IfrOpCodeHeader->Length));
    166             DEBUG ((EFI_D_INFO, "    IfrOpCodeHeader->Scope  - 0x02%x\n", IfrOpCodeHeader->Scope));
    167             DEBUG ((EFI_D_INFO, "      Prompt       - 0x%04x\n", ((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.Header.Prompt));
    168             DEBUG ((EFI_D_INFO, "      Help         - 0x%04x\n", ((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.Header.Help));
    169             DEBUG ((EFI_D_INFO, "      QuestionId   - 0x%04x\n", ((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.QuestionId));
    170             DEBUG ((EFI_D_INFO, "      VarStoreId   - 0x%04x\n", ((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.VarStoreId));
    171             DEBUG ((EFI_D_INFO, "      VarStoreInfo - 0x%04x\n", ((EFI_IFR_ONE_OF * )IfrOpCodeHeader)->Question.VarStoreInfo.VarOffset));
    172             {
    173               EFI_IFR_ONE_OF            *IfrOneOf;
    174               EFI_IFR_CHECKBOX          *IfrCheckBox;
    175               EFI_IFR_NUMERIC           *IfrNumeric;
    176               EFI_IFR_ORDERED_LIST      *IfrOrderedList;
    177 
    178               switch (IfrOpCodeHeader->OpCode) {
    179                 case EFI_IFR_ONE_OF_OP:
    180                   IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpCodeHeader;
    181                   DEBUG ((EFI_D_INFO, "      Flags         - 0x%02x\n", IfrOneOf->Flags));
    182                   switch (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE) {
    183                   case EFI_IFR_NUMERIC_SIZE_1:
    184                     DEBUG ((EFI_D_INFO, "      MinValue      - 0x%02x\n", IfrOneOf->data.u8.MinValue));
    185                     DEBUG ((EFI_D_INFO, "      MaxValue      - 0x%02x\n", IfrOneOf->data.u8.MaxValue));
    186                     DEBUG ((EFI_D_INFO, "      Step          - 0x%02x\n", IfrOneOf->data.u8.Step));
    187                     break;
    188                   case EFI_IFR_NUMERIC_SIZE_2:
    189                     DEBUG ((EFI_D_INFO, "      MinValue      - 0x%04x\n", IfrOneOf->data.u16.MinValue));
    190                     DEBUG ((EFI_D_INFO, "      MaxValue      - 0x%04x\n", IfrOneOf->data.u16.MaxValue));
    191                     DEBUG ((EFI_D_INFO, "      Step          - 0x%04x\n", IfrOneOf->data.u16.Step));
    192                     break;
    193                   case EFI_IFR_NUMERIC_SIZE_4:
    194                     DEBUG ((EFI_D_INFO, "      MinValue      - 0x%08x\n", IfrOneOf->data.u32.MinValue));
    195                     DEBUG ((EFI_D_INFO, "      MaxValue      - 0x%08x\n", IfrOneOf->data.u32.MaxValue));
    196                     DEBUG ((EFI_D_INFO, "      Step          - 0x%08x\n", IfrOneOf->data.u32.Step));
    197                     break;
    198                   case EFI_IFR_NUMERIC_SIZE_8:
    199                     DEBUG ((EFI_D_INFO, "      MinValue      - 0x%016lx\n", IfrOneOf->data.u64.MinValue));
    200                     DEBUG ((EFI_D_INFO, "      MaxValue      - 0x%016lx\n", IfrOneOf->data.u64.MaxValue));
    201                     DEBUG ((EFI_D_INFO, "      Step          - 0x%016lx\n", IfrOneOf->data.u64.Step));
    202                     break;
    203                   }
    204                   break;
    205                 case EFI_IFR_CHECKBOX_OP:
    206                   IfrCheckBox = (EFI_IFR_CHECKBOX *) IfrOpCodeHeader;
    207                   DEBUG ((EFI_D_INFO, "      Flags         - 0x%02x\n", IfrCheckBox->Flags));
    208                   break;
    209                 case EFI_IFR_NUMERIC_OP:
    210                   IfrNumeric = (EFI_IFR_NUMERIC *) IfrOpCodeHeader;
    211                   DEBUG ((EFI_D_INFO, "      Flags         - 0x%02x\n", IfrNumeric->Flags));
    212                   switch (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE) {
    213                   case EFI_IFR_NUMERIC_SIZE_1:
    214                     DEBUG ((EFI_D_INFO, "      MinValue      - 0x%02x\n", IfrNumeric->data.u8.MinValue));
    215                     DEBUG ((EFI_D_INFO, "      MaxValue      - 0x%02x\n", IfrNumeric->data.u8.MaxValue));
    216                     DEBUG ((EFI_D_INFO, "      Step          - 0x%02x\n", IfrNumeric->data.u8.Step));
    217                     break;
    218                   case EFI_IFR_NUMERIC_SIZE_2:
    219                     DEBUG ((EFI_D_INFO, "      MinValue      - 0x%04x\n", IfrNumeric->data.u16.MinValue));
    220                     DEBUG ((EFI_D_INFO, "      MaxValue      - 0x%04x\n", IfrNumeric->data.u16.MaxValue));
    221                     DEBUG ((EFI_D_INFO, "      Step          - 0x%04x\n", IfrNumeric->data.u16.Step));
    222                     break;
    223                   case EFI_IFR_NUMERIC_SIZE_4:
    224                     DEBUG ((EFI_D_INFO, "      MinValue      - 0x%08x\n", IfrNumeric->data.u32.MinValue));
    225                     DEBUG ((EFI_D_INFO, "      MaxValue      - 0x%08x\n", IfrNumeric->data.u32.MaxValue));
    226                     DEBUG ((EFI_D_INFO, "      Step          - 0x%08x\n", IfrNumeric->data.u32.Step));
    227                     break;
    228                   case EFI_IFR_NUMERIC_SIZE_8:
    229                     DEBUG ((EFI_D_INFO, "      MinValue      - 0x%016lx\n", IfrNumeric->data.u64.MinValue));
    230                     DEBUG ((EFI_D_INFO, "      MaxValue      - 0x%016lx\n", IfrNumeric->data.u64.MaxValue));
    231                     DEBUG ((EFI_D_INFO, "      Step          - 0x%016lx\n", IfrNumeric->data.u64.Step));
    232                     break;
    233                   }
    234                   break;
    235                 case EFI_IFR_ORDERED_LIST_OP:
    236                   IfrOrderedList = (EFI_IFR_ORDERED_LIST *) IfrOpCodeHeader;
    237                   DEBUG ((EFI_D_INFO, "      MaxContainers - 0x%02x\n", IfrOrderedList->MaxContainers));
    238                   DEBUG ((EFI_D_INFO, "      Flags         - 0x%02x\n", IfrOrderedList->Flags));
    239                   break;
    240                 default:
    241                   break;
    242               }
    243 
    244               if (IfrOpCodeHeader->Scope != 0) {
    245                 UINTN                       Scope;
    246                 EFI_IFR_ONE_OF_OPTION       *IfrOneOfOption;
    247 
    248                 IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
    249                 Scope = 1;
    250                 while (Scope != 0) {
    251                   switch (IfrOpCodeHeader->OpCode) {
    252                     case EFI_IFR_ONE_OF_OPTION_OP:
    253                       IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *)IfrOpCodeHeader;
    254                       DEBUG ((EFI_D_INFO, "!!!!    IfrOpCodeHeader->OpCode - 0x%02x (%a)\n", (UINTN)IfrOpCodeHeader->OpCode, IfrOpCodeToStr (IfrOpCodeHeader->OpCode)));
    255                       DEBUG ((EFI_D_INFO, "!!!!    IfrOpCodeHeader->Scope  - 0x%02x\n", IfrOpCodeHeader->Scope));
    256                       DEBUG ((EFI_D_INFO, "!!!!      Option                - 0x%04x\n", IfrOneOfOption->Option));
    257                       DEBUG ((EFI_D_INFO, "!!!!      Flags                 - 0x%02x\n", IfrOneOfOption->Flags));
    258                       DEBUG ((EFI_D_INFO, "!!!!      Type                  - 0x%02x\n", IfrOneOfOption->Type));
    259                       switch (IfrOneOfOption->Type) {
    260                         case EFI_IFR_TYPE_NUM_SIZE_8:
    261                           DEBUG ((EFI_D_INFO, "!!!!      Value                 - 0x%02x\n", IfrOneOfOption->Value.u8));
    262                           break;
    263                         case EFI_IFR_TYPE_NUM_SIZE_16:
    264                           DEBUG ((EFI_D_INFO, "!!!!      Value                 - 0x%04x\n", IfrOneOfOption->Value.u16));
    265                           break;
    266                         case EFI_IFR_TYPE_NUM_SIZE_32:
    267                           DEBUG ((EFI_D_INFO, "!!!!      Value                 - 0x%08x\n", IfrOneOfOption->Value.u32));
    268                           break;
    269                         case EFI_IFR_TYPE_NUM_SIZE_64:
    270                           DEBUG ((EFI_D_INFO, "!!!!      Value                 - 0x%016lx\n", IfrOneOfOption->Value.u64));
    271                           break;
    272                         case EFI_IFR_TYPE_BOOLEAN:
    273                           DEBUG ((EFI_D_INFO, "!!!!      Value                 - 0x%02x\n", IfrOneOfOption->Value.b));
    274                           break;
    275                         default:
    276                           break;
    277                       }
    278                       break;
    279                   }
    280 
    281                   if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) {
    282                     ASSERT (Scope > 0);
    283                     Scope--;
    284                     if (Scope == 0) {
    285                       break;
    286                     }
    287                   } else if (IfrOpCodeHeader->Scope != 0) {
    288                     Scope++;
    289                   }
    290                   IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
    291                 }
    292               }
    293             }
    294           default:
    295             break;
    296         }
    297         IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
    298       }
    299       break;
    300     default:
    301       break;
    302   }
    303 }
    304 
    305 /**
    306   Dump Hii Database.
    307 
    308   @param[in] HiiDatabase        Pointer to Hii Database.
    309   @param[in] HiiDatabaseSize    Hii Database size.
    310 
    311 **/
    312 VOID
    313 DumpHiiDatabase (
    314   IN VOID       *HiiDatabase,
    315   IN UINTN      HiiDatabaseSize
    316   )
    317 {
    318   EFI_HII_PACKAGE_LIST_HEADER   *HiiPackageListHeader;
    319   EFI_HII_PACKAGE_HEADER        *HiiPackageHeader;
    320 
    321   DEBUG ((EFI_D_INFO, "HiiDatabaseSize - 0x%x\n", HiiDatabaseSize));
    322   HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) HiiDatabase;
    323 
    324   while ((UINTN) HiiPackageListHeader < ((UINTN) HiiDatabase + HiiDatabaseSize)) {
    325     DEBUG ((EFI_D_INFO, "HiiPackageListHeader->PackageListGuid - %g\n", &HiiPackageListHeader->PackageListGuid));
    326     DEBUG ((EFI_D_INFO, "HiiPackageListHeader->PackageLength   - 0x%x\n", (UINTN)HiiPackageListHeader->PackageLength));
    327     HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *)(HiiPackageListHeader + 1);
    328 
    329     while ((UINTN) HiiPackageHeader < (UINTN) HiiPackageListHeader + HiiPackageListHeader->PackageLength) {
    330 
    331       DumpHiiPackage (HiiPackageHeader);
    332 
    333       HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINTN) HiiPackageHeader + HiiPackageHeader->Length);
    334     }
    335 
    336     HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) ((UINTN) HiiPackageListHeader + HiiPackageListHeader->PackageLength);
    337   }
    338 
    339   return ;
    340 }
    341 #endif
    342 
    343 /**
    344   Allocates a buffer of a certain pool type.
    345 
    346   Allocates the number bytes specified by AllocationSize of a certain pool type and returns a
    347   pointer to the allocated buffer.  If AllocationSize is 0, then a valid buffer of 0 size is
    348   returned.  If there is not enough memory remaining to satisfy the request, then NULL is returned.
    349 
    350   @param  MemoryType            The type of memory to allocate.
    351   @param  AllocationSize        The number of bytes to allocate.
    352 
    353   @return A pointer to the allocated buffer or NULL if allocation fails.
    354 
    355 **/
    356 VOID *
    357 InternalVarCheckAllocatePool (
    358   IN EFI_MEMORY_TYPE  MemoryType,
    359   IN UINTN            AllocationSize
    360   )
    361 {
    362   EFI_STATUS  Status;
    363   VOID        *Memory;
    364 
    365   Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);
    366   if (EFI_ERROR (Status)) {
    367     Memory = NULL;
    368   }
    369   return Memory;
    370 }
    371 
    372 /**
    373   Allocates and zeros a buffer of type EfiBootServicesData.
    374 
    375   Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
    376   buffer with zeros, and returns a pointer to the allocated buffer.  If AllocationSize is 0, then a
    377   valid buffer of 0 size is returned.  If there is not enough memory remaining to satisfy the
    378   request, then NULL is returned.
    379 
    380   @param  AllocationSize        The number of bytes to allocate and zero.
    381 
    382   @return A pointer to the allocated buffer or NULL if allocation fails.
    383 
    384 **/
    385 VOID *
    386 InternalVarCheckAllocateZeroPool (
    387   IN UINTN            AllocationSize
    388   )
    389 {
    390   VOID  *Memory;
    391 
    392   Memory = InternalVarCheckAllocatePool (EfiBootServicesData, AllocationSize);
    393   if (Memory != NULL) {
    394     Memory = ZeroMem (Memory, AllocationSize);
    395   }
    396   return Memory;
    397 }
    398 
    399 /**
    400   Frees a buffer that was previously allocated with one of the pool allocation functions in the
    401   Memory Allocation Library.
    402 
    403   Frees the buffer specified by Buffer.  Buffer must have been allocated on a previous call to the
    404   pool allocation services of the Memory Allocation Library.  If it is not possible to free pool
    405   resources, then this function will perform no actions.
    406 
    407   If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
    408   then ASSERT().
    409 
    410   @param  Buffer                The pointer to the buffer to free.
    411 
    412 **/
    413 VOID
    414 EFIAPI
    415 InternalVarCheckFreePool (
    416   IN VOID   *Buffer
    417   )
    418 {
    419   EFI_STATUS    Status;
    420 
    421   Status = gBS->FreePool (Buffer);
    422   ASSERT_EFI_ERROR (Status);
    423 }
    424 
    425 /**
    426   Reallocates a buffer of type EfiBootServicesData.
    427 
    428   Allocates and zeros the number bytes specified by NewSize from memory of type
    429   EfiBootServicesData.  If OldBuffer is not NULL, then the smaller of OldSize and
    430   NewSize bytes are copied from OldBuffer to the newly allocated buffer, and
    431   OldBuffer is freed.  A pointer to the newly allocated buffer is returned.
    432   If NewSize is 0, then a valid buffer of 0 size is  returned.  If there is not
    433   enough memory remaining to satisfy the request, then NULL is returned.
    434 
    435   If the allocation of the new buffer is successful and the smaller of NewSize and OldSize
    436   is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().
    437 
    438   @param  OldSize        The size, in bytes, of OldBuffer.
    439   @param  NewSize        The size, in bytes, of the buffer to reallocate.
    440   @param  OldBuffer      The buffer to copy to the allocated buffer.  This is an optional
    441                          parameter that may be NULL.
    442 
    443   @return A pointer to the allocated buffer or NULL if allocation fails.
    444 
    445 **/
    446 VOID *
    447 InternalVarCheckReallocatePool (
    448   IN UINTN            OldSize,
    449   IN UINTN            NewSize,
    450   IN VOID             *OldBuffer  OPTIONAL
    451   )
    452 {
    453   VOID  *NewBuffer;
    454 
    455   NewBuffer = InternalVarCheckAllocateZeroPool (NewSize);
    456   if (NewBuffer != NULL && OldBuffer != NULL) {
    457     CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));
    458     InternalVarCheckFreePool (OldBuffer);
    459   }
    460   return NewBuffer;
    461 }
    462 
    463 /**
    464   Merge Hii Question.
    465 
    466   @param[in, out] HiiVariableNode   Pointer to Hii Variable node.
    467   @param[in]      HiiQuestion       Pointer to Hii Question.
    468   @param[in]      FromFv            Hii Question from FV.
    469 
    470 **/
    471 VOID
    472 MergeHiiQuestion (
    473   IN OUT VAR_CHECK_HII_VARIABLE_NODE    *HiiVariableNode,
    474   IN VAR_CHECK_HII_QUESTION_HEADER      *HiiQuestion,
    475   IN BOOLEAN                            FromFv
    476   )
    477 {
    478   VAR_CHECK_HII_QUESTION_HEADER     *HiiQuestion1;
    479   VAR_CHECK_HII_QUESTION_HEADER     *HiiQuestion2;
    480   VAR_CHECK_HII_QUESTION_HEADER     *NewHiiQuestion;
    481   UINT8                             NewLength;
    482   UINT64                            Minimum1;
    483   UINT64                            Maximum1;
    484   UINT64                            OneValue1;
    485   UINT64                            Minimum2;
    486   UINT64                            Maximum2;
    487   UINT64                            OneValue2;
    488   UINT8                             *Ptr;
    489   UINT8                             *Ptr1;
    490   UINT8                             *Ptr2;
    491 
    492   //
    493   // Hii Question from Hii Database has high priority.
    494   // Do not to merge Hii Question from Fv to Hii Question from Hii Database.
    495   //
    496   if (FromFv) {
    497     InternalVarCheckFreePool (HiiQuestion);
    498     return;
    499   }
    500 
    501   HiiQuestion1 = HiiVariableNode->HiiQuestionArray[HiiQuestion->VarOffset];
    502   HiiQuestion2 = HiiQuestion;
    503 
    504   ASSERT ((HiiQuestion1->OpCode == HiiQuestion2->OpCode) && (HiiQuestion1->StorageWidth == HiiQuestion2->StorageWidth));
    505 
    506   switch (HiiQuestion1->OpCode) {
    507     case EFI_IFR_ONE_OF_OP:
    508       DEBUG ((EFI_D_INFO, "MergeHiiQuestion - EFI_IFR_ONE_OF_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset));
    509       //
    510       // Get the length of Hii Question 1.
    511       //
    512       NewLength = HiiQuestion1->Length;
    513 
    514       //
    515       // Check if the one of options in Hii Question 2 have been in Hii Question 1.
    516       //
    517       Ptr2 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion2 + 1);
    518       while ((UINTN) Ptr2 < (UINTN) HiiQuestion2 + HiiQuestion2->Length) {
    519         OneValue2 = 0;
    520         CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
    521 
    522         Ptr1 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion1 + 1);
    523         while ((UINTN) Ptr1 < (UINTN) HiiQuestion1 + HiiQuestion1->Length) {
    524           OneValue1 = 0;
    525           CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
    526           if (OneValue2 == OneValue1) {
    527             //
    528             // Match
    529             //
    530             break;
    531           }
    532           Ptr1 += HiiQuestion1->StorageWidth;
    533         }
    534         if ((UINTN) Ptr1 >= ((UINTN) HiiQuestion1 + HiiQuestion1->Length)) {
    535           //
    536           // No match
    537           //
    538           NewLength = (UINT8) (NewLength + HiiQuestion1->StorageWidth);
    539         }
    540         Ptr2 += HiiQuestion2->StorageWidth;
    541       }
    542 
    543       if (NewLength > HiiQuestion1->Length) {
    544         //
    545         // Merge the one of options of Hii Question 2 and Hii Question 1.
    546         //
    547         NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength);
    548         ASSERT (NewHiiQuestion != NULL);
    549         CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length);
    550         //
    551         // Use the new length.
    552         //
    553         NewHiiQuestion->Length = NewLength;
    554         Ptr = (UINT8 *) NewHiiQuestion + HiiQuestion1->Length;
    555 
    556         Ptr2 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion2 + 1);
    557         while ((UINTN) Ptr2 < (UINTN) HiiQuestion2 + HiiQuestion2->Length) {
    558           OneValue2 = 0;
    559           CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
    560 
    561           Ptr1 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion1 + 1);
    562           while ((UINTN) Ptr1 < (UINTN) HiiQuestion1 + HiiQuestion1->Length) {
    563             OneValue1 = 0;
    564             CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
    565             if (OneValue2 == OneValue1) {
    566               //
    567               // Match
    568               //
    569               break;
    570             }
    571             Ptr1 += HiiQuestion1->StorageWidth;
    572           }
    573           if ((UINTN) Ptr1 >= ((UINTN) HiiQuestion1 + HiiQuestion1->Length)) {
    574             //
    575             // No match
    576             //
    577             CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth);
    578             Ptr += HiiQuestion1->StorageWidth;
    579           }
    580           Ptr2 += HiiQuestion2->StorageWidth;
    581         }
    582 
    583         HiiVariableNode->HiiQuestionArray[HiiQuestion1->VarOffset] = NewHiiQuestion;
    584         InternalVarCheckFreePool (HiiQuestion1);
    585       }
    586       break;
    587 
    588     case EFI_IFR_CHECKBOX_OP:
    589       DEBUG ((EFI_D_INFO, "MergeHiiQuestion - EFI_IFR_CHECKBOX_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset));
    590       break;
    591 
    592     case EFI_IFR_NUMERIC_OP:
    593       DEBUG ((EFI_D_INFO, "MergeHiiQuestion - EFI_IFR_NUMERIC_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset));
    594       //
    595       // Get minimum and maximum of Hii Question 1.
    596       //
    597       Minimum1 = 0;
    598       Maximum1 = 0;
    599       Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_NUMERIC *) HiiQuestion1 + 1);
    600       CopyMem (&Minimum1, Ptr, HiiQuestion1->StorageWidth);
    601       Ptr += HiiQuestion1->StorageWidth;
    602       CopyMem (&Maximum1, Ptr, HiiQuestion1->StorageWidth);
    603 
    604       //
    605       // Get minimum and maximum of Hii Question 2.
    606       //
    607       Minimum2 = 0;
    608       Maximum2 = 0;
    609       Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_NUMERIC *) HiiQuestion2 + 1);
    610       CopyMem (&Minimum2, Ptr, HiiQuestion2->StorageWidth);
    611       Ptr += HiiQuestion2->StorageWidth;
    612       CopyMem (&Maximum2, Ptr, HiiQuestion2->StorageWidth);
    613 
    614       //
    615       // Update minimum.
    616       //
    617       Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_NUMERIC *) HiiQuestion1 + 1);
    618       if (Minimum2 < Minimum1) {
    619         Minimum1 = Minimum2;
    620         CopyMem (Ptr, &Minimum1, HiiQuestion1->StorageWidth);
    621       }
    622       //
    623       // Update maximum.
    624       //
    625       Ptr += HiiQuestion1->StorageWidth;
    626       if (Maximum2 > Maximum1) {
    627         Maximum1 = Maximum2;
    628         CopyMem (Ptr, &Maximum1, HiiQuestion1->StorageWidth);
    629       }
    630       break;
    631 
    632     case EFI_IFR_ORDERED_LIST_OP:
    633       DEBUG ((EFI_D_INFO, "MergeHiiQuestion - EFI_IFR_ORDERED_LIST_OP VarOffset = 0x%04x\n", HiiQuestion1->VarOffset));
    634       //
    635       // Get the length of Hii Question 1.
    636       //
    637       NewLength = HiiQuestion1->Length;
    638 
    639       //
    640       // Check if the one of options in Hii Question 2 have been in Hii Question 1.
    641       //
    642       Ptr2 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion2 + 1);
    643       while ((UINTN) Ptr2 < (UINTN) HiiQuestion2 + HiiQuestion2->Length) {
    644         OneValue2 = 0;
    645         CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
    646 
    647         Ptr1 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion1 + 1);
    648         while ((UINTN) Ptr1 < (UINTN) HiiQuestion1 + HiiQuestion1->Length) {
    649           OneValue1 = 0;
    650           CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
    651           if (OneValue2 == OneValue1) {
    652             //
    653             // Match
    654             //
    655             break;
    656           }
    657           Ptr1 += HiiQuestion1->StorageWidth;
    658         }
    659         if ((UINTN) Ptr1 >= ((UINTN) HiiQuestion1 + HiiQuestion1->Length)) {
    660           //
    661           // No match
    662           //
    663           NewLength = (UINT8) (NewLength + HiiQuestion1->StorageWidth);
    664         }
    665         Ptr2 += HiiQuestion2->StorageWidth;
    666       }
    667 
    668       if (NewLength > HiiQuestion1->Length) {
    669         //
    670         // Merge the one of options of Hii Question 2 and Hii Question 1.
    671         //
    672         NewHiiQuestion = InternalVarCheckAllocateZeroPool (NewLength);
    673         ASSERT (NewHiiQuestion != NULL);
    674         CopyMem (NewHiiQuestion, HiiQuestion1, HiiQuestion1->Length);
    675         //
    676         // Use the new length.
    677         //
    678         NewHiiQuestion->Length = NewLength;
    679         Ptr = (UINT8 *) NewHiiQuestion + HiiQuestion1->Length;
    680 
    681         Ptr2 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion2 + 1);
    682         while ((UINTN) Ptr2 < (UINTN) HiiQuestion2 + HiiQuestion2->Length) {
    683           OneValue2 = 0;
    684           CopyMem (&OneValue2, Ptr2, HiiQuestion2->StorageWidth);
    685 
    686           Ptr1 = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion1 + 1);
    687           while ((UINTN) Ptr1 < (UINTN) HiiQuestion1 + HiiQuestion1->Length) {
    688             OneValue1 = 0;
    689             CopyMem (&OneValue1, Ptr1, HiiQuestion1->StorageWidth);
    690             if (OneValue2 == OneValue1) {
    691               //
    692               // Match
    693               //
    694               break;
    695             }
    696             Ptr1 += HiiQuestion1->StorageWidth;
    697           }
    698           if ((UINTN) Ptr1 >= ((UINTN) HiiQuestion1 + HiiQuestion1->Length)) {
    699             //
    700             // No match
    701             //
    702             CopyMem (Ptr, &OneValue2, HiiQuestion1->StorageWidth);
    703             Ptr += HiiQuestion1->StorageWidth;
    704           }
    705           Ptr2 += HiiQuestion2->StorageWidth;
    706         }
    707 
    708         HiiVariableNode->HiiQuestionArray[HiiQuestion1->VarOffset] = NewHiiQuestion;
    709         InternalVarCheckFreePool (HiiQuestion1);
    710       }
    711       break;
    712 
    713     default:
    714       ASSERT (FALSE);
    715       return;
    716       break;
    717   }
    718 
    719   //
    720   //
    721   // Hii Question 2 has been merged with Hii Question 1.
    722   //
    723   InternalVarCheckFreePool (HiiQuestion2);
    724 }
    725 
    726 /**
    727   Get OneOf option data.
    728 
    729   @param[in]  IfrOpCodeHeader   Pointer to Ifr OpCode header.
    730   @param[out] Count             Pointer to option count.
    731   @param[out] Width             Pointer to option width.
    732   @param[out] OptionBuffer      Pointer to option buffer.
    733 
    734 **/
    735 VOID
    736 GetOneOfOption (
    737   IN  EFI_IFR_OP_HEADER     *IfrOpCodeHeader,
    738   OUT UINTN                 *Count,
    739   OUT UINT8                 *Width,
    740   OUT VOID                  *OptionBuffer OPTIONAL
    741   )
    742 {
    743   UINTN                     Scope;
    744   EFI_IFR_ONE_OF_OPTION     *IfrOneOfOption;
    745 
    746   //
    747   // Assume all OPTION has same Width.
    748   //
    749   *Count = 0;
    750 
    751   if (IfrOpCodeHeader->Scope != 0) {
    752     //
    753     // Nested OpCode.
    754     //
    755     Scope = 1;
    756     IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
    757     while (Scope != 0) {
    758       switch (IfrOpCodeHeader->OpCode) {
    759         case EFI_IFR_ONE_OF_OPTION_OP:
    760           IfrOneOfOption = (EFI_IFR_ONE_OF_OPTION *) IfrOpCodeHeader;
    761           switch (IfrOneOfOption->Type) {
    762             case EFI_IFR_TYPE_NUM_SIZE_8:
    763               *Count = *Count + 1;
    764               *Width = sizeof (UINT8);
    765               if (OptionBuffer != NULL) {
    766                 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u8, sizeof (UINT8));
    767                 OptionBuffer = (UINT8 *) OptionBuffer + 1;
    768               }
    769               break;
    770             case EFI_IFR_TYPE_NUM_SIZE_16:
    771               *Count = *Count + 1;
    772               *Width = sizeof (UINT16);
    773               if (OptionBuffer != NULL) {
    774                 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u16, sizeof (UINT16));
    775                 OptionBuffer = (UINT16 *) OptionBuffer + 1;
    776               }
    777               break;
    778             case EFI_IFR_TYPE_NUM_SIZE_32:
    779               *Count = *Count + 1;
    780               *Width = sizeof (UINT32);
    781               if (OptionBuffer != NULL) {
    782                 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u32, sizeof (UINT32));
    783                 OptionBuffer = (UINT32 *) OptionBuffer + 1;
    784               }
    785               break;
    786             case EFI_IFR_TYPE_NUM_SIZE_64:
    787               *Count = *Count + 1;
    788               *Width = sizeof (UINT64);
    789               if (OptionBuffer != NULL) {
    790                 CopyMem (OptionBuffer, &IfrOneOfOption->Value.u64, sizeof (UINT64));
    791                 OptionBuffer = (UINT64 *) OptionBuffer + 1;
    792               }
    793               break;
    794             case EFI_IFR_TYPE_BOOLEAN:
    795               *Count = *Count + 1;
    796               *Width = sizeof (BOOLEAN);
    797               if (OptionBuffer != NULL) {
    798                 CopyMem (OptionBuffer, &IfrOneOfOption->Value.b, sizeof (BOOLEAN));
    799                 OptionBuffer = (BOOLEAN *) OptionBuffer + 1;
    800               }
    801               break;
    802             default:
    803               break;
    804           }
    805           break;
    806       }
    807 
    808       //
    809       // Until End OpCode.
    810       //
    811       if (IfrOpCodeHeader->OpCode == EFI_IFR_END_OP) {
    812         ASSERT (Scope > 0);
    813         Scope--;
    814         if (Scope == 0) {
    815           break;
    816         }
    817       } else if (IfrOpCodeHeader->Scope != 0) {
    818         //
    819         // Nested OpCode.
    820         //
    821         Scope++;
    822       }
    823       IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
    824     }
    825   }
    826 
    827   return ;
    828 }
    829 
    830 /**
    831   Parse Hii Question Oneof.
    832 
    833   @param[in] IfrOpCodeHeader    Pointer to Ifr OpCode header.
    834 
    835   return Pointer to Hii Question.
    836 
    837 **/
    838 VAR_CHECK_HII_QUESTION_HEADER *
    839 ParseHiiQuestionOneOf (
    840   IN EFI_IFR_OP_HEADER  *IfrOpCodeHeader
    841   )
    842 {
    843   EFI_IFR_ONE_OF                *IfrOneOf;
    844   VAR_CHECK_HII_QUESTION_ONEOF  *OneOf;
    845   UINTN                         Length;
    846   UINT8                         Width;
    847   UINTN                         OptionCount;
    848   UINT8                         OptionWidth;
    849 
    850   IfrOneOf = (EFI_IFR_ONE_OF *) IfrOpCodeHeader;
    851 
    852   Width = (UINT8) (1 << (IfrOneOf->Flags & EFI_IFR_NUMERIC_SIZE));
    853 
    854   GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL);
    855   ASSERT (Width == OptionWidth);
    856 
    857   Length = sizeof (*OneOf) + OptionCount * Width;
    858 
    859   OneOf = InternalVarCheckAllocateZeroPool (Length);
    860   ASSERT (OneOf != NULL);
    861   OneOf->OpCode       = EFI_IFR_ONE_OF_OP;
    862   OneOf->Length       = (UINT8) Length;
    863   OneOf->VarOffset    = IfrOneOf->Question.VarStoreInfo.VarOffset;
    864   OneOf->StorageWidth = Width;
    865 
    866   GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OneOf + 1);
    867 
    868   return (VAR_CHECK_HII_QUESTION_HEADER *) OneOf;
    869 }
    870 
    871 /**
    872   Parse Hii Question CheckBox.
    873 
    874   @param[in] IfrOpCodeHeader    Pointer to Ifr OpCode header.
    875 
    876   return Pointer to Hii Question.
    877 
    878 **/
    879 VAR_CHECK_HII_QUESTION_HEADER *
    880 ParseHiiQuestionCheckBox (
    881   IN EFI_IFR_OP_HEADER  *IfrOpCodeHeader
    882   )
    883 {
    884   EFI_IFR_CHECKBOX                  *IfrCheckBox;
    885   VAR_CHECK_HII_QUESTION_CHECKBOX   *CheckBox;
    886 
    887   IfrCheckBox = (EFI_IFR_CHECKBOX *) IfrOpCodeHeader;
    888 
    889   CheckBox = InternalVarCheckAllocateZeroPool (sizeof (*CheckBox));
    890   ASSERT (CheckBox != NULL);
    891   CheckBox->OpCode       = EFI_IFR_CHECKBOX_OP;
    892   CheckBox->Length       = (UINT8) sizeof (*CheckBox);;
    893   CheckBox->VarOffset    = IfrCheckBox->Question.VarStoreInfo.VarOffset;
    894   CheckBox->StorageWidth = (UINT8) sizeof (BOOLEAN);
    895 
    896   return (VAR_CHECK_HII_QUESTION_HEADER *) CheckBox;
    897 }
    898 
    899 /**
    900   Parse Hii Question Numeric.
    901 
    902   @param[in] IfrOpCodeHeader    Pointer to Ifr OpCode header.
    903 
    904   return Pointer to Hii Question.
    905 
    906 **/
    907 VAR_CHECK_HII_QUESTION_HEADER *
    908 ParseHiiQuestionNumeric (
    909   IN EFI_IFR_OP_HEADER  *IfrOpCodeHeader
    910   )
    911 {
    912   EFI_IFR_NUMERIC                   *IfrNumeric;
    913   VAR_CHECK_HII_QUESTION_NUMERIC    *Numeric;
    914   UINT8                             Width;
    915 
    916   IfrNumeric = (EFI_IFR_NUMERIC *) IfrOpCodeHeader;
    917 
    918   Numeric = InternalVarCheckAllocateZeroPool (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * sizeof (UINT64));
    919   ASSERT (Numeric != NULL);
    920 
    921   Width = (UINT8) (1 << (IfrNumeric->Flags & EFI_IFR_NUMERIC_SIZE));
    922 
    923   Numeric->OpCode       = EFI_IFR_NUMERIC_OP;
    924   Numeric->Length       = (UINT8) (sizeof (VAR_CHECK_HII_QUESTION_NUMERIC) + 2 * Width);
    925   Numeric->VarOffset    = IfrNumeric->Question.VarStoreInfo.VarOffset;
    926   Numeric->StorageWidth = Width;
    927 
    928   CopyMem (Numeric + 1, &IfrNumeric->data, Width * 2);
    929 
    930   return (VAR_CHECK_HII_QUESTION_HEADER *) Numeric;
    931 }
    932 
    933 /**
    934   Parse Hii Question OrderedList.
    935 
    936   @param[in] IfrOpCodeHeader    Pointer to Ifr OpCode header.
    937 
    938   return Pointer to Hii Question.
    939 
    940 **/
    941 VAR_CHECK_HII_QUESTION_HEADER *
    942 ParseHiiQuestionOrderedList (
    943   IN EFI_IFR_OP_HEADER  *IfrOpCodeHeader
    944   )
    945 {
    946   EFI_IFR_ORDERED_LIST                  *IfrOrderedList;
    947   VAR_CHECK_HII_QUESTION_ORDEREDLIST    *OrderedList;
    948   UINTN                                 Length;
    949   UINTN                                 OptionCount;
    950   UINT8                                 OptionWidth;
    951 
    952   IfrOrderedList = (EFI_IFR_ORDERED_LIST *) IfrOpCodeHeader;
    953 
    954   GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, NULL);
    955 
    956   Length = sizeof (*OrderedList) + OptionCount * OptionWidth;
    957 
    958   OrderedList = InternalVarCheckAllocateZeroPool (Length);
    959   ASSERT (OrderedList != NULL);
    960   OrderedList->OpCode        = EFI_IFR_ORDERED_LIST_OP;
    961   OrderedList->Length        = (UINT8) Length;
    962   OrderedList->VarOffset     = IfrOrderedList->Question.VarStoreInfo.VarOffset;
    963   OrderedList->StorageWidth  = OptionWidth;
    964   OrderedList->MaxContainers = IfrOrderedList->MaxContainers;
    965 
    966   GetOneOfOption (IfrOpCodeHeader, &OptionCount, &OptionWidth, OrderedList + 1);
    967 
    968   return (VAR_CHECK_HII_QUESTION_HEADER *) OrderedList;
    969 }
    970 
    971 /**
    972   Parse and create Hii Question node.
    973 
    974   @param[in] HiiVariableNode    Pointer to Hii Variable node.
    975   @param[in] IfrOpCodeHeader    Pointer to Ifr OpCode header.
    976   @param[in] FromFv             Hii Question from FV.
    977 
    978 **/
    979 VOID
    980 ParseHiiQuestion (
    981   IN VAR_CHECK_HII_VARIABLE_NODE    *HiiVariableNode,
    982   IN  EFI_IFR_OP_HEADER             *IfrOpCodeHeader,
    983   IN BOOLEAN                        FromFv
    984   )
    985 {
    986   VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
    987 
    988   switch (IfrOpCodeHeader->OpCode) {
    989     case EFI_IFR_ONE_OF_OP:
    990       HiiQuestion = ParseHiiQuestionOneOf (IfrOpCodeHeader);
    991       break;
    992 
    993     case EFI_IFR_CHECKBOX_OP:
    994       HiiQuestion = ParseHiiQuestionCheckBox (IfrOpCodeHeader);
    995       break;
    996 
    997     case EFI_IFR_NUMERIC_OP:
    998       HiiQuestion = ParseHiiQuestionNumeric (IfrOpCodeHeader);
    999       break;
   1000 
   1001     case EFI_IFR_ORDERED_LIST_OP:
   1002       HiiQuestion = ParseHiiQuestionOrderedList (IfrOpCodeHeader);
   1003       break;
   1004 
   1005     default:
   1006       ASSERT (FALSE);
   1007       return;
   1008       break;
   1009   }
   1010 
   1011   if (HiiVariableNode->HiiQuestionArray[HiiQuestion->VarOffset] != NULL) {
   1012     MergeHiiQuestion (HiiVariableNode, HiiQuestion, FromFv);
   1013   } else {
   1014     HiiVariableNode->HiiQuestionArray[HiiQuestion->VarOffset] = HiiQuestion;
   1015   }
   1016 }
   1017 
   1018 /**
   1019   Find Hii variable node by name and GUID.
   1020 
   1021   @param[in] Name   Pointer to variable name.
   1022   @param[in] Guid   Pointer to vendor GUID.
   1023 
   1024   @return Pointer to Hii Variable node.
   1025 
   1026 **/
   1027 VAR_CHECK_HII_VARIABLE_NODE *
   1028 FindHiiVariableNode (
   1029   IN CHAR16     *Name,
   1030   IN EFI_GUID   *Guid
   1031   )
   1032 {
   1033   VAR_CHECK_HII_VARIABLE_NODE   *HiiVariableNode;
   1034   LIST_ENTRY                    *Link;
   1035 
   1036   for (Link = mVarCheckHiiList.ForwardLink
   1037       ;Link != &mVarCheckHiiList
   1038       ;Link = Link->ForwardLink) {
   1039     HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
   1040 
   1041     if ((StrCmp (Name, (CHAR16 *) (HiiVariableNode->HiiVariable + 1)) == 0) &&
   1042         CompareGuid (Guid, &HiiVariableNode->HiiVariable->Guid)) {
   1043       return HiiVariableNode;
   1044     }
   1045   }
   1046 
   1047   return NULL;
   1048 }
   1049 
   1050 /**
   1051   Find Hii variable node by var store id.
   1052 
   1053   @param[in] VarStoreId         Var store id.
   1054 
   1055   @return Pointer to Hii Variable node.
   1056 
   1057 **/
   1058 VAR_CHECK_HII_VARIABLE_NODE *
   1059 FindHiiVariableNodeByVarStoreId (
   1060   IN EFI_VARSTORE_ID            VarStoreId
   1061   )
   1062 {
   1063   VAR_CHECK_HII_VARIABLE_NODE   *HiiVariableNode;
   1064   LIST_ENTRY                    *Link;
   1065 
   1066   if (VarStoreId == 0) {
   1067     //
   1068     // The variable store identifier, which is unique within the current form set.
   1069     // A value of zero is invalid.
   1070     //
   1071     return NULL;
   1072   }
   1073 
   1074   for (Link = mVarCheckHiiList.ForwardLink
   1075       ;Link != &mVarCheckHiiList
   1076       ;Link = Link->ForwardLink) {
   1077     HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
   1078     //
   1079     // The variable store identifier, which is unique within the current form set.
   1080     //
   1081     if (VarStoreId == HiiVariableNode->VarStoreId) {
   1082       return HiiVariableNode;
   1083     }
   1084   }
   1085 
   1086   return NULL;
   1087 }
   1088 
   1089 /**
   1090   Destroy var store id in the Hii Variable node after parsing one Hii Package.
   1091 
   1092 **/
   1093 VOID
   1094 DestroyVarStoreId (
   1095   VOID
   1096   )
   1097 {
   1098   VAR_CHECK_HII_VARIABLE_NODE   *HiiVariableNode;
   1099   LIST_ENTRY                    *Link;
   1100 
   1101   for (Link = mVarCheckHiiList.ForwardLink
   1102       ;Link != &mVarCheckHiiList
   1103       ;Link = Link->ForwardLink) {
   1104     HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (Link);
   1105     //
   1106     // The variable store identifier, which is unique within the current form set.
   1107     // A value of zero is invalid.
   1108     //
   1109     HiiVariableNode->VarStoreId = 0;
   1110   }
   1111 }
   1112 
   1113 /**
   1114   Create Hii Variable node.
   1115 
   1116   @param[in] IfrEfiVarStore  Pointer to EFI VARSTORE.
   1117 
   1118 **/
   1119 VOID
   1120 CreateHiiVariableNode (
   1121   IN EFI_IFR_VARSTORE_EFI   *IfrEfiVarStore
   1122   )
   1123 {
   1124   VAR_CHECK_HII_VARIABLE_NODE   *HiiVariableNode;
   1125   VAR_CHECK_HII_VARIABLE_HEADER *HiiVariable;
   1126   UINTN                         HeaderLength;
   1127   CHAR16                        *VarName;
   1128   UINTN                         VarNameSize;
   1129 
   1130   //
   1131   // Get variable name.
   1132   //
   1133   VarNameSize = AsciiStrSize ((CHAR8 *) IfrEfiVarStore->Name) * sizeof (CHAR16);
   1134   if (VarNameSize > mMaxVarNameSize) {
   1135     mVarName = InternalVarCheckReallocatePool (mMaxVarNameSize, VarNameSize, mVarName);
   1136     ASSERT (mVarName != NULL);
   1137     mMaxVarNameSize = VarNameSize;
   1138   }
   1139   AsciiStrToUnicodeStrS ((CHAR8 *) IfrEfiVarStore->Name, mVarName, mMaxVarNameSize / sizeof (CHAR16));
   1140   VarName = mVarName;
   1141 
   1142   HiiVariableNode = FindHiiVariableNode (
   1143                       VarName,
   1144                       &IfrEfiVarStore->Guid
   1145                       );
   1146   if (HiiVariableNode == NULL) {
   1147     //
   1148     // Not found, then create new.
   1149     //
   1150     HeaderLength = sizeof (*HiiVariable) + VarNameSize;
   1151     HiiVariable = InternalVarCheckAllocateZeroPool (HeaderLength);
   1152     ASSERT (HiiVariable != NULL);
   1153     HiiVariable->Revision = VAR_CHECK_HII_REVISION;
   1154     HiiVariable->OpCode = EFI_IFR_VARSTORE_EFI_OP;
   1155     HiiVariable->HeaderLength = (UINT16) HeaderLength;
   1156     HiiVariable->Size = IfrEfiVarStore->Size;
   1157     HiiVariable->Attributes = IfrEfiVarStore->Attributes;
   1158     CopyGuid (&HiiVariable->Guid, &IfrEfiVarStore->Guid);
   1159     StrCpyS ((CHAR16 *) (HiiVariable + 1), VarNameSize / sizeof (CHAR16), VarName);
   1160 
   1161     HiiVariableNode = InternalVarCheckAllocateZeroPool (sizeof (*HiiVariableNode));
   1162     ASSERT (HiiVariableNode != NULL);
   1163     HiiVariableNode->Signature = VAR_CHECK_HII_VARIABLE_NODE_SIGNATURE;
   1164     HiiVariableNode->HiiVariable = HiiVariable;
   1165     //
   1166     // The variable store identifier, which is unique within the current form set.
   1167     //
   1168     HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId;
   1169     HiiVariableNode->HiiQuestionArray = InternalVarCheckAllocateZeroPool (IfrEfiVarStore->Size * sizeof (VAR_CHECK_HII_QUESTION_HEADER *));
   1170 
   1171     InsertTailList (&mVarCheckHiiList, &HiiVariableNode->Link);
   1172   } else {
   1173     HiiVariableNode->VarStoreId = IfrEfiVarStore->VarStoreId;
   1174   }
   1175 }
   1176 
   1177 /**
   1178   Parse and create Hii Variable node list.
   1179 
   1180   @param[in] HiiPackage         Pointer to Hii Package.
   1181 
   1182 **/
   1183 VOID
   1184 ParseHiiVariable (
   1185   IN VOID       *HiiPackage
   1186   )
   1187 {
   1188   EFI_HII_PACKAGE_HEADER    *HiiPackageHeader;
   1189   EFI_IFR_OP_HEADER         *IfrOpCodeHeader;
   1190   EFI_IFR_VARSTORE_EFI      *IfrEfiVarStore;
   1191 
   1192   HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiPackage;
   1193 
   1194   switch (HiiPackageHeader->Type) {
   1195     case EFI_HII_PACKAGE_FORMS:
   1196       IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) (HiiPackageHeader + 1);
   1197 
   1198       while ((UINTN) IfrOpCodeHeader < (UINTN) HiiPackageHeader + HiiPackageHeader->Length) {
   1199         switch (IfrOpCodeHeader->OpCode) {
   1200           case EFI_IFR_VARSTORE_EFI_OP:
   1201             //
   1202             // Come to EFI VARSTORE in Form Package.
   1203             //
   1204             IfrEfiVarStore = (EFI_IFR_VARSTORE_EFI *) IfrOpCodeHeader;
   1205             if ((IfrEfiVarStore->Header.Length >= sizeof (EFI_IFR_VARSTORE_EFI)) &&
   1206                 ((IfrEfiVarStore->Attributes & EFI_VARIABLE_NON_VOLATILE) != 0)) {
   1207               //
   1208               // Only create node list for Hii Variable with NV attribute.
   1209               //
   1210               CreateHiiVariableNode (IfrEfiVarStore);
   1211             }
   1212             break;
   1213 
   1214           default:
   1215             break;
   1216         }
   1217       IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
   1218       }
   1219       break;
   1220 
   1221     default:
   1222       break;
   1223   }
   1224 }
   1225 
   1226 /**
   1227   Var Check Parse Hii Package.
   1228 
   1229   @param[in] HiiPackage         Pointer to Hii Package.
   1230   @param[in] FromFv             Hii Package from FV.
   1231 
   1232 **/
   1233 VOID
   1234 VarCheckParseHiiPackage (
   1235   IN VOID       *HiiPackage,
   1236   IN BOOLEAN    FromFv
   1237   )
   1238 {
   1239   EFI_HII_PACKAGE_HEADER        *HiiPackageHeader;
   1240   EFI_IFR_OP_HEADER             *IfrOpCodeHeader;
   1241   VAR_CHECK_HII_VARIABLE_NODE   *HiiVariableNode;
   1242 
   1243   //
   1244   // Parse and create Hii Variable node list for this Hii Package.
   1245   //
   1246   ParseHiiVariable (HiiPackage);
   1247 
   1248   HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) HiiPackage;
   1249 
   1250   switch (HiiPackageHeader->Type) {
   1251     case EFI_HII_PACKAGE_FORMS:
   1252       IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) (HiiPackageHeader + 1);
   1253 
   1254       while ((UINTN) IfrOpCodeHeader < (UINTN) HiiPackageHeader + HiiPackageHeader->Length) {
   1255         switch (IfrOpCodeHeader->OpCode) {
   1256           case EFI_IFR_ONE_OF_OP:
   1257           case EFI_IFR_CHECKBOX_OP:
   1258           case EFI_IFR_NUMERIC_OP:
   1259           case EFI_IFR_ORDERED_LIST_OP:
   1260             HiiVariableNode = FindHiiVariableNodeByVarStoreId (((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.VarStoreId);
   1261             if ((HiiVariableNode == NULL) ||
   1262                 //
   1263                 // No related Hii Variable node found.
   1264                 //
   1265                 ((((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.Header.Prompt == 0) && (((EFI_IFR_ONE_OF *) IfrOpCodeHeader)->Question.Header.Help == 0))) {
   1266                 //
   1267                 // meanless IFR item introduced by ECP.
   1268                 //
   1269             } else {
   1270               //
   1271               // Normal IFR
   1272               //
   1273               ParseHiiQuestion (HiiVariableNode, IfrOpCodeHeader, FromFv);
   1274             }
   1275           default:
   1276             break;
   1277         }
   1278         IfrOpCodeHeader = (EFI_IFR_OP_HEADER *) ((UINTN) IfrOpCodeHeader + IfrOpCodeHeader->Length);
   1279       }
   1280       break;
   1281 
   1282     default:
   1283       break;
   1284   }
   1285   DestroyVarStoreId ();
   1286 }
   1287 
   1288 /**
   1289   Var Check Parse Hii Database.
   1290 
   1291   @param[in] HiiDatabase        Pointer to Hii Database.
   1292   @param[in] HiiDatabaseSize    Hii Database size.
   1293 
   1294 **/
   1295 VOID
   1296 VarCheckParseHiiDatabase (
   1297   IN VOID       *HiiDatabase,
   1298   IN UINTN      HiiDatabaseSize
   1299   )
   1300 {
   1301   EFI_HII_PACKAGE_LIST_HEADER   *HiiPackageListHeader;
   1302   EFI_HII_PACKAGE_HEADER        *HiiPackageHeader;
   1303 
   1304   HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) HiiDatabase;
   1305 
   1306   while ((UINTN) HiiPackageListHeader < ((UINTN) HiiDatabase + HiiDatabaseSize)) {
   1307     HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) (HiiPackageListHeader + 1);
   1308 
   1309     while ((UINTN) HiiPackageHeader < ((UINTN) HiiPackageListHeader + HiiPackageListHeader->PackageLength)) {
   1310       //
   1311       // Parse Hii Package.
   1312       //
   1313       VarCheckParseHiiPackage (HiiPackageHeader, FALSE);
   1314 
   1315       HiiPackageHeader = (EFI_HII_PACKAGE_HEADER *) ((UINTN) HiiPackageHeader + HiiPackageHeader->Length);
   1316     }
   1317 
   1318     HiiPackageListHeader = (EFI_HII_PACKAGE_LIST_HEADER *) ((UINTN) HiiPackageListHeader + HiiPackageListHeader->PackageLength);
   1319   }
   1320 }
   1321 
   1322 /**
   1323   Destroy Hii Variable node.
   1324 
   1325 **/
   1326 VOID
   1327 DestroyHiiVariableNode (
   1328   VOID
   1329   )
   1330 {
   1331   VAR_CHECK_HII_VARIABLE_NODE   *HiiVariableNode;
   1332   LIST_ENTRY                    *HiiVariableLink;
   1333   UINTN                         Index;
   1334 
   1335   while (mVarCheckHiiList.ForwardLink != &mVarCheckHiiList) {
   1336     HiiVariableLink = mVarCheckHiiList.ForwardLink;
   1337     HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
   1338 
   1339     RemoveEntryList (&HiiVariableNode->Link);
   1340 
   1341     //
   1342     // Free the allocated buffer.
   1343     //
   1344     for (Index = 0; Index < HiiVariableNode->HiiVariable->Size; Index++) {
   1345       if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
   1346         InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray[Index]);
   1347       }
   1348     }
   1349     InternalVarCheckFreePool (HiiVariableNode->HiiQuestionArray);
   1350     InternalVarCheckFreePool (HiiVariableNode->HiiVariable);
   1351     InternalVarCheckFreePool (HiiVariableNode);
   1352   }
   1353 }
   1354 
   1355 /**
   1356   Build VarCheckHiiBin.
   1357 
   1358   @param[out] Size      Pointer to VarCheckHii size.
   1359 
   1360   @return Pointer to VarCheckHiiBin.
   1361 
   1362 **/
   1363 VOID *
   1364 BuildVarCheckHiiBin (
   1365   OUT UINTN  *Size
   1366   )
   1367 {
   1368   VAR_CHECK_HII_VARIABLE_NODE   *HiiVariableNode;
   1369   LIST_ENTRY                    *HiiVariableLink;
   1370   UINTN                         Index;
   1371   VOID                          *Data;
   1372   UINT8                         *Ptr;
   1373   UINT32                        BinSize;
   1374   UINT32                        HiiVariableLength;
   1375 
   1376   //
   1377   // Get Size
   1378   //
   1379   BinSize = 0;
   1380 
   1381   for (HiiVariableLink = mVarCheckHiiList.ForwardLink
   1382       ;HiiVariableLink != &mVarCheckHiiList
   1383       ;HiiVariableLink = HiiVariableLink->ForwardLink) {
   1384     //
   1385     // For Hii Variable header align.
   1386     //
   1387     BinSize = (UINT32) HEADER_ALIGN (BinSize);
   1388 
   1389     HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
   1390     HiiVariableLength = HiiVariableNode->HiiVariable->HeaderLength;
   1391 
   1392     for (Index = 0; Index < HiiVariableNode->HiiVariable->Size; Index++) {
   1393       if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
   1394         //
   1395         // For Hii Question header align.
   1396         //
   1397         HiiVariableLength = (UINT32) HEADER_ALIGN (HiiVariableLength);
   1398         HiiVariableLength += HiiVariableNode->HiiQuestionArray[Index]->Length;
   1399       }
   1400     }
   1401 
   1402     HiiVariableNode->HiiVariable->Length = HiiVariableLength;
   1403     BinSize += HiiVariableLength;
   1404   }
   1405 
   1406   DEBUG ((EFI_D_INFO, "VarCheckHiiBin - size = 0x%x\n", BinSize));
   1407   if (BinSize == 0) {
   1408     *Size = BinSize;
   1409     return NULL;
   1410   }
   1411 
   1412   //
   1413   // AllocatePages () and AllocatePool () from gBS are used for the process of VarCheckHiiBin generation.
   1414   // Only here AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
   1415   // in SetVariable check handler.
   1416   //
   1417   Data = AllocateRuntimeZeroPool (BinSize);
   1418   ASSERT (Data != NULL);
   1419   DEBUG ((EFI_D_INFO, "VarCheckHiiBin - built at 0x%x\n", Data));
   1420 
   1421   //
   1422   // Gen Data
   1423   //
   1424   Ptr = Data;
   1425   for (HiiVariableLink = mVarCheckHiiList.ForwardLink
   1426       ;HiiVariableLink != &mVarCheckHiiList
   1427       ;HiiVariableLink = HiiVariableLink->ForwardLink) {
   1428     //
   1429     // For Hii Variable header align.
   1430     //
   1431     Ptr = (UINT8 *) HEADER_ALIGN (Ptr);
   1432 
   1433     HiiVariableNode = VAR_CHECK_HII_VARIABLE_FROM_LINK (HiiVariableLink);
   1434     CopyMem (Ptr, HiiVariableNode->HiiVariable, HiiVariableNode->HiiVariable->HeaderLength);
   1435     Ptr += HiiVariableNode->HiiVariable->HeaderLength;
   1436 
   1437     for (Index = 0; Index < HiiVariableNode->HiiVariable->Size; Index++) {
   1438       if (HiiVariableNode->HiiQuestionArray[Index] != NULL) {
   1439         //
   1440         // For Hii Question header align.
   1441         //
   1442         Ptr = (UINT8 *) HEADER_ALIGN (Ptr);
   1443         CopyMem (Ptr, HiiVariableNode->HiiQuestionArray[Index], HiiVariableNode->HiiQuestionArray[Index]->Length);
   1444         Ptr += HiiVariableNode->HiiQuestionArray[Index]->Length;
   1445       }
   1446     }
   1447   }
   1448 
   1449   *Size = BinSize;
   1450   return Data;
   1451 }
   1452 
   1453 /**
   1454   Generate VarCheckHiiBin from Hii Database and FV.
   1455 
   1456 **/
   1457 VOID
   1458 EFIAPI
   1459 VarCheckHiiGen (
   1460   VOID
   1461   )
   1462 {
   1463   VarCheckHiiGenFromHiiDatabase ();
   1464   VarCheckHiiGenFromFv ();
   1465 
   1466   mVarCheckHiiBin = BuildVarCheckHiiBin (&mVarCheckHiiBinSize);
   1467   if (mVarCheckHiiBin == NULL) {
   1468     DEBUG ((EFI_D_INFO, "[VarCheckHii] This driver could be removed from *.dsc and *.fdf\n"));
   1469     return;
   1470   }
   1471 
   1472   DestroyHiiVariableNode ();
   1473   if (mVarName != NULL) {
   1474     InternalVarCheckFreePool (mVarName);
   1475   }
   1476 
   1477 #ifdef DUMP_VAR_CHECK_HII
   1478   DEBUG_CODE (
   1479     DumpVarCheckHii (mVarCheckHiiBin, mVarCheckHiiBinSize);
   1480   );
   1481 #endif
   1482 }
   1483 
   1484