/** @file
  The functions to modify a user profile.

Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "UserProfileManager.h"

EFI_USER_PROFILE_HANDLE           mModifyUser = NULL;

/**
  Display user select form, cab select a user to modify.

**/
VOID
SelectUserToModify  (
  VOID
  )
{
  EFI_STATUS              Status;
  UINT8                   Index;
  EFI_USER_PROFILE_HANDLE User;
  EFI_USER_PROFILE_HANDLE CurrentUser;
  UINT32                  CurrentAccessRight;
  VOID                    *StartOpCodeHandle;
  VOID                    *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL      *StartLabel;
  EFI_IFR_GUID_LABEL      *EndLabel;

  //
  // Initialize the container for dynamic opcodes.
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode.
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                        StartOpCodeHandle,
                                        &gEfiIfrTianoGuid,
                                        NULL,
                                        sizeof (EFI_IFR_GUID_LABEL)
                                        );
  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number        = LABEL_USER_MOD_FUNC;

  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                      EndOpCodeHandle,
                                      &gEfiIfrTianoGuid,
                                      NULL,
                                      sizeof (EFI_IFR_GUID_LABEL)
                                      );
  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number        = LABEL_END;

  //
  // Add each user can be modified.
  //
  User  = NULL;
  Index = 1;
  mUserManager->Current (mUserManager, &CurrentUser);
  while (TRUE) {
    Status = mUserManager->GetNext (mUserManager, &User);
    if (EFI_ERROR (Status)) {
      break;
    }

    Status = GetAccessRight (&CurrentAccessRight);
    if (EFI_ERROR (Status)) {
      CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
    }

    if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) || (User == CurrentUser)) {
      AddUserToForm (User, (UINT16)(KEY_MODIFY_USER | KEY_SELECT_USER | Index), StartOpCodeHandle);
    }
    Index++;
  }

  HiiUpdateForm (
    mCallbackInfo->HiiHandle, // HII handle
    &gUserProfileManagerGuid, // Formset GUID
    FORMID_MODIFY_USER,       // Form ID
    StartOpCodeHandle,        // Label for where to insert opcodes
    EndOpCodeHandle           // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}


/**
  Get all the user info from mModifyUser in the user manager, and save on the
  global variable.

**/
VOID
GetAllUserInfo (
  VOID
  )
{
  EFI_STATUS            Status;
  EFI_USER_INFO_HANDLE  UserInfo;
  EFI_USER_INFO         *Info;
  UINTN                 InfoSize;
  UINTN                 MemSize;
  UINTN                 DataLen;

  //
  // Init variable to default value.
  //
  mProviderChoice                   = 0;
  mConncetLogical                   = 0;

  mUserInfo.CreateDateExist         = FALSE;
  mUserInfo.UsageDateExist          = FALSE;
  mUserInfo.UsageCount              = 0;

  mUserInfo.AccessPolicyLen         = 0;
  mUserInfo.AccessPolicyModified    = FALSE;
  if (mUserInfo.AccessPolicy != NULL) {
    FreePool (mUserInfo.AccessPolicy);
    mUserInfo.AccessPolicy = NULL;
  }
  mUserInfo.IdentityPolicyLen       = 0;
  mUserInfo.IdentityPolicyModified  = FALSE;
  if (mUserInfo.IdentityPolicy != NULL) {
    FreePool (mUserInfo.IdentityPolicy);
    mUserInfo.IdentityPolicy = NULL;
  }

  //
  // Allocate user information memory.
  //
  MemSize = sizeof (EFI_USER_INFO) + 63;
  Info    = AllocateZeroPool (MemSize);
  if (Info == NULL) {
    return ;
  }

  //
  // Get each user information.
  //
  UserInfo = NULL;
  while (TRUE) {
    Status = mUserManager->GetNextInfo (mUserManager, mModifyUser, &UserInfo);
    if (EFI_ERROR (Status)) {
      break;
    }
    //
    // Get information.
    //
    InfoSize  = MemSize;
    Status    = mUserManager->GetInfo (
                                mUserManager,
                                mModifyUser,
                                UserInfo,
                                Info,
                                &InfoSize
                                );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      MemSize = InfoSize;
      FreePool (Info);
      Info = AllocateZeroPool (MemSize);
      if (Info == NULL) {
        return ;
      }

      Status = mUserManager->GetInfo (
                               mUserManager,
                               mModifyUser,
                               UserInfo,
                               Info,
                               &InfoSize
                               );
    }

    if (Status == EFI_SUCCESS) {
      //
      // Deal with each information according to informaiton type.
      //
      DataLen = Info->InfoSize - sizeof (EFI_USER_INFO);
      switch (Info->InfoType) {
      case EFI_USER_INFO_NAME_RECORD:
        CopyMem (&mUserInfo.UserName, (UINT8 *) (Info + 1), DataLen);
        break;

      case EFI_USER_INFO_CREATE_DATE_RECORD:
        CopyMem (&mUserInfo.CreateDate, (UINT8 *) (Info + 1), DataLen);
        mUserInfo.CreateDateExist = TRUE;
        break;

      case EFI_USER_INFO_USAGE_DATE_RECORD:
        CopyMem (&mUserInfo.UsageDate, (UINT8 *) (Info + 1), DataLen);
        mUserInfo.UsageDateExist = TRUE;
        break;

      case EFI_USER_INFO_USAGE_COUNT_RECORD:
        CopyMem (&mUserInfo.UsageCount, (UINT8 *) (Info + 1), DataLen);
        break;

      case EFI_USER_INFO_ACCESS_POLICY_RECORD:
        mUserInfo.AccessPolicy = AllocateZeroPool (DataLen);
        if (mUserInfo.AccessPolicy == NULL) {
          break;
        }

        CopyMem (mUserInfo.AccessPolicy, (UINT8 *) (Info + 1), DataLen);
        mUserInfo.AccessPolicyLen = DataLen;
        break;

      case EFI_USER_INFO_IDENTITY_POLICY_RECORD:
        mUserInfo.IdentityPolicy = AllocateZeroPool (DataLen);
        if (mUserInfo.IdentityPolicy == NULL) {
          break;
        }

        CopyMem (mUserInfo.IdentityPolicy, (UINT8 *) (Info + 1), DataLen);
        mUserInfo.IdentityPolicyLen = DataLen;
        break;

      default:
        break;
      }
    }
  }
  FreePool (Info);
}


