Home | History | Annotate | Download | only in UserProfileManagerDxe
      1 /** @file
      2   The functions to modify a user profile.
      3 
      4 Copyright (c) 2009 - 2015, 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 EFI_USER_PROFILE_HANDLE           mModifyUser = NULL;
     18 
     19 /**
     20   Display user select form, cab select a user to modify.
     21 
     22 **/
     23 VOID
     24 SelectUserToModify  (
     25   VOID
     26   )
     27 {
     28   EFI_STATUS              Status;
     29   UINT8                   Index;
     30   EFI_USER_PROFILE_HANDLE User;
     31   EFI_USER_PROFILE_HANDLE CurrentUser;
     32   UINT32                  CurrentAccessRight;
     33   VOID                    *StartOpCodeHandle;
     34   VOID                    *EndOpCodeHandle;
     35   EFI_IFR_GUID_LABEL      *StartLabel;
     36   EFI_IFR_GUID_LABEL      *EndLabel;
     37 
     38   //
     39   // Initialize the container for dynamic opcodes.
     40   //
     41   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
     42   ASSERT (StartOpCodeHandle != NULL);
     43 
     44   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
     45   ASSERT (EndOpCodeHandle != NULL);
     46 
     47   //
     48   // Create Hii Extend Label OpCode.
     49   //
     50   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
     51                                         StartOpCodeHandle,
     52                                         &gEfiIfrTianoGuid,
     53                                         NULL,
     54                                         sizeof (EFI_IFR_GUID_LABEL)
     55                                         );
     56   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
     57   StartLabel->Number        = LABEL_USER_MOD_FUNC;
     58 
     59   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
     60                                       EndOpCodeHandle,
     61                                       &gEfiIfrTianoGuid,
     62                                       NULL,
     63                                       sizeof (EFI_IFR_GUID_LABEL)
     64                                       );
     65   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
     66   EndLabel->Number        = LABEL_END;
     67 
     68   //
     69   // Add each user can be modified.
     70   //
     71   User  = NULL;
     72   Index = 1;
     73   mUserManager->Current (mUserManager, &CurrentUser);
     74   while (TRUE) {
     75     Status = mUserManager->GetNext (mUserManager, &User);
     76     if (EFI_ERROR (Status)) {
     77       break;
     78     }
     79 
     80     Status = GetAccessRight (&CurrentAccessRight);
     81     if (EFI_ERROR (Status)) {
     82       CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
     83     }
     84 
     85     if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) || (User == CurrentUser)) {
     86       AddUserToForm (User, (UINT16)(KEY_MODIFY_USER | KEY_SELECT_USER | Index), StartOpCodeHandle);
     87     }
     88     Index++;
     89   }
     90 
     91   HiiUpdateForm (
     92     mCallbackInfo->HiiHandle, // HII handle
     93     &gUserProfileManagerGuid, // Formset GUID
     94     FORMID_MODIFY_USER,       // Form ID
     95     StartOpCodeHandle,        // Label for where to insert opcodes
     96     EndOpCodeHandle           // Replace data
     97     );
     98 
     99   HiiFreeOpCodeHandle (StartOpCodeHandle);
    100   HiiFreeOpCodeHandle (EndOpCodeHandle);
    101 }
    102 
    103 
    104 /**
    105   Get all the user info from mModifyUser in the user manager, and save on the
    106   global variable.
    107 
    108 **/
    109 VOID
    110 GetAllUserInfo (
    111   VOID
    112   )
    113 {
    114   EFI_STATUS            Status;
    115   EFI_USER_INFO_HANDLE  UserInfo;
    116   EFI_USER_INFO         *Info;
    117   UINTN                 InfoSize;
    118   UINTN                 MemSize;
    119   UINTN                 DataLen;
    120 
    121   //
    122   // Init variable to default value.
    123   //
    124   mProviderChoice                   = 0;
    125   mConncetLogical                   = 0;
    126 
    127   mUserInfo.CreateDateExist         = FALSE;
    128   mUserInfo.UsageDateExist          = FALSE;
    129   mUserInfo.UsageCount              = 0;
    130 
    131   mUserInfo.AccessPolicyLen         = 0;
    132   mUserInfo.AccessPolicyModified    = FALSE;
    133   if (mUserInfo.AccessPolicy != NULL) {
    134     FreePool (mUserInfo.AccessPolicy);
    135     mUserInfo.AccessPolicy = NULL;
    136   }
    137   mUserInfo.IdentityPolicyLen       = 0;
    138   mUserInfo.IdentityPolicyModified  = FALSE;
    139   if (mUserInfo.IdentityPolicy != NULL) {
    140     FreePool (mUserInfo.IdentityPolicy);
    141     mUserInfo.IdentityPolicy = NULL;
    142   }
    143 
    144   //
    145   // Allocate user information memory.
    146   //
    147   MemSize = sizeof (EFI_USER_INFO) + 63;
    148   Info    = AllocateZeroPool (MemSize);
    149   if (Info == NULL) {
    150     return ;
    151   }
    152 
    153   //
    154   // Get each user information.
    155   //
    156   UserInfo = NULL;
    157   while (TRUE) {
    158     Status = mUserManager->GetNextInfo (mUserManager, mModifyUser, &UserInfo);
    159     if (EFI_ERROR (Status)) {
    160       break;
    161     }
    162     //
    163     // Get information.
    164     //
    165     InfoSize  = MemSize;
    166     Status    = mUserManager->GetInfo (
    167                                 mUserManager,
    168                                 mModifyUser,
    169                                 UserInfo,
    170                                 Info,
    171                                 &InfoSize
    172                                 );
    173     if (Status == EFI_BUFFER_TOO_SMALL) {
    174       MemSize = InfoSize;
    175       FreePool (Info);
    176       Info = AllocateZeroPool (MemSize);
    177       if (Info == NULL) {
    178         return ;
    179       }
    180 
    181       Status = mUserManager->GetInfo (
    182                                mUserManager,
    183                                mModifyUser,
    184                                UserInfo,
    185                                Info,
    186                                &InfoSize
    187                                );
    188     }
    189 
    190     if (Status == EFI_SUCCESS) {
    191       //
    192       // Deal with each information according to informaiton type.
    193       //
    194       DataLen = Info->InfoSize - sizeof (EFI_USER_INFO);
    195       switch (Info->InfoType) {
    196       case EFI_USER_INFO_NAME_RECORD:
    197         CopyMem (&mUserInfo.UserName, (UINT8 *) (Info + 1), DataLen);
    198         break;
    199 
    200       case EFI_USER_INFO_CREATE_DATE_RECORD:
    201         CopyMem (&mUserInfo.CreateDate, (UINT8 *) (Info + 1), DataLen);
    202         mUserInfo.CreateDateExist = TRUE;
    203         break;
    204 
    205       case EFI_USER_INFO_USAGE_DATE_RECORD:
    206         CopyMem (&mUserInfo.UsageDate, (UINT8 *) (Info + 1), DataLen);
    207         mUserInfo.UsageDateExist = TRUE;
    208         break;
    209 
    210       case EFI_USER_INFO_USAGE_COUNT_RECORD:
    211         CopyMem (&mUserInfo.UsageCount, (UINT8 *) (Info + 1), DataLen);
    212         break;
    213 
    214       case EFI_USER_INFO_ACCESS_POLICY_RECORD:
    215         mUserInfo.AccessPolicy = AllocateZeroPool (DataLen);
    216         if (mUserInfo.AccessPolicy == NULL) {
    217           break;
    218         }
    219 
    220         CopyMem (mUserInfo.AccessPolicy, (UINT8 *) (Info + 1), DataLen);
    221         mUserInfo.AccessPolicyLen = DataLen;
    222         break;
    223 
    224       case EFI_USER_INFO_IDENTITY_POLICY_RECORD:
    225         mUserInfo.IdentityPolicy = AllocateZeroPool (DataLen);
    226         if (mUserInfo.IdentityPolicy == NULL) {
    227           break;
    228         }
    229 
    230         CopyMem (mUserInfo.IdentityPolicy, (UINT8 *) (Info + 1), DataLen);
    231         mUserInfo.IdentityPolicyLen = DataLen;
    232         break;
    233 
    234       default:
    235         break;
    236       }
    237     }
    238   }
    239   FreePool (Info);
    240 }
    241 
    242 
    243 /**
    244   Convert the Date to a string, and update the Hii database DateID string with it.
    245 
    246   @param[in] Date       Points to the date to be converted.
    247   @param[in] DateId     String ID in the HII database to be replaced.
    248 
    249 **/
    250 VOID
    251 ResolveDate (
    252   IN EFI_TIME                                   *Date,
    253   IN EFI_STRING_ID                              DateId
    254   )
    255 {
    256   CHAR16  *Str;
    257   UINTN   DateBufLen;
    258 
    259   //
    260   // Convert date to string.
    261   //
    262   DateBufLen = 64;
    263   Str        = AllocateZeroPool (DateBufLen);
    264   if (Str == NULL) {
    265     return ;
    266   }
    267 
    268   UnicodeSPrint (
    269     Str,
    270     DateBufLen,
    271     L"%4d-%2d-%2d ",
    272     Date->Year,
    273     Date->Month,
    274     Date->Day
    275     );
    276 
    277   //
    278   // Convert time to string.
    279   //
    280   DateBufLen -= StrLen (Str);
    281   UnicodeSPrint (
    282     Str + StrLen (Str),
    283     DateBufLen,
    284     L"%2d:%2d:%2d",
    285     Date->Hour,
    286     Date->Minute,
    287     Date->Second
    288     );
    289 
    290   HiiSetString (mCallbackInfo->HiiHandle, DateId, Str, NULL);
    291   FreePool (Str);
    292 }
    293 
    294 
    295 /**
    296   Convert the CountVal to a string, and update the Hii database CountId string
    297   with it.
    298 
    299   @param[in]  CountVal   The hex value to convert.
    300   @param[in]  CountId    String ID in the HII database to be replaced.
    301 
    302 **/
    303 VOID
    304 ResolveCount (
    305   IN UINT32                                     CountVal,
    306   IN EFI_STRING_ID                              CountId
    307   )
    308 {
    309   CHAR16  Count[10];
    310 
    311   UnicodeSPrint (Count, 20, L"%d", CountVal);
    312   HiiSetString (mCallbackInfo->HiiHandle, CountId, Count, NULL);
    313 }
    314 
    315 
    316 /**
    317   Concatenates one Null-terminated Unicode string to another Null-terminated
    318   Unicode string.
    319 
    320   @param[in, out]  Source1      On entry, point to a Null-terminated Unicode string.
    321                                 On exit, point to a new concatenated Unicode string
    322   @param[in]       Source2      Pointer to a Null-terminated Unicode string.
    323 
    324 **/
    325 VOID
    326 AddStr (
    327   IN OUT  CHAR16                  **Source1,
    328   IN      CONST CHAR16            *Source2
    329   )
    330 {
    331   CHAR16                        *TmpStr;
    332   UINTN                         StrLength;
    333 
    334   ASSERT (Source1 != NULL);
    335   ASSERT (Source2 != NULL);
    336 
    337   if (*Source1 == NULL) {
    338     StrLength = StrSize (Source2);
    339   } else {
    340     StrLength  = StrSize (*Source1);
    341     StrLength += StrSize (Source2) - 2;
    342   }
    343 
    344   TmpStr     = AllocateZeroPool (StrLength);
    345   ASSERT (TmpStr != NULL);
    346 
    347   if (*Source1 == NULL) {
    348     StrCpyS (TmpStr, StrLength / sizeof (CHAR16), Source2);
    349   } else {
    350     StrCpyS (TmpStr, StrLength / sizeof (CHAR16), *Source1);
    351     FreePool (*Source1);
    352     StrCatS (TmpStr, StrLength / sizeof (CHAR16),Source2);
    353   }
    354 
    355   *Source1 = TmpStr;
    356 }
    357 
    358 
    359 /**
    360   Convert the identity policy to a unicode string and update the Hii database
    361   IpStringId string with it.
    362 
    363   @param[in]  Ip         Points to identity policy.
    364   @param[in]  IpLen      The identity policy length.
    365   @param[in]  IpStringId String ID in the HII database to be replaced.
    366 
    367 **/
    368 VOID
    369 ResolveIdentityPolicy (
    370   IN  UINT8                                     *Ip,
    371   IN  UINTN                                     IpLen,
    372   IN  EFI_STRING_ID                             IpStringId
    373   )
    374 {
    375   CHAR16                        *TmpStr;
    376   UINTN                         ChkLen;
    377   EFI_USER_INFO_IDENTITY_POLICY *Identity;
    378   UINT16                        Index;
    379   CHAR16                        *ProvStr;
    380   EFI_STRING_ID                 ProvId;
    381   EFI_HII_HANDLE                HiiHandle;
    382   EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;
    383 
    384   TmpStr = NULL;
    385 
    386   //
    387   // Resolve each policy.
    388   //
    389   ChkLen  = 0;
    390   while (ChkLen < IpLen) {
    391     Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (Ip + ChkLen);
    392     switch (Identity->Type) {
    393     case EFI_USER_INFO_IDENTITY_FALSE:
    394       AddStr (&TmpStr, L"False");
    395       break;
    396 
    397     case EFI_USER_INFO_IDENTITY_TRUE:
    398       AddStr (&TmpStr, L"None");
    399       break;
    400 
    401     case EFI_USER_INFO_IDENTITY_NOT:
    402       AddStr (&TmpStr, L"! ");
    403       break;
    404 
    405     case EFI_USER_INFO_IDENTITY_AND:
    406       AddStr (&TmpStr, L" && ");
    407       break;
    408 
    409     case EFI_USER_INFO_IDENTITY_OR:
    410       AddStr (&TmpStr, L" || ");
    411       break;
    412 
    413     case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:
    414       for (Index = 0; Index < mProviderInfo->Count; Index++) {
    415         UserCredential = mProviderInfo->Provider[Index];
    416         if (CompareGuid ((EFI_GUID *) (Identity + 1), &UserCredential->Type)) {
    417           UserCredential->Title (
    418                             UserCredential,
    419                             &HiiHandle,
    420                             &ProvId
    421                             );
    422           ProvStr = HiiGetString (HiiHandle, ProvId, NULL);
    423           if (ProvStr != NULL) {
    424             AddStr (&TmpStr, ProvStr);
    425             FreePool (ProvStr);
    426           }
    427           break;
    428         }
    429       }
    430       break;
    431 
    432     case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
    433       for (Index = 0; Index < mProviderInfo->Count; Index++) {
    434         UserCredential = mProviderInfo->Provider[Index];
    435         if (CompareGuid ((EFI_GUID *) (Identity + 1), &UserCredential->Identifier)) {
    436           UserCredential->Title (
    437                             UserCredential,
    438                             &HiiHandle,
    439                             &ProvId
    440                             );
    441           ProvStr = HiiGetString (HiiHandle, ProvId, NULL);
    442           if (ProvStr != NULL) {
    443             AddStr (&TmpStr, ProvStr);
    444             FreePool (ProvStr);
    445           }
    446           break;
    447         }
    448       }
    449       break;
    450     }
    451 
    452     ChkLen += Identity->Length;
    453   }
    454 
    455   if (TmpStr != NULL) {
    456     HiiSetString (mCallbackInfo->HiiHandle, IpStringId, TmpStr, NULL);
    457     FreePool (TmpStr);
    458   }
    459 }
    460 
    461 
    462 /**
    463   Display modify user information form.
    464 
    465   This form displays, username, create Date, usage date, usage count, identity policy,
    466   and access policy.
    467 
    468   @param[in] UserIndex       The index of the user in display list to modify.
    469 
    470 **/
    471 VOID
    472 ModifyUserInfo (
    473   IN UINT8                                      UserIndex
    474   )
    475 {
    476   EFI_STATUS               Status;
    477   EFI_USER_PROFILE_HANDLE  CurrentUser;
    478   UINT32                   CurrentAccessRight;
    479   VOID                     *StartOpCodeHandle;
    480   VOID                     *EndOpCodeHandle;
    481   EFI_IFR_GUID_LABEL       *StartLabel;
    482   EFI_IFR_GUID_LABEL       *EndLabel;
    483 
    484   //
    485   // Initialize the container for dynamic opcodes.
    486   //
    487   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    488   ASSERT (StartOpCodeHandle != NULL);
    489 
    490   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    491   ASSERT (EndOpCodeHandle != NULL);
    492 
    493   //
    494   // Create Hii Extend Label OpCode.
    495   //
    496   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    497                                         StartOpCodeHandle,
    498                                         &gEfiIfrTianoGuid,
    499                                         NULL,
    500                                         sizeof (EFI_IFR_GUID_LABEL)
    501                                         );
    502   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
    503   StartLabel->Number        = LABEL_USER_INFO_FUNC;
    504 
    505   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    506                                       EndOpCodeHandle,
    507                                       &gEfiIfrTianoGuid,
    508                                       NULL,
    509                                       sizeof (EFI_IFR_GUID_LABEL)
    510                                       );
    511   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
    512   EndLabel->Number        = LABEL_END;
    513 
    514   //
    515   // Find the user profile to be modified.
    516   //
    517   mModifyUser = NULL;
    518   Status      = mUserManager->GetNext (mUserManager, &mModifyUser);
    519   if (EFI_ERROR (Status)) {
    520     return ;
    521   }
    522 
    523   while (UserIndex > 1) {
    524     Status = mUserManager->GetNext (mUserManager, &mModifyUser);
    525     if (EFI_ERROR (Status)) {
    526       return ;
    527     }
    528     UserIndex--;
    529   }
    530 
    531   //
    532   // Get user profile information.
    533   //
    534   GetAllUserInfo ();
    535 
    536   //
    537   // Update user name.
    538   HiiSetString (
    539     mCallbackInfo->HiiHandle,
    540     STRING_TOKEN (STR_USER_NAME_VAL),
    541     mUserInfo.UserName,
    542     NULL
    543     );
    544 
    545   //
    546   // Update create date.
    547   //
    548   if (mUserInfo.CreateDateExist) {
    549     ResolveDate (&mUserInfo.CreateDate, STRING_TOKEN (STR_CREATE_DATE_VAL));
    550   } else {
    551     HiiSetString (
    552       mCallbackInfo->HiiHandle,
    553       STRING_TOKEN (STR_CREATE_DATE_VAL),
    554       L"",
    555       NULL
    556       );
    557   }
    558 
    559   //
    560   // Add usage date.
    561   //
    562   if (mUserInfo.UsageDateExist) {
    563     ResolveDate (&mUserInfo.UsageDate, STRING_TOKEN (STR_USAGE_DATE_VAL));
    564   } else {
    565     HiiSetString (
    566       mCallbackInfo->HiiHandle,
    567       STRING_TOKEN (STR_USAGE_DATE_VAL),
    568       L"",
    569       NULL
    570       );
    571   }
    572 
    573   //
    574   // Add usage count.
    575   //
    576   ResolveCount ((UINT32) mUserInfo.UsageCount, STRING_TOKEN (STR_USAGE_COUNT_VAL));
    577 
    578   //
    579   // Add identity policy.
    580   //
    581   mUserManager->Current (mUserManager, &CurrentUser);
    582   if (mModifyUser == CurrentUser) {
    583     ResolveIdentityPolicy (
    584       mUserInfo.IdentityPolicy,
    585       mUserInfo.IdentityPolicyLen,
    586       STRING_TOKEN (STR_IDENTIFY_POLICY_VAL)
    587       );
    588     HiiCreateGotoOpCode (
    589       StartOpCodeHandle,                                  // Container for opcodes
    590       FORMID_MODIFY_IP,                                   // Target Form ID
    591       STRING_TOKEN (STR_IDENTIFY_POLICY),                 // Prompt text
    592       STRING_TOKEN (STR_IDENTIFY_POLICY_VAL),             // Help text
    593       EFI_IFR_FLAG_CALLBACK,                              // Question flag
    594       KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP   // Question ID
    595       );
    596   }
    597 
    598   //
    599   // Add access policy.
    600   //
    601   Status = GetAccessRight (&CurrentAccessRight);
    602   if (EFI_ERROR (Status)) {
    603     CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
    604   }
    605 
    606   if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) {
    607     HiiCreateGotoOpCode (
    608       StartOpCodeHandle,                                  // Container for opcodes
    609       FORMID_MODIFY_AP,                                   // Target Form ID
    610       STRING_TOKEN (STR_ACCESS_POLICY),                   // Prompt text
    611       STRING_TOKEN (STR_NULL_STRING),                     // Help text
    612       EFI_IFR_FLAG_CALLBACK,                              // Question flag
    613       KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP   // Question ID
    614       );
    615   }
    616 
    617   HiiUpdateForm (
    618     mCallbackInfo->HiiHandle,                             // HII handle
    619     &gUserProfileManagerGuid,                             // Formset GUID
    620     FORMID_USER_INFO,                                     // Form ID
    621     StartOpCodeHandle,                                    // Label
    622     EndOpCodeHandle                                       // Replace data
    623     );
    624 
    625   HiiFreeOpCodeHandle (StartOpCodeHandle);
    626   HiiFreeOpCodeHandle (EndOpCodeHandle);
    627 }
    628 
    629 
    630 /**
    631   Get all the access policy info from current user info, and save in the global
    632   variable.
    633 
    634 **/
    635 VOID
    636 ResolveAccessPolicy (
    637   VOID
    638   )
    639 {
    640   UINTN                         OffSet;
    641   EFI_USER_INFO_ACCESS_CONTROL  Control;
    642   UINTN                         ValLen;
    643   UINT8                         *AccessData;
    644 
    645   //
    646   // Set default value
    647   //
    648   mAccessInfo.AccessRight       = EFI_USER_INFO_ACCESS_ENROLL_SELF;
    649   mAccessInfo.AccessSetup       = ACCESS_SETUP_RESTRICTED;
    650   mAccessInfo.AccessBootOrder   = EFI_USER_INFO_ACCESS_BOOT_ORDER_INSERT;
    651 
    652   mAccessInfo.LoadPermitLen     = 0;
    653   mAccessInfo.LoadForbidLen     = 0;
    654   mAccessInfo.ConnectPermitLen  = 0;
    655   mAccessInfo.ConnectForbidLen  = 0;
    656 
    657   //
    658   // Get each user access policy.
    659   //
    660   OffSet = 0;
    661   while (OffSet < mUserInfo.AccessPolicyLen) {
    662     CopyMem (&Control, mUserInfo.AccessPolicy + OffSet, sizeof (Control));
    663     ValLen = Control.Size - sizeof (Control);
    664     switch (Control.Type) {
    665     case EFI_USER_INFO_ACCESS_ENROLL_SELF:
    666       mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
    667       break;
    668 
    669     case EFI_USER_INFO_ACCESS_ENROLL_OTHERS:
    670       mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_ENROLL_OTHERS;
    671       break;
    672 
    673     case EFI_USER_INFO_ACCESS_MANAGE:
    674       mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_MANAGE;
    675       break;
    676 
    677     case EFI_USER_INFO_ACCESS_SETUP:
    678       AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
    679       if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupNormalGuid)) {
    680         mAccessInfo.AccessSetup = ACCESS_SETUP_NORMAL;
    681       } else if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupRestrictedGuid)) {
    682         mAccessInfo.AccessSetup = ACCESS_SETUP_RESTRICTED;
    683       } else if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupAdminGuid)) {
    684         mAccessInfo.AccessSetup = ACCESS_SETUP_ADMIN;
    685       }
    686       break;
    687 
    688     case EFI_USER_INFO_ACCESS_BOOT_ORDER:
    689       AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
    690       CopyMem (&mAccessInfo.AccessBootOrder, AccessData, sizeof (UINT32));
    691       break;
    692 
    693     case EFI_USER_INFO_ACCESS_FORBID_LOAD:
    694       if (mAccessInfo.LoadForbid != NULL) {
    695         FreePool (mAccessInfo.LoadForbid);
    696       }
    697 
    698       mAccessInfo.LoadForbid = AllocateZeroPool (ValLen);
    699       if (mAccessInfo.LoadForbid != NULL) {
    700         AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
    701         CopyMem (mAccessInfo.LoadForbid, AccessData, ValLen);
    702         mAccessInfo.LoadForbidLen = ValLen;
    703       }
    704       break;
    705 
    706     case EFI_USER_INFO_ACCESS_PERMIT_LOAD:
    707       if (mAccessInfo.LoadPermit != NULL) {
    708         FreePool (mAccessInfo.LoadPermit);
    709       }
    710 
    711       mAccessInfo.LoadPermit = AllocateZeroPool (ValLen);
    712       if (mAccessInfo.LoadPermit != NULL) {
    713         AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
    714         CopyMem (mAccessInfo.LoadPermit, AccessData, ValLen);
    715         mAccessInfo.LoadPermitLen = ValLen;
    716       }
    717       break;
    718 
    719     case EFI_USER_INFO_ACCESS_FORBID_CONNECT:
    720       if (mAccessInfo.ConnectForbid != NULL) {
    721         FreePool (mAccessInfo.ConnectForbid);
    722       }
    723 
    724       mAccessInfo.ConnectForbid = AllocateZeroPool (ValLen);
    725       if (mAccessInfo.ConnectForbid != NULL) {
    726         AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
    727         CopyMem (mAccessInfo.ConnectForbid, AccessData, ValLen);
    728         mAccessInfo.ConnectForbidLen = ValLen;
    729       }
    730       break;
    731 
    732     case EFI_USER_INFO_ACCESS_PERMIT_CONNECT:
    733       if (mAccessInfo.ConnectPermit != NULL) {
    734         FreePool (mAccessInfo.ConnectPermit);
    735       }
    736 
    737       mAccessInfo.ConnectPermit = AllocateZeroPool (ValLen);
    738       if (mAccessInfo.ConnectPermit != NULL) {
    739         AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
    740         CopyMem (mAccessInfo.ConnectPermit, AccessData, ValLen);
    741         mAccessInfo.ConnectPermitLen = ValLen;
    742       }
    743       break;
    744     }
    745 
    746     OffSet += Control.Size;
    747   }
    748 }
    749 
    750 
    751 /**
    752   Find the specified info in User profile by the InfoType.
    753 
    754   @param[in]  User         Handle of the user whose information will be searched.
    755   @param[in]  InfoType     The user information type to find.
    756   @param[out] UserInfo     Points to user information handle found.
    757 
    758   @retval EFI_SUCCESS      Find the user information successfully.
    759   @retval Others           Fail to find the user information.
    760 
    761 **/
    762 EFI_STATUS
    763 FindInfoByType (
    764   IN  EFI_USER_PROFILE_HANDLE                   User,
    765   IN  UINT8                                     InfoType,
    766   OUT EFI_USER_INFO_HANDLE                      *UserInfo
    767   )
    768 {
    769   EFI_STATUS    Status;
    770   EFI_USER_INFO *Info;
    771   UINTN         InfoSize;
    772   UINTN         MemSize;
    773 
    774   if (UserInfo == NULL) {
    775     return EFI_INVALID_PARAMETER;
    776   }
    777 
    778   *UserInfo = NULL;
    779   //
    780   // Allocate user information memory.
    781   //
    782   MemSize = sizeof (EFI_USER_INFO) + 63;
    783   Info    = AllocateZeroPool (MemSize);
    784   if (Info == NULL) {
    785     return EFI_OUT_OF_RESOURCES;
    786   }
    787 
    788   //
    789   // Get each user information.
    790   //
    791   while (TRUE) {
    792     Status = mUserManager->GetNextInfo (mUserManager, User, UserInfo);
    793     if (EFI_ERROR (Status)) {
    794       break;
    795     }
    796     //
    797     // Get information.
    798     //
    799     InfoSize  = MemSize;
    800     Status    = mUserManager->GetInfo (
    801                                 mUserManager,
    802                                 User,
    803                                 *UserInfo,
    804                                 Info,
    805                                 &InfoSize
    806                                 );
    807     if (Status == EFI_BUFFER_TOO_SMALL) {
    808       MemSize = InfoSize;
    809       FreePool (Info);
    810       Info = AllocateZeroPool (MemSize);
    811       if (Info == NULL) {
    812         return EFI_OUT_OF_RESOURCES;
    813       }
    814       Status = mUserManager->GetInfo (
    815                                mUserManager,
    816                                User,
    817                                *UserInfo,
    818                                Info,
    819                                &InfoSize
    820                                );
    821     }
    822     if (Status == EFI_SUCCESS) {
    823       if (Info->InfoType == InfoType) {
    824         break;
    825       }
    826     }
    827   }
    828 
    829   FreePool (Info);
    830   return Status;
    831 }
    832 
    833 
    834 /**
    835   Display modify user access policy form.
    836 
    837   In this form, access right, access setup and access boot order are dynamically
    838   added. Load devicepath and connect devicepath are displayed too.
    839 
    840 **/
    841 VOID
    842 ModidyAccessPolicy (
    843   VOID
    844   )
    845 {
    846   VOID                *StartOpCodeHandle;
    847   VOID                *EndOpCodeHandle;
    848   VOID                *OptionsOpCodeHandle;
    849   EFI_IFR_GUID_LABEL  *StartLabel;
    850   EFI_IFR_GUID_LABEL  *EndLabel;
    851   VOID                *DefaultOpCodeHandle;
    852 
    853   //
    854   // Initialize the container for dynamic opcodes.
    855   //
    856   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    857   ASSERT (StartOpCodeHandle != NULL);
    858 
    859   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    860   ASSERT (EndOpCodeHandle != NULL);
    861 
    862   //
    863   // Create Hii Extend Label OpCode.
    864   //
    865   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    866                                         StartOpCodeHandle,
    867                                         &gEfiIfrTianoGuid,
    868                                         NULL,
    869                                         sizeof (EFI_IFR_GUID_LABEL)
    870                                         );
    871   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
    872   StartLabel->Number        = LABEL_AP_MOD_FUNC;
    873 
    874   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    875                                       EndOpCodeHandle,
    876                                       &gEfiIfrTianoGuid,
    877                                       NULL,
    878                                       sizeof (EFI_IFR_GUID_LABEL)
    879                                       );
    880   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
    881   EndLabel->Number        = LABEL_END;
    882 
    883 
    884   //
    885   // Resolve access policy information.
    886   //
    887   ResolveAccessPolicy ();
    888 
    889   //
    890   // Add access right one-of-code.
    891   //
    892   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    893   ASSERT (OptionsOpCodeHandle != NULL);
    894   DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
    895   ASSERT (DefaultOpCodeHandle != NULL);
    896 
    897   HiiCreateOneOfOptionOpCode (
    898     OptionsOpCodeHandle,
    899     STRING_TOKEN (STR_NORMAL),
    900     0,
    901     EFI_IFR_NUMERIC_SIZE_1,
    902     EFI_USER_INFO_ACCESS_ENROLL_SELF
    903     );
    904 
    905   HiiCreateOneOfOptionOpCode (
    906     OptionsOpCodeHandle,
    907     STRING_TOKEN (STR_ENROLL),
    908     0,
    909     EFI_IFR_NUMERIC_SIZE_1,
    910     EFI_USER_INFO_ACCESS_ENROLL_OTHERS
    911     );
    912 
    913   HiiCreateOneOfOptionOpCode (
    914     OptionsOpCodeHandle,
    915     STRING_TOKEN (STR_MANAGE),
    916     0,
    917     EFI_IFR_NUMERIC_SIZE_1,
    918     EFI_USER_INFO_ACCESS_MANAGE
    919     );
    920 
    921   HiiCreateDefaultOpCode (
    922     DefaultOpCodeHandle,
    923     EFI_HII_DEFAULT_CLASS_STANDARD,
    924     EFI_IFR_NUMERIC_SIZE_1,
    925     mAccessInfo.AccessRight
    926     );
    927 
    928   HiiCreateOneOfOpCode (
    929     StartOpCodeHandle,                    // Container for dynamic created opcodes
    930     KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_RIGHT, // Question ID
    931     0,                                    // VarStore ID
    932     0,                                    // Offset in Buffer Storage
    933     STRING_TOKEN (STR_ACCESS_RIGHT),      // Question prompt text
    934     STRING_TOKEN (STR_ACCESS_RIGHT_HELP), // Question help text
    935     EFI_IFR_FLAG_CALLBACK,                // Question flag
    936     EFI_IFR_NUMERIC_SIZE_1,               // Data type of Question Value
    937     OptionsOpCodeHandle,                  // Option Opcode list
    938     DefaultOpCodeHandle                   // Default Opcode
    939     );
    940   HiiFreeOpCodeHandle (DefaultOpCodeHandle);
    941   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
    942 
    943 
    944   //
    945   // Add setup type one-of-code.
    946   //
    947   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    948   ASSERT (OptionsOpCodeHandle != NULL);
    949   DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
    950   ASSERT (DefaultOpCodeHandle != NULL);
    951 
    952   HiiCreateOneOfOptionOpCode (
    953     OptionsOpCodeHandle,
    954     STRING_TOKEN (STR_RESTRICTED),
    955     0,
    956     EFI_IFR_NUMERIC_SIZE_1,
    957     ACCESS_SETUP_RESTRICTED
    958     );
    959 
    960   HiiCreateOneOfOptionOpCode (
    961     OptionsOpCodeHandle,
    962     STRING_TOKEN (STR_NORMAL),
    963     0,
    964     EFI_IFR_NUMERIC_SIZE_1,
    965     ACCESS_SETUP_NORMAL
    966     );
    967 
    968   HiiCreateOneOfOptionOpCode (
    969     OptionsOpCodeHandle,
    970     STRING_TOKEN (STR_ADMIN),
    971     0,
    972     EFI_IFR_NUMERIC_SIZE_1,
    973     ACCESS_SETUP_ADMIN
    974     );
    975 
    976   HiiCreateDefaultOpCode (
    977     DefaultOpCodeHandle,
    978     EFI_HII_DEFAULT_CLASS_STANDARD,
    979     EFI_IFR_NUMERIC_SIZE_1,
    980     mAccessInfo.AccessSetup
    981     );
    982 
    983   HiiCreateOneOfOpCode (
    984     StartOpCodeHandle,                    // Container for dynamic created opcodes
    985     KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_SETUP, // Question ID
    986     0,                                    // VarStore ID
    987     0,                                    // Offset in Buffer Storage
    988     STRING_TOKEN (STR_ACCESS_SETUP),      // Question prompt text
    989     STRING_TOKEN (STR_ACCESS_SETUP_HELP), // Question help text
    990     EFI_IFR_FLAG_CALLBACK,                // Question flag
    991     EFI_IFR_NUMERIC_SIZE_1,               // Data type of Question Value
    992     OptionsOpCodeHandle,                  // Option Opcode list
    993     DefaultOpCodeHandle                   // Default Opcode
    994     );
    995   HiiFreeOpCodeHandle (DefaultOpCodeHandle);
    996   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
    997 
    998   //
    999   // Add boot order one-of-code.
   1000   //
   1001   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
   1002   ASSERT (OptionsOpCodeHandle != NULL);
   1003   DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
   1004   ASSERT (DefaultOpCodeHandle != NULL);
   1005 
   1006   HiiCreateOneOfOptionOpCode (
   1007     OptionsOpCodeHandle,
   1008     STRING_TOKEN (STR_INSERT),
   1009     0,
   1010     EFI_IFR_NUMERIC_SIZE_4,
   1011     EFI_USER_INFO_ACCESS_BOOT_ORDER_INSERT
   1012     );
   1013 
   1014   HiiCreateOneOfOptionOpCode (
   1015     OptionsOpCodeHandle,
   1016     STRING_TOKEN (STR_APPEND),
   1017     0,
   1018     EFI_IFR_NUMERIC_SIZE_4,
   1019     EFI_USER_INFO_ACCESS_BOOT_ORDER_APPEND
   1020     );
   1021 
   1022   HiiCreateOneOfOptionOpCode (
   1023     OptionsOpCodeHandle,
   1024     STRING_TOKEN (STR_REPLACE),
   1025     0,
   1026     EFI_IFR_NUMERIC_SIZE_4,
   1027     EFI_USER_INFO_ACCESS_BOOT_ORDER_REPLACE
   1028     );
   1029 
   1030   HiiCreateOneOfOptionOpCode (
   1031     OptionsOpCodeHandle,
   1032     STRING_TOKEN (STR_NODEFAULT),
   1033     0,
   1034     EFI_IFR_NUMERIC_SIZE_4,
   1035     EFI_USER_INFO_ACCESS_BOOT_ORDER_NODEFAULT
   1036     );
   1037 
   1038   HiiCreateDefaultOpCode (
   1039     DefaultOpCodeHandle,
   1040     EFI_HII_DEFAULT_CLASS_STANDARD,
   1041     EFI_IFR_NUMERIC_SIZE_4,
   1042     mAccessInfo.AccessBootOrder
   1043     );
   1044 
   1045   HiiCreateOneOfOpCode (
   1046     StartOpCodeHandle,                  // Container for dynamic created opcodes
   1047     KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_BOOT, // Question ID
   1048     0,                                  // VarStore ID
   1049     0,                                  // Offset in Buffer Storage
   1050     STRING_TOKEN (STR_BOOR_ORDER),      // Question prompt text
   1051     STRING_TOKEN (STR_BOOT_ORDER_HELP), // Question help text
   1052     EFI_IFR_FLAG_CALLBACK,              // Question flag
   1053     EFI_IFR_NUMERIC_SIZE_1,             // Data type of Question Value
   1054     OptionsOpCodeHandle,                // Option Opcode list
   1055     DefaultOpCodeHandle                 // Default Opcode
   1056     );
   1057   HiiFreeOpCodeHandle (DefaultOpCodeHandle);
   1058   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1059 
   1060   //
   1061   // Update Form.
   1062   //
   1063   HiiUpdateForm (
   1064     mCallbackInfo->HiiHandle,           // HII handle
   1065     &gUserProfileManagerGuid,           // Formset GUID
   1066     FORMID_MODIFY_AP,                   // Form ID
   1067     StartOpCodeHandle,                  // Label for where to insert opcodes
   1068     EndOpCodeHandle                     // Replace data
   1069     );
   1070 
   1071   HiiFreeOpCodeHandle (StartOpCodeHandle);
   1072   HiiFreeOpCodeHandle (EndOpCodeHandle);
   1073 }
   1074 
   1075 
   1076 /**
   1077   Expand access policy memory size.
   1078 
   1079   @param[in] ValidLen       The valid access policy length.
   1080   @param[in] ExpandLen      The length that is needed to expand.
   1081 
   1082 **/
   1083 VOID
   1084 ExpandMemory (
   1085   IN      UINTN                                 ValidLen,
   1086   IN      UINTN                                 ExpandLen
   1087   )
   1088 {
   1089   UINT8 *Mem;
   1090   UINTN Len;
   1091 
   1092   //
   1093   // Expand memory.
   1094   //
   1095   Len = mUserInfo.AccessPolicyLen + (ExpandLen / 64 + 1) * 64;
   1096   Mem = AllocateZeroPool (Len);
   1097   ASSERT (Mem != NULL);
   1098 
   1099   if (mUserInfo.AccessPolicy != NULL) {
   1100     CopyMem (Mem, mUserInfo.AccessPolicy, ValidLen);
   1101     FreePool (mUserInfo.AccessPolicy);
   1102   }
   1103 
   1104   mUserInfo.AccessPolicy    = Mem;
   1105   mUserInfo.AccessPolicyLen = Len;
   1106 }
   1107 
   1108 
   1109 /**
   1110   Get the username from user input, and update username string in the Hii
   1111   database with it.
   1112 
   1113 **/
   1114 VOID
   1115 ModifyUserName (
   1116   VOID
   1117   )
   1118 {
   1119   EFI_STATUS              Status;
   1120   CHAR16                  UserName[USER_NAME_LENGTH];
   1121   UINTN                   Len;
   1122   EFI_INPUT_KEY           Key;
   1123   EFI_USER_INFO_HANDLE    UserInfo;
   1124   EFI_USER_INFO           *Info;
   1125   EFI_USER_PROFILE_HANDLE TempUser;
   1126 
   1127   //
   1128   // Get the new user name.
   1129   //
   1130   Len = sizeof (UserName);
   1131   Status = GetUserNameInput (&Len, UserName);
   1132   if (EFI_ERROR (Status)) {
   1133     if (Status != EFI_ABORTED) {
   1134       CreatePopUp (
   1135         EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
   1136         &Key,
   1137         L"Failed To Get User Name.",
   1138         L"",
   1139         L"Please Press Any Key to Continue ...",
   1140         NULL
   1141         );
   1142     }
   1143     return ;
   1144   }
   1145 
   1146   //
   1147   // Check whether the username had been used or not.
   1148   //
   1149   Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + Len);
   1150   if (Info == NULL) {
   1151     return ;
   1152   }
   1153 
   1154   Info->InfoType    = EFI_USER_INFO_NAME_RECORD;
   1155   Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
   1156                       EFI_USER_INFO_PUBLIC |
   1157                       EFI_USER_INFO_EXCLUSIVE;
   1158   Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + Len);
   1159   CopyMem ((UINT8 *) (Info + 1), UserName, Len);
   1160 
   1161   TempUser  = NULL;
   1162   Status    = mUserManager->Find (
   1163                               mUserManager,
   1164                               &TempUser,
   1165                               NULL,
   1166                               Info,
   1167                               Info->InfoSize
   1168                               );
   1169   if (!EFI_ERROR (Status)) {
   1170     CreatePopUp (
   1171       EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
   1172       &Key,
   1173       L"The User Name Had Been Used.",
   1174       L"",
   1175       L"Please Use Other User Name",
   1176       NULL
   1177       );
   1178     FreePool (Info);
   1179     return ;
   1180   }
   1181 
   1182   //
   1183   // Update username display in the form.
   1184   //
   1185   CopyMem (mUserInfo.UserName, UserName, Len);
   1186   HiiSetString (
   1187     mCallbackInfo->HiiHandle,
   1188     STRING_TOKEN (STR_USER_NAME_VAL),
   1189     mUserInfo.UserName,
   1190     NULL
   1191     );
   1192 
   1193   //
   1194   // Save the user name.
   1195   //
   1196   Status = FindInfoByType (mModifyUser, EFI_USER_INFO_NAME_RECORD, &UserInfo);
   1197   if (!EFI_ERROR (Status)) {
   1198     mUserManager->SetInfo (
   1199                     mUserManager,
   1200                     mModifyUser,
   1201                     &UserInfo,
   1202                     Info,
   1203                     Info->InfoSize
   1204                     );
   1205   }
   1206   FreePool (Info);
   1207 }
   1208 
   1209 
   1210 /**
   1211   Display the form of the modifying user identity policy.
   1212 
   1213 **/
   1214 VOID
   1215 ModifyIdentityPolicy (
   1216   VOID
   1217   )
   1218 {
   1219   UINTN               Index;
   1220   CHAR16              *ProvStr;
   1221   EFI_STRING_ID       ProvID;
   1222   EFI_HII_HANDLE      HiiHandle;
   1223   VOID                *OptionsOpCodeHandle;
   1224   VOID                *StartOpCodeHandle;
   1225   VOID                *EndOpCodeHandle;
   1226   EFI_IFR_GUID_LABEL  *StartLabel;
   1227   EFI_IFR_GUID_LABEL  *EndLabel;
   1228 
   1229   //
   1230   // Initialize the container for dynamic opcodes.
   1231   //
   1232   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
   1233   ASSERT (StartOpCodeHandle != NULL);
   1234 
   1235   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
   1236   ASSERT (EndOpCodeHandle != NULL);
   1237 
   1238   //
   1239   // Create Hii Extend Label OpCode.
   1240   //
   1241   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
   1242                                         StartOpCodeHandle,
   1243                                         &gEfiIfrTianoGuid,
   1244                                         NULL,
   1245                                         sizeof (EFI_IFR_GUID_LABEL)
   1246                                         );
   1247   StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
   1248   StartLabel->Number        = LABEL_IP_MOD_FUNC;
   1249 
   1250   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
   1251                                       EndOpCodeHandle,
   1252                                       &gEfiIfrTianoGuid,
   1253                                       NULL,
   1254                                       sizeof (EFI_IFR_GUID_LABEL)
   1255                                       );
   1256   EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
   1257   EndLabel->Number        = LABEL_END;
   1258 
   1259   //
   1260   // Add credential providers
   1261   //.
   1262   if (mProviderInfo->Count > 0) {
   1263     OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
   1264     ASSERT (OptionsOpCodeHandle != NULL);
   1265 
   1266     //
   1267     // Add credential provider Option OpCode.
   1268     //
   1269     for (Index = 0; Index < mProviderInfo->Count; Index++) {
   1270       mProviderInfo->Provider[Index]->Title (
   1271                                         mProviderInfo->Provider[Index],
   1272                                         &HiiHandle,
   1273                                         &ProvID
   1274                                         );
   1275       ProvStr = HiiGetString (HiiHandle, ProvID, NULL);
   1276       ProvID  = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);
   1277       FreePool (ProvStr);
   1278       if (ProvID == 0) {
   1279         return ;
   1280       }
   1281 
   1282       HiiCreateOneOfOptionOpCode (
   1283         OptionsOpCodeHandle,
   1284         ProvID,
   1285         0,
   1286         EFI_IFR_NUMERIC_SIZE_1,
   1287         (UINT8) Index
   1288         );
   1289     }
   1290 
   1291     HiiCreateOneOfOpCode (
   1292       StartOpCodeHandle,                // Container for dynamic created opcodes
   1293       KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP | KEY_MODIFY_PROV,  // Question ID
   1294       0,                                // VarStore ID
   1295       0,                                // Offset in Buffer Storage
   1296       STRING_TOKEN (STR_PROVIDER),      // Question prompt text
   1297       STRING_TOKEN (STR_PROVIDER_HELP), // Question help text
   1298       EFI_IFR_FLAG_CALLBACK,            // Question flag
   1299       EFI_IFR_NUMERIC_SIZE_1,           // Data type of Question Value
   1300       OptionsOpCodeHandle,              // Option Opcode list
   1301       NULL                              // Default Opcode is NULl
   1302       );
   1303 
   1304     HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1305   }
   1306 
   1307   //
   1308   // Add logical connector Option OpCode.
   1309   //
   1310   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
   1311   ASSERT (OptionsOpCodeHandle != NULL);
   1312 
   1313   HiiCreateOneOfOptionOpCode (
   1314     OptionsOpCodeHandle,
   1315     STRING_TOKEN (STR_AND_CON),
   1316     0,
   1317     EFI_IFR_NUMERIC_SIZE_1,
   1318     0
   1319     );
   1320 
   1321   HiiCreateOneOfOptionOpCode (
   1322     OptionsOpCodeHandle,
   1323     STRING_TOKEN (STR_OR_CON),
   1324     0,
   1325     EFI_IFR_NUMERIC_SIZE_1,
   1326     1
   1327     );
   1328 
   1329   HiiCreateOneOfOpCode (
   1330     StartOpCodeHandle,                  // Container for dynamic created opcodes
   1331     KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP | KEY_MODIFY_CONN,  // Question ID
   1332     0,                                  // VarStore ID
   1333     0,                                  // Offset in Buffer Storage
   1334     STRING_TOKEN (STR_CONNECTOR),       // Question prompt text
   1335     STRING_TOKEN (STR_CONNECTOR_HELP),  // Question help text
   1336     EFI_IFR_FLAG_CALLBACK,              // Question flag
   1337     EFI_IFR_NUMERIC_SIZE_1,             // Data type of Question Value
   1338     OptionsOpCodeHandle,                // Option Opcode list
   1339     NULL                                // Default Opcode is NULl
   1340     );
   1341 
   1342   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1343 
   1344   //
   1345   // Update identity policy in the form.
   1346   //
   1347   ResolveIdentityPolicy (
   1348     mUserInfo.IdentityPolicy,
   1349     mUserInfo.IdentityPolicyLen,
   1350     STRING_TOKEN (STR_IDENTIFY_POLICY_VALUE)
   1351     );
   1352 
   1353   if (mUserInfo.NewIdentityPolicy != NULL) {
   1354     FreePool (mUserInfo.NewIdentityPolicy);
   1355     mUserInfo.NewIdentityPolicy         = NULL;
   1356     mUserInfo.NewIdentityPolicyLen      = 0;
   1357     mUserInfo.NewIdentityPolicyModified = FALSE;
   1358   }
   1359   mProviderChoice = 0;
   1360   mConncetLogical = 0;
   1361 
   1362   HiiUpdateForm (
   1363     mCallbackInfo->HiiHandle, // HII handle
   1364     &gUserProfileManagerGuid, // Formset GUID
   1365     FORMID_MODIFY_IP,         // Form ID
   1366     StartOpCodeHandle,        // Label for where to insert opcodes
   1367     EndOpCodeHandle           // Replace data
   1368     );
   1369 
   1370   HiiFreeOpCodeHandle (StartOpCodeHandle);
   1371   HiiFreeOpCodeHandle (EndOpCodeHandle);
   1372 }
   1373 
   1374 
   1375 /**
   1376   Get current user's access right.
   1377 
   1378   @param[out]  AccessRight  Points to the buffer used for user's access right.
   1379 
   1380   @retval EFI_SUCCESS       Get current user access right successfully.
   1381   @retval others            Fail to get current user access right.
   1382 
   1383 **/
   1384 EFI_STATUS
   1385 GetAccessRight (
   1386   OUT  UINT32                                    *AccessRight
   1387   )
   1388 {
   1389   EFI_STATUS                    Status;
   1390   EFI_USER_INFO_HANDLE          UserInfo;
   1391   EFI_USER_INFO                 *Info;
   1392   UINTN                         InfoSize;
   1393   UINTN                         MemSize;
   1394   EFI_USER_INFO_ACCESS_CONTROL  Access;
   1395   EFI_USER_PROFILE_HANDLE       CurrentUser;
   1396   UINTN                         TotalLen;
   1397   UINTN                         CheckLen;
   1398 
   1399   //
   1400   // Allocate user information memory.
   1401   //
   1402   MemSize = sizeof (EFI_USER_INFO) + 63;
   1403   Info    = AllocateZeroPool (MemSize);
   1404   if (Info == NULL) {
   1405     return EFI_OUT_OF_RESOURCES;
   1406   }
   1407 
   1408   //
   1409   // Get user access information.
   1410   //
   1411   UserInfo = NULL;
   1412   mUserManager->Current (mUserManager, &CurrentUser);
   1413   while (TRUE) {
   1414     InfoSize = MemSize;
   1415     //
   1416     // Get next user information.
   1417     //
   1418     Status = mUserManager->GetNextInfo (mUserManager, CurrentUser, &UserInfo);
   1419     if (EFI_ERROR (Status)) {
   1420       break;
   1421     }
   1422 
   1423     Status = mUserManager->GetInfo (
   1424                              mUserManager,
   1425                              CurrentUser,
   1426                              UserInfo,
   1427                              Info,
   1428                              &InfoSize
   1429                              );
   1430     if (Status == EFI_BUFFER_TOO_SMALL) {
   1431       MemSize = InfoSize;
   1432       FreePool (Info);
   1433       Info = AllocateZeroPool (MemSize);
   1434       if (Info == NULL) {
   1435         return EFI_OUT_OF_RESOURCES;
   1436       }
   1437       Status = mUserManager->GetInfo (
   1438                                mUserManager,
   1439                                CurrentUser,
   1440                                UserInfo,
   1441                                Info,
   1442                                &InfoSize
   1443                                );
   1444     }
   1445     if (EFI_ERROR (Status)) {
   1446       break;
   1447     }
   1448 
   1449     //
   1450     // Check user information.
   1451     //
   1452     if (Info->InfoType == EFI_USER_INFO_ACCESS_POLICY_RECORD) {
   1453       TotalLen  = Info->InfoSize - sizeof (EFI_USER_INFO);
   1454       CheckLen  = 0;
   1455       //
   1456       // Get specified access information.
   1457       //
   1458       while (CheckLen < TotalLen) {
   1459         CopyMem (&Access, (UINT8 *) (Info + 1) + CheckLen, sizeof (Access));
   1460         if ((Access.Type == EFI_USER_INFO_ACCESS_ENROLL_SELF) ||
   1461             (Access.Type == EFI_USER_INFO_ACCESS_ENROLL_OTHERS) ||
   1462             (Access.Type == EFI_USER_INFO_ACCESS_MANAGE)
   1463             ) {
   1464           *AccessRight = Access.Type;
   1465           FreePool (Info);
   1466           return EFI_SUCCESS;
   1467         }
   1468         CheckLen += Access.Size;
   1469       }
   1470     }
   1471   }
   1472   FreePool (Info);
   1473   return EFI_NOT_FOUND;
   1474 }
   1475 
   1476