/** @file
  The functions to modify a user profile.
    
Copyright (c) 2009 - 2011, 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) -1;
  }

  TmpStr     = AllocateZeroPool (StrLength);
  ASSERT (TmpStr != NULL);

  if (*Source1 == NULL) {
    StrCpy (TmpStr, Source2);;
  } else {
    StrCpy (TmpStr, *Source1);
    FreePool (*Source1);
    StrCat (TmpStr, 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;
}

