Home | History | Annotate | Download | only in VarCheckHiiLib
      1 /** @file
      2   Var Check Hii handler.
      3 
      4 Copyright (c) 2015, 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 "VarCheckHii.h"
     16 
     17 GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckHiiHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
     18 
     19 /**
     20   Dump some hexadecimal data.
     21 
     22   @param[in] Indent     How many spaces to indent the output.
     23   @param[in] Offset     The offset of the dump.
     24   @param[in] DataSize   The size in bytes of UserData.
     25   @param[in] UserData   The data to dump.
     26 
     27 **/
     28 VOID
     29 VarCheckHiiInternalDumpHex (
     30   IN UINTN        Indent,
     31   IN UINTN        Offset,
     32   IN UINTN        DataSize,
     33   IN VOID         *UserData
     34   )
     35 {
     36   UINT8 *Data;
     37 
     38   CHAR8 Val[50];
     39 
     40   CHAR8 Str[20];
     41 
     42   UINT8 TempByte;
     43   UINTN Size;
     44   UINTN Index;
     45 
     46   Data = UserData;
     47   while (DataSize != 0) {
     48     Size = 16;
     49     if (Size > DataSize) {
     50       Size = DataSize;
     51     }
     52 
     53     for (Index = 0; Index < Size; Index += 1) {
     54       TempByte            = Data[Index];
     55       Val[Index * 3 + 0]  = mVarCheckHiiHex[TempByte >> 4];
     56       Val[Index * 3 + 1]  = mVarCheckHiiHex[TempByte & 0xF];
     57       Val[Index * 3 + 2]  = (CHAR8) ((Index == 7) ? '-' : ' ');
     58       Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
     59     }
     60 
     61     Val[Index * 3]  = 0;
     62     Str[Index]      = 0;
     63     DEBUG ((EFI_D_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
     64 
     65     Data += Size;
     66     Offset += Size;
     67     DataSize -= Size;
     68   }
     69 }
     70 
     71 /**
     72   Var Check Hii Question.
     73 
     74   @param[in] HiiQuestion    Pointer to Hii Question
     75   @param[in] Data           Data pointer.
     76   @param[in] DataSize       Size of Data to set.
     77 
     78   @retval TRUE  Check pass
     79   @retval FALSE Check fail.
     80 
     81 **/
     82 BOOLEAN
     83 VarCheckHiiQuestion (
     84   IN VAR_CHECK_HII_QUESTION_HEADER  *HiiQuestion,
     85   IN VOID                           *Data,
     86   IN UINTN                          DataSize
     87   )
     88 {
     89   UINT64   OneData;
     90   UINT64   Minimum;
     91   UINT64   Maximum;
     92   UINT64   OneValue;
     93   UINT8    *Ptr;
     94   UINT8    Index;
     95   UINT8    MaxContainers;
     96 
     97   if ((UINTN) (HiiQuestion->VarOffset + HiiQuestion->StorageWidth) > DataSize) {
     98     DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, DataSize));
     99     return FALSE;
    100   }
    101 
    102   OneData = 0;
    103   CopyMem (&OneData, (UINT8 *) Data + HiiQuestion->VarOffset, HiiQuestion->StorageWidth);
    104 
    105   switch (HiiQuestion->OpCode) {
    106     case EFI_IFR_ONE_OF_OP:
    107       Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion + 1);
    108       while ((UINTN) Ptr < (UINTN) HiiQuestion + HiiQuestion->Length) {
    109         OneValue = 0;
    110         CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
    111         if (OneData == OneValue) {
    112           //
    113           // Match
    114           //
    115           break;
    116         }
    117         Ptr += HiiQuestion->StorageWidth;
    118       }
    119       if ((UINTN) Ptr >= ((UINTN) HiiQuestion + HiiQuestion->Length)) {
    120         //
    121         // No match
    122         //
    123         DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: OneOf mismatch (0x%lx)\n", OneData));
    124         DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *) HiiQuestion););
    125         return FALSE;
    126       }
    127       break;
    128 
    129     case EFI_IFR_CHECKBOX_OP:
    130       if ((OneData != 0) && (OneData != 1)) {
    131         DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: CheckBox mismatch (0x%lx)\n", OneData));
    132         DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *) HiiQuestion););
    133         return FALSE;
    134       }
    135       break;
    136 
    137     case EFI_IFR_NUMERIC_OP:
    138       Minimum = 0;
    139       Maximum = 0;
    140       Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_NUMERIC *) HiiQuestion + 1);
    141       CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
    142       Ptr += HiiQuestion->StorageWidth;
    143       CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
    144       Ptr += HiiQuestion->StorageWidth;
    145 
    146       //
    147       // No need to check Step, because it is ONLY for UI.
    148       //
    149       if ((OneData < Minimum) || (OneData > Maximum)) {
    150         DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: Numeric mismatch (0x%lx)\n", OneData));
    151         DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *) HiiQuestion););
    152         return FALSE;
    153       }
    154       break;
    155 
    156     case EFI_IFR_ORDERED_LIST_OP:
    157       MaxContainers = ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion)->MaxContainers;
    158       if ((UINTN) (HiiQuestion->VarOffset + HiiQuestion->StorageWidth * MaxContainers) > DataSize) {
    159         DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: (VarOffset(0x%04x) + StorageWidth(0x%02x) * MaxContainers(0x%02x)) > Size(0x%x)\n", HiiQuestion->VarOffset, HiiQuestion->StorageWidth, MaxContainers, DataSize));
    160         return FALSE;
    161       }
    162       for (Index = 0; Index < MaxContainers; Index++) {
    163         OneData = 0;
    164         CopyMem (&OneData, (UINT8 *) Data + HiiQuestion->VarOffset + HiiQuestion->StorageWidth * Index, HiiQuestion->StorageWidth);
    165         if (OneData == 0) {
    166           //
    167           // The value of 0 is used to determine if a particular "slot" in the array is empty.
    168           //
    169           continue;
    170         }
    171 
    172         Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion + 1);
    173         while ((UINTN) Ptr < ((UINTN) HiiQuestion + HiiQuestion->Length)) {
    174           OneValue = 0;
    175           CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
    176           if (OneData == OneValue) {
    177             //
    178             // Match
    179             //
    180             break;
    181           }
    182           Ptr += HiiQuestion->StorageWidth;
    183         }
    184         if ((UINTN) Ptr >= ((UINTN) HiiQuestion + HiiQuestion->Length)) {
    185           //
    186           // No match
    187           //
    188           DEBUG ((EFI_D_INFO, "VarCheckHiiQuestion fail: OrderedList mismatch\n"));
    189           DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->StorageWidth * MaxContainers, (UINT8 *) Data + HiiQuestion->VarOffset););
    190           DEBUG_CODE (VarCheckHiiInternalDumpHex (2, 0, HiiQuestion->Length, (UINT8 *) HiiQuestion););
    191           return FALSE;
    192         }
    193       }
    194       break;
    195 
    196     default:
    197       ASSERT (FALSE);
    198       break;
    199   }
    200 
    201   return TRUE;
    202 }
    203 
    204 VAR_CHECK_HII_VARIABLE_HEADER   *mVarCheckHiiBin = NULL;
    205 UINTN                           mVarCheckHiiBinSize = 0;
    206 
    207 /**
    208   SetVariable check handler HII.
    209 
    210   @param[in] VariableName       Name of Variable to set.
    211   @param[in] VendorGuid         Variable vendor GUID.
    212   @param[in] Attributes         Attribute value of the variable.
    213   @param[in] DataSize           Size of Data to set.
    214   @param[in] Data               Data pointer.
    215 
    216   @retval EFI_SUCCESS               The SetVariable check result was success.
    217   @retval EFI_SECURITY_VIOLATION    Check fail.
    218 
    219 **/
    220 EFI_STATUS
    221 EFIAPI
    222 SetVariableCheckHandlerHii (
    223   IN CHAR16     *VariableName,
    224   IN EFI_GUID   *VendorGuid,
    225   IN UINT32     Attributes,
    226   IN UINTN      DataSize,
    227   IN VOID       *Data
    228   )
    229 {
    230   VAR_CHECK_HII_VARIABLE_HEADER     *HiiVariable;
    231   VAR_CHECK_HII_QUESTION_HEADER     *HiiQuestion;
    232 
    233   if (mVarCheckHiiBin == NULL) {
    234     return EFI_SUCCESS;
    235   }
    236 
    237   if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
    238     //
    239     // Do not check delete variable.
    240     //
    241     return EFI_SUCCESS;
    242   }
    243 
    244   //
    245   // For Hii Variable header align.
    246   //
    247   HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *) HEADER_ALIGN (mVarCheckHiiBin);
    248   while ((UINTN) HiiVariable < ((UINTN) mVarCheckHiiBin + mVarCheckHiiBinSize)) {
    249     if ((StrCmp ((CHAR16 *) (HiiVariable + 1), VariableName) == 0) &&
    250         (CompareGuid (&HiiVariable->Guid, VendorGuid))) {
    251       //
    252       // Found the Hii Variable that could be used to do check.
    253       //
    254       DEBUG ((EFI_D_INFO, "VarCheckHiiVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
    255       if (HiiVariable->Attributes != Attributes) {
    256         DEBUG ((EFI_D_INFO, "VarCheckHiiVariable fail for Attributes - 0x%08x\n", HiiVariable->Attributes));
    257         return EFI_SECURITY_VIOLATION;
    258       }
    259 
    260       if (DataSize == 0) {
    261         DEBUG ((EFI_D_INFO, "VarCheckHiiVariable - CHECK PASS with DataSize == 0 !\n"));
    262         return EFI_SUCCESS;
    263       }
    264 
    265       if (HiiVariable->Size != DataSize) {
    266         DEBUG ((EFI_D_INFO, "VarCheckHiiVariable fail for Size - 0x%x\n", HiiVariable->Size));
    267         return EFI_SECURITY_VIOLATION;
    268       }
    269 
    270       //
    271       // Do the check.
    272       // For Hii Question header align.
    273       //
    274       HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *) HEADER_ALIGN (((UINTN) HiiVariable + HiiVariable->HeaderLength));
    275       while ((UINTN) HiiQuestion < ((UINTN) HiiVariable + HiiVariable->Length)) {
    276         if (!VarCheckHiiQuestion (HiiQuestion, Data, DataSize)) {
    277           return EFI_SECURITY_VIOLATION;
    278         }
    279         //
    280         // For Hii Question header align.
    281         //
    282         HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *) HEADER_ALIGN (((UINTN) HiiQuestion + HiiQuestion->Length));
    283       }
    284 
    285       DEBUG ((EFI_D_INFO, "VarCheckHiiVariable - ALL CHECK PASS!\n"));
    286       return EFI_SUCCESS;
    287     }
    288     //
    289     // For Hii Variable header align.
    290     //
    291     HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) HiiVariable + HiiVariable->Length));
    292   }
    293 
    294   // Not found, so pass.
    295   return EFI_SUCCESS;
    296 }
    297 
    298 #ifdef DUMP_VAR_CHECK_HII
    299 GLOBAL_REMOVE_IF_UNREFERENCED VAR_CHECK_HII_OPCODE_STRING   mHiiOpCodeStringTable[] = {
    300   {EFI_IFR_VARSTORE_EFI_OP,     "EfiVarStore"},
    301   {EFI_IFR_ONE_OF_OP,           "OneOf"},
    302   {EFI_IFR_CHECKBOX_OP,         "CheckBox"},
    303   {EFI_IFR_NUMERIC_OP,          "Numeric"},
    304   {EFI_IFR_ORDERED_LIST_OP,     "OrderedList"},
    305 };
    306 
    307 /**
    308   HII opcode to string.
    309 
    310   @param[in] HiiOpCode  Hii OpCode.
    311 
    312   @return Pointer to string.
    313 
    314 **/
    315 CHAR8 *
    316 HiiOpCodeToStr (
    317   IN UINT8  HiiOpCode
    318   )
    319 {
    320   UINTN     Index;
    321   for (Index = 0; Index < sizeof (mHiiOpCodeStringTable) / sizeof (mHiiOpCodeStringTable[0]); Index++) {
    322     if (mHiiOpCodeStringTable[Index].HiiOpCode == HiiOpCode) {
    323       return mHiiOpCodeStringTable[Index].HiiOpCodeStr;
    324     }
    325   }
    326 
    327   return "<UnknownHiiOpCode>";
    328 }
    329 
    330 /**
    331   Dump Hii Question.
    332 
    333   @param[in] HiiQuestion    Pointer to Hii Question.
    334 
    335 **/
    336 VOID
    337 DumpHiiQuestion (
    338   IN VAR_CHECK_HII_QUESTION_HEADER  *HiiQuestion
    339   )
    340 {
    341   UINT64    Minimum;
    342   UINT64    Maximum;
    343   UINT64    OneValue;
    344   UINT8     *Ptr;
    345 
    346   DEBUG ((EFI_D_INFO, "  VAR_CHECK_HII_QUESTION_HEADER\n"));
    347   DEBUG ((EFI_D_INFO, "    OpCode        - 0x%02x (%a)\n", HiiQuestion->OpCode, HiiOpCodeToStr (HiiQuestion->OpCode)));
    348   DEBUG ((EFI_D_INFO, "    Length        - 0x%02x\n", HiiQuestion->Length));
    349   DEBUG ((EFI_D_INFO, "    VarOffset     - 0x%04x\n", HiiQuestion->VarOffset));
    350   DEBUG ((EFI_D_INFO, "    StorageWidth  - 0x%02x\n", HiiQuestion->StorageWidth));
    351 
    352   switch (HiiQuestion->OpCode) {
    353     case EFI_IFR_ONE_OF_OP:
    354       Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ONEOF *) HiiQuestion + 1);
    355       while ((UINTN) Ptr < ((UINTN) HiiQuestion + HiiQuestion->Length)) {
    356         OneValue = 0;
    357         CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
    358         switch (HiiQuestion->StorageWidth) {
    359           case sizeof (UINT8):
    360             DEBUG ((EFI_D_INFO, "    OneOfOption   - 0x%02x\n", OneValue));
    361             break;
    362           case sizeof (UINT16):
    363             DEBUG ((EFI_D_INFO, "    OneOfOption   - 0x%04x\n", OneValue));
    364             break;
    365           case sizeof (UINT32):
    366             DEBUG ((EFI_D_INFO, "    OneOfOption   - 0x%08x\n", OneValue));
    367             break;
    368           case sizeof (UINT64):
    369             DEBUG ((EFI_D_INFO, "    OneOfOption   - 0x%016lx\n", OneValue));
    370             break;
    371           default:
    372             ASSERT (FALSE);
    373             break;
    374         }
    375         Ptr += HiiQuestion->StorageWidth;
    376       }
    377       break;
    378 
    379     case EFI_IFR_CHECKBOX_OP:
    380       break;
    381 
    382     case EFI_IFR_NUMERIC_OP:
    383       Minimum = 0;
    384       Maximum = 0;
    385       Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_NUMERIC *) HiiQuestion + 1);
    386       CopyMem (&Minimum, Ptr, HiiQuestion->StorageWidth);
    387       Ptr += HiiQuestion->StorageWidth;
    388       CopyMem (&Maximum, Ptr, HiiQuestion->StorageWidth);
    389       Ptr += HiiQuestion->StorageWidth;
    390 
    391       switch (HiiQuestion->StorageWidth) {
    392         case sizeof (UINT8):
    393           DEBUG ((EFI_D_INFO, "    Minimum       - 0x%02x\n", Minimum));
    394           DEBUG ((EFI_D_INFO, "    Maximum       - 0x%02x\n", Maximum));
    395           break;
    396         case sizeof (UINT16):
    397           DEBUG ((EFI_D_INFO, "    Minimum       - 0x%04x\n", Minimum));
    398           DEBUG ((EFI_D_INFO, "    Maximum       - 0x%04x\n", Maximum));
    399           break;
    400         case sizeof (UINT32):
    401           DEBUG ((EFI_D_INFO, "    Minimum       - 0x%08x\n", Minimum));
    402           DEBUG ((EFI_D_INFO, "    Maximum       - 0x%08x\n", Maximum));
    403           break;
    404         case sizeof (UINT64):
    405           DEBUG ((EFI_D_INFO, "    Minimum       - 0x%016lx\n", Minimum));
    406           DEBUG ((EFI_D_INFO, "    Maximum       - 0x%016lx\n", Maximum));
    407           break;
    408         default:
    409           ASSERT (FALSE);
    410           break;
    411       }
    412       break;
    413 
    414     case EFI_IFR_ORDERED_LIST_OP:
    415       DEBUG ((EFI_D_INFO, "    MaxContainers - 0x%02x\n", ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion)->MaxContainers));
    416       Ptr = (UINT8 *) ((VAR_CHECK_HII_QUESTION_ORDEREDLIST *) HiiQuestion + 1);
    417       while ((UINTN) Ptr < ((UINTN) HiiQuestion + HiiQuestion->Length)) {
    418         OneValue = 0;
    419         CopyMem (&OneValue, Ptr, HiiQuestion->StorageWidth);
    420         switch (HiiQuestion->StorageWidth) {
    421           case sizeof (UINT8):
    422             DEBUG ((EFI_D_INFO, "    OneOfOption   - 0x%02x\n", OneValue));
    423             break;
    424           case sizeof (UINT16):
    425             DEBUG ((EFI_D_INFO, "    OneOfOption   - 0x%04x\n", OneValue));
    426             break;
    427           case sizeof (UINT32):
    428             DEBUG ((EFI_D_INFO, "    OneOfOption   - 0x%08x\n", OneValue));
    429             break;
    430           case sizeof (UINT64):
    431             DEBUG ((EFI_D_INFO, "    OneOfOption   - 0x%016lx\n", OneValue));
    432             break;
    433           default:
    434             ASSERT (FALSE);
    435             break;
    436         }
    437         Ptr += HiiQuestion->StorageWidth;
    438       }
    439       break;
    440 
    441     default:
    442       ASSERT (FALSE);
    443       break;
    444   }
    445 }
    446 
    447 /**
    448   Dump Hii Variable.
    449 
    450   @param[in] HiiVariable    Pointer to Hii Variable.
    451 
    452 **/
    453 VOID
    454 DumpHiiVariable (
    455   IN VAR_CHECK_HII_VARIABLE_HEADER  *HiiVariable
    456   )
    457 {
    458   VAR_CHECK_HII_QUESTION_HEADER *HiiQuestion;
    459 
    460   DEBUG ((EFI_D_INFO, "VAR_CHECK_HII_VARIABLE_HEADER\n"));
    461   DEBUG ((EFI_D_INFO, "  Revision        - 0x%04x\n", HiiVariable->Revision));
    462   DEBUG ((EFI_D_INFO, "  HeaderLength    - 0x%04x\n", HiiVariable->HeaderLength));
    463   DEBUG ((EFI_D_INFO, "  Length          - 0x%08x\n", HiiVariable->Length));
    464   DEBUG ((EFI_D_INFO, "  OpCode          - 0x%02x (%a)\n", HiiVariable->OpCode, HiiOpCodeToStr (HiiVariable->OpCode)));
    465   DEBUG ((EFI_D_INFO, "  Size            - 0x%04x\n", HiiVariable->Size));
    466   DEBUG ((EFI_D_INFO, "  Attributes      - 0x%08x\n", HiiVariable->Attributes));
    467   DEBUG ((EFI_D_INFO, "  Guid            - %g\n", &HiiVariable->Guid));
    468   DEBUG ((EFI_D_INFO, "  Name            - %s\n", HiiVariable + 1));
    469 
    470   //
    471   // For Hii Question header align.
    472   //
    473   HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *) HEADER_ALIGN (((UINTN) HiiVariable + HiiVariable->HeaderLength));
    474   while ((UINTN) HiiQuestion < ((UINTN) HiiVariable + HiiVariable->Length)) {
    475     //
    476     // Dump Hii Question related to the Hii Variable.
    477     //
    478     DumpHiiQuestion (HiiQuestion);
    479     //
    480     // For Hii Question header align.
    481     //
    482     HiiQuestion = (VAR_CHECK_HII_QUESTION_HEADER *) HEADER_ALIGN (((UINTN) HiiQuestion + HiiQuestion->Length));
    483   }
    484 }
    485 
    486 /**
    487   Dump Var Check HII.
    488 
    489   @param[in] VarCheckHiiBin     Pointer to VarCheckHiiBin.
    490   @param[in] VarCheckHiiBinSize VarCheckHiiBin size.
    491 
    492 **/
    493 VOID
    494 DumpVarCheckHii (
    495   IN VOID   *VarCheckHiiBin,
    496   IN UINTN  VarCheckHiiBinSize
    497   )
    498 {
    499   VAR_CHECK_HII_VARIABLE_HEADER     *HiiVariable;
    500 
    501   DEBUG ((EFI_D_INFO, "DumpVarCheckHii\n"));
    502 
    503   //
    504   // For Hii Variable header align.
    505   //
    506   HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *) HEADER_ALIGN (VarCheckHiiBin);
    507   while ((UINTN) HiiVariable < ((UINTN) VarCheckHiiBin + VarCheckHiiBinSize)) {
    508     DumpHiiVariable (HiiVariable);
    509     //
    510     // For Hii Variable header align.
    511     //
    512     HiiVariable = (VAR_CHECK_HII_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) HiiVariable + HiiVariable->Length));
    513   }
    514 }
    515 #endif
    516 
    517 /**
    518   Constructor function of VarCheckHiiLib to register var check HII handler.
    519 
    520   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
    521   @param[in] SystemTable    A pointer to the EFI System Table.
    522 
    523   @retval EFI_SUCCESS       The constructor executed correctly.
    524 
    525 **/
    526 EFI_STATUS
    527 EFIAPI
    528 VarCheckHiiLibNullClassConstructor (
    529   IN EFI_HANDLE             ImageHandle,
    530   IN EFI_SYSTEM_TABLE       *SystemTable
    531   )
    532 {
    533   VarCheckLibRegisterEndOfDxeCallback (VarCheckHiiGen);
    534   VarCheckLibRegisterAddressPointer ((VOID **) &mVarCheckHiiBin);
    535   VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerHii);
    536 
    537   return EFI_SUCCESS;
    538 }
    539 
    540