/**
  Convert the Date to a string, and update the Hii database DateID string with it.

  @param[in] Date       Points to the date to be converted.
  @param[in] DateId     String ID in the HII database to be replaced.

**/
VOID
ResolveDate (
  IN EFI_TIME                                   *Date,
  IN EFI_STRING_ID                              DateId
  )
{
  CHAR16  *Str;
  UINTN   DateBufLen;

  //
  // Convert date to string.
  //
  DateBufLen = 64;
  Str        = AllocateZeroPool (DateBufLen);
  if (Str == NULL) {
    return ;
  }

  UnicodeSPrint (
    Str,
    DateBufLen,
    L"%4d-%2d-%2d ",
    Date->Year,
    Date->Month,
    Date->Day
    );

  //
  // Convert time to string.
  //
  DateBufLen -= StrLen (Str);
  UnicodeSPrint (
    Str + StrLen (Str),
    DateBufLen,
    L"%2d:%2d:%2d",
    Date->Hour,
    Date->Minute,
    Date->Second
    );

  HiiSetString (mCallbackInfo->HiiHandle, DateId, Str, NULL);
  FreePool (Str);
}


/**
  Convert the CountVal to a string, and update the Hii database CountId string
  with it.

  @param[in]  CountVal   The hex value to convert.
  @param[in]  CountId    String ID in the HII database to be replaced.

**/
VOID
ResolveCount (
  IN UINT32                                     CountVal,
  IN EFI_STRING_ID                              CountId
  )
{
  CHAR16  Count[10];

  UnicodeSPrint (Count, 20, L"%d", CountVal);
  HiiSetString (mCallbackInfo->HiiHandle, CountId, Count, NULL);
}


/**
  Concatenates one Null-terminated Unicode string to another Null-terminated
  Unicode string.

  @param[in, out]  Source1      On entry, point to a Null-terminated Unicode string.
                                On exit, point to a new concatenated Unicode string
  @param[in]       Source2      Pointer to a Null-terminated Unicode string.

**/
VOID
AddStr (
  IN OUT  CHAR16                  **Source1,
  IN      CONST CHAR16            *Source2
  )
{
  CHAR16                        *TmpStr;
  UINTN                         StrLength;

  ASSERT (Source1 != NULL);
  ASSERT (Source2 != NULL);

  if (*Source1 == NULL) {
    StrLength = StrSize (Source2);
  } else {
    StrLength  = StrSize (*Source1);
    StrLength += StrSize (Source2) - 2;
  }

  TmpStr     = AllocateZeroPool (StrLength);
  ASSERT (TmpStr != NULL);

  if (*Source1 == NULL) {
    StrCpyS (TmpStr, StrLength / sizeof (CHAR16), Source2);
  } else {
    StrCpyS (TmpStr, StrLength / sizeof (CHAR16), *Source1);
    FreePool (*Source1);
    StrCatS (TmpStr, StrLength / sizeof (CHAR16),Source2);
  }

  *Source1 = TmpStr;
}


