/** @file
  The functions for access policy modification.
    
Copyright (c) 2009 - 2013, 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"

/**
  Collect all the access policy data to mUserInfo.AccessPolicy, 
  and save it to user profile.

**/
VOID
SaveAccessPolicy (
  VOID
  )
{
  EFI_STATUS                    Status;
  UINTN                         OffSet;
  UINTN                         Size;
  EFI_USER_INFO_ACCESS_CONTROL  Control;
  EFI_USER_INFO_HANDLE          UserInfo;
  EFI_USER_INFO                 *Info;

  if (mUserInfo.AccessPolicy != NULL) {
    FreePool (mUserInfo.AccessPolicy);
  }
  mUserInfo.AccessPolicy          = NULL;
  mUserInfo.AccessPolicyLen       = 0;
  mUserInfo.AccessPolicyModified  = TRUE;
  OffSet                          = 0;
  
  //
  // Save access right.
  //
  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL);
  if (mUserInfo.AccessPolicyLen - OffSet < Size) {
    ExpandMemory (OffSet, Size);
  }

  Control.Type = mAccessInfo.AccessRight;
  Control.Size = (UINT32) Size;
  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
  OffSet += sizeof (Control);
  
  //
  // Save access setup.
  //
  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (EFI_GUID);
  if (mUserInfo.AccessPolicyLen - OffSet < Size) {
    ExpandMemory (OffSet, Size);
  }

  Control.Type = EFI_USER_INFO_ACCESS_SETUP;
  Control.Size = (UINT32) Size;  
  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
  OffSet += sizeof (Control);
  
  if (mAccessInfo.AccessSetup == ACCESS_SETUP_NORMAL) {
    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupNormalGuid);
  } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_RESTRICTED) {
    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupRestrictedGuid);
  } else if (mAccessInfo.AccessSetup == ACCESS_SETUP_ADMIN) {
    CopyGuid ((EFI_GUID *) (mUserInfo.AccessPolicy + OffSet), &gEfiUserInfoAccessSetupAdminGuid);
  }
  OffSet += sizeof (EFI_GUID);
  
  //
  // Save access of boot order.
  //
  Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + sizeof (UINT32);
  if (mUserInfo.AccessPolicyLen - OffSet < Size) {
    ExpandMemory (OffSet, Size);
  }

  Control.Type = EFI_USER_INFO_ACCESS_BOOT_ORDER;
  Control.Size = (UINT32) Size;  
  CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
  OffSet += sizeof (Control);

  CopyMem ((UINT8 *) (mUserInfo.AccessPolicy + OffSet), &mAccessInfo.AccessBootOrder, sizeof (UINT32));
  OffSet += sizeof (UINT32);
  
  //
  // Save permit load.
  //
  if (mAccessInfo.LoadPermitLen > 0) {
    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadPermitLen;
    if (mUserInfo.AccessPolicyLen - OffSet < Size) {
      ExpandMemory (OffSet, Size);
    }

    Control.Type = EFI_USER_INFO_ACCESS_PERMIT_LOAD;
    Control.Size = (UINT32) Size;  
    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
    OffSet += sizeof (Control);
  
    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadPermit, mAccessInfo.LoadPermitLen);
    OffSet += mAccessInfo.LoadPermitLen;
  }
  
  //
  // Save forbid load.
  //
  if (mAccessInfo.LoadForbidLen > 0) {
    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.LoadForbidLen;
    if (mUserInfo.AccessPolicyLen - OffSet < Size) {
      ExpandMemory (OffSet, Size);
    }

    Control.Type = EFI_USER_INFO_ACCESS_FORBID_LOAD;
    Control.Size = (UINT32) Size;  
    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
    OffSet += sizeof (Control);
    
    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);
    OffSet += mAccessInfo.LoadForbidLen;
  }
  
  //
  // Save permit connect.
  //
  if (mAccessInfo.ConnectPermitLen > 0) {
    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectPermitLen;
    if (mUserInfo.AccessPolicyLen - OffSet < Size) {
      ExpandMemory (OffSet, Size);
    }

    Control.Type = EFI_USER_INFO_ACCESS_PERMIT_CONNECT;
    Control.Size = (UINT32) Size;  
    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
    OffSet += sizeof (Control);
    
    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectPermit, mAccessInfo.ConnectPermitLen);
    OffSet += mAccessInfo.ConnectPermitLen;
  }
  
  //
  // Save forbid connect.
  //
  if (mAccessInfo.ConnectForbidLen > 0) {
    Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL) + mAccessInfo.ConnectForbidLen;
    if (mUserInfo.AccessPolicyLen - OffSet < Size) {
      ExpandMemory (OffSet, Size);
    }

    Control.Type = EFI_USER_INFO_ACCESS_FORBID_CONNECT;
    Control.Size = (UINT32) Size;  
    CopyMem (mUserInfo.AccessPolicy + OffSet, &Control, sizeof (Control));
    OffSet += sizeof (Control);
    
    CopyMem (mUserInfo.AccessPolicy + OffSet, mAccessInfo.ConnectForbid, mAccessInfo.ConnectForbidLen);
    OffSet += mAccessInfo.ConnectForbidLen;
  }

  mUserInfo.AccessPolicyLen = OffSet;

  //
  // Save access policy.
  //
  if (mUserInfo.AccessPolicyModified && (mUserInfo.AccessPolicyLen > 0) && (mUserInfo.AccessPolicy != NULL)) {
    Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);
    if (Info == NULL) {
      return ;
    }

    Status = FindInfoByType (mModifyUser, EFI_USER_INFO_ACCESS_POLICY_RECORD, &UserInfo);
    if (!EFI_ERROR (Status)) {
      Info->InfoType    = EFI_USER_INFO_ACCESS_POLICY_RECORD;
      Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV |
                          EFI_USER_INFO_PUBLIC |
                          EFI_USER_INFO_EXCLUSIVE;
      Info->InfoSize    = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen);
      CopyMem ((UINT8 *) (Info + 1), mUserInfo.AccessPolicy, mUserInfo.AccessPolicyLen);
      Status = mUserManager->SetInfo (
                               mUserManager,
                               mModifyUser,
                               &UserInfo,
                               Info,
                               Info->InfoSize
                               );
      mUserInfo.AccessPolicyModified = FALSE;
    }
    FreePool (Info);
  }

  if (mAccessInfo.ConnectForbid != NULL) {
    FreePool (mAccessInfo.ConnectForbid);
    mAccessInfo.ConnectForbid = NULL;
  }

  if (mAccessInfo.ConnectPermit != NULL) {
    FreePool (mAccessInfo.ConnectPermit);
    mAccessInfo.ConnectPermit = NULL;
  }

  if (mAccessInfo.LoadForbid != NULL) {
    FreePool (mAccessInfo.LoadForbid);
    mAccessInfo.LoadForbid = NULL;
  }

  if (mAccessInfo.LoadPermit != NULL) {
    FreePool (mAccessInfo.LoadPermit);
    mAccessInfo.LoadPermit = NULL;
  }
}

