The check will be based on PcdVarCheck binary that generated by BaseTools. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18294 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			475 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			475 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   Var Check PCD handler.
 | |
| 
 | |
| Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
 | |
| 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.
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include <Library/VarCheckLib.h>
 | |
| #include <Library/BaseLib.h>
 | |
| #include <Library/DebugLib.h>
 | |
| #include <Library/BaseMemoryLib.h>
 | |
| #include <Library/MemoryAllocationLib.h>
 | |
| #include <Library/DxeServicesLib.h>
 | |
| 
 | |
| #include "VarCheckPcdStructure.h"
 | |
| 
 | |
| //#define DUMP_VAR_CHECK_PCD
 | |
| 
 | |
| GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckPcdHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
 | |
| 
 | |
| /**
 | |
|   Dump some hexadecimal data.
 | |
| 
 | |
|   @param[in] Indent     How many spaces to indent the output.
 | |
|   @param[in] Offset     The offset of the dump.
 | |
|   @param[in] DataSize   The size in bytes of UserData.
 | |
|   @param[in] UserData   The data to dump.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| VarCheckPcdInternalDumpHex (
 | |
|   IN UINTN        Indent,
 | |
|   IN UINTN        Offset,
 | |
|   IN UINTN        DataSize,
 | |
|   IN VOID         *UserData
 | |
|   )
 | |
| {
 | |
|   UINT8 *Data;
 | |
| 
 | |
|   CHAR8 Val[50];
 | |
| 
 | |
|   CHAR8 Str[20];
 | |
| 
 | |
|   UINT8 TempByte;
 | |
|   UINTN Size;
 | |
|   UINTN Index;
 | |
| 
 | |
|   Data = UserData;
 | |
|   while (DataSize != 0) {
 | |
|     Size = 16;
 | |
|     if (Size > DataSize) {
 | |
|       Size = DataSize;
 | |
|     }
 | |
| 
 | |
|     for (Index = 0; Index < Size; Index += 1) {
 | |
|       TempByte            = Data[Index];
 | |
|       Val[Index * 3 + 0]  = mVarCheckPcdHex[TempByte >> 4];
 | |
|       Val[Index * 3 + 1]  = mVarCheckPcdHex[TempByte & 0xF];
 | |
|       Val[Index * 3 + 2]  = (CHAR8) ((Index == 7) ? '-' : ' ');
 | |
|       Str[Index]          = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
 | |
|     }
 | |
| 
 | |
|     Val[Index * 3]  = 0;
 | |
|     Str[Index]      = 0;
 | |
|     DEBUG ((EFI_D_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
 | |
| 
 | |
|     Data += Size;
 | |
|     Offset += Size;
 | |
|     DataSize -= Size;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Var Check Pcd ValidData.
 | |
| 
 | |
|   @param[in] PcdValidData   Pointer to Pcd ValidData
 | |
|   @param[in] Data           Data pointer.
 | |
|   @param[in] DataSize       Size of Data to set.
 | |
| 
 | |
|   @retval TRUE  Check pass
 | |
|   @retval FALSE Check fail.
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| VarCheckPcdValidData (
 | |
|   IN VAR_CHECK_PCD_VALID_DATA_HEADER    *PcdValidData,
 | |
|   IN VOID                               *Data,
 | |
|   IN UINTN                              DataSize
 | |
|   )
 | |
| {
 | |
|   UINT64   OneData;
 | |
|   UINT64   Minimum;
 | |
|   UINT64   Maximum;
 | |
|   UINT64   OneValue;
 | |
|   UINT8    *Ptr;
 | |
| 
 | |
|   OneData = 0;
 | |
|   CopyMem (&OneData, (UINT8 *) Data + PcdValidData->VarOffset, PcdValidData->StorageWidth);
 | |
| 
 | |
|   switch (PcdValidData->Type) {
 | |
|     case VarCheckPcdValidList:
 | |
|       Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_LIST *) PcdValidData + 1);
 | |
|       while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {
 | |
|         OneValue = 0;
 | |
|         CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);
 | |
|         if (OneData == OneValue) {
 | |
|           //
 | |
|           // Match
 | |
|           //
 | |
|           break;
 | |
|         }
 | |
|         Ptr += PcdValidData->StorageWidth;
 | |
|       }
 | |
|       if ((UINTN) Ptr >= ((UINTN) PcdValidData + PcdValidData->Length)) {
 | |
|         //
 | |
|         // No match
 | |
|         //
 | |
|         DEBUG ((EFI_D_INFO, "VarCheckPcdValidData fail: ValidList mismatch (0x%lx)\n", OneData));
 | |
|         DEBUG_CODE (VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *) PcdValidData););
 | |
|         return FALSE;
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case VarCheckPcdValidRange:
 | |
|       Minimum = 0;
 | |
|       Maximum = 0;
 | |
|       Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_RANGE *) PcdValidData + 1);
 | |
|       while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {
 | |
|         CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);
 | |
|         Ptr += PcdValidData->StorageWidth;
 | |
|         CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);
 | |
|         Ptr += PcdValidData->StorageWidth;
 | |
| 
 | |
|         if ((OneData >= Minimum) && (OneData <= Maximum)) {
 | |
|           return TRUE;
 | |
|         }
 | |
|       }
 | |
|       DEBUG ((EFI_D_INFO, "VarCheckPcdValidData fail: ValidRange mismatch (0x%lx)\n", OneData));
 | |
|       DEBUG_CODE (VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *) PcdValidData););
 | |
|       return FALSE;
 | |
|       break;
 | |
| 
 | |
|     default:
 | |
|       ASSERT (FALSE);
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   return TRUE;
 | |
| }
 | |
| 
 | |
| VAR_CHECK_PCD_VARIABLE_HEADER   *mVarCheckPcdBin = NULL;
 | |
| UINTN                           mVarCheckPcdBinSize = 0;
 | |
| 
 | |
| /**
 | |
|   SetVariable check handler PCD.
 | |
| 
 | |
|   @param[in] VariableName       Name of Variable to set.
 | |
|   @param[in] VendorGuid         Variable vendor GUID.
 | |
|   @param[in] Attributes         Attribute value of the variable.
 | |
|   @param[in] DataSize           Size of Data to set.
 | |
|   @param[in] Data               Data pointer.
 | |
| 
 | |
|   @retval EFI_SUCCESS               The SetVariable check result was success.
 | |
|   @retval EFI_SECURITY_VIOLATION    Check fail.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| SetVariableCheckHandlerPcd (
 | |
|   IN CHAR16     *VariableName,
 | |
|   IN EFI_GUID   *VendorGuid,
 | |
|   IN UINT32     Attributes,
 | |
|   IN UINTN      DataSize,
 | |
|   IN VOID       *Data
 | |
|   )
 | |
| {
 | |
|   VAR_CHECK_PCD_VARIABLE_HEADER     *PcdVariable;
 | |
|   VAR_CHECK_PCD_VALID_DATA_HEADER   *PcdValidData;
 | |
| 
 | |
|   if (mVarCheckPcdBin == NULL) {
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
 | |
|     //
 | |
|     // Do not check delete variable.
 | |
|     //
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   //
 | |
|   // For Pcd Variable header align.
 | |
|   //
 | |
|   PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (mVarCheckPcdBin);
 | |
|   while ((UINTN) PcdVariable < ((UINTN) mVarCheckPcdBin + mVarCheckPcdBinSize)) {
 | |
|     if ((StrCmp ((CHAR16 *) (PcdVariable + 1), VariableName) == 0) &&
 | |
|         (CompareGuid (&PcdVariable->Guid, VendorGuid))) {
 | |
|       //
 | |
|       // Found the Pcd Variable that could be used to do check.
 | |
|       //
 | |
|       DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
 | |
|       if ((PcdVariable->Attributes != 0) && PcdVariable->Attributes != Attributes) {
 | |
|         DEBUG ((EFI_D_INFO, "VarCheckPcdVariable fail for Attributes - 0x%08x\n", PcdVariable->Attributes));
 | |
|         return EFI_SECURITY_VIOLATION;
 | |
|       }
 | |
| 
 | |
|       if (DataSize == 0) {
 | |
|         DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - CHECK PASS with DataSize == 0 !\n"));
 | |
|         return EFI_SUCCESS;
 | |
|       }
 | |
| 
 | |
|       //
 | |
|       // Do the check.
 | |
|       // For Pcd ValidData header align.
 | |
|       //
 | |
|       PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->HeaderLength));
 | |
|       while ((UINTN) PcdValidData < ((UINTN) PcdVariable + PcdVariable->Length)) {
 | |
|         if (((UINTN) PcdValidData->VarOffset + PcdValidData->StorageWidth) <= DataSize) {
 | |
|           if (!VarCheckPcdValidData (PcdValidData, Data, DataSize)) {
 | |
|             return EFI_SECURITY_VIOLATION;
 | |
|           }
 | |
|         }
 | |
|         //
 | |
|         // For Pcd ValidData header align.
 | |
|         //
 | |
|         PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdValidData + PcdValidData->Length));
 | |
|       }
 | |
| 
 | |
|       DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - ALL CHECK PASS!\n"));
 | |
|       return EFI_SUCCESS;
 | |
|     }
 | |
|     //
 | |
|     // For Pcd Variable header align.
 | |
|     //
 | |
|     PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->Length));
 | |
|   }
 | |
| 
 | |
|   // Not found, so pass.
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| #ifdef DUMP_VAR_CHECK_PCD
 | |
| /**
 | |
|   Dump Pcd ValidData.
 | |
| 
 | |
|   @param[in] PcdValidData    Pointer to Pcd ValidData.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| DumpPcdValidData (
 | |
|   IN VAR_CHECK_PCD_VALID_DATA_HEADER    *PcdValidData
 | |
|   )
 | |
| {
 | |
|   UINT64    Minimum;
 | |
|   UINT64    Maximum;
 | |
|   UINT64    OneValue;
 | |
|   UINT8     *Ptr;
 | |
| 
 | |
|   DEBUG ((EFI_D_INFO, "  VAR_CHECK_PCD_VALID_DATA_HEADER\n"));
 | |
|   DEBUG ((EFI_D_INFO, "    Type          - 0x%02x\n", PcdValidData->Type));
 | |
|   DEBUG ((EFI_D_INFO, "    Length        - 0x%02x\n", PcdValidData->Length));
 | |
|   DEBUG ((EFI_D_INFO, "    VarOffset     - 0x%04x\n", PcdValidData->VarOffset));
 | |
|   DEBUG ((EFI_D_INFO, "    StorageWidth  - 0x%02x\n", PcdValidData->StorageWidth));
 | |
| 
 | |
|   switch (PcdValidData->Type) {
 | |
|     case VarCheckPcdValidList:
 | |
|       Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_LIST *) PcdValidData + 1);
 | |
|       while ((UINTN) Ptr < ((UINTN) PcdValidData + PcdValidData->Length)) {
 | |
|         OneValue = 0;
 | |
|         CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);
 | |
|         switch (PcdValidData->StorageWidth) {
 | |
|           case sizeof (UINT8):
 | |
|             DEBUG ((EFI_D_INFO, "    ValidList   - 0x%02x\n", OneValue));
 | |
|             break;
 | |
|           case sizeof (UINT16):
 | |
|             DEBUG ((EFI_D_INFO, "    ValidList   - 0x%04x\n", OneValue));
 | |
|             break;
 | |
|           case sizeof (UINT32):
 | |
|             DEBUG ((EFI_D_INFO, "    ValidList   - 0x%08x\n", OneValue));
 | |
|             break;
 | |
|           case sizeof (UINT64):
 | |
|             DEBUG ((EFI_D_INFO, "    ValidList   - 0x%016lx\n", OneValue));
 | |
|             break;
 | |
|           default:
 | |
|             ASSERT (FALSE);
 | |
|             break;
 | |
|         }
 | |
|         Ptr += PcdValidData->StorageWidth;
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case VarCheckPcdValidRange:
 | |
|       Minimum = 0;
 | |
|       Maximum = 0;
 | |
|       Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_RANGE *) PcdValidData + 1);
 | |
|       while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {
 | |
|         CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);
 | |
|         Ptr += PcdValidData->StorageWidth;
 | |
|         CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);
 | |
|         Ptr += PcdValidData->StorageWidth;
 | |
| 
 | |
|         switch (PcdValidData->StorageWidth) {
 | |
|           case sizeof (UINT8):
 | |
|             DEBUG ((EFI_D_INFO, "    Minimum       - 0x%02x\n", Minimum));
 | |
|             DEBUG ((EFI_D_INFO, "    Maximum       - 0x%02x\n", Maximum));
 | |
|             break;
 | |
|           case sizeof (UINT16):
 | |
|             DEBUG ((EFI_D_INFO, "    Minimum       - 0x%04x\n", Minimum));
 | |
|             DEBUG ((EFI_D_INFO, "    Maximum       - 0x%04x\n", Maximum));
 | |
|             break;
 | |
|           case sizeof (UINT32):
 | |
|             DEBUG ((EFI_D_INFO, "    Minimum       - 0x%08x\n", Minimum));
 | |
|             DEBUG ((EFI_D_INFO, "    Maximum       - 0x%08x\n", Maximum));
 | |
|             break;
 | |
|           case sizeof (UINT64):
 | |
|             DEBUG ((EFI_D_INFO, "    Minimum       - 0x%016lx\n", Minimum));
 | |
|             DEBUG ((EFI_D_INFO, "    Maximum       - 0x%016lx\n", Maximum));
 | |
|             break;
 | |
|           default:
 | |
|             ASSERT (FALSE);
 | |
|             break;
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     default:
 | |
|       ASSERT (FALSE);
 | |
|       break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump Pcd Variable.
 | |
| 
 | |
|   @param[in] PcdVariable    Pointer to Pcd Variable.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| DumpPcdVariable (
 | |
|   IN VAR_CHECK_PCD_VARIABLE_HEADER  *PcdVariable
 | |
|   )
 | |
| {
 | |
|   VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData;
 | |
| 
 | |
|   DEBUG ((EFI_D_INFO, "VAR_CHECK_PCD_VARIABLE_HEADER\n"));
 | |
|   DEBUG ((EFI_D_INFO, "  Revision        - 0x%04x\n", PcdVariable->Revision));
 | |
|   DEBUG ((EFI_D_INFO, "  HeaderLength    - 0x%04x\n", PcdVariable->HeaderLength));
 | |
|   DEBUG ((EFI_D_INFO, "  Length          - 0x%08x\n", PcdVariable->Length));
 | |
|   DEBUG ((EFI_D_INFO, "  Type            - 0x%02x\n", PcdVariable->Type));
 | |
|   DEBUG ((EFI_D_INFO, "  Attributes      - 0x%08x\n", PcdVariable->Attributes));
 | |
|   DEBUG ((EFI_D_INFO, "  Guid            - %g\n", &PcdVariable->Guid));
 | |
|   DEBUG ((EFI_D_INFO, "  Name            - %s\n", PcdVariable + 1));
 | |
| 
 | |
|   //
 | |
|   // For Pcd ValidData header align.
 | |
|   //
 | |
|   PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->HeaderLength));
 | |
|   while ((UINTN) PcdValidData < ((UINTN) PcdVariable + PcdVariable->Length)) {
 | |
|     //
 | |
|     // Dump Pcd ValidData related to the Pcd Variable.
 | |
|     //
 | |
|     DumpPcdValidData (PcdValidData);
 | |
|     //
 | |
|     // For Pcd ValidData header align.
 | |
|     //
 | |
|     PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdValidData + PcdValidData->Length));
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Dump Var Check PCD.
 | |
| 
 | |
|   @param[in] VarCheckPcdBin     Pointer to VarCheckPcdBin.
 | |
|   @param[in] VarCheckPcdBinSize VarCheckPcdBin size.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| DumpVarCheckPcd (
 | |
|   IN VOID   *VarCheckPcdBin,
 | |
|   IN UINTN  VarCheckPcdBinSize
 | |
|   )
 | |
| {
 | |
|   VAR_CHECK_PCD_VARIABLE_HEADER     *PcdVariable;
 | |
| 
 | |
|   DEBUG ((EFI_D_INFO, "DumpVarCheckPcd\n"));
 | |
| 
 | |
|   //
 | |
|   // For Pcd Variable header align.
 | |
|   //
 | |
|   PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (VarCheckPcdBin);
 | |
|   while ((UINTN) PcdVariable < ((UINTN) VarCheckPcdBin + VarCheckPcdBinSize)) {
 | |
|     DumpPcdVariable (PcdVariable);
 | |
|     //
 | |
|     // For Pcd Variable header align.
 | |
|     //
 | |
|     PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->Length));
 | |
|   }
 | |
| }
 | |
| #endif
 | |
| 
 | |
| /**
 | |
|   Locate VarCheckPcdBin.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| LocateVarCheckPcdBin (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                        Status;
 | |
|   VAR_CHECK_PCD_VARIABLE_HEADER     *VarCheckPcdBin;
 | |
|   UINTN                             VarCheckPcdBinSize;
 | |
| 
 | |
|   //
 | |
|   // Search the VarCheckPcdBin from the first RAW section of current FFS.
 | |
|   //
 | |
|   Status = GetSectionFromFfs (
 | |
|              EFI_SECTION_RAW,
 | |
|              0,
 | |
|              (VOID **) &VarCheckPcdBin,
 | |
|              &VarCheckPcdBinSize
 | |
|              );
 | |
|   if (!EFI_ERROR (Status)) {
 | |
|     //
 | |
|     // AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
 | |
|     // in SetVariable check handler.
 | |
|     //
 | |
|     mVarCheckPcdBin = AllocateRuntimeCopyPool (VarCheckPcdBinSize, VarCheckPcdBin);
 | |
|     ASSERT (mVarCheckPcdBin != NULL);
 | |
|     mVarCheckPcdBinSize = VarCheckPcdBinSize;
 | |
|     FreePool (VarCheckPcdBin);
 | |
| 
 | |
|     DEBUG ((EFI_D_INFO, "VarCheckPcdBin - at 0x%x size = 0x%x\n", mVarCheckPcdBin, mVarCheckPcdBinSize));
 | |
| 
 | |
| #ifdef DUMP_VAR_CHECK_PCD
 | |
|     DEBUG_CODE (
 | |
|       DumpVarCheckPcd (mVarCheckPcdBin, mVarCheckPcdBinSize);
 | |
|     );
 | |
| #endif
 | |
|   } else {
 | |
|     DEBUG ((EFI_D_INFO, "[VarCheckPcd] No VarCheckPcdBin found at the first RAW section\n"));
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Constructor function of VarCheckPcdLib to register var check PCD handler.
 | |
| 
 | |
|   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
 | |
|   @param[in] SystemTable    A pointer to the EFI System Table.
 | |
| 
 | |
|   @retval EFI_SUCCESS       The constructor executed correctly.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| EFIAPI
 | |
| VarCheckPcdLibNullClassConstructor (
 | |
|   IN EFI_HANDLE             ImageHandle,
 | |
|   IN EFI_SYSTEM_TABLE       *SystemTable
 | |
|   )
 | |
| {
 | |
|   LocateVarCheckPcdBin ();
 | |
|   VarCheckLibRegisterAddressPointer ((VOID **) &mVarCheckPcdBin);
 | |
|   VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerPcd);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 |