/**
  Convert the identity policy to a unicode string and update the Hii database
  IpStringId string with it.

  @param[in]  Ip         Points to identity policy.
  @param[in]  IpLen      The identity policy length.
  @param[in]  IpStringId String ID in the HII database to be replaced.

**/
VOID
ResolveIdentityPolicy (
  IN  UINT8                                     *Ip,
  IN  UINTN                                     IpLen,
  IN  EFI_STRING_ID                             IpStringId
  )
{
  CHAR16                        *TmpStr;
  UINTN                         ChkLen;
  EFI_USER_INFO_IDENTITY_POLICY *Identity;
  UINT16                        Index;
  CHAR16                        *ProvStr;
  EFI_STRING_ID                 ProvId;
  EFI_HII_HANDLE                HiiHandle;
  EFI_USER_CREDENTIAL2_PROTOCOL *UserCredential;

  TmpStr = NULL;

  //
  // Resolve each policy.
  //
  ChkLen  = 0;
  while (ChkLen < IpLen) {
    Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (Ip + ChkLen);
    switch (Identity->Type) {
    case EFI_USER_INFO_IDENTITY_FALSE:
      AddStr (&TmpStr, L"False");
      break;

    case EFI_USER_INFO_IDENTITY_TRUE:
      AddStr (&TmpStr, L"None");
      break;

    case EFI_USER_INFO_IDENTITY_NOT:
      AddStr (&TmpStr, L"! ");
      break;

    case EFI_USER_INFO_IDENTITY_AND:
      AddStr (&TmpStr, L" && ");
      break;

    case EFI_USER_INFO_IDENTITY_OR:
      AddStr (&TmpStr, L" || ");
      break;

    case EFI_USER_INFO_IDENTITY_CREDENTIAL_TYPE:
      for (Index = 0; Index < mProviderInfo->Count; Index++) {
        UserCredential = mProviderInfo->Provider[Index];
        if (CompareGuid ((EFI_GUID *) (Identity + 1), &UserCredential->Type)) {
          UserCredential->Title (
                            UserCredential,
                            &HiiHandle,
                            &ProvId
                            );
          ProvStr = HiiGetString (HiiHandle, ProvId, NULL);
          if (ProvStr != NULL) {
            AddStr (&TmpStr, ProvStr);
            FreePool (ProvStr);
          }
          break;
        }
      }
      break;

    case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER:
      for (Index = 0; Index < mProviderInfo->Count; Index++) {
        UserCredential = mProviderInfo->Provider[Index];
        if (CompareGuid ((EFI_GUID *) (Identity + 1), &UserCredential->Identifier)) {
          UserCredential->Title (
                            UserCredential,
                            &HiiHandle,
                            &ProvId
                            );
          ProvStr = HiiGetString (HiiHandle, ProvId, NULL);
          if (ProvStr != NULL) {
            AddStr (&TmpStr, ProvStr);
            FreePool (ProvStr);
          }
          break;
        }
      }
      break;
    }

    ChkLen += Identity->Length;
  }

  if (TmpStr != NULL) {
    HiiSetString (mCallbackInfo->HiiHandle, IpStringId, TmpStr, NULL);
    FreePool (TmpStr);
  }
}