/**
  Create an action OpCode with QuestionID and DevicePath on a given OpCodeHandle.

  @param[in]  QuestionID            The question ID.
  @param[in]  DevicePath            Points to device path.
  @param[in]  OpCodeHandle          Points to container for dynamic created opcodes.

**/
VOID
AddDevicePath (
  IN  UINTN                                     QuestionID,
  IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath,
  IN     VOID                                   *OpCodeHandle
  )
{
  EFI_DEVICE_PATH_PROTOCOL          *Next;
  EFI_STRING_ID                     NameID;
  EFI_STRING                        DriverName;

  //
  // Get driver file name node.
  //
  Next = DevicePath;
  while (!IsDevicePathEnd (Next)) {
    DevicePath  = Next;
    Next        = NextDevicePathNode (Next);
  }

  //
  // Display the device path in form.
  //
  DriverName = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
  NameID = HiiSetString (mCallbackInfo->HiiHandle, 0, DriverName, NULL);
  FreePool (DriverName);
  if (NameID == 0) {
    return ;
  }

  HiiCreateActionOpCode (
    OpCodeHandle,                   // Container for dynamic created opcodes
    (UINT16) QuestionID,            // Question ID
    NameID,                         // Prompt text
    STRING_TOKEN (STR_NULL_STRING), // Help text
    EFI_IFR_FLAG_CALLBACK,          // Question flag
    0                               // Action String ID
    );
}


