--- /dev/null
+/** @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