/**
  Display modify user information form.

  This form displays, username, create Date, usage date, usage count, identity policy,
  and access policy.

  @param[in] UserIndex       The index of the user in display list to modify.

**/
VOID
ModifyUserInfo (
  IN UINT8                                      UserIndex
  )
{
  EFI_STATUS               Status;
  EFI_USER_PROFILE_HANDLE  CurrentUser;
  UINT32                   CurrentAccessRight;
  VOID                     *StartOpCodeHandle;
  VOID                     *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL       *StartLabel;
  EFI_IFR_GUID_LABEL       *EndLabel;

  //
  // Initialize the container for dynamic opcodes.
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode.
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                        StartOpCodeHandle,
                                        &gEfiIfrTianoGuid,
                                        NULL,
                                        sizeof (EFI_IFR_GUID_LABEL)
                                        );
  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number        = LABEL_USER_INFO_FUNC;

  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                      EndOpCodeHandle,
                                      &gEfiIfrTianoGuid,
                                      NULL,
                                      sizeof (EFI_IFR_GUID_LABEL)
                                      );
  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number        = LABEL_END;

  //
  // Find the user profile to be modified.
  //
  mModifyUser = NULL;
  Status      = mUserManager->GetNext (mUserManager, &mModifyUser);
  if (EFI_ERROR (Status)) {
    return ;
  }

  while (UserIndex > 1) {
    Status = mUserManager->GetNext (mUserManager, &mModifyUser);
    if (EFI_ERROR (Status)) {
      return ;
    }
    UserIndex--;
  }

  //
  // Get user profile information.
  //
  GetAllUserInfo ();

  //
  // Update user name.
  HiiSetString (
    mCallbackInfo->HiiHandle,
    STRING_TOKEN (STR_USER_NAME_VAL),
    mUserInfo.UserName,
    NULL
    );

  //
  // Update create date.
  //
  if (mUserInfo.CreateDateExist) {
    ResolveDate (&mUserInfo.CreateDate, STRING_TOKEN (STR_CREATE_DATE_VAL));
  } else {
    HiiSetString (
      mCallbackInfo->HiiHandle,
      STRING_TOKEN (STR_CREATE_DATE_VAL),
      L"",
      NULL
      );
  }

  //
  // Add usage date.
  //
  if (mUserInfo.UsageDateExist) {
    ResolveDate (&mUserInfo.UsageDate, STRING_TOKEN (STR_USAGE_DATE_VAL));
  } else {
    HiiSetString (
      mCallbackInfo->HiiHandle,
      STRING_TOKEN (STR_USAGE_DATE_VAL),
      L"",
      NULL
      );
  }

  //
  // Add usage count.
  //
  ResolveCount ((UINT32) mUserInfo.UsageCount, STRING_TOKEN (STR_USAGE_COUNT_VAL));

  //
  // Add identity policy.
  //
  mUserManager->Current (mUserManager, &CurrentUser);
  if (mModifyUser == CurrentUser) {
    ResolveIdentityPolicy (
      mUserInfo.IdentityPolicy,
      mUserInfo.IdentityPolicyLen,
      STRING_TOKEN (STR_IDENTIFY_POLICY_VAL)
      );
    HiiCreateGotoOpCode (
      StartOpCodeHandle,                                  // Container for opcodes
      FORMID_MODIFY_IP,                                   // Target Form ID
      STRING_TOKEN (STR_IDENTIFY_POLICY),                 // Prompt text
      STRING_TOKEN (STR_IDENTIFY_POLICY_VAL),             // Help text
      EFI_IFR_FLAG_CALLBACK,                              // Question flag
      KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP   // Question ID
      );
  }

  //
  // Add access policy.
  //
  Status = GetAccessRight (&CurrentAccessRight);
  if (EFI_ERROR (Status)) {
    CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
  }

  if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) {
    HiiCreateGotoOpCode (
      StartOpCodeHandle,                                  // Container for opcodes
      FORMID_MODIFY_AP,                                   // Target Form ID
      STRING_TOKEN (STR_ACCESS_POLICY),                   // Prompt text
      STRING_TOKEN (STR_NULL_STRING),                     // Help text
      EFI_IFR_FLAG_CALLBACK,                              // Question flag
      KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP   // Question ID
      );
  }

  HiiUpdateForm (
    mCallbackInfo->HiiHandle,                             // HII handle
    &gUserProfileManagerGuid,                             // Formset GUID
    FORMID_USER_INFO,                                     // Form ID
    StartOpCodeHandle,                                    // Label
    EndOpCodeHandle                                       // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}


/**
  Get all the access policy info from current user info, and save in the global
  variable.

**/
VOID
ResolveAccessPolicy (
  VOID
  )
{
  UINTN                         OffSet;
  EFI_USER_INFO_ACCESS_CONTROL  Control;
  UINTN                         ValLen;
  UINT8                         *AccessData;

  //
  // Set default value
  //
  mAccessInfo.AccessRight       = EFI_USER_INFO_ACCESS_ENROLL_SELF;
  mAccessInfo.AccessSetup       = ACCESS_SETUP_RESTRICTED;
  mAccessInfo.AccessBootOrder   = EFI_USER_INFO_ACCESS_BOOT_ORDER_INSERT;

  mAccessInfo.LoadPermitLen     = 0;
  mAccessInfo.LoadForbidLen     = 0;
  mAccessInfo.ConnectPermitLen  = 0;
  mAccessInfo.ConnectForbidLen  = 0;

  //
  // Get each user access policy.
  //
  OffSet = 0;
  while (OffSet < mUserInfo.AccessPolicyLen) {
    CopyMem (&Control, mUserInfo.AccessPolicy + OffSet, sizeof (Control));
    ValLen = Control.Size - sizeof (Control);
    switch (Control.Type) {
    case EFI_USER_INFO_ACCESS_ENROLL_SELF:
      mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF;
      break;

    case EFI_USER_INFO_ACCESS_ENROLL_OTHERS:
      mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_ENROLL_OTHERS;
      break;

    case EFI_USER_INFO_ACCESS_MANAGE:
      mAccessInfo.AccessRight = EFI_USER_INFO_ACCESS_MANAGE;
      break;

    case EFI_USER_INFO_ACCESS_SETUP:
      AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
      if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupNormalGuid)) {
        mAccessInfo.AccessSetup = ACCESS_SETUP_NORMAL;
      } else if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupRestrictedGuid)) {
        mAccessInfo.AccessSetup = ACCESS_SETUP_RESTRICTED;
      } else if (CompareGuid ((EFI_GUID *) AccessData, &gEfiUserInfoAccessSetupAdminGuid)) {
        mAccessInfo.AccessSetup = ACCESS_SETUP_ADMIN;
      }
      break;

    case EFI_USER_INFO_ACCESS_BOOT_ORDER:
      AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
      CopyMem (&mAccessInfo.AccessBootOrder, AccessData, sizeof (UINT32));
      break;

    case EFI_USER_INFO_ACCESS_FORBID_LOAD:
      if (mAccessInfo.LoadForbid != NULL) {
        FreePool (mAccessInfo.LoadForbid);
      }

      mAccessInfo.LoadForbid = AllocateZeroPool (ValLen);
      if (mAccessInfo.LoadForbid != NULL) {
        AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
        CopyMem (mAccessInfo.LoadForbid, AccessData, ValLen);
        mAccessInfo.LoadForbidLen = ValLen;
      }
      break;

    case EFI_USER_INFO_ACCESS_PERMIT_LOAD:
      if (mAccessInfo.LoadPermit != NULL) {
        FreePool (mAccessInfo.LoadPermit);
      }

      mAccessInfo.LoadPermit = AllocateZeroPool (ValLen);
      if (mAccessInfo.LoadPermit != NULL) {
        AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
        CopyMem (mAccessInfo.LoadPermit, AccessData, ValLen);
        mAccessInfo.LoadPermitLen = ValLen;
      }
      break;

    case EFI_USER_INFO_ACCESS_FORBID_CONNECT:
      if (mAccessInfo.ConnectForbid != NULL) {
        FreePool (mAccessInfo.ConnectForbid);
      }

      mAccessInfo.ConnectForbid = AllocateZeroPool (ValLen);
      if (mAccessInfo.ConnectForbid != NULL) {
        AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
        CopyMem (mAccessInfo.ConnectForbid, AccessData, ValLen);
        mAccessInfo.ConnectForbidLen = ValLen;
      }
      break;

    case EFI_USER_INFO_ACCESS_PERMIT_CONNECT:
      if (mAccessInfo.ConnectPermit != NULL) {
        FreePool (mAccessInfo.ConnectPermit);
      }

      mAccessInfo.ConnectPermit = AllocateZeroPool (ValLen);
      if (mAccessInfo.ConnectPermit != NULL) {
        AccessData = mUserInfo.AccessPolicy + OffSet + sizeof (Control);
        CopyMem (mAccessInfo.ConnectPermit, AccessData, ValLen);
        mAccessInfo.ConnectPermitLen = ValLen;
      }
      break;
    }

    OffSet += Control.Size;
  }
}