/**
  Check whether the DevicePath is in the device path forbid list 
  (mAccessInfo.LoadForbid).

  @param[in]  DevicePath           Points to device path.
  
  @retval TRUE     The DevicePath is in the device path forbid list.
  @retval FALSE    The DevicePath is not in the device path forbid list.

**/
BOOLEAN
IsLoadForbidden (
  IN  EFI_DEVICE_PATH_PROTOCOL                  *DevicePath
  )
{
  UINTN                     OffSet;
  UINTN                     DPSize;
  UINTN                     Size;
  EFI_DEVICE_PATH_PROTOCOL  *Dp;

  OffSet = 0;
  Size   = GetDevicePathSize (DevicePath);
  //
  // Check each device path.
  //
  while (OffSet < mAccessInfo.LoadForbidLen) {
    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
    DPSize  = GetDevicePathSize (Dp);
    //
    // Compare device path.
    //
    if ((DPSize == Size) && (CompareMem (DevicePath, Dp, Size) == 0)) {
      return TRUE;
    }
    OffSet += DPSize;
  }
  return FALSE;
}


/**
  Display the permit load device path in the loadable device path list.

**/
VOID
DisplayLoadPermit(
  VOID
  )
{
  EFI_STATUS          Status;
  CHAR16              *Order;
  UINTN               OrderSize;
  UINTN               ListCount;
  UINTN               Index;
  UINT8               *Var;
  UINT8               *VarPtr;
  CHAR16              VarName[12];
  VOID                *StartOpCodeHandle;
  VOID                *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL  *StartLabel;
  EFI_IFR_GUID_LABEL  *EndLabel;

  //
  // Get DriverOrder.
  //
  OrderSize = 0;
  Status    = gRT->GetVariable (
                     L"DriverOrder", 
                     &gEfiGlobalVariableGuid, 
                     NULL, 
                     &OrderSize, 
                     NULL
                     );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return ;
  }

  Order = AllocateZeroPool (OrderSize);
  if (Order == NULL) {
    return ;
  }

  Status = gRT->GetVariable (
                  L"DriverOrder", 
                  &gEfiGlobalVariableGuid, 
                  NULL, 
                  &OrderSize, 
                  Order
                  );
  if (EFI_ERROR (Status)) {
    return ;
  }
  
  //
  // 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_PERMIT_LOAD_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 driver option.
  //
  Var       = NULL;
  ListCount = OrderSize / sizeof (UINT16);
  for (Index = 0; Index < ListCount; Index++) {
    //
    // Get driver device path.
    //
    UnicodeSPrint (VarName, sizeof (VarName), L"Driver%04x", Order[Index]);
    GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL);
    if (Var == NULL) {
      continue;
    }
    
    //
    // Check whether the driver is already forbidden.
    //
    
    VarPtr = Var;
    //
    // Skip attribute.
    //
    VarPtr += sizeof (UINT32);

    //
    // Skip device path lenth.
    //
    VarPtr += sizeof (UINT16);

    //
    // Skip descript string.
    //
    VarPtr += StrSize ((UINT16 *) VarPtr);

    if (IsLoadForbidden ((EFI_DEVICE_PATH_PROTOCOL *) VarPtr)) {
      FreePool (Var);
      Var = NULL;
      continue;
    }

    AddDevicePath (
      KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_PERMIT_MODIFY | Order[Index],
      (EFI_DEVICE_PATH_PROTOCOL *) VarPtr,
      StartOpCodeHandle
      );
    FreePool (Var);
    Var = NULL;
  }

  HiiUpdateForm (
    mCallbackInfo->HiiHandle, // HII handle
    &gUserProfileManagerGuid, // Formset GUID
    FORMID_PERMIT_LOAD_DP,    // Form ID
    StartOpCodeHandle,        // Label for where to insert opcodes
    EndOpCodeHandle           // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  //
  // Clear Environment.
  //
  if (Var != NULL) {
    FreePool (Var);
  }
  FreePool (Order);
}


