Home | History | Annotate | Download | only in UserProfileManagerDxe
      1 /** @file
      2   The functions for access policy modification.
      3 
      4 Copyright (c) 2009 - 2013, 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 "UserProfileManager.h"
     16 
     17 /**
     18   Collect all the access policy data to mUserInfo.AccessPolicy,
     19   and save it to user profile.
     20 
     21 **/
     22 VOID
     23 SaveAccessPolicy (
     24   VOID
     25   )
     26 {
     27   EFI_STATUS                    Status;
     28   UINTN                         OffSet;
     29   UINTN                         Size;
     30   EFI_USER_INFO_ACCESS_CONTROL  Control;
     31   EFI_USER_INFO_HANDLE          UserInfo;
     32   EFI_USER_INFO                 *Info;
     33 
     34   if (mUserInfo.AccessPolicy != NULL) {
     35     FreePool (mUserInfo.AccessPolicy);
     36   }
     37   mUserInfo.AccessPolicy          = NULL;
     38   mUserInfo.AccessPolicyLen       = 0;
     39   mUserInfo.AccessPolicyModified  = TRUE;
     40   OffSet                          = 0;
     41 
     42   //
     43   // Save access right.
     44   //
     45   Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);
     46   if (mUserInfo.AccessPolicyLen - OffSet < Size) {
     47     ExpandMemory (OffSet, Size);
     48   }
     49 
     50   Control.Type = mAccessInfo.AccessRight;
     51   Control.Size = (UINT32) Size;
     52   CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
     53   OffSet += sizeof (Control);
     54 
     55   //
     56   // Save access setup.
     57   //
     58   Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (EFI_GUID);
     59   if (mUserInfo.AccessPolicyLen - OffSet < Size) {
     60     ExpandMemory (OffSet, Size);
     61   }
     62 
     63   Control.Type = EFI_USER_INFO_ACCESS_SETUP;
     64   Control.Size = (UINT32) Size;
     65   CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
     66   OffSet += sizeof (Control);
     67 
     68   if (mAccessInfo.AccessSetup == ACCESS_SETUP_NORMAL) {
     69     CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupNormalGuid);
     70   } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_RESTRICTED) {
     71     CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupRestrictedGuid);
     72   } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_ADMIN) {
     73     CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupAdminGuid);
     74   }
     75   OffSet += sizeof (EFI_GUID);
     76 
     77   //
     78   // Save access of boot order.
     79   //
     80   Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (UINT32);
     81   if (mUserInfo.AccessPolicyLen - OffSet < Size) {
     82     ExpandMemory (OffSet, Size);
     83   }
     84 
     85   Control.Type = EFI_USER_INFO_ACCESS_BOOT_ORDER;
     86   Control.Size = (UINT32) Size;
     87   CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
     88   OffSet += sizeof (Control);
     89 
     90   CopyMem ((UINT8 *) (mUserInfo.AccessPolicy + OffSet), &mAccessInfo.AccessBootOrder, sizeof (UINT32));
     91   OffSet += sizeof (UINT32);
     92 
     93   //
     94   // Save permit load.
     95   //
     96   if (mAccessInfo.LoadPermitLen > 0) {
     97     Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadPermitLen;
     98     if (mUserInfo.AccessPolicyLen - OffSet < Size) {
     99       ExpandMemory (OffSet, Size);
    100     }
    101 
    102     Control.Type = EFI_USER_INFO_ACCESS_PERMIT_LOAD;
    103     Control.Size = (UINT32) Size;
    104     CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
    105     OffSet += sizeof (Control);
    106 
    107     CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadPermit, mAccessInfo.LoadPermitLen);
    108     OffSet += mAccessInfo.LoadPermitLen;
    109   }
    110 
    111   //
    112   // Save forbid load.
    113   //
    114   if (mAccessInfo.LoadForbidLen > 0) {
    115     Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadForbidLen;
    116     if (mUserInfo.AccessPolicyLen - OffSet < Size) {
    117       ExpandMemory (OffSet, Size);
    118     }
    119 
    120     Control.Type = EFI_USER_INFO_ACCESS_FORBID_LOAD;
    121     Control.Size = (UINT32) Size;
    122     CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
    123     OffSet += sizeof (Control);
    124 
    125     CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);
    126     OffSet += mAccessInfo.LoadForbidLen;
    127   }
    128 
    129   //
    130   // Save permit connect.
    131   //
    132   if (mAccessInfo.ConnectPermitLen > 0) {
    133     Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectPermitLen;
    134     if (mUserInfo.AccessPolicyLen - OffSet < Size) {
    135       ExpandMemory (OffSet, Size);
    136     }
    137 
    138     Control.Type = EFI_USER_INFO_ACCESS_PERMIT_CONNECT;
    139     Control.Size = (UINT32) Size;
    140     CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
    141     OffSet += sizeof (Control);
    142 
    143     CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectPermit, mAccessInfo.ConnectPermitLen);
    144     OffSet += mAccessInfo.ConnectPermitLen;
    145   }
    146 
    147   //
    148   // Save forbid connect.
    149   //
    150   if (mAccessInfo.ConnectForbidLen > 0) {
    151     Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectForbidLen;
    152     if (mUserInfo.AccessPolicyLen - OffSet < Size) {
    153       ExpandMemory (OffSet, Size);
    154     }
    155 
    156     Control.Type = EFI_USER_INFO_ACCESS_FORBID_CONNECT;
    157     Control.Size = (UINT32) Size;
    158     CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
    159     OffSet += sizeof (Control);
    160 
    161     CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectForbid, mAccessInfo.ConnectForbidLen);
    162     OffSet += mAccessInfo.ConnectForbidLen;
    163   }
    164 
    165   mUserInfo.AccessPolicyLen = OffSet;
    166 
    167   //
    168   // Save access policy.
    169   //
    170   if (mUserInfo.AccessPolicyModified && (mUserInfo.AccessPolicyLen > 0) && (mUserInfo.AccessPolicy != NULL)) {
    171     Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);
    172     if (Info == NULL) {
    173       return ;
    174     }
    175 
    176     Status = FindInfoByType (mModifyUser, EFI_USER_INFO_ACCESS_POLICY_RECORD, &UserInfo);
    177     if (!EFI_ERROR (Status)) {
    178       Info->InfoType    = EFI_USER_INFO_ACCESS_POLICY_RECORD;
    179       Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
    180                           EFI_USER_INFO_PUBLIC |
    181                           EFI_USER_INFO_EXCLUSIVE;
    182       Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);
    183       CopyMem ((UINT8 *) (Info + 1), mUserInfo.AccessPolicy, mUserInfo.AccessPolicyLen);
    184       Status = mUserManager->SetInfo (
    185                                mUserManager,
    186                                mModifyUser,
    187                                &UserInfo,
    188                                Info,
    189                                Info->InfoSize
    190                                );
    191       mUserInfo.AccessPolicyModified = FALSE;
    192     }
    193     FreePool (Info);
    194   }
    195 
    196   if (mAccessInfo.ConnectForbid != NULL) {
    197     FreePool (mAccessInfo.ConnectForbid);
    198     mAccessInfo.ConnectForbid = NULL;
    199   }
    200 
    201   if (mAccessInfo.ConnectPermit != NULL) {
    202     FreePool (mAccessInfo.ConnectPermit);
    203     mAccessInfo.ConnectPermit = NULL;
    204   }
    205 
    206   if (mAccessInfo.LoadForbid != NULL) {
    207     FreePool (mAccessInfo.LoadForbid);
    208     mAccessInfo.LoadForbid = NULL;
    209   }
    210 
    211   if (mAccessInfo.LoadPermit != NULL) {
    212     FreePool (mAccessInfo.LoadPermit);
    213     mAccessInfo.LoadPermit = NULL;
    214   }
    215 }
    216 
    217 /**
    218   Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle.
    219 
    220   @param[in]  QuestionID            The question ID.
    221   @param[in]  DevicePath            Points to device path.
    222   @param[in]  OpCodeHandle          Points to container for dynamic created opcodes.
    223 
    224 **/
    225 VOID
    226 AddDevicePath (
    227   IN  UINTN                                     QuestionID,
    228   IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath,
    229   IN     VOID                                   *OpCodeHandle
    230   )
    231 {
    232   EFI_DEVICE_PATH_PROTOCOL          *Next;
    233   EFI_STRING_ID                     NameID;
    234   EFI_STRING                        DriverName;
    235 
    236   //
    237   // Get driver file name node.
    238   //
    239   Next = DevicePath;
    240   while (!IsDevicePathEnd (Next)) {
    241     DevicePath  = Next;
    242     Next        = NextDevicePathNode (Next);
    243   }
    244 
    245   //
    246   // Display the device path in form.
    247   //
    248   DriverName = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
    249   NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL);
    250   FreePool (DriverName);
    251   if (NameID == 0) {
    252     return ;
    253   }
    254 
    255   HiiCreateActionOpCode (
    256     OpCodeHandle,                   // Container for dynamic created opcodes
    257     (UINT16) QuestionID,            // Question ID
    258     NameID,                         // Prompt text
    259     STRING_TOKEN (STR_NULL_STRING), // Help text
    260     EFI_IFR_FLAG_CALLBACK,          // Question flag
    261     0                               // Action String ID
    262     );
    263 }
    264 
    265 
    266 /**
    267   Check whether the DevicePath is in the device path forbid list
    268   (mAccessInfo.LoadForbid).
    269 
    270   @param[in]  DevicePath           Points to device path.
    271 
    272   @retval TRUE     The DevicePath is in the device path forbid list.
    273   @retval FALSE    The DevicePath is not in the device path forbid list.
    274 
    275 **/
    276 BOOLEAN
    277 IsLoadForbidden (
    278   IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath
    279   )
    280 {
    281   UINTN                     OffSet;
    282   UINTN                     DPSize;
    283   UINTN                     Size;
    284   EFI_DEVICE_PATH_PROTOCOL  *Dp;
    285 
    286   OffSet = 0;
    287   Size   = GetDevicePathSize (DevicePath);
    288   //
    289   // Check each device path.
    290   //
    291   while (OffSet < mAccessInfo.LoadForbidLen) {
    292     Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
    293     DPSize  = GetDevicePathSize (Dp);
    294     //
    295     // Compare device path.
    296     //
    297     if ((DPSize == Size) && (CompareMem (DevicePath, Dp, Size) == 0)) {
    298       return TRUE;
    299     }
    300     OffSet += DPSize;
    301   }
    302   return FALSE;
    303 }
    304 
    305 
    306 /**
    307   Display the permit load device path in the loadable device path list.
    308 
    309 **/
    310 VOID
    311 DisplayLoadPermit(
    312   VOID
    313   )
    314 {
    315   EFI_STATUS          Status;
    316   CHAR16              *Order;
    317   UINTN               OrderSize;
    318   UINTN               ListCount;
    319   UINTN               Index;
    320   UINT8               *Var;
    321   UINT8               *VarPtr;
    322   CHAR16              VarName[12];
    323   VOID                *StartOpCodeHandle;
    324   VOID                *EndOpCodeHandle;
    325   EFI_IFR_GUID_LABEL  *StartLabel;
    326   EFI_IFR_GUID_LABEL  *EndLabel;
    327 
    328   //
    329   // Get DriverOrder.
    330   //
    331   OrderSize = 0;
    332   Status    = gRT->GetVariable (
    333                      L"DriverOrder",
    334                      &gEfiGlobalVariableGuid,
    335                      NULL,
    336                      &OrderSize,
    337                      NULL
    338                      );
    339   if (Status != EFI_BUFFER_TOO_SMALL) {
    340     return ;
    341   }
    342 
    343   Order = AllocateZeroPool (OrderSize);
    344   if (Order == NULL) {
    345     return ;
    346   }
    347 
    348   Status = gRT->GetVariable (
    349                   L"DriverOrder",
    350                   &gEfiGlobalVariableGuid,
    351                   NULL,
    352                   &OrderSize,
    353                   Order
    354                   );
    355   if (EFI_ERROR (Status)) {
    356     return ;
    357   }
    358 
    359   //
    360   // Initialize the container for dynamic opcodes.
    361   //
    362   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    363   ASSERT (StartOpCodeHandle != NULL);
    364 
    365   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    366   ASSERT (EndOpCodeHandle != NULL);
    367 
    368   //
    369   // Create Hii Extend Label OpCode.
    370   //
    371   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    372                                         StartOpCodeHandle,
    373                                         &gEfiIfrTianoGuid,
    374                                         NULL,
    375                                         sizeof (EFI_IFR_GUID_LABEL)
    376                                         );
    377   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
    378   StartLabel->Number        = LABEL_PERMIT_LOAD_FUNC;
    379 
    380   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    381                                       EndOpCodeHandle,
    382                                       &gEfiIfrTianoGuid,
    383                                       NULL,
    384                                       sizeof (EFI_IFR_GUID_LABEL)
    385                                       );
    386   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
    387   EndLabel->Number        = LABEL_END;
    388 
    389   //
    390   // Add each driver option.
    391   //
    392   Var       = NULL;
    393   ListCount = OrderSize / sizeof (UINT16);
    394   for (Index = 0; Index < ListCount; Index++) {
    395     //
    396     // Get driver device path.
    397     //
    398     UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]);
    399     GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL);
    400     if (Var == NULL) {
    401       continue;
    402     }
    403 
    404     //
    405     // Check whether the driver is already forbidden.
    406     //
    407 
    408     VarPtr = Var;
    409     //
    410     // Skip attribute.
    411     //
    412     VarPtr += sizeof (UINT32);
    413 
    414     //
    415     // Skip device path lenth.
    416     //
    417     VarPtr += sizeof (UINT16);
    418 
    419     //
    420     // Skip descript string.
    421     //
    422     VarPtr += StrSize ((UINT16 *) VarPtr);
    423 
    424     if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) {
    425       FreePool (Var);
    426       Var = NULL;
    427       continue;
    428     }
    429 
    430     AddDevicePath (
    431       KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index],
    432       (EFI_DEVICE_PATH_PROTOCOL *) VarPtr,
    433       StartOpCodeHandle
    434       );
    435     FreePool (Var);
    436     Var = NULL;
    437   }
    438 
    439   HiiUpdateForm (
    440     mCallbackInfo->HiiHandle, // HII handle
    441     &gUserProfileManagerGuid, // Formset GUID
    442     FORMID_PERMIT_LOAD_DP,    // Form ID
    443     StartOpCodeHandle,        // Label for where to insert opcodes
    444     EndOpCodeHandle           // Replace data
    445     );
    446 
    447   HiiFreeOpCodeHandle (StartOpCodeHandle);
    448   HiiFreeOpCodeHandle (EndOpCodeHandle);
    449 
    450   //
    451   // Clear Environment.
    452   //
    453   if (Var != NULL) {
    454     FreePool (Var);
    455   }
    456   FreePool (Order);
    457 }
    458 
    459 
    460 /**
    461   Display the forbid load device path list (mAccessInfo.LoadForbid).
    462 
    463 **/
    464 VOID
    465 DisplayLoadForbid (
    466   VOID
    467   )
    468 {
    469   UINTN                     Offset;
    470   UINTN                     DPSize;
    471   UINTN                     Index;
    472   EFI_DEVICE_PATH_PROTOCOL  *Dp;
    473   VOID                      *StartOpCodeHandle;
    474   VOID                      *EndOpCodeHandle;
    475   EFI_IFR_GUID_LABEL        *StartLabel;
    476   EFI_IFR_GUID_LABEL        *EndLabel;
    477 
    478   //
    479   // Initialize the container for dynamic opcodes.
    480   //
    481   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    482   ASSERT (StartOpCodeHandle != NULL);
    483 
    484   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    485   ASSERT (EndOpCodeHandle != NULL);
    486 
    487   //
    488   // Create Hii Extend Label OpCode.
    489   //
    490   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    491                                         StartOpCodeHandle,
    492                                         &gEfiIfrTianoGuid,
    493                                         NULL,
    494                                         sizeof (EFI_IFR_GUID_LABEL)
    495                                         );
    496   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
    497   StartLabel->Number        = LABLE_FORBID_LOAD_FUNC;
    498 
    499   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    500                                       EndOpCodeHandle,
    501                                       &gEfiIfrTianoGuid,
    502                                       NULL,
    503                                       sizeof (EFI_IFR_GUID_LABEL)
    504                                       );
    505   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
    506   EndLabel->Number        = LABEL_END;
    507 
    508   //
    509   // Add each forbid load drivers.
    510   //
    511   Offset  = 0;
    512   Index   = 0;
    513   while (Offset < mAccessInfo.LoadForbidLen) {
    514     Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset);
    515     DPSize  = GetDevicePathSize (Dp);
    516     AddDevicePath (
    517       KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index,
    518       Dp,
    519       StartOpCodeHandle
    520       );
    521     Index++;
    522     Offset += DPSize;
    523   }
    524 
    525   HiiUpdateForm (
    526     mCallbackInfo->HiiHandle, // HII handle
    527     &gUserProfileManagerGuid, // Formset GUID
    528     FORMID_FORBID_LOAD_DP,    // Form ID
    529     StartOpCodeHandle,        // Label for where to insert opcodes
    530     EndOpCodeHandle           // Replace data
    531     );
    532 
    533   HiiFreeOpCodeHandle (StartOpCodeHandle);
    534   HiiFreeOpCodeHandle (EndOpCodeHandle);
    535 }
    536 
    537 
    538 /**
    539   Display the permit connect device path.
    540 
    541 **/
    542 VOID
    543 DisplayConnectPermit (
    544   VOID
    545   )
    546 {
    547   //
    548   // Note:
    549   // As no architect protocol/interface to be called in ConnectController()
    550   // to verify the device path, just add a place holder for permitted connect
    551   // device path.
    552   //
    553 }
    554 
    555 
    556 /**
    557   Display the forbid connect device path list.
    558 
    559 **/
    560 VOID
    561 DisplayConnectForbid (
    562   VOID
    563   )
    564 {
    565   //
    566   // Note:
    567   // As no architect protocol/interface to be called in ConnectController()
    568   // to verify the device path, just add a place holder for forbidden connect
    569   // device path.
    570   //
    571 }
    572 
    573 
    574 /**
    575   Delete the specified device path by DriverIndex from the forbid device path
    576   list (mAccessInfo.LoadForbid).
    577 
    578   @param[in]  DriverIndex   The index of driver in forbidden device path list.
    579 
    580 **/
    581 VOID
    582 DeleteFromForbidLoad (
    583   IN  UINT16                                    DriverIndex
    584   )
    585 {
    586   UINTN                     OffSet;
    587   UINTN                     DPSize;
    588   UINTN                     OffLen;
    589   EFI_DEVICE_PATH_PROTOCOL  *Dp;
    590 
    591   OffSet = 0;
    592   //
    593   // Find the specified device path.
    594   //
    595   while ((OffSet < mAccessInfo.LoadForbidLen) && (DriverIndex > 0)) {
    596     Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
    597     DPSize  = GetDevicePathSize (Dp);
    598     OffSet += DPSize;
    599     DriverIndex--;
    600   }
    601 
    602   //
    603   // Specified device path found.
    604   //
    605   if (DriverIndex == 0) {
    606     Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
    607     DPSize  = GetDevicePathSize (Dp);
    608     OffLen  = mAccessInfo.LoadForbidLen - OffSet - DPSize;
    609     if (OffLen > 0) {
    610       CopyMem (
    611         mAccessInfo.LoadForbid + OffSet,
    612         mAccessInfo.LoadForbid + OffSet + DPSize,
    613         OffLen
    614         );
    615     }
    616     mAccessInfo.LoadForbidLen -= DPSize;
    617   }
    618 }
    619 
    620 
    621 /**
    622   Add the specified device path by DriverIndex to the forbid device path
    623   list (mAccessInfo.LoadForbid).
    624 
    625   @param[in]  DriverIndex   The index of driver saved in driver options.
    626 
    627 **/
    628 VOID
    629 AddToForbidLoad (
    630   IN  UINT16                                    DriverIndex
    631   )
    632 {
    633   UINTN       DevicePathLen;
    634   UINT8       *Var;
    635   UINT8       *VarPtr;
    636   UINTN       NewLen;
    637   UINT8       *NewFL;
    638   CHAR16      VarName[13];
    639 
    640   //
    641   // Get loadable driver device path.
    642   //
    643   UnicodeSPrint  (VarName, sizeof (VarName), L"Driver%04x", DriverIndex);
    644   GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL);
    645   if (Var == NULL) {
    646     return;
    647   }
    648 
    649   //
    650   // Save forbid load driver.
    651   //
    652 
    653   VarPtr = Var;
    654   //
    655   // Skip attribute.
    656   //
    657   VarPtr += sizeof (UINT32);
    658 
    659   DevicePathLen = *(UINT16 *) VarPtr;
    660   //
    661   // Skip device path length.
    662   //
    663   VarPtr += sizeof (UINT16);
    664 
    665   //
    666   // Skip description string.
    667   //
    668   VarPtr += StrSize ((UINT16 *) VarPtr);
    669 
    670   NewLen  = mAccessInfo.LoadForbidLen + DevicePathLen;
    671   NewFL   = AllocateZeroPool (NewLen);
    672   if (NewFL == NULL) {
    673     FreePool (Var);
    674     return ;
    675   }
    676 
    677   if (mAccessInfo.LoadForbidLen > 0) {
    678     CopyMem (NewFL, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);
    679     FreePool (mAccessInfo.LoadForbid);
    680   }
    681 
    682   CopyMem (NewFL + mAccessInfo.LoadForbidLen, VarPtr, DevicePathLen);
    683   mAccessInfo.LoadForbidLen = NewLen;
    684   mAccessInfo.LoadForbid    = NewFL;
    685   FreePool (Var);
    686 }
    687 
    688 
    689