/**
  Find the specified info in User profile by the InfoType.

  @param[in]  User         Handle of the user whose information will be searched.
  @param[in]  InfoType     The user information type to find.
  @param[out] UserInfo     Points to user information handle found.

  @retval EFI_SUCCESS      Find the user information successfully.
  @retval Others           Fail to find the user information.

**/
EFI_STATUS
FindInfoByType (
  IN  EFI_USER_PROFILE_HANDLE                   User,
  IN  UINT8                                     InfoType,
  OUT EFI_USER_INFO_HANDLE                      *UserInfo
  )
{
  EFI_STATUS    Status;
  EFI_USER_INFO *Info;
  UINTN         InfoSize;
  UINTN         MemSize;

  if (UserInfo == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *UserInfo = NULL;
  //
  // Allocate user information memory.
  //
  MemSize = sizeof (EFI_USER_INFO) + 63;
  Info    = AllocateZeroPool (MemSize);
  if (Info == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get each user information.
  //
  while (TRUE) {
    Status = mUserManager->GetNextInfo (mUserManager, User, UserInfo);
    if (EFI_ERROR (Status)) {
      break;
    }
    //
    // Get information.
    //
    InfoSize  = MemSize;
    Status    = mUserManager->GetInfo (
                                mUserManager,
                                User,
                                *UserInfo,
                                Info,
                                &InfoSize
                                );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      MemSize = InfoSize;
      FreePool (Info);
      Info = AllocateZeroPool (MemSize);
      if (Info == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      Status = mUserManager->GetInfo (
                               mUserManager,
                               User,
                               *UserInfo,
                               Info,
                               &InfoSize
                               );
    }
    if (Status == EFI_SUCCESS) {
      if (Info->InfoType == InfoType) {
        break;
      }
    }
  }

  FreePool (Info);
  return Status;
}


/**
  Display modify user access policy form.

  In this form, access right, access setup and access boot order are dynamically
  added. Load devicepath and connect devicepath are displayed too.

**/
VOID
ModidyAccessPolicy (
  VOID
  )
{
  VOID                *StartOpCodeHandle;
  VOID                *EndOpCodeHandle;
  VOID                *OptionsOpCodeHandle;
  EFI_IFR_GUID_LABEL  *StartLabel;
  EFI_IFR_GUID_LABEL  *EndLabel;
  VOID                *DefaultOpCodeHandle;

  //
  // Initialize the container for dynamic opcodes.
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode.
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                        StartOpCodeHandle,
                                        &gEfiIfrTianoGuid,
                                        NULL,
                                        sizeof (EFI_IFR_GUID_LABEL)
                                        );
  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number        = LABEL_AP_MOD_FUNC;

  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                      EndOpCodeHandle,
                                      &gEfiIfrTianoGuid,
                                      NULL,
                                      sizeof (EFI_IFR_GUID_LABEL)
                                      );
  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number        = LABEL_END;


  //
  // Resolve access policy information.
  //
  ResolveAccessPolicy ();

  //
  // Add access right one-of-code.
  //
  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (OptionsOpCodeHandle != NULL);
  DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (DefaultOpCodeHandle != NULL);

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_NORMAL),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    EFI_USER_INFO_ACCESS_ENROLL_SELF
    );

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_ENROLL),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    EFI_USER_INFO_ACCESS_ENROLL_OTHERS
    );

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_MANAGE),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    EFI_USER_INFO_ACCESS_MANAGE
    );

  HiiCreateDefaultOpCode (
    DefaultOpCodeHandle,
    EFI_HII_DEFAULT_CLASS_STANDARD,
    EFI_IFR_NUMERIC_SIZE_1,
    mAccessInfo.AccessRight
    );

  HiiCreateOneOfOpCode (
    StartOpCodeHandle,                    // Container for dynamic created opcodes
    KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_RIGHT, // Question ID
    0,                                    // VarStore ID
    0,                                    // Offset in Buffer Storage
    STRING_TOKEN (STR_ACCESS_RIGHT),      // Question prompt text
    STRING_TOKEN (STR_ACCESS_RIGHT_HELP), // Question help text
    EFI_IFR_FLAG_CALLBACK,                // Question flag
    EFI_IFR_NUMERIC_SIZE_1,               // Data type of Question Value
    OptionsOpCodeHandle,                  // Option Opcode list
    DefaultOpCodeHandle                   // Default Opcode
    );
  HiiFreeOpCodeHandle (DefaultOpCodeHandle);
  HiiFreeOpCodeHandle (OptionsOpCodeHandle);


  //
  // Add setup type one-of-code.
  //
  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (OptionsOpCodeHandle != NULL);
  DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (DefaultOpCodeHandle != NULL);

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_RESTRICTED),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    ACCESS_SETUP_RESTRICTED
    );

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_NORMAL),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    ACCESS_SETUP_NORMAL
    );

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_ADMIN),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    ACCESS_SETUP_ADMIN
    );

  HiiCreateDefaultOpCode (
    DefaultOpCodeHandle,
    EFI_HII_DEFAULT_CLASS_STANDARD,
    EFI_IFR_NUMERIC_SIZE_1,
    mAccessInfo.AccessSetup
    );

  HiiCreateOneOfOpCode (
    StartOpCodeHandle,                    // Container for dynamic created opcodes
    KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_SETUP, // Question ID
    0,                                    // VarStore ID
    0,                                    // Offset in Buffer Storage
    STRING_TOKEN (STR_ACCESS_SETUP),      // Question prompt text
    STRING_TOKEN (STR_ACCESS_SETUP_HELP), // Question help text
    EFI_IFR_FLAG_CALLBACK,                // Question flag
    EFI_IFR_NUMERIC_SIZE_1,               // Data type of Question Value
    OptionsOpCodeHandle,                  // Option Opcode list
    DefaultOpCodeHandle                   // Default Opcode
    );
  HiiFreeOpCodeHandle (DefaultOpCodeHandle);
  HiiFreeOpCodeHandle (OptionsOpCodeHandle);

  //
  // Add boot order one-of-code.
  //
  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (OptionsOpCodeHandle != NULL);
  DefaultOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (DefaultOpCodeHandle != NULL);

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_INSERT),
    0,
    EFI_IFR_NUMERIC_SIZE_4,
    EFI_USER_INFO_ACCESS_BOOT_ORDER_INSERT
    );

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_APPEND),
    0,
    EFI_IFR_NUMERIC_SIZE_4,
    EFI_USER_INFO_ACCESS_BOOT_ORDER_APPEND
    );

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_REPLACE),
    0,
    EFI_IFR_NUMERIC_SIZE_4,
    EFI_USER_INFO_ACCESS_BOOT_ORDER_REPLACE
    );

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_NODEFAULT),
    0,
    EFI_IFR_NUMERIC_SIZE_4,
    EFI_USER_INFO_ACCESS_BOOT_ORDER_NODEFAULT
    );

  HiiCreateDefaultOpCode (
    DefaultOpCodeHandle,
    EFI_HII_DEFAULT_CLASS_STANDARD,
    EFI_IFR_NUMERIC_SIZE_4,
    mAccessInfo.AccessBootOrder
    );

  HiiCreateOneOfOpCode (
    StartOpCodeHandle,                  // Container for dynamic created opcodes
    KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_AP | KEY_MODIFY_BOOT, // Question ID
    0,                                  // VarStore ID
    0,                                  // Offset in Buffer Storage
    STRING_TOKEN (STR_BOOR_ORDER),      // Question prompt text
    STRING_TOKEN (STR_BOOT_ORDER_HELP), // Question help text
    EFI_IFR_FLAG_CALLBACK,              // Question flag
    EFI_IFR_NUMERIC_SIZE_1,             // Data type of Question Value
    OptionsOpCodeHandle,                // Option Opcode list
    DefaultOpCodeHandle                 // Default Opcode
    );
  HiiFreeOpCodeHandle (DefaultOpCodeHandle);
  HiiFreeOpCodeHandle (OptionsOpCodeHandle);

  //
  // Update Form.
  //
  HiiUpdateForm (
    mCallbackInfo->HiiHandle,           // HII handle
    &gUserProfileManagerGuid,           // Formset GUID
    FORMID_MODIFY_AP,                   // Form ID
    StartOpCodeHandle,                  // Label for where to insert opcodes
    EndOpCodeHandle                     // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}


/**
  Expand access policy memory size.

  @param[in] ValidLen       The valid access policy length.
  @param[in] ExpandLen      The length that is needed to expand.

**/
VOID
ExpandMemory (
  IN      UINTN                                 ValidLen,
  IN      UINTN                                 ExpandLen
  )
{
  UINT8 *Mem;
  UINTN Len;

  //
  // Expand memory.
  //
  Len = mUserInfo.AccessPolicyLen + (ExpandLen / 64 + 1) * 64;
  Mem = AllocateZeroPool (Len);
  ASSERT (Mem != NULL);

  if (mUserInfo.AccessPolicy != NULL) {
    CopyMem (Mem, mUserInfo.AccessPolicy, ValidLen);
    FreePool (mUserInfo.AccessPolicy);
  }

  mUserInfo.AccessPolicy    = Mem;
  mUserInfo.AccessPolicyLen = Len;
}


/**
  Get the username from user input, and update username string in the Hii
  database with it.

**/
VOID
ModifyUserName (
  VOID
  )
{
  EFI_STATUS              Status;
  CHAR16                  UserName[USER_NAME_LENGTH];
  UINTN                   Len;
  EFI_INPUT_KEY           Key;
  EFI_USER_INFO_HANDLE    UserInfo;
  EFI_USER_INFO           *Info;
  EFI_USER_PROFILE_HANDLE TempUser;

  //
  // Get the new user name.
  //
  Len = sizeof (UserName);
  Status = GetUserNameInput (&Len, UserName);
  if (EFI_ERROR (Status)) {
    if (Status != EFI_ABORTED) {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Failed To Get User Name.",
        L"",
        L"Please Press Any Key to Continue ...",
        NULL
        );
    }
    return ;
  }

  //
  // Check whether the username had been used or not.
  //
  Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + Len);
  if (Info == NULL) {
    return ;
  }

  Info->InfoType    = EFI_USER_INFO_NAME_RECORD;
  Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
                      EFI_USER_INFO_PUBLIC |
                      EFI_USER_INFO_EXCLUSIVE;
  Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + Len);
  CopyMem ((UINT8 *) (Info + 1), UserName, Len);

  TempUser  = NULL;
  Status    = mUserManager->Find (
                              mUserManager,
                              &TempUser,
                              NULL,
                              Info,
                              Info->InfoSize
                              );
  if (!EFI_ERROR (Status)) {
    CreatePopUp (
      EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
      &Key,
      L"The User Name Had Been Used.",
      L"",
      L"Please Use Other User Name",
      NULL
      );
    FreePool (Info);
    return ;
  }

  //
  // Update username display in the form.
  //
  CopyMem (mUserInfo.UserName, UserName, Len);
  HiiSetString (
    mCallbackInfo->HiiHandle,
    STRING_TOKEN (STR_USER_NAME_VAL),
    mUserInfo.UserName,
    NULL
    );

  //
  // Save the user name.
  //
  Status = FindInfoByType (mModifyUser, EFI_USER_INFO_NAME_RECORD, &UserInfo);
  if (!EFI_ERROR (Status)) {
    mUserManager->SetInfo (
                    mUserManager,
                    mModifyUser,
                    &UserInfo,
                    Info,
                    Info->InfoSize
                    );
  }
  FreePool (Info);
}