/**
  Display the forbid load device path list (mAccessInfo.LoadForbid).

**/
VOID
DisplayLoadForbid (
  VOID
  )
{
  UINTN                     Offset;
  UINTN                     DPSize;
  UINTN                     Index;
  EFI_DEVICE_PATH_PROTOCOL  *Dp;
  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        = LABLE_FORBID_LOAD_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 forbid load drivers.
  //
  Offset  = 0;
  Index   = 0;
  while (Offset < mAccessInfo.LoadForbidLen) {
    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + Offset);
    DPSize  = GetDevicePathSize (Dp);
    AddDevicePath (
      KEY_MODIFY_USER | KEY_MODIFY_AP_DP | KEY_LOAD_FORBID_MODIFY | Index,
      Dp,
      StartOpCodeHandle
      );
    Index++;
    Offset += DPSize;
  }

  HiiUpdateForm (
    mCallbackInfo->HiiHandle, // HII handle
    &gUserProfileManagerGuid, // Formset GUID
    FORMID_FORBID_LOAD_DP,    // Form ID
    StartOpCodeHandle,        // Label for where to insert opcodes
    EndOpCodeHandle           // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}


/**
  Display the permit connect device path.

**/
VOID
DisplayConnectPermit (
  VOID
  )
{
  //
  // Note: 
  // As no architect protocol/interface to be called in ConnectController()
  // to verify the device path, just add a place holder for permitted connect
  // device path.
  //
}


/**
  Display the forbid connect device path list.

**/
VOID
DisplayConnectForbid (
  VOID
  )
{
  //
  // Note: 
  // As no architect protocol/interface to be called in ConnectController()
  // to verify the device path, just add a place holder for forbidden connect
  // device path.
  //
}


/**
  Delete the specified device path by DriverIndex from the forbid device path 
  list (mAccessInfo.LoadForbid).

  @param[in]  DriverIndex   The index of driver in forbidden device path list.
  
**/
VOID
DeleteFromForbidLoad (
  IN  UINT16                                    DriverIndex
  )
{
  UINTN                     OffSet;
  UINTN                     DPSize;
  UINTN                     OffLen;
  EFI_DEVICE_PATH_PROTOCOL  *Dp;

  OffSet = 0;
  //
  // Find the specified device path.
  //
  while ((OffSet < mAccessInfo.LoadForbidLen) && (DriverIndex > 0)) {
    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
    DPSize  = GetDevicePathSize (Dp);
    OffSet += DPSize;
    DriverIndex--;
  }
  
  //
  // Specified device path found.
  //
  if (DriverIndex == 0) {
    Dp      = (EFI_DEVICE_PATH_PROTOCOL *) (mAccessInfo.LoadForbid + OffSet);
    DPSize  = GetDevicePathSize (Dp);
    OffLen  = mAccessInfo.LoadForbidLen - OffSet - DPSize;
    if (OffLen > 0) {
      CopyMem (
        mAccessInfo.LoadForbid + OffSet, 
        mAccessInfo.LoadForbid + OffSet + DPSize, 
        OffLen
        );
    }
    mAccessInfo.LoadForbidLen -= DPSize;
  }
}


/**
  Add the specified device path by DriverIndex to the forbid device path 
  list (mAccessInfo.LoadForbid).

  @param[in]  DriverIndex   The index of driver saved in driver options.
  
**/
VOID
AddToForbidLoad (
  IN  UINT16                                    DriverIndex
  )
{
  UINTN       DevicePathLen;
  UINT8       *Var;
  UINT8       *VarPtr;
  UINTN       NewLen;
  UINT8       *NewFL;
  CHAR16      VarName[13];

  //
  // Get loadable driver device path.
  //
  UnicodeSPrint  (VarName, sizeof (VarName), L"Driver%04x", DriverIndex);
  GetEfiGlobalVariable2 (VarName, (VOID**)&Var, NULL);
  if (Var == NULL) {
    return;
  }
  
  //
  // Save forbid load driver.
  //
  
  VarPtr = Var;
  //
  // Skip attribute.
  //
  VarPtr += sizeof (UINT32);

  DevicePathLen = *(UINT16 *) VarPtr;
  //
  // Skip device path length.
  //
  VarPtr += sizeof (UINT16);

  //
  // Skip description string.
  //
  VarPtr += StrSize ((UINT16 *) VarPtr);

  NewLen  = mAccessInfo.LoadForbidLen + DevicePathLen;
  NewFL   = AllocateZeroPool (NewLen);
  if (NewFL == NULL) {
    FreePool (Var);
    return ;
  }

  if (mAccessInfo.LoadForbidLen > 0) {
    CopyMem (NewFL, mAccessInfo.LoadForbid, mAccessInfo.LoadForbidLen);
    FreePool (mAccessInfo.LoadForbid);
  }

  CopyMem (NewFL + mAccessInfo.LoadForbidLen, VarPtr, DevicePathLen);
  mAccessInfo.LoadForbidLen = NewLen;
  mAccessInfo.LoadForbid    = NewFL;
  FreePool (Var);
}


