]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/UserIdentification/UserProfileManagerDxe/ModifyAccessPolicy.c
Update UID drivers to align with latest UEFI spec 2.3.1.
[mirror_edk2.git] / SecurityPkg / UserIdentification / UserProfileManagerDxe / ModifyAccessPolicy.c
diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/ModifyAccessPolicy.c b/SecurityPkg/UserIdentification/UserProfileManagerDxe/ModifyAccessPolicy.c
new file mode 100644 (file)
index 0000000..613751e
--- /dev/null
@@ -0,0 +1,702 @@
+/** @file\r
+  The functions for access policy modification.\r
+    \r
+Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution.  The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UserProfileManager.h"\r
+\r
+/**\r
+  Collect all the access policy data to mUserInfo.AccessPolicy, \r
+  and save it to user profile.\r
+\r
+**/\r
+VOID\r
+SaveAccessPolicy (\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  UINTN                         OffSet;\r
+  UINTN                         Size;\r
+  EFI_USER_INFO_ACCESS_CONTROL  Control;\r
+  EFI_USER_INFO_HANDLE          UserInfo;\r
+  EFI_USER_INFO                 *Info;\r
+\r
+  if (mUserInfo.AccessPolicy != NULL) {\r
+    FreePool (mUserInfo.AccessPolicy);\r
+  }\r
+  mUserInfo.AccessPolicy          = NULL;\r
+  mUserInfo.AccessPolicyLen       = 0;\r
+  mUserInfo.AccessPolicyModified  = TRUE;\r
+  OffSet                          = 0;\r
+  \r
+  //\r
+  // Save access right.\r
+  //\r
+  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
+  if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
+    ExpandMemory (OffSet, Size);\r
+  }\r
+\r
+  Control.Type = mAccessInfo.AccessRight;\r
+  Control.Size = (UINT32) Size;\r
+  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
+  OffSet += sizeof (Control);\r
+  \r
+  //\r
+  // Save access setup.\r
+  //\r
+  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (EFI_GUID);\r
+  if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
+    ExpandMemory (OffSet, Size);\r
+  }\r
+\r
+  Control.Type = EFI_USER_INFO_ACCESS_SETUP;\r
+  Control.Size = (UINT32) Size;  \r
+  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
+  OffSet += sizeof (Control);\r
+  \r
+  if (mAccessInfo.AccessSetup == ACCESS_SETUP_NORMAL) {\r
+    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupNormalGuid);\r
+  } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_RESTRICTED) {\r
+    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupRestrictedGuid);\r
+  } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_ADMIN) {\r
+    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupAdminGuid);\r
+  }\r
+  OffSet += sizeof (EFI_GUID);\r
+  \r
+  //\r
+  // Save access of boot order.\r
+  //\r
+  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (UINT32);\r
+  if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
+    ExpandMemory (OffSet, Size);\r
+  }\r
+\r
+  Control.Type = EFI_USER_INFO_ACCESS_BOOT_ORDER;\r
+  Control.Size = (UINT32) Size;  \r
+  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
+  OffSet += sizeof (Control);\r
+\r
+  CopyMem ((UINT8 *) (mUserInfo.AccessPolicy + OffSet), &mAccessInfo.AccessBootOrder, sizeof (UINT32));\r
+  OffSet += sizeof (UINT32);\r
+  \r
+  //\r
+  // Save permit load.\r
+  //\r
+  if (mAccessInfo.LoadPermitLen > 0) {\r
+    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadPermitLen;\r
+    if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
+      ExpandMemory (OffSet, Size);\r
+    }\r
+\r
+    Control.Type = EFI_USER_INFO_ACCESS_PERMIT_LOAD;\r
+    Control.Size = (UINT32) Size;  \r
+    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
+    OffSet += sizeof (Control);\r
+  \r
+    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadPermit, mAccessInfo.LoadPermitLen);\r
+    OffSet += mAccessInfo.LoadPermitLen;\r
+  }\r
+  \r
+  //\r
+  // Save forbid load.\r
+  //\r
+  if (mAccessInfo.LoadForbidLen > 0) {\r
+    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadForbidLen;\r
+    if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
+      ExpandMemory (OffSet, Size);\r
+    }\r
+\r
+    Control.Type = EFI_USER_INFO_ACCESS_FORBID_LOAD;\r
+    Control.Size = (UINT32) Size;  \r
+    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
+    OffSet += sizeof (Control);\r
+    \r
+    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);\r
+    OffSet += mAccessInfo.LoadForbidLen;\r
+  }\r
+  \r
+  //\r
+  // Save permit connect.\r
+  //\r
+  if (mAccessInfo.ConnectPermitLen > 0) {\r
+    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectPermitLen;\r
+    if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
+      ExpandMemory (OffSet, Size);\r
+    }\r
+\r
+    Control.Type = EFI_USER_INFO_ACCESS_PERMIT_CONNECT;\r
+    Control.Size = (UINT32) Size;  \r
+    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
+    OffSet += sizeof (Control);\r
+    \r
+    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectPermit, mAccessInfo.ConnectPermitLen);\r
+    OffSet += mAccessInfo.ConnectPermitLen;\r
+  }\r
+  \r
+  //\r
+  // Save forbid connect.\r
+  //\r
+  if (mAccessInfo.ConnectForbidLen > 0) {\r
+    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectForbidLen;\r
+    if (mUserInfo.AccessPolicyLen - OffSet < Size) {\r
+      ExpandMemory (OffSet, Size);\r
+    }\r
+\r
+    Control.Type = EFI_USER_INFO_ACCESS_FORBID_CONNECT;\r
+    Control.Size = (UINT32) Size;  \r
+    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));\r
+    OffSet += sizeof (Control);\r
+    \r
+    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectForbid, mAccessInfo.ConnectForbidLen);\r
+    OffSet += mAccessInfo.ConnectForbidLen;\r
+  }\r
+\r
+  mUserInfo.AccessPolicyLen = OffSet;\r
+\r
+  //\r
+  // Save access policy.\r
+  //\r
+  if (mUserInfo.AccessPolicyModified && (mUserInfo.AccessPolicyLen > 0)) {\r
+    Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);\r
+    if (Info == NULL) {\r
+      return ;\r
+    }\r
+\r
+    Status = FindInfoByType (mModifyUser, EFI_USER_INFO_ACCESS_POLICY_RECORD, &UserInfo);\r
+    if (!EFI_ERROR (Status)) {\r
+      Info->InfoType    = EFI_USER_INFO_ACCESS_POLICY_RECORD;\r
+      Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |\r
+                          EFI_USER_INFO_PUBLIC |\r
+                          EFI_USER_INFO_EXCLUSIVE;\r
+      Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);\r
+      CopyMem ((UINT8 *) (Info + 1), mUserInfo.AccessPolicy, mUserInfo.AccessPolicyLen);\r
+      Status = mUserManager->SetInfo (\r
+                               mUserManager,\r
+                               mModifyUser,\r
+                               &UserInfo,\r
+                               Info,\r
+                               Info->InfoSize\r
+                               );\r
+      mUserInfo.AccessPolicyModified = FALSE;\r
+    }\r
+    FreePool (Info);\r
+  }\r
+\r
+  if (mAccessInfo.ConnectForbid != NULL) {\r
+    FreePool (mAccessInfo.ConnectForbid);\r
+    mAccessInfo.ConnectForbid = NULL;\r
+  }\r
+\r
+  if (mAccessInfo.ConnectPermit != NULL) {\r
+    FreePool (mAccessInfo.ConnectPermit);\r
+    mAccessInfo.ConnectPermit = NULL;\r
+  }\r
+\r
+  if (mAccessInfo.LoadForbid != NULL) {\r
+    FreePool (mAccessInfo.LoadForbid);\r
+    mAccessInfo.LoadForbid = NULL;\r
+  }\r
+\r
+  if (mAccessInfo.LoadPermit != NULL) {\r
+    FreePool (mAccessInfo.LoadPermit);\r
+    mAccessInfo.LoadPermit = NULL;\r
+  }\r
+}\r
+\r
+/**\r
+  Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle.\r
+\r
+  @param[in]  QuestionID            The question ID.\r
+  @param[in]  DevicePath            Points to device path.\r
+  @param[in]  OpCodeHandle          Points to container for dynamic created opcodes.\r
+\r
+**/\r
+VOID\r
+AddDevicePath (\r
+  IN  UINTN                                     QuestionID,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath,\r
+  IN     VOID                                   *OpCodeHandle\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  EFI_DEVICE_PATH_PROTOCOL          *Next;\r
+  EFI_STRING_ID                     NameID;\r
+  EFI_STRING                        DriverName;\r
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevicePathText;\r
+\r
+  //\r
+  // Locate device path to text protocol.\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiDevicePathToTextProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &DevicePathText\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return ;\r
+  }\r
+  \r
+  //\r
+  // Get driver file name node.\r
+  //\r
+  Next = DevicePath;\r
+  while (!IsDevicePathEnd (Next)) {\r
+    DevicePath  = Next;\r
+    Next        = NextDevicePathNode (Next);\r
+  }\r
+\r
+  //\r
+  // Display the device path in form.\r
+  //\r
+  DriverName = DevicePathText->ConvertDevicePathToText (DevicePath, FALSE, FALSE);\r
+  NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL);\r
+  FreePool (DriverName);\r
+  if (NameID == 0) {\r
+    return ;\r
+  }\r
+\r
+  HiiCreateActionOpCode (\r
+    OpCodeHandle,                   // Container for dynamic created opcodes\r
+    (UINT16) QuestionID,            // Question ID\r
+    NameID,                         // Prompt text\r
+    STRING_TOKEN (STR_NULL_STRING), // Help text\r
+    EFI_IFR_FLAG_CALLBACK,          // Question flag\r
+    0                               // Action String ID\r
+    );\r
+}\r
+\r
+\r
+/**\r
+  Check whether the DevicePath is in the device path forbid list \r
+  (mAccessInfo.LoadForbid).\r
+\r
+  @param[in]  DevicePath           Points to device path.\r
+  \r
+  @retval TRUE     The DevicePath is in the device path forbid list.\r
+  @retval FALSE    The DevicePath is not in the device path forbid list.\r
+\r
+**/\r
+BOOLEAN\r
+IsLoadForbidden (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath\r
+  )\r
+{\r
+  UINTN                     OffSet;\r
+  UINTN                     DPSize;\r
+  UINTN                     Size;\r
+  EFI_DEVICE_PATH_PROTOCOL  *Dp;\r
+\r
+  OffSet = 0;\r
+  Size   = GetDevicePathSize (DevicePath);\r
+  //\r
+  // Check each device path.\r
+  //\r
+  while (OffSet < mAccessInfo.LoadForbidLen) {\r
+    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
+    DPSize  = GetDevicePathSize (Dp);\r
+    //\r
+    // Compare device path.\r
+    //\r
+    if ((DPSize == Size) && (CompareMem (DevicePath, Dp, Size) == 0)) {\r
+      return TRUE;\r
+    }\r
+    OffSet += DPSize;\r
+  }\r
+  return FALSE;\r
+}\r
+\r
+\r
+/**\r
+  Display the permit load device path in the loadable device path list.\r
+\r
+**/\r
+VOID\r
+DisplayLoadPermit(\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  CHAR16              *Order;\r
+  UINTN               OrderSize;\r
+  UINTN               ListCount;\r
+  UINTN               Index;\r
+  UINT8               *Var;\r
+  UINT8               *VarPtr;\r
+  CHAR16              VarName[12];\r
+  VOID                *StartOpCodeHandle;\r
+  VOID                *EndOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL  *StartLabel;\r
+  EFI_IFR_GUID_LABEL  *EndLabel;\r
+\r
+  //\r
+  // Get DriverOrder.\r
+  //\r
+  OrderSize = 0;\r
+  Status    = gRT->GetVariable (\r
+                     L"DriverOrder", \r
+                     &gEfiGlobalVariableGuid, \r
+                     NULL, \r
+                     &OrderSize, \r
+                     NULL\r
+                     );\r
+  if (Status != EFI_BUFFER_TOO_SMALL) {\r
+    return ;\r
+  }\r
+\r
+  Order = AllocateZeroPool (OrderSize);\r
+  if (Order == NULL) {\r
+    return ;\r
+  }\r
+\r
+  Status = gRT->GetVariable (\r
+                  L"DriverOrder", \r
+                  &gEfiGlobalVariableGuid, \r
+                  NULL, \r
+                  &OrderSize, \r
+                  Order\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return ;\r
+  }\r
+  \r
+  //\r
+  // Initialize the container for dynamic opcodes.\r
+  //\r
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (StartOpCodeHandle != NULL);\r
+\r
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (EndOpCodeHandle != NULL);\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode.\r
+  //\r
+  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                        StartOpCodeHandle,\r
+                                        &gEfiIfrTianoGuid,\r
+                                        NULL,\r
+                                        sizeof (EFI_IFR_GUID_LABEL)\r
+                                        );\r
+  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
+  StartLabel->Number        = LABEL_PERMIT_LOAD_FUNC;\r
+\r
+  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                      EndOpCodeHandle,\r
+                                      &gEfiIfrTianoGuid,\r
+                                      NULL,\r
+                                      sizeof (EFI_IFR_GUID_LABEL)\r
+                                      );\r
+  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
+  EndLabel->Number        = LABEL_END;\r
+\r
+  //\r
+  // Add each driver option.\r
+  //\r
+  Var       = NULL;\r
+  ListCount = OrderSize / sizeof (UINT16);\r
+  for (Index = 0; Index < ListCount; Index++) {\r
+    //\r
+    // Get driver device path.\r
+    //\r
+    UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]);\r
+    Var = GetEfiGlobalVariable (VarName);\r
+    if (Var == NULL) {\r
+      continue;\r
+    }\r
+    \r
+    //\r
+    // Check whether the driver is already forbidden.\r
+    //\r
+    \r
+    VarPtr = Var;\r
+    //\r
+    // Skip attribute.\r
+    //\r
+    VarPtr += sizeof (UINT32);\r
+\r
+    //\r
+    // Skip device path lenth.\r
+    //\r
+    VarPtr += sizeof (UINT16);\r
+\r
+    //\r
+    // Skip descript string.\r
+    //\r
+    VarPtr += StrSize ((UINT16 *) VarPtr);\r
+\r
+    if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) {\r
+      FreePool (Var);\r
+      Var = NULL;\r
+      continue;\r
+    }\r
+\r
+    AddDevicePath (\r
+      KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index],\r
+      (EFI_DEVICE_PATH_PROTOCOL *) VarPtr,\r
+      StartOpCodeHandle\r
+      );\r
+    FreePool (Var);\r
+    Var = NULL;\r
+  }\r
+\r
+  HiiUpdateForm (\r
+    mCallbackInfo->HiiHandle, // HII handle\r
+    &gUserProfileManagerGuid, // Formset GUID\r
+    FORMID_PERMIT_LOAD_DP,    // Form ID\r
+    StartOpCodeHandle,        // Label for where to insert opcodes\r
+    EndOpCodeHandle           // Replace data\r
+    );\r
+\r
+  HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+  HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+\r
+  //\r
+  // Clear Environment.\r
+  //\r
+  if (Var != NULL) {\r
+    FreePool (Var);\r
+  }\r
+  FreePool (Order);\r
+}\r
+\r
+\r
+/**\r
+  Display the forbid load device path list (mAccessInfo.LoadForbid).\r
+\r
+**/\r
+VOID\r
+DisplayLoadForbid (\r
+  VOID\r
+  )\r
+{\r
+  UINTN                     Offset;\r
+  UINTN                     DPSize;\r
+  UINTN                     Index;\r
+  EFI_DEVICE_PATH_PROTOCOL  *Dp;\r
+  VOID                      *StartOpCodeHandle;\r
+  VOID                      *EndOpCodeHandle;\r
+  EFI_IFR_GUID_LABEL        *StartLabel;\r
+  EFI_IFR_GUID_LABEL        *EndLabel;\r
+\r
+  //\r
+  // Initialize the container for dynamic opcodes.\r
+  //\r
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (StartOpCodeHandle != NULL);\r
+\r
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  ASSERT (EndOpCodeHandle != NULL);\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode.\r
+  //\r
+  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                        StartOpCodeHandle,\r
+                                        &gEfiIfrTianoGuid,\r
+                                        NULL,\r
+                                        sizeof (EFI_IFR_GUID_LABEL)\r
+                                        );\r
+  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
+  StartLabel->Number        = LABLE_FORBID_LOAD_FUNC;\r
+\r
+  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                      EndOpCodeHandle,\r
+                                      &gEfiIfrTianoGuid,\r
+                                      NULL,\r
+                                      sizeof (EFI_IFR_GUID_LABEL)\r
+                                      );\r
+  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;\r
+  EndLabel->Number        = LABEL_END;\r
+\r
+  //\r
+  // Add each forbid load drivers.\r
+  //\r
+  Offset  = 0;\r
+  Index   = 0;\r
+  while (Offset < mAccessInfo.LoadForbidLen) {\r
+    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset);\r
+    DPSize  = GetDevicePathSize (Dp);\r
+    AddDevicePath (\r
+      KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index,\r
+      Dp,\r
+      StartOpCodeHandle\r
+      );\r
+    Index++;\r
+    Offset += DPSize;\r
+  }\r
+\r
+  HiiUpdateForm (\r
+    mCallbackInfo->HiiHandle, // HII handle\r
+    &gUserProfileManagerGuid, // Formset GUID\r
+    FORMID_FORBID_LOAD_DP,    // Form ID\r
+    StartOpCodeHandle,        // Label for where to insert opcodes\r
+    EndOpCodeHandle           // Replace data\r
+    );\r
+\r
+  HiiFreeOpCodeHandle (StartOpCodeHandle);\r
+  HiiFreeOpCodeHandle (EndOpCodeHandle);\r
+}\r
+\r
+\r
+/**\r
+  Display the permit connect device path.\r
+\r
+**/\r
+VOID\r
+DisplayConnectPermit (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Note: \r
+  // As no architect protocol/interface to be called in ConnectController()\r
+  // to verify the device path, just add a place holder for permitted connect\r
+  // device path.\r
+  //\r
+}\r
+\r
+\r
+/**\r
+  Display the forbid connect device path list.\r
+\r
+**/\r
+VOID\r
+DisplayConnectForbid (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Note: \r
+  // As no architect protocol/interface to be called in ConnectController()\r
+  // to verify the device path, just add a place holder for forbidden connect\r
+  // device path.\r
+  //\r
+}\r
+\r
+\r
+/**\r
+  Delete the specified device path by DriverIndex from the forbid device path \r
+  list (mAccessInfo.LoadForbid).\r
+\r
+  @param[in]  DriverIndex   The index of driver in forbidden device path list.\r
+  \r
+**/\r
+VOID\r
+DeleteFromForbidLoad (\r
+  IN  UINT16                                    DriverIndex\r
+  )\r
+{\r
+  UINTN                     OffSet;\r
+  UINTN                     DPSize;\r
+  UINTN                     OffLen;\r
+  EFI_DEVICE_PATH_PROTOCOL  *Dp;\r
+\r
+  OffSet = 0;\r
+  //\r
+  // Find the specified device path.\r
+  //\r
+  while ((OffSet < mAccessInfo.LoadForbidLen) && (DriverIndex > 0)) {\r
+    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
+    DPSize  = GetDevicePathSize (Dp);\r
+    OffSet += DPSize;\r
+    DriverIndex--;\r
+  }\r
+  \r
+  //\r
+  // Specified device path found.\r
+  //\r
+  if (DriverIndex == 0) {\r
+    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);\r
+    DPSize  = GetDevicePathSize (Dp);\r
+    OffLen  = mAccessInfo.LoadForbidLen - OffSet - DPSize;\r
+    if (OffLen > 0) {\r
+      CopyMem (\r
+        mAccessInfo.LoadForbid + OffSet, \r
+        mAccessInfo.LoadForbid + OffSet + DPSize, \r
+        OffLen\r
+        );\r
+    }\r
+    mAccessInfo.LoadForbidLen -= DPSize;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Add the specified device path by DriverIndex to the forbid device path \r
+  list (mAccessInfo.LoadForbid).\r
+\r
+  @param[in]  DriverIndex   The index of driver saved in driver options.\r
+  \r
+**/\r
+VOID\r
+AddToForbidLoad (\r
+  IN  UINT16                                    DriverIndex\r
+  )\r
+{\r
+  UINTN       DevicePathLen;\r
+  UINT8       *Var;\r
+  UINT8       *VarPtr;\r
+  UINTN       NewLen;\r
+  UINT8       *NewFL;\r
+  CHAR16      VarName[13];\r
+\r
+  //\r
+  // Get loadable driver device path.\r
+  //\r
+  UnicodeSPrint  (VarName, sizeof (VarName), L"Driver%04x", DriverIndex);\r
+  Var = GetEfiGlobalVariable (VarName);\r
+  if (Var == NULL) {\r
+    return;\r
+  }\r
+  \r
+  //\r
+  // Save forbid load driver.\r
+  //\r
+  \r
+  VarPtr = Var;\r
+  //\r
+  // Skip attribute.\r
+  //\r
+  VarPtr += sizeof (UINT32);\r
+\r
+  DevicePathLen = *(UINT16 *) VarPtr;\r
+  //\r
+  // Skip device path length.\r
+  //\r
+  VarPtr += sizeof (UINT16);\r
+\r
+  //\r
+  // Skip description string.\r
+  //\r
+  VarPtr += StrSize ((UINT16 *) VarPtr);\r
+\r
+  NewLen  = mAccessInfo.LoadForbidLen + DevicePathLen;\r
+  NewFL   = AllocateZeroPool (NewLen);\r
+  if (NewFL == NULL) {\r
+    FreePool (Var);\r
+    return ;\r
+  }\r
+\r
+  if (mAccessInfo.LoadForbidLen > 0) {\r
+    CopyMem (NewFL, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);\r
+    FreePool (mAccessInfo.LoadForbid);\r
+  }\r
+\r
+  CopyMem (NewFL + mAccessInfo.LoadForbidLen, VarPtr, DevicePathLen);\r
+  mAccessInfo.LoadForbidLen = NewLen;\r
+  mAccessInfo.LoadForbid    = NewFL;\r
+  FreePool (Var);\r
+}\r
+\r
+\r