/**
  Display the form of the modifying user identity policy.

**/
VOID
ModifyIdentityPolicy (
  VOID
  )
{
  UINTN               Index;
  CHAR16              *ProvStr;
  EFI_STRING_ID       ProvID;
  EFI_HII_HANDLE      HiiHandle;
  VOID                *OptionsOpCodeHandle;
  VOID                *StartOpCodeHandle;
  VOID                *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL  *StartLabel;
  EFI_IFR_GUID_LABEL  *EndLabel;

  //
  // Initialize the container for dynamic opcodes.
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode.
  //
  StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                        StartOpCodeHandle,
                                        &gEfiIfrTianoGuid,
                                        NULL,
                                        sizeof (EFI_IFR_GUID_LABEL)
                                        );
  StartLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number        = LABEL_IP_MOD_FUNC;

  EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
                                      EndOpCodeHandle,
                                      &gEfiIfrTianoGuid,
                                      NULL,
                                      sizeof (EFI_IFR_GUID_LABEL)
                                      );
  EndLabel->ExtendOpCode  = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number        = LABEL_END;

  //
  // Add credential providers
  //.
  if (mProviderInfo->Count > 0) {
    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    ASSERT (OptionsOpCodeHandle != NULL);

    //
    // Add credential provider Option OpCode.
    //
    for (Index = 0; Index < mProviderInfo->Count; Index++) {
      mProviderInfo->Provider[Index]->Title (
                                        mProviderInfo->Provider[Index],
                                        &HiiHandle,
                                        &ProvID
                                        );
      ProvStr = HiiGetString (HiiHandle, ProvID, NULL);
      ProvID  = HiiSetString (mCallbackInfo->HiiHandle, 0, ProvStr, NULL);
      FreePool (ProvStr);
      if (ProvID == 0) {
        return ;
      }

      HiiCreateOneOfOptionOpCode (
        OptionsOpCodeHandle,
        ProvID,
        0,
        EFI_IFR_NUMERIC_SIZE_1,
        (UINT8) Index
        );
    }

    HiiCreateOneOfOpCode (
      StartOpCodeHandle,                // Container for dynamic created opcodes
      KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP | KEY_MODIFY_PROV,  // Question ID
      0,                                // VarStore ID
      0,                                // Offset in Buffer Storage
      STRING_TOKEN (STR_PROVIDER),      // Question prompt text
      STRING_TOKEN (STR_PROVIDER_HELP), // Question help text
      EFI_IFR_FLAG_CALLBACK,            // Question flag
      EFI_IFR_NUMERIC_SIZE_1,           // Data type of Question Value
      OptionsOpCodeHandle,              // Option Opcode list
      NULL                              // Default Opcode is NULl
      );

    HiiFreeOpCodeHandle (OptionsOpCodeHandle);
  }

  //
  // Add logical connector Option OpCode.
  //
  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (OptionsOpCodeHandle != NULL);

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_AND_CON),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    0
    );

  HiiCreateOneOfOptionOpCode (
    OptionsOpCodeHandle,
    STRING_TOKEN (STR_OR_CON),
    0,
    EFI_IFR_NUMERIC_SIZE_1,
    1
    );

  HiiCreateOneOfOpCode (
    StartOpCodeHandle,                  // Container for dynamic created opcodes
    KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_IP | KEY_MODIFY_CONN,  // Question ID
    0,                                  // VarStore ID
    0,                                  // Offset in Buffer Storage
    STRING_TOKEN (STR_CONNECTOR),       // Question prompt text
    STRING_TOKEN (STR_CONNECTOR_HELP),  // Question help text
    EFI_IFR_FLAG_CALLBACK,              // Question flag
    EFI_IFR_NUMERIC_SIZE_1,             // Data type of Question Value
    OptionsOpCodeHandle,                // Option Opcode list
    NULL                                // Default Opcode is NULl
    );

  HiiFreeOpCodeHandle (OptionsOpCodeHandle);

  //
  // Update identity policy in the form.
  //
  ResolveIdentityPolicy (
    mUserInfo.IdentityPolicy,
    mUserInfo.IdentityPolicyLen,
    STRING_TOKEN (STR_IDENTIFY_POLICY_VALUE)
    );

  if (mUserInfo.NewIdentityPolicy != NULL) {
    FreePool (mUserInfo.NewIdentityPolicy);
    mUserInfo.NewIdentityPolicy         = NULL;
    mUserInfo.NewIdentityPolicyLen      = 0;
    mUserInfo.NewIdentityPolicyModified = FALSE;
  }
  mProviderChoice = 0;
  mConncetLogical = 0;

  HiiUpdateForm (
    mCallbackInfo->HiiHandle, // HII handle
    &gUserProfileManagerGuid, // Formset GUID
    FORMID_MODIFY_IP,         // Form ID
    StartOpCodeHandle,        // Label for where to insert opcodes
    EndOpCodeHandle           // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}


/**
  Get current user's access right.

  @param[out]  AccessRight  Points to the buffer used for user's access right.

  @retval EFI_SUCCESS       Get current user access right successfully.
  @retval others            Fail to get current user access right.

**/
EFI_STATUS
GetAccessRight (
  OUT  UINT32                                    *AccessRight
  )
{
  EFI_STATUS                    Status;
  EFI_USER_INFO_HANDLE          UserInfo;
  EFI_USER_INFO                 *Info;
  UINTN                         InfoSize;
  UINTN                         MemSize;
  EFI_USER_INFO_ACCESS_CONTROL  Access;
  EFI_USER_PROFILE_HANDLE       CurrentUser;
  UINTN                         TotalLen;
  UINTN                         CheckLen;

  //
  // Allocate user information memory.
  //
  MemSize = sizeof (EFI_USER_INFO) + 63;
  Info    = AllocateZeroPool (MemSize);
  if (Info == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get user access information.
  //
  UserInfo = NULL;
  mUserManager->Current (mUserManager, &CurrentUser);
  while (TRUE) {
    InfoSize = MemSize;
    //
    // Get next user information.
    //
    Status = mUserManager->GetNextInfo (mUserManager, CurrentUser, &UserInfo);
    if (EFI_ERROR (Status)) {
      break;
    }

    Status = mUserManager->GetInfo (
                             mUserManager,
                             CurrentUser,
                             UserInfo,
                             Info,
                             &InfoSize
                             );
    if (Status == EFI_BUFFER_TOO_SMALL) {
      MemSize = InfoSize;
      FreePool (Info);
      Info = AllocateZeroPool (MemSize);
      if (Info == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
      Status = mUserManager->GetInfo (
                               mUserManager,
                               CurrentUser,
                               UserInfo,
                               Info,
                               &InfoSize
                               );
    }
    if (EFI_ERROR (Status)) {
      break;
    }

    //
    // Check user information.
    //
    if (Info->InfoType == EFI_USER_INFO_ACCESS_POLICY_RECORD) {
      TotalLen  = Info->InfoSize - sizeof (EFI_USER_INFO);
      CheckLen  = 0;
      //
      // Get specified access information.
      //
      while (CheckLen < TotalLen) {
        CopyMem (&Access, (UINT8 *) (Info + 1) + CheckLen, sizeof (Access));
        if ((Access.Type == EFI_USER_INFO_ACCESS_ENROLL_SELF) ||
            (Access.Type == EFI_USER_INFO_ACCESS_ENROLL_OTHERS) ||
            (Access.Type == EFI_USER_INFO_ACCESS_MANAGE)
            ) {
          *AccessRight = Access.Type;
          FreePool (Info);
          return EFI_SUCCESS;
        }
        CheckLen += Access.Size;
      }
    }
  }
  FreePool (Info);
  return EFI_NOT_FOUND;
}

