]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c
SecurityPkg/DxeDeferImageLoadLib: Remove DxeDeferImageLoadLib
[mirror_edk2.git] / SecurityPkg / Library / DxeDeferImageLoadLib / DxeDeferImageLoadLib.c
diff --git a/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c b/SecurityPkg/Library/DxeDeferImageLoadLib/DxeDeferImageLoadLib.c
deleted file mode 100644 (file)
index a6a3fe3..0000000
+++ /dev/null
@@ -1,927 +0,0 @@
-/** @file\r
-  Implement defer image load services for user identification in UEFI2.2.\r
-\r
-Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "DxeDeferImageLoadLib.h"\r
-\r
-//\r
-// Handle for the Deferred Image Load Protocol instance produced by this driver.\r
-//\r
-EFI_HANDLE                       mDeferredImageHandle = NULL;\r
-BOOLEAN                          mIsProtocolInstalled = FALSE;\r
-EFI_USER_MANAGER_PROTOCOL        *mUserManager        = NULL;\r
-DEFERRED_IMAGE_TABLE             mDeferredImage       = {\r
-  0,       // Deferred image count\r
-  NULL     // The deferred image info\r
-};\r
-\r
-EFI_DEFERRED_IMAGE_LOAD_PROTOCOL gDeferredImageLoad   = {\r
-  GetDefferedImageInfo\r
-};\r
-\r
-/**\r
-  Get the image type.\r
-\r
-  @param[in]    File    This is a pointer to the device path of the file\r
-                        that is being dispatched.\r
-\r
-  @return       UINT32  Image Type\r
-\r
-**/\r
-UINT32\r
-GetFileType (\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File\r
-  )\r
-{\r
-  EFI_STATUS                        Status;\r
-  EFI_HANDLE                        DeviceHandle;\r
-  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePath;\r
-  EFI_BLOCK_IO_PROTOCOL             *BlockIo;\r
-\r
-  //\r
-  // First check to see if File is from a Firmware Volume\r
-  //\r
-  DeviceHandle      = NULL;\r
-  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
-  Status = gBS->LocateDevicePath (\r
-                  &gEfiFirmwareVolume2ProtocolGuid,\r
-                  &TempDevicePath,\r
-                  &DeviceHandle\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    Status = gBS->OpenProtocol (\r
-                    DeviceHandle,\r
-                    &gEfiFirmwareVolume2ProtocolGuid,\r
-                    NULL,\r
-                    NULL,\r
-                    NULL,\r
-                    EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                    );\r
-    if (!EFI_ERROR (Status)) {\r
-      return IMAGE_FROM_FV;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Next check to see if File is from a Block I/O device\r
-  //\r
-  DeviceHandle   = NULL;\r
-  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
-  Status = gBS->LocateDevicePath (\r
-                  &gEfiBlockIoProtocolGuid,\r
-                  &TempDevicePath,\r
-                  &DeviceHandle\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    BlockIo = NULL;\r
-    Status = gBS->OpenProtocol (\r
-                    DeviceHandle,\r
-                    &gEfiBlockIoProtocolGuid,\r
-                    (VOID **) &BlockIo,\r
-                    NULL,\r
-                    NULL,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-    if (!EFI_ERROR (Status) && BlockIo != NULL) {\r
-      if (BlockIo->Media != NULL) {\r
-        if (BlockIo->Media->RemovableMedia) {\r
-          //\r
-          // Block I/O is present and specifies the media is removable\r
-          //\r
-          return IMAGE_FROM_REMOVABLE_MEDIA;\r
-        } else {\r
-          //\r
-          // Block I/O is present and specifies the media is not removable\r
-          //\r
-          return IMAGE_FROM_FIXED_MEDIA;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // File is not in a Firmware Volume or on a Block I/O device, so check to see if\r
-  // the device path supports the Simple File System Protocol.\r
-  //\r
-  DeviceHandle   = NULL;\r
-  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
-  Status = gBS->LocateDevicePath (\r
-                  &gEfiSimpleFileSystemProtocolGuid,\r
-                  &TempDevicePath,\r
-                  &DeviceHandle\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    //\r
-    // Simple File System is present without Block I/O, so assume media is fixed.\r
-    //\r
-    return IMAGE_FROM_FIXED_MEDIA;\r
-  }\r
-\r
-  //\r
-  // File is not from an FV, Block I/O or Simple File System, so the only options\r
-  // left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.\r
-  //\r
-  TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;\r
-  while (!IsDevicePathEndType (TempDevicePath)) {\r
-    switch (DevicePathType (TempDevicePath)) {\r
-\r
-    case MEDIA_DEVICE_PATH:\r
-      if (DevicePathSubType (TempDevicePath) == MEDIA_RELATIVE_OFFSET_RANGE_DP) {\r
-        return IMAGE_FROM_OPTION_ROM;\r
-      }\r
-      break;\r
-\r
-    case MESSAGING_DEVICE_PATH:\r
-      if (DevicePathSubType(TempDevicePath) == MSG_MAC_ADDR_DP) {\r
-        return IMAGE_FROM_REMOVABLE_MEDIA;\r
-      }\r
-      break;\r
-\r
-    default:\r
-      break;\r
-    }\r
-    TempDevicePath = NextDevicePathNode (TempDevicePath);\r
-  }\r
-  return IMAGE_UNKNOWN;\r
-}\r
-\r
-\r
-/**\r
-  Get current user's access right.\r
-\r
-  @param[out]  AccessControl Points to the user's access control data, the\r
-                             caller should free data buffer.\r
-  @param[in]   AccessType    The type of user access control.\r
-\r
-  @retval      EFI_SUCCESS   Get current user access control successfully\r
-  @retval      others        Fail to get current user access control\r
-\r
-**/\r
-EFI_STATUS\r
-GetAccessControl (\r
-  OUT  EFI_USER_INFO_ACCESS_CONTROL     **AccessControl,\r
-  IN   UINT32                           AccessType\r
-  )\r
-{\r
-  EFI_STATUS                    Status;\r
-  EFI_USER_INFO_HANDLE          UserInfo;\r
-  EFI_USER_INFO                 *Info;\r
-  UINTN                         InfoSize;\r
-  EFI_USER_INFO_ACCESS_CONTROL  *Access;\r
-  EFI_USER_PROFILE_HANDLE       CurrentUser;\r
-  UINTN                         CheckLen;\r
-  EFI_USER_MANAGER_PROTOCOL     *UserManager;\r
-\r
-  CurrentUser = NULL;\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiUserManagerProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &UserManager\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Get current user access information.\r
-  //\r
-  UserManager->Current (UserManager, &CurrentUser);\r
-\r
-  UserInfo = NULL;\r
-  Info     = NULL;\r
-  InfoSize = 0;\r
-  while (TRUE) {\r
-    //\r
-    // Get next user information.\r
-    //\r
-    Status = UserManager->GetNextInfo (UserManager, CurrentUser, &UserInfo);\r
-    if (EFI_ERROR (Status)) {\r
-      return Status;\r
-    }\r
-\r
-    Status = UserManager->GetInfo (\r
-                            UserManager,\r
-                            CurrentUser,\r
-                            UserInfo,\r
-                            Info,\r
-                            &InfoSize\r
-                            );\r
-    if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      if (Info != NULL) {\r
-        FreePool (Info);\r
-      }\r
-      Info = AllocateZeroPool (InfoSize);\r
-      ASSERT (Info != NULL);\r
-      Status = UserManager->GetInfo (\r
-                              UserManager,\r
-                              CurrentUser,\r
-                              UserInfo,\r
-                              Info,\r
-                              &InfoSize\r
-                              );\r
-    }\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-\r
-    ASSERT (Info != NULL);\r
-    if (Info->InfoType != EFI_USER_INFO_ACCESS_POLICY_RECORD) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Get specified access information.\r
-    //\r
-    CheckLen  = 0;\r
-    while (CheckLen < Info->InfoSize - sizeof (EFI_USER_INFO)) {\r
-      Access = (EFI_USER_INFO_ACCESS_CONTROL *) ((UINT8 *) (Info + 1) + CheckLen);\r
-      if (Access->Type == AccessType) {\r
-        *AccessControl = AllocateZeroPool (Access->Size);\r
-        ASSERT (*AccessControl != NULL);\r
-        CopyMem (*AccessControl, Access, Access->Size);\r
-        FreePool (Info);\r
-        return EFI_SUCCESS;\r
-      }\r
-      CheckLen += Access->Size;\r
-    }\r
-  }\r
-\r
-  if (Info != NULL) {\r
-    FreePool (Info);\r
-  }\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
-/**\r
-  Get file name from device path.\r
-\r
-  The file name may contain one or more device path node. Save the file name in a\r
-  buffer if file name is found. The caller is responsible to free the buffer.\r
-\r
-  @param[in]  DevicePath     A pointer to a device path.\r
-  @param[out] FileName       The callee allocated buffer to save the file name if file name is found.\r
-  @param[out] FileNameOffset The offset of file name in device path if file name is found.\r
-\r
-  @retval     UINTN          The file name length. 0 means file name is not found.\r
-\r
-**/\r
-UINTN\r
-GetFileName (\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL          *DevicePath,\r
-  OUT UINT8                                   **FileName,\r
-  OUT UINTN                                   *FileNameOffset\r
-  )\r
-{\r
-  UINTN                                       Length;\r
-  EFI_DEVICE_PATH_PROTOCOL                    *TmpDevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL                    *RootDevicePath;\r
-  CHAR8                                       *NodeStr;\r
-  UINTN                                       NodeStrLength;\r
-  CHAR16                                      LastNodeChar;\r
-  CHAR16                                      FirstNodeChar;\r
-\r
-  //\r
-  // Get the length of DevicePath before file name.\r
-  //\r
-  Length = 0;\r
-  RootDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;\r
-  while (!IsDevicePathEnd (RootDevicePath)) {\r
-    if ((DevicePathType(RootDevicePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType(RootDevicePath) == MEDIA_FILEPATH_DP)) {\r
-      break;\r
-    }\r
-    Length += DevicePathNodeLength (RootDevicePath);\r
-    RootDevicePath = NextDevicePathNode (RootDevicePath);\r
-  }\r
-\r
-  *FileNameOffset = Length;\r
-  if (Length == 0) {\r
-    return 0;\r
-  }\r
-\r
-  //\r
-  // Get the file name length.\r
-  //\r
-  Length = 0;\r
-  TmpDevicePath = RootDevicePath;\r
-  while (!IsDevicePathEnd (TmpDevicePath)) {\r
-    if ((DevicePathType(TmpDevicePath) != MEDIA_DEVICE_PATH) || (DevicePathSubType(TmpDevicePath) != MEDIA_FILEPATH_DP)) {\r
-      break;\r
-    }\r
-    Length += DevicePathNodeLength (TmpDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
-    TmpDevicePath = NextDevicePathNode (TmpDevicePath);\r
-  }\r
-  if (Length == 0) {\r
-    return 0;\r
-  }\r
-\r
-  *FileName = AllocateZeroPool (Length);\r
-  ASSERT (*FileName != NULL);\r
-\r
-  //\r
-  // Copy the file name to the buffer.\r
-  //\r
-  Length = 0;\r
-  LastNodeChar = '\\';\r
-  TmpDevicePath = RootDevicePath;\r
-  while (!IsDevicePathEnd (TmpDevicePath)) {\r
-    if ((DevicePathType(TmpDevicePath) != MEDIA_DEVICE_PATH) || (DevicePathSubType(TmpDevicePath) != MEDIA_FILEPATH_DP)) {\r
-      break;\r
-    }\r
-\r
-    FirstNodeChar = (CHAR16) ReadUnaligned16 ((UINT16 *)((UINT8 *)TmpDevicePath + sizeof (EFI_DEVICE_PATH_PROTOCOL)));\r
-    NodeStr = (CHAR8 *)TmpDevicePath + sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
-    NodeStrLength = DevicePathNodeLength (TmpDevicePath) - sizeof (EFI_DEVICE_PATH_PROTOCOL) - sizeof(CHAR16);\r
-\r
-    if ((FirstNodeChar == '\\') && (LastNodeChar == '\\')) {\r
-      //\r
-      // Skip separator "\" when there are two separators.\r
-      //\r
-      NodeStr += sizeof (CHAR16);\r
-      NodeStrLength -= sizeof (CHAR16);\r
-    } else if ((FirstNodeChar != '\\') && (LastNodeChar != '\\')) {\r
-      //\r
-      // Add separator "\" when there is no separator.\r
-      //\r
-      WriteUnaligned16 ((UINT16 *)(*FileName + Length), '\\');\r
-      Length += sizeof (CHAR16);\r
-    }\r
-    CopyMem (*FileName + Length, NodeStr, NodeStrLength);\r
-    Length += NodeStrLength;\r
-\r
-    LastNodeChar  = (CHAR16) ReadUnaligned16 ((UINT16 *) (NodeStr + NodeStrLength - sizeof(CHAR16)));\r
-    TmpDevicePath = NextDevicePathNode (TmpDevicePath);\r
-  }\r
-\r
-  return Length;\r
-}\r
-\r
-\r
-/**\r
-  Check whether the DevicePath2 is identical with DevicePath1, or identical with\r
-  DevicePath1's child device path.\r
-\r
-  If DevicePath2 is identical with DevicePath1, or with DevicePath1's child device\r
-  path, then TRUE returned. Otherwise, FALSE is returned.\r
-\r
-  If DevicePath1 is NULL, then ASSERT().\r
-  If DevicePath2 is NULL, then ASSERT().\r
-\r
-  @param[in]  DevicePath1   A pointer to a device path.\r
-  @param[in]  DevicePath2   A pointer to a device path.\r
-\r
-  @retval     TRUE          Two device paths are identical , or DevicePath2 is\r
-                            DevicePath1's child device path.\r
-  @retval     FALSE         Two device paths are not identical, and DevicePath2\r
-                            is not DevicePath1's child device path.\r
-\r
-**/\r
-BOOLEAN\r
-CheckDevicePath (\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL          *DevicePath1,\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL          *DevicePath2\r
-  )\r
-{\r
-  UINTN                                       DevicePathSize;\r
-  UINTN                                       FileNameSize1;\r
-  UINTN                                       FileNameSize2;\r
-  UINT8                                       *FileName1;\r
-  UINT8                                       *FileName2;\r
-  UINTN                                       FileNameOffset1;\r
-  UINTN                                       FileNameOffset2;\r
-  BOOLEAN                                     DevicePathEqual;\r
-\r
-  FileName1       = NULL;\r
-  FileName2       = NULL;\r
-  DevicePathEqual = TRUE;\r
-\r
-  ASSERT (DevicePath1 != NULL);\r
-  ASSERT (DevicePath2 != NULL);\r
-  if (IsDevicePathEnd (DevicePath1)) {\r
-    return FALSE;\r
-  }\r
-\r
-  //\r
-  // The file name may contain one or more device path node.\r
-  // To compare the file name, copy file name to a buffer and compare the buffer.\r
-  //\r
-  FileNameSize1 = GetFileName (DevicePath1, &FileName1, &FileNameOffset1);\r
-  if (FileNameSize1 != 0) {\r
-    FileNameSize2 = GetFileName (DevicePath2, &FileName2, &FileNameOffset2);\r
-    if (FileNameOffset1 != FileNameOffset2) {\r
-      DevicePathEqual = FALSE;\r
-      goto Done;\r
-    }\r
-    if (CompareMem (DevicePath1, DevicePath2, FileNameOffset1) != 0) {\r
-      DevicePathEqual = FALSE;\r
-      goto Done;\r
-    }\r
-    if (FileNameSize1 > FileNameSize2) {\r
-      DevicePathEqual = FALSE;\r
-      goto Done;\r
-    }\r
-    if (CompareMem (FileName1, FileName2, FileNameSize1) != 0) {\r
-      DevicePathEqual = FALSE;\r
-      goto Done;\r
-    }\r
-    DevicePathEqual = TRUE;\r
-    goto Done;\r
-  }\r
-\r
-  DevicePathSize = GetDevicePathSize (DevicePath1);\r
-  if (DevicePathSize > GetDevicePathSize (DevicePath2)) {\r
-    return FALSE;\r
-  }\r
-\r
-  //\r
-  // Exclude the end of device path node.\r
-  //\r
-  DevicePathSize -= sizeof (EFI_DEVICE_PATH_PROTOCOL);\r
-  if (CompareMem (DevicePath1, DevicePath2, DevicePathSize) != 0) {\r
-    DevicePathEqual = FALSE;\r
-  }\r
-\r
-Done:\r
-  if (FileName1 != NULL) {\r
-    FreePool (FileName1);\r
-  }\r
-  if (FileName2 != NULL) {\r
-    FreePool (FileName2);\r
-  }\r
-  return DevicePathEqual;\r
-}\r
-\r
-\r
-/**\r
-  Check whether the image pointed to by DevicePath is in the device path list\r
-  specified by AccessType.\r
-\r
-  @param[in] DevicePath  Points to device path.\r
-  @param[in] AccessType  The type of user access control.\r
-\r
-  @retval    TRUE        The DevicePath is in the specified List.\r
-  @retval    FALSE       The DevicePath is not in the specified List.\r
-\r
-**/\r
-BOOLEAN\r
-IsDevicePathInList (\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath,\r
-  IN        UINT32                     AccessType\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_USER_INFO_ACCESS_CONTROL          *Access;\r
-  EFI_DEVICE_PATH_PROTOCOL              *Path;\r
-  UINTN                                 OffSet;\r
-\r
-  Status = GetAccessControl (&Access, AccessType);\r
-  if (EFI_ERROR (Status)) {\r
-    return FALSE;\r
-  }\r
-\r
-  OffSet = 0;\r
-  while (OffSet < Access->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
-    Path = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)(Access + 1) + OffSet);\r
-    if (CheckDevicePath (Path, DevicePath)) {\r
-      //\r
-      // The device path is found in list.\r
-      //\r
-      FreePool (Access);\r
-      return TRUE;\r
-    }\r
-    OffSet += GetDevicePathSize (Path);\r
-  }\r
-\r
-  FreePool (Access);\r
-  return FALSE;\r
-}\r
-\r
-\r
-/**\r
-  Check whether the image pointed to by DevicePath is permitted to load.\r
-\r
-  @param[in] DevicePath  Points to device path\r
-\r
-  @retval    TRUE        The image pointed by DevicePath is permitted to load.\r
-  @retval    FALSE       The image pointed by DevicePath is forbidden to load.\r
-\r
-**/\r
-BOOLEAN\r
-VerifyDevicePath (\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *DevicePath\r
-  )\r
-{\r
-  if (IsDevicePathInList (DevicePath, EFI_USER_INFO_ACCESS_PERMIT_LOAD)) {\r
-    //\r
-    // This access control overrides any restrictions put in place by the\r
-    // EFI_USER_INFO_ACCESS_FORBID_LOAD record.\r
-    //\r
-    return TRUE;\r
-  }\r
-\r
-  if (IsDevicePathInList (DevicePath, EFI_USER_INFO_ACCESS_FORBID_LOAD)) {\r
-    //\r
-    // The device path is found in the forbidden list.\r
-    //\r
-    return FALSE;\r
-  }\r
-\r
-  return TRUE;\r
-}\r
-\r
-\r
-/**\r
-  Check the image pointed by DevicePath is a boot option or not.\r
-\r
-  @param[in] DevicePath  Points to device path.\r
-\r
-  @retval    TRUE        The image pointed by DevicePath is a boot option.\r
-  @retval    FALSE       The image pointed by DevicePath is not a boot option.\r
-\r
-**/\r
-BOOLEAN\r
-IsBootOption (\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL      *DevicePath\r
-  )\r
-{\r
-  EFI_STATUS                        Status;\r
-  UINT16                            *BootOrderList;\r
-  UINTN                             BootOrderListSize;\r
-  UINTN                             Index;\r
-  CHAR16                            StrTemp[20];\r
-  UINT8                             *OptionBuffer;\r
-  UINT8                             *OptionPtr;\r
-  EFI_DEVICE_PATH_PROTOCOL          *OptionDevicePath;\r
-\r
-  //\r
-  // Get BootOrder\r
-  //\r
-  BootOrderListSize = 0;\r
-  BootOrderList     = NULL;\r
-  Status = gRT->GetVariable (\r
-                  L"BootOrder",\r
-                  &gEfiGlobalVariableGuid,\r
-                  NULL,\r
-                  &BootOrderListSize,\r
-                  NULL\r
-                  );\r
-  if (Status == EFI_BUFFER_TOO_SMALL) {\r
-    BootOrderList = AllocateZeroPool (BootOrderListSize);\r
-    ASSERT (BootOrderList != NULL);\r
-    Status = gRT->GetVariable (\r
-                    L"BootOrder",\r
-                    &gEfiGlobalVariableGuid,\r
-                    NULL,\r
-                    &BootOrderListSize,\r
-                    BootOrderList\r
-                    );\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    //\r
-    // No Boot option\r
-    //\r
-    return FALSE;\r
-  }\r
-\r
-  OptionBuffer = NULL;\r
-  for (Index = 0; Index < BootOrderListSize / sizeof (UINT16); Index++) {\r
-    //\r
-    // Try to find the DevicePath in BootOption\r
-    //\r
-    UnicodeSPrint (StrTemp, sizeof (StrTemp), L"Boot%04x", Index);\r
-    GetEfiGlobalVariable2 (StrTemp, (VOID**)&OptionBuffer, NULL);\r
-    if (OptionBuffer == NULL) {\r
-      continue;\r
-    }\r
-\r
-    //\r
-    // Check whether the image is forbidden.\r
-    //\r
-\r
-    OptionPtr = OptionBuffer;\r
-    //\r
-    // Skip attribute.\r
-    //\r
-    OptionPtr += sizeof (UINT32);\r
-\r
-    //\r
-    // Skip device path length.\r
-    //\r
-    OptionPtr += sizeof (UINT16);\r
-\r
-    //\r
-    // Skip descript string\r
-    //\r
-    OptionPtr += StrSize ((UINT16 *) OptionPtr);\r
-\r
-    //\r
-    // Now OptionPtr points to Device Path.\r
-    //\r
-    OptionDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) OptionPtr;\r
-\r
-    if (CheckDevicePath (DevicePath, OptionDevicePath)) {\r
-      FreePool (OptionBuffer);\r
-      OptionBuffer = NULL;\r
-      return TRUE;\r
-    }\r
-    FreePool (OptionBuffer);\r
-    OptionBuffer = NULL;\r
-  }\r
-\r
-  if (BootOrderList != NULL) {\r
-    FreePool (BootOrderList);\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
-\r
-/**\r
-  Add the image info to a deferred image list.\r
-\r
-  @param[in]  ImageDevicePath  A pointer to the device path of a image.\r
-  @param[in]  Image            Points to the first byte of the image, or NULL if the\r
-                               image is not available.\r
-  @param[in]  ImageSize        The size of the image, or 0 if the image is not available.\r
-\r
-**/\r
-VOID\r
-PutDefferedImageInfo (\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL    *ImageDevicePath,\r
-  IN        VOID                        *Image,\r
-  IN        UINTN                       ImageSize\r
-  )\r
-{\r
-  DEFERRED_IMAGE_INFO    *CurImageInfo;\r
-  UINTN                  PathSize;\r
-\r
-  //\r
-  // Expand memory for the new deferred image.\r
-  //\r
-  if (mDeferredImage.Count == 0) {\r
-    mDeferredImage.ImageInfo = AllocatePool (sizeof (DEFERRED_IMAGE_INFO));\r
-    ASSERT (mDeferredImage.ImageInfo != NULL);\r
-  } else {\r
-    CurImageInfo = AllocatePool ((mDeferredImage.Count + 1) * sizeof (DEFERRED_IMAGE_INFO));\r
-    ASSERT (CurImageInfo != NULL);\r
-\r
-    CopyMem (\r
-      CurImageInfo,\r
-      mDeferredImage.ImageInfo,\r
-      mDeferredImage.Count * sizeof (DEFERRED_IMAGE_INFO)\r
-      );\r
-    FreePool (mDeferredImage.ImageInfo);\r
-    mDeferredImage.ImageInfo = CurImageInfo;\r
-  }\r
-  mDeferredImage.Count++;\r
-\r
-  //\r
-  // Save the deferred image information.\r
-  //\r
-  CurImageInfo = &mDeferredImage.ImageInfo[mDeferredImage.Count - 1];\r
-  PathSize     = GetDevicePathSize (ImageDevicePath);\r
-  CurImageInfo->ImageDevicePath = AllocateZeroPool (PathSize);\r
-  ASSERT (CurImageInfo->ImageDevicePath != NULL);\r
-  CopyMem (CurImageInfo->ImageDevicePath, ImageDevicePath, PathSize);\r
-\r
-  CurImageInfo->Image      = Image;\r
-  CurImageInfo->ImageSize  = ImageSize;\r
-  CurImageInfo->BootOption = IsBootOption (ImageDevicePath);\r
-}\r
-\r
-\r
-/**\r
-  Returns information about a deferred image.\r
-\r
-  This function returns information about a single deferred image. The deferred images are\r
-  numbered consecutively, starting with 0.  If there is no image which corresponds to\r
-  ImageIndex, then EFI_NOT_FOUND is returned. All deferred images may be returned by\r
-  iteratively calling this function until EFI_NOT_FOUND is returned.\r
-  Image may be NULL and ImageSize set to 0 if the decision to defer execution was made\r
-  because of the location of the executable image, rather than its actual contents.\r
-\r
-  @param[in]  This             Points to this instance of the EFI_DEFERRED_IMAGE_LOAD_PROTOCOL.\r
-  @param[in]  ImageIndex       Zero-based index of the deferred index.\r
-  @param[out] ImageDevicePath  On return, points to a pointer to the device path of the image.\r
-                               The device path should not be freed by the caller.\r
-  @param[out] Image            On return, points to the first byte of the image or NULL if the\r
-                               image is not available. The image should not be freed by the caller\r
-                               unless LoadImage() has been successfully called.\r
-  @param[out] ImageSize        On return, the size of the image, or 0 if the image is not available.\r
-  @param[out] BootOption       On return, points to TRUE if the image was intended as a boot option\r
-                               or FALSE if it was not intended as a boot option.\r
-\r
-  @retval EFI_SUCCESS           Image information returned successfully.\r
-  @retval EFI_NOT_FOUND         ImageIndex does not refer to a valid image.\r
-  @retval EFI_INVALID_PARAMETER ImageDevicePath is NULL or Image is NULL or ImageSize is NULL or\r
-                                BootOption is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-GetDefferedImageInfo (\r
-  IN     EFI_DEFERRED_IMAGE_LOAD_PROTOCOL  *This,\r
-  IN     UINTN                             ImageIndex,\r
-     OUT EFI_DEVICE_PATH_PROTOCOL          **ImageDevicePath,\r
-     OUT VOID                              **Image,\r
-     OUT UINTN                             *ImageSize,\r
-     OUT BOOLEAN                           *BootOption\r
-  )\r
-{\r
-  DEFERRED_IMAGE_INFO   *ReqImageInfo;\r
-\r
-  //\r
-  // Check the parameter.\r
-  //\r
-\r
-  if ((This == NULL) || (ImageSize == NULL) || (Image == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((ImageDevicePath == NULL) || (BootOption == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (ImageIndex >= mDeferredImage.Count) {\r
-    return EFI_NOT_FOUND;\r
-  }\r
-\r
-  //\r
-  // Get the request deferred image.\r
-  //\r
-  ReqImageInfo = &mDeferredImage.ImageInfo[ImageIndex];\r
-\r
-  *ImageDevicePath = ReqImageInfo->ImageDevicePath;\r
-  *Image           = ReqImageInfo->Image;\r
-  *ImageSize       = ReqImageInfo->ImageSize;\r
-  *BootOption      = ReqImageInfo->BootOption;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Provides the service of deferring image load based on platform policy control,\r
-  and installs Deferred Image Load Protocol.\r
-\r
-  @param[in]  AuthenticationStatus  This is the authentication status returned from the\r
-                                    security measurement services for the input file.\r
-  @param[in]  File                  This is a pointer to the device path of the file that\r
-                                    is being dispatched. This will optionally be used for\r
-                                    logging.\r
-  @param[in]  FileBuffer            File buffer matches the input file device path.\r
-  @param[in]  FileSize              Size of File buffer matches the input file device path.\r
-  @param[in]  BootPolicy            A boot policy that was used to call LoadImage() UEFI service.\r
-\r
-  @retval EFI_SUCCESS               FileBuffer is NULL and current user has permission to start\r
-                                    UEFI device drivers on the device path specified by DevicePath.\r
-  @retval EFI_SUCCESS               The file specified by DevicePath and non-NULL\r
-                                    FileBuffer did authenticate, and the platform policy dictates\r
-                                    that the DXE Foundation may use the file.\r
-  @retval EFI_SECURITY_VIOLATION    FileBuffer is NULL and the user has no\r
-                                    permission to start UEFI device drivers on the device path specified\r
-                                    by DevicePath.\r
-  @retval EFI_SECURITY_VIOLATION    FileBuffer is not NULL and the user has no permission to load\r
-                                    drivers from the device path specified by DevicePath. The\r
-                                    image has been added into the list of the deferred images.\r
-  @retval EFI_ACCESS_DENIED         The file specified by File and FileBuffer did not\r
-                                    authenticate, and the platform policy dictates that the DXE\r
-                                    Foundation many not use File.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DxeDeferImageLoadHandler (\r
-  IN  UINT32                           AuthenticationStatus,\r
-  IN  CONST EFI_DEVICE_PATH_PROTOCOL   *File,\r
-  IN  VOID                             *FileBuffer,\r
-  IN  UINTN                            FileSize,\r
-  IN  BOOLEAN                          BootPolicy\r
-  )\r
-{\r
-  EFI_STATUS                           Status;\r
-  EFI_USER_PROFILE_HANDLE              CurrentUser;\r
-  UINT32                               Policy;\r
-  UINT32                               FileType;\r
-\r
-  //\r
-  // Ignore if File is NULL.\r
-  //\r
-  if (File == NULL) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  //\r
-  // Check whether user has a logon.\r
-  //\r
-  CurrentUser = NULL;\r
-  if (mUserManager != NULL) {\r
-    mUserManager->Current (mUserManager, &CurrentUser);\r
-    if (CurrentUser != NULL) {\r
-      //\r
-      // The user is logon; verify the FilePath by current user access policy.\r
-      //\r
-      if (!VerifyDevicePath (File)) {\r
-        DEBUG ((EFI_D_ERROR, "[Security] The image is forbidden to load!\n"));\r
-        return EFI_SECURITY_VIOLATION;\r
-      }\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Still no user logon.\r
-  // Check the file type and get policy setting.\r
-  //\r
-  FileType = GetFileType (File);\r
-  Policy   = PcdGet32 (PcdDeferImageLoadPolicy);\r
-  if ((Policy & FileType) == FileType) {\r
-    //\r
-    // This file type is secure to load.\r
-    //\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  DEBUG ((EFI_D_INFO, "[Security] No user identified, the image is deferred to load!\n"));\r
-  PutDefferedImageInfo (File, FileBuffer, FileSize);\r
-\r
-  //\r
-  // Install the Deferred Image Load Protocol onto a new handle.\r
-  //\r
-  if (!mIsProtocolInstalled) {\r
-    Status = gBS->InstallMultipleProtocolInterfaces (\r
-                    &mDeferredImageHandle,\r
-                    &gEfiDeferredImageLoadProtocolGuid,\r
-                    &gDeferredImageLoad,\r
-                    NULL\r
-                    );\r
-    ASSERT_EFI_ERROR (Status);\r
-    mIsProtocolInstalled = TRUE;\r
-  }\r
-\r
-  return EFI_ACCESS_DENIED;\r
-}\r
-\r
-/**\r
-  Locate user manager protocol when user manager is installed.\r
-\r
-  @param[in] Event    The Event that is being processed, not used.\r
-  @param[in] Context  Event Context, not used.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-FindUserManagerProtocol (\r
-  IN EFI_EVENT    Event,\r
-  IN VOID*        Context\r
-  )\r
-{\r
-  gBS->LocateProtocol (\r
-         &gEfiUserManagerProtocolGuid,\r
-         NULL,\r
-         (VOID **) &mUserManager\r
-         );\r
-\r
-}\r
-\r
-\r
-/**\r
-  Register security handler for deferred image load.\r
-\r
-  @param[in]  ImageHandle   ImageHandle of the loaded driver.\r
-  @param[in]  SystemTable   Pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS   The handlers were registered successfully.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DxeDeferImageLoadLibConstructor (\r
-  IN EFI_HANDLE        ImageHandle,\r
-  IN EFI_SYSTEM_TABLE  *SystemTable\r
-  )\r
-{\r
-  VOID                 *Registration;\r
-\r
-  //\r
-  // Register user manager notification function.\r
-  //\r
-  EfiCreateProtocolNotifyEvent (\r
-    &gEfiUserManagerProtocolGuid,\r
-    TPL_CALLBACK,\r
-    FindUserManagerProtocol,\r
-    NULL,\r
-    &Registration\r
-    );\r
-\r
-  return RegisterSecurity2Handler (\r
-           DxeDeferImageLoadHandler,\r
-           EFI_AUTH_OPERATION_DEFER_IMAGE_LOAD\r
-           );\r
-}\r
-\r
-\r