From 0c18794ea4289f03fefc7117b56740414cc0536c Mon Sep 17 00:00:00 2001 From: gdong1 Date: Fri, 2 Sep 2011 07:49:32 +0000 Subject: Add security package to repository. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12261 6f19259b-4bc3-4df7-8a09-765794883524 --- .../UserProfileManagerDxe/UserProfileAdd.c | 372 +++ .../UserProfileManagerDxe/UserProfileDelete.c | 314 +++ .../UserProfileManagerDxe/UserProfileManager.c | 806 +++++++ .../UserProfileManagerDxe/UserProfileManager.h | 387 +++ .../UserProfileManagerDxe/UserProfileManagerData.h | 161 ++ .../UserProfileManagerDxe.inf | 60 + .../UserProfileManagerStrings.uni | Bin 0 -> 21532 bytes .../UserProfileManagerVfr.Vfr | 247 ++ .../UserProfileManagerDxe/UserProfileModify.c | 2511 ++++++++++++++++++++ 9 files changed, 4858 insertions(+) create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileAdd.c create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileDelete.c create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.c create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.h create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerData.h create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerStrings.uni create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerVfr.Vfr create mode 100644 SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileModify.c (limited to 'SecurityPkg/UserIdentification/UserProfileManagerDxe') diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileAdd.c b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileAdd.c new file mode 100644 index 0000000000..eb96c8edf6 --- /dev/null +++ b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileAdd.c @@ -0,0 +1,372 @@ +/** @file + The functions to add a user profile. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+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" + + +/** + Get user name from the popup windows. + + @param[in, out] UserNameLen On entry, point to UserName buffer lengh, in bytes. + On exit, point to input user name length, in bytes. + @param[out] UserName The buffer to hold the input user name. + + @retval EFI_ABORTED It is given up by pressing 'ESC' key. + @retval EFI_NOT_READY Not a valid input at all. + @retval EFI_SUCCESS Get a user name successfully. + +**/ +EFI_STATUS +GetUserNameInput ( + IN OUT UINTN *UserNameLen, + OUT CHAR16 *UserName + ) +{ + EFI_INPUT_KEY Key; + UINTN NameLen; + CHAR16 Name[USER_NAME_LENGTH]; + + NameLen = 0; + while (TRUE) { + Name[NameLen] = L'_'; + Name[NameLen + 1] = L'\0'; + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Input User Name", + L"---------------------", + Name, + NULL + ); + // + // Check key. + // + if (Key.ScanCode == SCAN_NULL) { + if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) { + // + // Add the null terminator. + // + Name[NameLen] = 0; + NameLen++; + break; + } else if ((Key.UnicodeChar == CHAR_NULL) || + (Key.UnicodeChar == CHAR_TAB) || + (Key.UnicodeChar == CHAR_LINEFEED) + ) { + continue; + } else { + if (Key.UnicodeChar == CHAR_BACKSPACE) { + if (NameLen > 0) { + NameLen--; + } + } else { + Name[NameLen] = Key.UnicodeChar; + NameLen++; + if (NameLen + 1 == USER_NAME_LENGTH) { + // + // Add the null terminator. + // + Name[NameLen] = 0; + NameLen++; + break; + } + } + } + } + + if (Key.ScanCode == SCAN_ESC) { + return EFI_ABORTED; + } + } + + if (NameLen <= 1) { + return EFI_NOT_READY; + } + + if (*UserNameLen < NameLen * sizeof (CHAR16)) { + return EFI_NOT_READY; + } + + *UserNameLen = NameLen * sizeof (CHAR16); + CopyMem (UserName, Name, *UserNameLen); + + return EFI_SUCCESS; +} + +/** + Set a user's username. + + @param[in] User Handle of a user profile . + @param[in] UserNameLen The lengh of UserName. + @param[in] UserName Point to the buffer of user name. + + @retval EFI_NOT_READY The usernme in mAddUserName had been used. + @retval EFI_SUCCESS Change the user's username successfully with + username in mAddUserName. + +**/ +EFI_STATUS +SetUserName ( + IN EFI_USER_PROFILE_HANDLE User, + IN UINTN UserNameLen, + IN CHAR16 *UserName + ) +{ + EFI_STATUS Status; + EFI_USER_INFO_HANDLE UserInfo; + EFI_USER_PROFILE_HANDLE TempUser; + EFI_USER_INFO *NewUserInfo; + + NewUserInfo = AllocateZeroPool (sizeof (EFI_USER_INFO) + UserNameLen); + ASSERT (NewUserInfo != NULL); + + NewUserInfo->InfoType = EFI_USER_INFO_NAME_RECORD; + NewUserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | + EFI_USER_INFO_PUBLIC | + EFI_USER_INFO_EXCLUSIVE; + NewUserInfo->InfoSize = (UINT32) (sizeof (EFI_USER_INFO) + UserNameLen); + CopyMem ((UINT8 *) (NewUserInfo + 1), UserName, UserNameLen); + TempUser = NULL; + Status = mUserManager->Find ( + mUserManager, + &TempUser, + NULL, + NewUserInfo, + NewUserInfo->InfoSize + ); + if (!EFI_ERROR (Status)) { + // + // The user name had been used, return error. + // + FreePool (NewUserInfo); + return EFI_NOT_READY; + } + + UserInfo = NULL; + mUserManager->SetInfo ( + mUserManager, + User, + &UserInfo, + NewUserInfo, + NewUserInfo->InfoSize + ); + FreePool (NewUserInfo); + return EFI_SUCCESS; +} + + +/** + Set create date of the specified user. + + @param[in] User Handle of a user profile. + +**/ +VOID +SetCreateDate ( + IN EFI_USER_PROFILE_HANDLE User + ) +{ + EFI_STATUS Status; + EFI_USER_INFO_HANDLE UserInfo; + EFI_USER_INFO_CREATE_DATE Date; + EFI_USER_INFO *NewUserInfo; + + NewUserInfo = AllocateZeroPool ( + sizeof (EFI_USER_INFO) + + sizeof (EFI_USER_INFO_CREATE_DATE) + ); + ASSERT (NewUserInfo != NULL); + + NewUserInfo->InfoType = EFI_USER_INFO_CREATE_DATE_RECORD; + NewUserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | + EFI_USER_INFO_PUBLIC | + EFI_USER_INFO_EXCLUSIVE; + NewUserInfo->InfoSize = sizeof (EFI_USER_INFO) + sizeof (EFI_USER_INFO_CREATE_DATE); + Status = gRT->GetTime (&Date, NULL); + if (EFI_ERROR (Status)) { + FreePool (NewUserInfo); + return ; + } + + CopyMem ((UINT8 *) (NewUserInfo + 1), &Date, sizeof (EFI_USER_INFO_CREATE_DATE)); + UserInfo = NULL; + mUserManager->SetInfo ( + mUserManager, + User, + &UserInfo, + NewUserInfo, + NewUserInfo->InfoSize + ); + FreePool (NewUserInfo); +} + + +/** + Set the default identity policy of the specified user. + + @param[in] User Handle of a user profile. + +**/ +VOID +SetIdentityPolicy ( + IN EFI_USER_PROFILE_HANDLE User + ) +{ + EFI_USER_INFO_IDENTITY_POLICY *Policy; + EFI_USER_INFO_HANDLE UserInfo; + EFI_USER_INFO *NewUserInfo; + + NewUserInfo = AllocateZeroPool ( + sizeof (EFI_USER_INFO) + + sizeof (EFI_USER_INFO_IDENTITY_POLICY) + ); + ASSERT (NewUserInfo != NULL); + + Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (NewUserInfo + 1); + Policy->Type = EFI_USER_INFO_IDENTITY_TRUE; + Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY); + + NewUserInfo->InfoType = EFI_USER_INFO_IDENTITY_POLICY_RECORD; + NewUserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | + EFI_USER_INFO_PRIVATE | + EFI_USER_INFO_EXCLUSIVE; + NewUserInfo->InfoSize = sizeof (EFI_USER_INFO) + Policy->Length; + UserInfo = NULL; + mUserManager->SetInfo ( + mUserManager, + User, + &UserInfo, + NewUserInfo, + NewUserInfo->InfoSize + ); + FreePool (NewUserInfo); +} + + +/** + Set the default access policy of the specified user. + + @param[in] User Handle of a user profile. + +**/ +VOID +SetAccessPolicy ( + IN EFI_USER_PROFILE_HANDLE User + ) +{ + EFI_USER_INFO_ACCESS_CONTROL *Control; + EFI_USER_INFO_HANDLE UserInfo; + EFI_USER_INFO *NewUserInfo; + + NewUserInfo = AllocateZeroPool ( + sizeof (EFI_USER_INFO) + + sizeof (EFI_USER_INFO_ACCESS_CONTROL) + ); + ASSERT (NewUserInfo != NULL); + + Control = (EFI_USER_INFO_ACCESS_CONTROL *) (NewUserInfo + 1); + Control->Type = EFI_USER_INFO_ACCESS_ENROLL_SELF; + Control->Size = sizeof (EFI_USER_INFO_ACCESS_CONTROL); + + NewUserInfo->InfoType = EFI_USER_INFO_ACCESS_POLICY_RECORD; + NewUserInfo->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | + EFI_USER_INFO_PUBLIC | + EFI_USER_INFO_EXCLUSIVE; + NewUserInfo->InfoSize = sizeof (EFI_USER_INFO) + Control->Size; + UserInfo = NULL; + mUserManager->SetInfo ( + mUserManager, + User, + &UserInfo, + NewUserInfo, + NewUserInfo->InfoSize + ); + FreePool (NewUserInfo); +} + + +/** + Add a new user profile into the user profile database. + +**/ +VOID +CallAddUser ( + VOID + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + EFI_USER_PROFILE_HANDLE User; + UINTN UserNameLen; + CHAR16 UserName[USER_NAME_LENGTH]; + CHAR16 *QuestionStr; + CHAR16 *PromptStr; + + QuestionStr = NULL; + PromptStr = NULL; + + // + // Get user name to add. + // + UserNameLen = sizeof (UserName); + Status = GetUserNameInput (&UserNameLen, UserName); + if (EFI_ERROR (Status)) { + if (Status != EFI_ABORTED) { + QuestionStr = GetStringById (STRING_TOKEN (STR_GET_USERNAME_FAILED)); + PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE)); + goto Done; + } + return ; + } + + // + // Create a new user profile. + // + User = NULL; + Status = mUserManager->Create (mUserManager, &User); + if (EFI_ERROR (Status)) { + QuestionStr = GetStringById (STRING_TOKEN (STR_CREATE_PROFILE_FAILED)); + PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE)); + } else { + // + // Add default user information. + // + Status = SetUserName (User, UserNameLen, UserName); + if (EFI_ERROR (Status)) { + QuestionStr = GetStringById (STRING_TOKEN (STR_USER_ALREADY_EXISTED)); + PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE)); + goto Done; + } + + SetCreateDate (User); + SetIdentityPolicy (User); + SetAccessPolicy (User); + + QuestionStr = GetStringById (STRING_TOKEN (STR_CREATE_PROFILE_SUCCESS)); + PromptStr = GetStringById (STRING_TOKEN (STR_STROKE_KEY_CONTINUE)); + } + +Done: + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + QuestionStr, + L"", + PromptStr, + NULL + ); + FreePool (QuestionStr); + FreePool (PromptStr); +} + diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileDelete.c b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileDelete.c new file mode 100644 index 0000000000..d0295b731b --- /dev/null +++ b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileDelete.c @@ -0,0 +1,314 @@ +/** @file + The functions to delete a user profile. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+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" + +/** + Get the username from the specified user. + + @param[in] User Handle of a user profile. + + @retval EFI_STRING_ID The String Id of the user's username. + +**/ +EFI_STRING_ID +GetUserName ( + IN EFI_USER_PROFILE_HANDLE User + ) +{ + EFI_STATUS Status; + EFI_USER_INFO_HANDLE UserInfo; + EFI_USER_INFO *Info; + UINTN InfoSize; + UINTN MemSize; + UINTN NameLen; + CHAR16 UserName[USER_NAME_LENGTH]; + EFI_STRING_ID UserId; + + // + // Allocate user information memory. + // + MemSize = sizeof (EFI_USER_INFO) + 63; + Info = AllocateZeroPool (MemSize); + ASSERT (Info != NULL); + + // + // Get user name information. + // + UserInfo = NULL; + while (TRUE) { + InfoSize = MemSize; + // + // Get next user information. + // + Status = mUserManager->GetNextInfo ( + mUserManager, + User, + &UserInfo + ); + if (EFI_ERROR (Status)) { + break; + } + + Status = mUserManager->GetInfo ( + mUserManager, + User, + UserInfo, + Info, + &InfoSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + MemSize = InfoSize; + FreePool (Info); + Info = AllocateZeroPool (MemSize); + ASSERT (Info != NULL); + + Status = mUserManager->GetInfo ( + mUserManager, + User, + UserInfo, + Info, + &InfoSize + ); + } + // + // Check user information. + // + if (Status == EFI_SUCCESS) { + if (Info->InfoType == EFI_USER_INFO_NAME_RECORD) { + NameLen = Info->InfoSize - sizeof (EFI_USER_INFO); + if (NameLen > USER_NAME_LENGTH * sizeof (CHAR16)) { + NameLen = USER_NAME_LENGTH * sizeof (CHAR16); + } + ASSERT (NameLen >= sizeof (CHAR16)); + CopyMem (UserName, (UINT8 *) (Info + 1), NameLen); + UserName[NameLen / sizeof (CHAR16) - 1] = 0; + UserId = HiiSetString ( + mCallbackInfo->HiiHandle, + 0, + UserName, + NULL + ); + if (UserId != 0) { + FreePool (Info); + return UserId; + } + } + } + } + + FreePool (Info); + return 0; +} + + +/** + Add a username item in form. + + @param[in] User Points to the user profile whose username is added. + @param[in] Index The index of the user in the user name list + @param[in] OpCodeHandle Points to container for dynamic created opcodes. + +**/ +VOID +AddUserToForm ( + IN EFI_USER_PROFILE_HANDLE User, + IN UINT16 Index, + IN VOID *OpCodeHandle + ) +{ + EFI_STRING_ID NameId; + + // + // Get user name + // + NameId = GetUserName (User); + if (NameId == 0) { + return ; + } + + // + // Create user name option. + // + switch (Index & KEY_FIRST_FORM_MASK) { + case KEY_MODIFY_USER: + HiiCreateGotoOpCode ( + OpCodeHandle, // Container for dynamic created opcodes + FORMID_USER_INFO, // Target Form ID + NameId, // Prompt text + STRING_TOKEN (STR_NULL_STRING), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + Index // Question ID + ); + break; + + case KEY_DEL_USER: + HiiCreateActionOpCode ( + OpCodeHandle, // Container for dynamic created opcodes + Index, // Question ID + NameId, // Prompt text + STRING_TOKEN (STR_NULL_STRING), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + 0 // Action String ID + ); + break; + + default: + break; + } +} + + +/** + Delete the user specified by UserIndex in user profile database. + + @param[in] UserIndex The index of user in the user name list + to be deleted. + +**/ +VOID +DeleteUser ( + IN UINT8 UserIndex + ) +{ + EFI_STATUS Status; + EFI_USER_PROFILE_HANDLE User; + EFI_INPUT_KEY Key; + + // + // Find specified user profile and delete it. + // + User = NULL; + Status = mUserManager->GetNext (mUserManager, &User); + if (EFI_ERROR (Status)) { + goto Done; + } + + while (UserIndex > 1) { + Status = mUserManager->GetNext (mUserManager, &User); + if (EFI_ERROR (Status)) { + goto Done; + } + UserIndex--; + } + + if (UserIndex == 1) { + Status = mUserManager->Delete (mUserManager, User); + if (EFI_ERROR (Status)) { + goto Done; + } + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Delete User Succeed!", + L"", + L"Please Press Any Key to Continue ...", + NULL + ); + return ; + } + +Done: + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Delete User Failed!", + L"", + L"Please Press Any Key to Continue ...", + NULL + ); +} + + +/** + Display user select form, cab select a user to delete. + +**/ +VOID +SelectUserToDelete ( + VOID + ) +{ + EFI_STATUS Status; + UINT8 Index; + EFI_USER_PROFILE_HANDLE User; + EFI_USER_PROFILE_HANDLE CurrentUser; + 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_DEL_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 deleted. + // + User = NULL; + Index = 1; + mUserManager->Current (mUserManager, &CurrentUser); + while (TRUE) { + Status = mUserManager->GetNext (mUserManager, &User); + if (EFI_ERROR (Status)) { + break; + } + + if (User != CurrentUser) { + AddUserToForm ( + User, + (UINT16)(KEY_DEL_USER | KEY_SELECT_USER | Index), + StartOpCodeHandle + ); + } + Index++; + } + + HiiUpdateForm ( + mCallbackInfo->HiiHandle, // HII handle + &mUserProfileManagerGuid, // Formset GUID + FORMID_DEL_USER, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Replace data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); +} diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.c b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.c new file mode 100644 index 0000000000..74c979d58e --- /dev/null +++ b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.c @@ -0,0 +1,806 @@ +/** @file + This driver is a configuration tool for adding, deleting or modifying user + profiles, including gathering the necessary information to ascertain their + identity in the future, updating user access policy and identification + policy, etc. + +Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+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_GUID mUserProfileManagerGuid = USER_PROFILE_MANAGER_GUID; +EFI_USER_MANAGER_PROTOCOL *mUserManager = NULL; +CREDENTIAL_PROVIDER_INFO *mProviderInfo = NULL; +UINT8 mProviderChoice; +UINT8 mConncetLogical; +USER_INFO_ACCESS mAccessInfo; +USER_INFO mUserInfo; +USER_PROFILE_MANAGER_CALLBACK_INFO *mCallbackInfo; +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + {0xad2e3474, 0x93e6, 0x488b, {0x93, 0x19, 0x64, 0x88, 0xfc, 0x68, 0x1f, 0x16}} + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH), + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + + +/** + Get string by string id from HII Interface. + + + @param[in] Id String ID to get the string from. + + @retval CHAR16 * String from ID. + @retval NULL If error occurs. + +**/ +CHAR16 * +GetStringById ( + IN EFI_STRING_ID Id + ) +{ + // + // Get the current string for the current Language. + // + return HiiGetString (mCallbackInfo->HiiHandle, Id, NULL); +} + + +/** + This function gets all the credential providers in the system and saved them + to mProviderInfo. + + @retval EFI_SUCESS Init credential provider database successfully. + @retval Others Fail to init credential provider database. + +**/ +EFI_STATUS +InitProviderInfo ( + VOID + ) +{ + EFI_STATUS Status; + UINTN HandleCount; + EFI_HANDLE *HandleBuf; + UINTN Index; + + // + // Try to find all the user credential provider driver. + // + HandleCount = 0; + HandleBuf = NULL; + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiUserCredentialProtocolGuid, + NULL, + &HandleCount, + &HandleBuf + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Get provider infomation. + // + if (mProviderInfo != NULL) { + FreePool (mProviderInfo); + } + mProviderInfo = AllocateZeroPool ( + sizeof (CREDENTIAL_PROVIDER_INFO) - + sizeof (EFI_USER_CREDENTIAL_PROTOCOL *) + + HandleCount * sizeof (EFI_USER_CREDENTIAL_PROTOCOL *) + ); + if (mProviderInfo == NULL) { + FreePool (HandleBuf); + return EFI_OUT_OF_RESOURCES; + } + + mProviderInfo->Count = HandleCount; + for (Index = 0; Index < HandleCount; Index++) { + Status = gBS->HandleProtocol ( + HandleBuf[Index], + &gEfiUserCredentialProtocolGuid, + (VOID **) &mProviderInfo->Provider[Index] + ); + if (EFI_ERROR (Status)) { + FreePool (HandleBuf); + FreePool (mProviderInfo); + mProviderInfo = NULL; + return Status; + } + } + + FreePool (HandleBuf); + return EFI_SUCCESS; +} + + +/** + This function processes changes in user profile configuration. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Action Specifies the type of action taken by the browser. + @param QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the original + exporting driver. + @param ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval Others Fail to handle the action. + +**/ +EFI_STATUS +EFIAPI +UserProfileManagerCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + EFI_STATUS Status; + EFI_INPUT_KEY Key; + UINT32 CurrentAccessRight; + CHAR16 *QuestionStr; + CHAR16 *PromptStr; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; + EFI_USER_PROFILE_HANDLE CurrentUser; + + Status = EFI_SUCCESS; + + switch (Action) { + case EFI_BROWSER_ACTION_FORM_OPEN: + { + // + // Update user manage Form when user manage Form is opened. + // This will be done only in FORM_OPEN CallBack of question with QUESTIONID_USER_MANAGE from user manage Form. + // + if (QuestionId != QUESTIONID_USER_MANAGE) { + return EFI_SUCCESS; + } + + // + // Get current user + // + CurrentUser = NULL; + mUserManager->Current (mUserManager, &CurrentUser); + if (CurrentUser == NULL) { + DEBUG ((DEBUG_ERROR, "Error: current user does not exist!\n")); + return EFI_NOT_READY; + } + + // + // Get current user's right information. + // + Status = GetAccessRight (&CurrentAccessRight); + if (EFI_ERROR (Status)) { + CurrentAccessRight = EFI_USER_INFO_ACCESS_ENROLL_SELF; + } + + // + // Init credential provider information. + // + Status = InitProviderInfo (); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // 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_MANAGE_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 user profile option. + // + if ((CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) || + (CurrentAccessRight == EFI_USER_INFO_ACCESS_ENROLL_OTHERS) + ) { + HiiCreateActionOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + KEY_ADD_USER, // Question ID + STRING_TOKEN (STR_ADD_USER_TITLE), // Prompt text + STRING_TOKEN (STR_ADD_USER_HELP), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + 0 // Action String ID + ); + } + + // + // Add modify user profile option. + // + HiiCreateGotoOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + FORMID_MODIFY_USER, // Target Form ID + STRING_TOKEN (STR_MODIFY_USER_TITLE), // Prompt text + STRING_TOKEN (STR_MODIFY_USER_HELP), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + KEY_MODIFY_USER // Question ID + ); + + // + // Add delete user profile option + // + if (CurrentAccessRight == EFI_USER_INFO_ACCESS_MANAGE) { + HiiCreateGotoOpCode ( + StartOpCodeHandle, // Container for dynamic created opcodes + FORMID_DEL_USER, // Target Form ID + STRING_TOKEN (STR_DELETE_USER_TITLE), // Prompt text + STRING_TOKEN (STR_DELETE_USER_HELP), // Help text + EFI_IFR_FLAG_CALLBACK, // Question flag + KEY_DEL_USER // Question ID + ); + } + + HiiUpdateForm ( + mCallbackInfo->HiiHandle, // HII handle + &mUserProfileManagerGuid, // Formset GUID + FORMID_USER_MANAGE, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Replace data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); + + return EFI_SUCCESS; + } + break; + + case EFI_BROWSER_ACTION_FORM_CLOSE: + Status = EFI_SUCCESS; + break; + + case EFI_BROWSER_ACTION_CHANGING: + { + // + // Handle the request from form. + // + if ((Value == NULL) || (ActionRequest == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Judge first 2 bits. + // + switch (QuestionId & KEY_FIRST_FORM_MASK) { + // + // Add user profile operation. + // + case KEY_ADD_USER: + CallAddUser (); + break; + + // + // Delete user profile operation. + // + case KEY_DEL_USER: + // + // Judge next 2 bits. + // + switch (QuestionId & KEY_SECOND_FORM_MASK) { + // + // Enter delete user profile form. + // + case KEY_ENTER_NEXT_FORM: + SelectUserToDelete (); + break; + + // + // Delete specified user profile. + // + case KEY_SELECT_USER: + DeleteUser ((UINT8) QuestionId); + // + // Update select user form after delete a user. + // + SelectUserToDelete (); + break; + + default: + break; + } + break; + + // + // Modify user profile operation. + // + case KEY_MODIFY_USER: + // + // Judge next 2 bits. + // + switch (QuestionId & KEY_SECOND_FORM_MASK) { + // + // Enter modify user profile form. + // + case KEY_ENTER_NEXT_FORM: + SelectUserToModify (); + break; + + // + // Enter user profile information form. + // + case KEY_SELECT_USER: + // + // Judge next 3 bits. + // + switch (QuestionId & KEY_MODIFY_INFO_MASK) { + // + // Display user information form. + // + case KEY_ENTER_NEXT_FORM: + ModifyUserInfo ((UINT8) QuestionId); + break; + + // + // Modify user name. + // + case KEY_MODIFY_NAME: + ModifyUserName (); + // + // Update username in parent form. + // + SelectUserToModify (); + break; + + // + // Modify identity policy. + // + case KEY_MODIFY_IP: + // + // Judge next 3 bits + // + switch (QuestionId & KEY_MODIFY_IP_MASK) { + // + // Display identity policy modify form. + // + case KEY_ENTER_NEXT_FORM: + ModifyIdentityPolicy (); + break; + + // + // Change credential provider option. + // + case KEY_MODIFY_PROV: + mProviderChoice = Value->u8; + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + break; + + // + // Change logical connector. + // + case KEY_MODIFY_CONN: + mConncetLogical = Value->u8; + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + break; + + // + // Save option. + // + case KEY_ADD_IP_OP: + AddIdentityPolicyItem (); + break; + + // + // Return to user profile information form. + // + case KEY_IP_RETURN_UIF: + SaveIdentityPolicy (); + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + break; + + default: + break; + } + break; + + // + // Modify access policy. + // + case KEY_MODIFY_AP: + // + // Judge next 3 bits. + // + switch (QuestionId & KEY_MODIFY_AP_MASK) { + // + // Display access policy modify form. + // + case KEY_ENTER_NEXT_FORM: + ModidyAccessPolicy (); + break; + + // + // Change access right choice. + // + case KEY_MODIFY_RIGHT: + mAccessInfo.AccessRight = Value->u8; + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + break; + + // + // Change setup choice. + // + case KEY_MODIFY_SETUP: + mAccessInfo.AccessSetup= Value->u8; + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + break; + + // + // Change boot order choice. + // + case KEY_MODIFY_BOOT: + mAccessInfo.AccessBootOrder = Value->u32; + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + break; + + // + // Load device path form. + // + case KEY_MODIFY_LOAD: + // + // Judge next 2 bits. + // + switch (QuestionId & KEY_DISPLAY_DP_MASK) { + // + // Permit load device path. + // + case KEY_PERMIT_MODIFY: + DisplayLoadPermit (); + break; + + // + // Forbid load device path. + // + case KEY_FORBID_MODIFY: + DisplayLoadForbid (); + break; + + default: + break; + } + break; + + // + // Connect device path form. + // + case KEY_MODIFY_CONNECT: + // + // Judge next 2 bits. + // + switch (QuestionId & KEY_DISPLAY_DP_MASK) { + // + // Permit connect device path. + // + case KEY_PERMIT_MODIFY: + DisplayConnectPermit (); + break; + + // + // Forbid connect device path. + // + case KEY_FORBID_MODIFY: + DisplayConnectForbid (); + break; + + default: + break; + } + break; + + // + // Return to user profile information form. + // + case KEY_AP_RETURN_UIF: + SaveAccessPolicy (); + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; + break; + + default: + break; + } + break; + + default: + break; + } + break; + + // + // Access policy device path modified. + // + case KEY_MODIFY_AP_DP: + // + // Judge next 2 bits. + // + switch (QuestionId & KEY_MODIFY_DP_MASK) { + // + // Load permit device path modified. + // + case KEY_LOAD_PERMIT_MODIFY: + QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_FORBID_LIST)); + PromptStr = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE)); + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + QuestionStr, + L"", + PromptStr, + NULL + ); + FreePool (QuestionStr); + FreePool (PromptStr); + if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) { + break; + } + + AddToForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1))); + DisplayLoadPermit (); + break; + + // + // Load forbid device path modified. + // + case KEY_LOAD_FORBID_MODIFY: + QuestionStr = GetStringById (STRING_TOKEN (STR_MOVE_TO_PERMIT_LIST)); + PromptStr = GetStringById (STRING_TOKEN (STR_PRESS_KEY_CONTINUE)); + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + QuestionStr, + L"", + PromptStr, + NULL + ); + FreePool (QuestionStr); + FreePool (PromptStr); + if (Key.UnicodeChar != CHAR_CARRIAGE_RETURN) { + break; + } + + DeleteFromForbidLoad ((UINT16)(QuestionId & (KEY_MODIFY_DP_MASK - 1))); + DisplayLoadForbid (); + break; + + // + // Connect permit device path modified. + // + case KEY_CONNECT_PERMIT_MODIFY: + break; + + // + // Connect forbid device path modified. + // + case KEY_CONNECT_FORBID_MODIFY: + break; + + default: + break; + } + break; + + default: + break; + } + break; + + default: + break; + } + } + break; + + default: + // + // All other action return unsupported. + // + Status = EFI_UNSUPPORTED; + break; + } + + + return Status; +} + + +/** + This function allows a caller to extract the current configuration for one + or more named elements from the target driver. + + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Request A null-terminated Unicode string in format. + @param Progress On return, points to a character in the Request string. + Points to the string's null terminator if request was successful. + Points to the most recent '&' before the first failing name/value + pair (or the beginning of the string if the failure is in the + first name/value pair) if the request was not successful. + @param Results A null-terminated Unicode string in format which + has all values filled in for the names in the Request string. + String to be allocated by the called function. + + @retval EFI_SUCCESS The Results is filled with the requested values. + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. + @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. + +**/ +EFI_STATUS +EFIAPI +FakeExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + if (Progress == NULL || Results == NULL) { + return EFI_INVALID_PARAMETER; + } + *Progress = Request; + return EFI_NOT_FOUND; +} + +/** + This function processes the results of changes in configuration. + + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Configuration A null-terminated Unicode string in format. + @param Progress A pointer to a string filled in with the offset of the most + recent '&' before the first failing name/value pair (or the + beginning of the string if the failure is in the first + name/value pair) or the terminating NULL if all was successful. + + @retval EFI_SUCCESS The Results is processed successfully. + @retval EFI_INVALID_PARAMETER Configuration is NULL. + @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. + +**/ +EFI_STATUS +EFIAPI +FakeRouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ) +{ + if (Configuration == NULL || Progress == NULL) { + return EFI_INVALID_PARAMETER; + } + + return EFI_NOT_FOUND; +} + + +/** + Main entry for this driver. + + @param ImageHandle Image handle this driver. + @param SystemTable Pointer to SystemTable. + + @retval EFI_SUCESS This function always complete successfully. + +**/ +EFI_STATUS +EFIAPI +UserProfileManagerInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + USER_PROFILE_MANAGER_CALLBACK_INFO *CallbackInfo; + + Status = gBS->LocateProtocol ( + &gEfiUserManagerProtocolGuid, + NULL, + (VOID **) &mUserManager + ); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + // + // Initialize driver private data. + // + ZeroMem (&mUserInfo, sizeof (mUserInfo)); + ZeroMem (&mAccessInfo, sizeof (mAccessInfo)); + + CallbackInfo = AllocateZeroPool (sizeof (USER_PROFILE_MANAGER_CALLBACK_INFO)); + ASSERT (CallbackInfo != NULL); + + CallbackInfo->Signature = USER_PROFILE_MANAGER_SIGNATURE; + CallbackInfo->ConfigAccess.ExtractConfig = FakeExtractConfig; + CallbackInfo->ConfigAccess.RouteConfig = FakeRouteConfig; + CallbackInfo->ConfigAccess.Callback = UserProfileManagerCallback; + CallbackInfo->DriverHandle = NULL; + + // + // Install Device Path Protocol and Config Access protocol to driver handle. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &CallbackInfo->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &CallbackInfo->ConfigAccess, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Publish HII data. + // + CallbackInfo->HiiHandle = HiiAddPackages ( + &mUserProfileManagerGuid, + CallbackInfo->DriverHandle, + UserProfileManagerStrings, + UserProfileManagerVfrBin, + NULL + ); + ASSERT (CallbackInfo->HiiHandle != NULL); + mCallbackInfo = CallbackInfo; + + return Status; +} + + diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.h b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.h new file mode 100644 index 0000000000..b7098dc7b6 --- /dev/null +++ b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManager.h @@ -0,0 +1,387 @@ +/** @file + The header file for user profile manager driver. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef __EFI_USER_PROFILE_MANAGER_H__ +#define __EFI_USER_PROFILE_MANAGER_H__ + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "UserProfileManagerData.h" + +#define USER_NAME_LENGTH 17 + +// +// Credential Provider Information. +// +typedef struct { + UINTN Count; + EFI_USER_CREDENTIAL_PROTOCOL *Provider[1]; +} CREDENTIAL_PROVIDER_INFO; + +// +// User profile information structure. +// +typedef struct { + UINT64 UsageCount; + EFI_TIME CreateDate; + EFI_TIME UsageDate; + UINTN AccessPolicyLen; + UINTN IdentityPolicyLen; + UINTN NewIdentityPolicyLen; + UINT8 *AccessPolicy; + UINT8 *IdentityPolicy; + UINT8 *NewIdentityPolicy; + CHAR16 UserName[USER_NAME_LENGTH]; + BOOLEAN CreateDateExist; + BOOLEAN UsageDateExist; + BOOLEAN AccessPolicyModified; + BOOLEAN IdentityPolicyModified; + BOOLEAN NewIdentityPolicyModified; +} USER_INFO; + +// +// User access information structure. +// +typedef struct { + UINTN LoadPermitLen; + UINTN LoadForbidLen; + UINTN ConnectPermitLen; + UINTN ConnectForbidLen; + UINT8 *LoadPermit; + UINT8 *LoadForbid; + UINT8 *ConnectPermit; + UINT8 *ConnectForbid; + UINT32 AccessBootOrder; + UINT8 AccessRight; + UINT8 AccessSetup; +} USER_INFO_ACCESS; + +#define USER_PROFILE_MANAGER_SIGNATURE SIGNATURE_32 ('U', 'P', 'M', 'S') + +typedef struct { + UINTN Signature; + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE HiiHandle; + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; +} USER_PROFILE_MANAGER_CALLBACK_INFO; + +// +// HII specific Vendor Device Path definition. +// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; + +// +// This is the generated IFR binary data for each formset defined in VFR. +// +extern UINT8 UserProfileManagerVfrBin[]; + +// +// This is the generated String package data for .UNI file. +// +extern UINT8 UserProfileManagerStrings[]; + +// +// Guid used in the form browse. +// +extern EFI_GUID mUserProfileManagerGuid; + +// +// The user manager protocol, used in several function. +// +extern EFI_USER_MANAGER_PROTOCOL *mUserManager; + +// +// The credential providers database in system. +// +extern CREDENTIAL_PROVIDER_INFO *mProviderInfo; + +// +// The variables used to update identity policy. +// +extern UINT8 mProviderChoice; +extern UINT8 mConncetLogical; + +// +// The variables used to update access policy. +// +extern USER_INFO_ACCESS mAccessInfo; + +// +// The user information used to record all data in UI. +// +extern USER_INFO mUserInfo; + +extern USER_PROFILE_MANAGER_CALLBACK_INFO *mCallbackInfo; + + +/** + Get string by string id from HII Interface. + + + @param[in] Id String ID to get the string from. + + @retval CHAR16 * String from ID. + @retval NULL If error occurs. + +**/ +CHAR16 * +GetStringById ( + IN EFI_STRING_ID Id + ); + +/** + Add a new user profile into the user profile database. + +**/ +VOID +CallAddUser ( + VOID + ); + +/** + Display user select form; can select a user to modify. + +**/ +VOID +SelectUserToModify ( + VOID + ); + +/** + Display user select form, cab select a user to delete. + +**/ +VOID +SelectUserToDelete ( + VOID + ); + +/** + Delete the user specified by UserIndex in user profile database. + + @param[in] UserIndex The index of user in the user name list to be deleted. + +**/ +VOID +DeleteUser ( + IN UINT8 UserIndex + ); + +/** + Add a username item in form. + + @param[in] User Points to the user profile whose username is added. + @param[in] Index The index of the user in the user name list. + @param[in] OpCodeHandle Points to container for dynamic created opcodes. + +**/ +VOID +AddUserToForm ( + IN EFI_USER_PROFILE_HANDLE User, + IN UINT16 Index, + IN VOID *OpCodeHandle + ); + +/** + Display modify user information form + + In this form, username, create Date, usage date, usage count, identity policy, + and access policy are displayed. + + @param[in] UserIndex The index of the user in display list to modify. + +**/ +VOID +ModifyUserInfo ( + IN UINT8 UserIndex + ); + +/** + Get the username from user input and update username string in Hii + database with it. + +**/ +VOID +ModifyUserName ( + VOID + ); + +/** + Display the form of modifying user identity policy. + +**/ +VOID +ModifyIdentityPolicy ( + VOID + ); + +/** + Update the mUserInfo.NewIdentityPolicy and UI when 'add option' is pressed. + +**/ +VOID +AddIdentityPolicyItem ( + VOID + ); + +/** + Save the identity policy and update UI with it. + + This funciton will verify the new identity policy, in current implementation, + the identity policy can be: T, P & P & P & ..., P | P | P | ... + Here, "T" means "True", "P" means "Credential Provider", "&" means "and", "|" means "or". + Other identity policies are not supported. + +**/ +VOID +SaveIdentityPolicy ( + VOID + ); + +/** + Display modify user access policy form + + In this form, access right, access setu,p and access boot order are dynamically + added. Load devicepath and connect devicepath are displayed too. + +**/ +VOID +ModidyAccessPolicy ( + VOID + ); + +/** + Collect all the access policy data to mUserInfo.AccessPolicy, + and save it to user profile. + +**/ +VOID +SaveAccessPolicy ( + VOID + ); + +/** + Get current user's access rights. + + @param[out] AccessRight Points to the buffer used for user's access rights. + + @retval EFI_SUCCESS Get current user access rights successfully. + @retval others Fail to get current user access rights. + +**/ +EFI_STATUS +GetAccessRight ( + OUT UINT32 *AccessRight + ); + +/** + Display the permit load device path in the loadable device path list. + +**/ +VOID +DisplayLoadPermit( + VOID + ); + +/** + Display the forbid load device path list (mAccessInfo.LoadForbid). + +**/ +VOID +DisplayLoadForbid ( + VOID + ); + +/** + Display the permit connect device path. + +**/ +VOID +DisplayConnectPermit ( + VOID + ); + +/** + Display the forbid connect device path list. + +**/ +VOID +DisplayConnectForbid ( + VOID + ); + +/** + Delete the specified device path by DriverIndex from the forbid device path + list (mAccessInfo.LoadForbid). + + @param[in] DriverIndex The index of driver in a forbidden device path list. + +**/ +VOID +DeleteFromForbidLoad ( + IN UINT16 DriverIndex + ); + +/** + 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 + ); + +/** + Get user name from the popup windows. + + @param[in, out] UserNameLen On entry, point to the buffer lengh of UserName. + On exit, point to the input user name length. + @param[out] UserName The buffer to hold the input user name. + + @retval EFI_ABORTED It is given up by pressing 'ESC' key. + @retval EFI_NOT_READY Not a valid input at all. + @retval EFI_SUCCESS Get a user name successfully. + +**/ +EFI_STATUS +GetUserNameInput ( + IN OUT UINTN *UserNameLen, + OUT CHAR16 *UserName + ); + +#endif diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerData.h b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerData.h new file mode 100644 index 0000000000..58b6cb8c1e --- /dev/null +++ b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerData.h @@ -0,0 +1,161 @@ +/** @file + The form data for user profile manager driver. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef __USER_PROFILE_MANAGER_DATA_H__ +#define __USER_PROFILE_MANAGER_DATA_H__ + +#define USER_PROFILE_MANAGER_GUID \ + { \ + 0xc35f272c, 0x97c2, 0x465a, { 0xa2, 0x16, 0x69, 0x6b, 0x66, 0x8a, 0x8c, 0xfe } \ + } + +// +// Form ID +// +#define FORMID_USER_MANAGE 0x0001 +#define FORMID_MODIFY_USER 0x0002 +#define FORMID_DEL_USER 0x0003 +#define FORMID_USER_INFO 0x0004 +#define FORMID_MODIFY_IP 0x0005 +#define FORMID_MODIFY_AP 0x0006 +#define FORMID_LOAD_DP 0x0007 +#define FORMID_CONNECT_DP 0x0008 +#define FORMID_PERMIT_LOAD_DP 0x0009 +#define FORMID_FORBID_LOAD_DP 0x000A +#define FORMID_PERMIT_CONNECT_DP 0x000B +#define FORMID_FORBID_CONNECT_DP 0x000C + +// +// Label ID +// +#define LABEL_USER_MANAGE_FUNC 0x0010 +#define LABEL_USER_DEL_FUNC 0x0020 +#define LABEL_USER_MOD_FUNC 0x0030 +#define LABEL_USER_INFO_FUNC 0x0040 +#define LABEL_IP_MOD_FUNC 0x0050 +#define LABEL_AP_MOD_FUNC 0x0060 +#define LABEL_PERMIT_LOAD_FUNC 0x0070 +#define LABLE_FORBID_LOAD_FUNC 0x0080 +#define LABEL_END 0x00F0 + +// +// First form key (Add/modify/del user profile). +// First 2 bits (bit 16~15). +// +#define KEY_MODIFY_USER 0x4000 +#define KEY_DEL_USER 0x8000 +#define KEY_ADD_USER 0xC000 +#define KEY_FIRST_FORM_MASK 0xC000 + +// +// Second form key (Display new form /Select user / modify device path in access policy). +// Next 2 bits (bit 14~13). +// +#define KEY_ENTER_NEXT_FORM 0x0000 +#define KEY_SELECT_USER 0x1000 +#define KEY_MODIFY_AP_DP 0x2000 +#define KEY_OPEN_CLOSE_FORM_ACTION 0x3000 +#define KEY_SECOND_FORM_MASK 0x3000 + +// +// User profile information form key. +// Next 3 bits (bit 12~10). +// +#define KEY_MODIFY_NAME 0x0200 +#define KEY_MODIFY_IP 0x0400 +#define KEY_MODIFY_AP 0x0600 +#define KEY_MODIFY_INFO_MASK 0x0E00 + +// +// Specified key, used in VFR (KEY_MODIFY_USER | KEY_SELECT_USER | KEY_MODIFY_NAME). +// +#define KEY_MODIFY_USER_NAME 0x5200 + +// +// Modify identity policy form key. +// Next 3 bits (bit 9~7). +// +#define KEY_MODIFY_PROV 0x0040 +#define KEY_MODIFY_MTYPE 0x0080 +#define KEY_MODIFY_CONN 0x00C0 +#define KEY_ADD_IP_OP 0x0100 +#define KEY_IP_RETURN_UIF 0x0140 +#define KEY_MODIFY_IP_MASK 0x01C0 + +// +// Specified key. +// +#define KEY_ADD_LOGICAL_OP 0x5500 +#define KEY_IP_RETURN 0x5540 + +// +// Modify access policy form key. +// Next 3 bits (bit 9~7). +// +#define KEY_MODIFY_RIGHT 0x0040 +#define KEY_MODIFY_SETUP 0x0080 +#define KEY_MODIFY_BOOT 0x00C0 +#define KEY_MODIFY_LOAD 0x0100 +#define KEY_MODIFY_CONNECT 0x0140 +#define KEY_AP_RETURN_UIF 0x0180 +#define KEY_MODIFY_AP_MASK 0x01C0 + +// +// Specified key. +// +#define KEY_LOAD_DP 0x5700 +#define KEY_CONN_DP 0x5740 +#define KEY_AP_RETURN 0x5780 + +// +// Device path form key. +// Next 2 bits (bit 6~5). +// +#define KEY_PERMIT_MODIFY 0x0010 +#define KEY_FORBID_MODIFY 0x0020 +#define KEY_DISPLAY_DP_MASK 0x0030 + +// +// Specified key. +// +#define KEY_LOAD_PERMIT 0x5710 +#define KEY_LOAD_FORBID 0x5720 +#define KEY_CONNECT_PERMIT 0x5750 +#define KEY_CONNECT_FORBID 0x5760 + +// +// Device path modify key. +// 2 bits (bit 12~11). +// +#define KEY_LOAD_PERMIT_MODIFY 0x0000 +#define KEY_LOAD_FORBID_MODIFY 0x0400 +#define KEY_CONNECT_PERMIT_MODIFY 0x0800 +#define KEY_CONNECT_FORBID_MODIFY 0x0C00 +#define KEY_MODIFY_DP_MASK 0x0C00 + + +// +// The permissions usable when configuring the platform. +// +#define ACCESS_SETUP_RESTRICTED 1 +#define ACCESS_SETUP_NORMAL 2 +#define ACCESS_SETUP_ADMIN 3 + +// +// Question ID for the question used in each form (KEY_OPEN_CLOSE_FORM_ACTION | FORMID_FORM_USER_MANAGE) +// This ID is used in FORM OPEN/CLOSE CallBack action. +// +#define QUESTIONID_USER_MANAGE 0x3001 + +#endif diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf new file mode 100644 index 0000000000..27b3464dcf --- /dev/null +++ b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerDxe.inf @@ -0,0 +1,60 @@ +## @file +# Component description file for user profile manager driver. +# +# Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.
+# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UserProfileManager + FILE_GUID = E38CB52D-A74D-45db-A8D0-290C9B21BBF2 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = UserProfileManagerInit + +[Sources] + UserProfileManager.c + UserProfileManager.h + UserProfileAdd.c + UserProfileDelete.c + UserProfileModify.c + UserProfileManagerData.h + UserProfileManagerStrings.uni + UserProfileManagerVfr.Vfr + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiRuntimeServicesTableLib + UefiBootServicesTableLib + UefiDriverEntryPoint + MemoryAllocationLib + BaseMemoryLib + DebugLib + HiiLib + UefiLib + + [Guids] + gEfiIfrTianoGuid ## CONSUMES ## Guid + gEfiUserInfoAccessSetupAdminGuid ## CONSUMES ## Guid + gEfiUserInfoAccessSetupNormalGuid ## CONSUMES ## Guid + gEfiUserInfoAccessSetupRestrictedGuid ## CONSUMES ## Guid + +[Protocols] + gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED + gEfiHiiConfigAccessProtocolGuid + gEfiUserCredentialProtocolGuid + gEfiUserManagerProtocolGuid + gEfiDevicePathToTextProtocolGuid + +[Depex] + gEfiUserManagerProtocolGuid \ No newline at end of file diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerStrings.uni b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerStrings.uni new file mode 100644 index 0000000000..64631bb921 Binary files /dev/null and b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerStrings.uni differ diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerVfr.Vfr b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerVfr.Vfr new file mode 100644 index 0000000000..d094d78a76 --- /dev/null +++ b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileManagerVfr.Vfr @@ -0,0 +1,247 @@ +/** @file + User Profile Manager formset. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+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 "UserProfileManagerData.h" + +#define USER_MANAGER_CLASS 0x00 +#define USER_MANAGER_SUBCLASS 0x04 + +formset + guid = USER_PROFILE_MANAGER_GUID, + title = STRING_TOKEN(STR_FORMSET_TITLE), + help = STRING_TOKEN(STR_TITLE_HELP), + class = USER_MANAGER_CLASS, + subclass = USER_MANAGER_SUBCLASS, + + // User manager form + form formid = FORMID_USER_MANAGE, + title = STRING_TOKEN(STR_USERMAN_TITLE); + + label LABEL_USER_MANAGE_FUNC; + label LABEL_END; + + suppressif TRUE; + text + help = STRING_TOKEN(STR_NULL_STRING), + text = STRING_TOKEN(STR_NULL_STRING), + text = STRING_TOKEN(STR_NULL_STRING), + flags = INTERACTIVE, + key = QUESTIONID_USER_MANAGE; + endif; + + endform; + + // Modify user profile form + form formid = FORMID_MODIFY_USER, + title = STRING_TOKEN(STR_MODIFY_USER_TITLE); + + label LABEL_USER_MOD_FUNC; + label LABEL_END; + + endform; + + // Delete user profile form + form formid = FORMID_DEL_USER, + title = STRING_TOKEN(STR_DELETE_USER_TITLE); + + label LABEL_USER_DEL_FUNC; + label LABEL_END; + + subtitle + text = STRING_TOKEN(STR_NULL_STRING); + endform; + + // + // User profile information form + // + form formid = FORMID_USER_INFO, + title = STRING_TOKEN(STR_USER_INFO); + + text + help = STRING_TOKEN(STR_USER_NAME_VAL), + text = STRING_TOKEN(STR_USER_NAME), + flags = INTERACTIVE, + key = KEY_MODIFY_USER_NAME; + + text + help = STRING_TOKEN(STR_CREATE_DATE_VAL), + text = STRING_TOKEN(STR_CREATE_DATE); + + text + help = STRING_TOKEN(STR_USAGE_DATE_VAL), + text = STRING_TOKEN(STR_USAGE_DATE); + + text + help = STRING_TOKEN(STR_USAGE_COUNT_VAL), + text = STRING_TOKEN(STR_USAGE_COUNT); + + label LABEL_USER_INFO_FUNC; + label LABEL_END; + + endform; + + // + // Identify policy modify form + // + form formid = FORMID_MODIFY_IP, + title = STRING_TOKEN(STR_IDENTIFY_POLICY); + + text + help = STRING_TOKEN(STR_IDENTIFY_POLICY_HELP), + text = STRING_TOKEN(STR_IDENTIFY_POLICY), + text = STRING_TOKEN(STR_IDENTIFY_POLICY_VALUE); + + label LABEL_IP_MOD_FUNC; + label LABEL_END; + + text + help = STRING_TOKEN(STR_ADD_OPTION_HELP), + text = STRING_TOKEN(STR_ADD_OPTION), + flags = INTERACTIVE, + key = KEY_ADD_LOGICAL_OP; + + subtitle + text = STRING_TOKEN(STR_NULL_STRING); + + goto FORMID_USER_INFO, + prompt = STRING_TOKEN(STR_SAVE), + help = STRING_TOKEN(STR_IDENTIFY_SAVE_HELP), + flags = INTERACTIVE, + key = KEY_IP_RETURN; + + endform; + + // + // Access policy modify form + // + form formid = FORMID_MODIFY_AP, + title = STRING_TOKEN(STR_ACCESS_POLICY); + + label LABEL_AP_MOD_FUNC; + label LABEL_END; + + goto FORMID_LOAD_DP, + prompt = STRING_TOKEN(STR_LOAD), + help = STRING_TOKEN(STR_LOAD_HELP), + flags = INTERACTIVE, + key = KEY_LOAD_DP; + + goto FORMID_CONNECT_DP, + prompt = STRING_TOKEN(STR_CONNECT), + help = STRING_TOKEN(STR_CONNECT_HELP), + flags = INTERACTIVE, + key = KEY_CONN_DP; + + subtitle + text = STRING_TOKEN(STR_NULL_STRING); + + goto FORMID_USER_INFO, + prompt = STRING_TOKEN(STR_SAVE), + help = STRING_TOKEN(STR_ACCESS_SAVE_HELP), + flags = INTERACTIVE, + key = KEY_AP_RETURN; + + endform; + + // + // Load device path form + // + form formid = FORMID_LOAD_DP, + title = STRING_TOKEN(STR_LOAD); + + goto FORMID_PERMIT_LOAD_DP, + prompt = STRING_TOKEN(STR_LOAD_PERMIT), + help = STRING_TOKEN(STR_LOAD_PERMIT_HELP), + flags = INTERACTIVE, + key = KEY_LOAD_PERMIT; + + goto FORMID_FORBID_LOAD_DP, + prompt = STRING_TOKEN(STR_LOAD_FORBID), + help = STRING_TOKEN(STR_LOAD_FORBID_HELP), + flags = INTERACTIVE, + key = KEY_LOAD_FORBID; + + endform; + + // + // Permit load device path form + // + form formid = FORMID_PERMIT_LOAD_DP, + title = STRING_TOKEN(STR_LOAD_PERMIT); + + label LABEL_PERMIT_LOAD_FUNC; + label LABEL_END; + + subtitle + text = STRING_TOKEN(STR_NULL_STRING); + + endform; + + // + // Forbid load device path form + // + form formid = FORMID_FORBID_LOAD_DP, + title = STRING_TOKEN(STR_LOAD_FORBID); + + label LABLE_FORBID_LOAD_FUNC; + label LABEL_END; + + subtitle + text = STRING_TOKEN(STR_NULL_STRING); + + endform; + + // + // Connect device path form + // + form formid = FORMID_CONNECT_DP, + title = STRING_TOKEN(STR_CONNECT); + + goto FORMID_PERMIT_CONNECT_DP, + prompt = STRING_TOKEN(STR_CONNECT_PERMIT), + help = STRING_TOKEN(STR_CONNECT_PERMIT_HELP), + flags = INTERACTIVE, + key = KEY_CONNECT_PERMIT; + + goto FORMID_FORBID_CONNECT_DP, + prompt = STRING_TOKEN(STR_CONNECT_FORBID), + help = STRING_TOKEN(STR_CONNECT_FORBID_HELP), + flags = INTERACTIVE, + key = KEY_CONNECT_FORBID; + + endform; + + // + // Permit connect device path form + // + form formid = FORMID_PERMIT_CONNECT_DP, + title = STRING_TOKEN(STR_CONNECT_PERMIT); + + subtitle + text = STRING_TOKEN(STR_NULL_STRING); + + endform; + + // + // Forbid connect device path form + // + form formid = FORMID_FORBID_CONNECT_DP, + title = STRING_TOKEN(STR_CONNECT_FORBID); + + subtitle + text = STRING_TOKEN(STR_NULL_STRING); + + endform; + +endformset; diff --git a/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileModify.c b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileModify.c new file mode 100644 index 0000000000..156c155c2c --- /dev/null +++ b/SecurityPkg/UserIdentification/UserProfileManagerDxe/UserProfileModify.c @@ -0,0 +1,2511 @@ +/** @file + The functions to modify a user profile. + +Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
+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 + &mUserProfileManagerGuid, // 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_CREDENTIAL_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 + &mUserProfileManagerGuid, // 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 profile mModifyUser by the InfoType. + + @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 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, 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 EFI_OUT_OF_RESOURCES; + } + Status = mUserManager->GetInfo ( + mUserManager, + mModifyUser, + *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 + &mUserProfileManagerGuid, // 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; +} + + +/** + 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)) { + Info = AllocateZeroPool (sizeof (EFI_USER_INFO) + mUserInfo.AccessPolicyLen); + if (Info == NULL) { + return ; + } + + Status = FindInfoByType (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; + } +} + + +/** + 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 (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 + &mUserProfileManagerGuid, // Formset GUID + FORMID_MODIFY_IP, // Form ID + StartOpCodeHandle, // Label for where to insert opcodes + EndOpCodeHandle // Replace data + ); + + HiiFreeOpCodeHandle (StartOpCodeHandle); + HiiFreeOpCodeHandle (EndOpCodeHandle); +} + + +/** + Save the identity policy and update UI with it. + + This funciton will verify the new identity policy, in current implementation, + the identity policy can be: T, P & P & P & ..., P | P | P | ... + Here, "T" means "True", "P" means "Credential Provider", "&" means "and", "|" means "or". + Other identity policies are not supported. + +**/ +VOID +SaveIdentityPolicy ( + VOID + ) +{ + EFI_STATUS Status; + EFI_USER_INFO_IDENTITY_POLICY *Identity; + EFI_USER_INFO_HANDLE UserInfo; + EFI_USER_INFO *Info; + EFI_INPUT_KEY Key; + UINTN Offset; + UINT32 OpCode; + UINTN InfoSize; + + if (!mUserInfo.NewIdentityPolicyModified || (mUserInfo.NewIdentityPolicyLen == 0)) { + return; + } + + // + // Check policy expression. + // + OpCode = EFI_USER_INFO_IDENTITY_FALSE; + Offset = 0; + while (Offset < mUserInfo.NewIdentityPolicyLen) { + // + // Check access policy according to type + // + Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset); + switch (Identity->Type) { + + case EFI_USER_INFO_IDENTITY_TRUE: + break; + + case EFI_USER_INFO_IDENTITY_OR: + if (OpCode == EFI_USER_INFO_IDENTITY_AND) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Invalid Identity Policy, Mixed Connector Unsupport!", + L"", + L"Press Any Key to Continue ...", + NULL + ); + return ; + } + + OpCode = EFI_USER_INFO_IDENTITY_OR; + break; + + case EFI_USER_INFO_IDENTITY_AND: + if (OpCode == EFI_USER_INFO_IDENTITY_OR) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Invalid Identity Policy, Mixed Connector Unsupport!", + L"", + L"Press Any Key to Continue ...", + NULL + ); + return ; + } + + OpCode = EFI_USER_INFO_IDENTITY_AND; + break; + + case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER: + break; + + default: + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Unsupport parameter", + L"", + L"Press Any Key to Continue ...", + NULL + ); + return ; + } + Offset += Identity->Length; + } + + // + // Save identity policy. + // + Info = AllocateZeroPool ( + sizeof (EFI_USER_INFO) + + mUserInfo.NewIdentityPolicyLen + ); + if (Info == NULL) { + return ; + } + + Status = FindInfoByType (EFI_USER_INFO_IDENTITY_POLICY_RECORD, &UserInfo); + if (EFI_ERROR (Status)) { + FreePool (Info); + return ; + } + + Info->InfoType = EFI_USER_INFO_IDENTITY_POLICY_RECORD; + Info->InfoAttribs = EFI_USER_INFO_STORAGE_PLATFORM_NV | + EFI_USER_INFO_PRIVATE | + EFI_USER_INFO_EXCLUSIVE; + Info->InfoSize = (UINT32) (sizeof (EFI_USER_INFO) + mUserInfo.NewIdentityPolicyLen); + CopyMem ((UINT8 *) (Info + 1), mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen); + Status = mUserManager->SetInfo ( + mUserManager, + mModifyUser, + &UserInfo, + Info, + Info->InfoSize + ); + FreePool (Info); + if (EFI_ERROR (Status)) { + // + // Get the user information again, it may be changed during saving it. + // + InfoSize = 0; + Status = mUserManager->GetInfo ( + mUserManager, + mModifyUser, + UserInfo, + Info, + &InfoSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + Info = AllocateZeroPool (InfoSize); + ASSERT (Info != NULL); + Status = mUserManager->GetInfo ( + mUserManager, + mModifyUser, + UserInfo, + Info, + &InfoSize + ); + } + ASSERT_EFI_ERROR (Status); + + // + // Save current identification policy to mUserInfo.IdentityPolicy. + // + ASSERT (Info != NULL); + if (mUserInfo.IdentityPolicy != NULL) { + FreePool (mUserInfo.IdentityPolicy); + } + + mUserInfo.IdentityPolicyLen = Info->InfoSize - sizeof (EFI_USER_INFO); + mUserInfo.IdentityPolicy = AllocateCopyPool (mUserInfo.IdentityPolicyLen, Info + 1); + ASSERT (mUserInfo.IdentityPolicy != NULL); + + // + // Free the memory + // + FreePool (Info); + FreePool (mUserInfo.NewIdentityPolicy); + } else { + // + // Update the mUserInfo.IdentityPolicy by mUserInfo.NewIdentityPolicy + // + if (mUserInfo.IdentityPolicy != NULL) { + FreePool (mUserInfo.IdentityPolicy); + } + mUserInfo.IdentityPolicy = mUserInfo.NewIdentityPolicy; + mUserInfo.IdentityPolicyLen = mUserInfo.NewIdentityPolicyLen; + } + + mUserInfo.NewIdentityPolicy = NULL; + mUserInfo.NewIdentityPolicyLen = 0; + mUserInfo.NewIdentityPolicyModified = FALSE; + + // + // Update identity policy choice. + // + ResolveIdentityPolicy ( + mUserInfo.IdentityPolicy, + mUserInfo.IdentityPolicyLen, + STRING_TOKEN (STR_IDENTIFY_POLICY_VAL) + ); +} + + +/** + Verify the new identity policy in the current implementation. The same credential + provider can't appear twice in one identity policy. + + @param[in] NewGuid Points to the credential provider guid. + + @retval TRUE The NewGuid was found in the identity policy. + @retval FALSE The NewGuid was not found. + +**/ +BOOLEAN +CheckIdentityPolicy ( + IN EFI_GUID *NewGuid + ) +{ + UINTN Offset; + EFI_USER_INFO_IDENTITY_POLICY *Identity; + EFI_INPUT_KEY Key; + + Offset = 0; + while (Offset < mUserInfo.NewIdentityPolicyLen) { + // + // Check access policy according to type. + // + Identity = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + Offset); + switch (Identity->Type) { + + case EFI_USER_INFO_IDENTITY_TRUE: + case EFI_USER_INFO_IDENTITY_OR: + case EFI_USER_INFO_IDENTITY_AND: + break; + + case EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER: + if (CompareGuid (NewGuid, (EFI_GUID *) (Identity + 1))) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"This Credential Provider Are Already Used!", + L"", + L"Press Any Key to Continue ...", + NULL + ); + return FALSE; + } + break; + + default: + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"Unsupport parameter", + L"", + L"Press Any Key to Continue ...", + NULL + ); + return FALSE; + } + + Offset += Identity->Length; + } + return TRUE; +} + + +/** + Update the mUserInfo.NewIdentityPolicy, and UI when 'add option' is pressed. + +**/ +VOID +AddIdentityPolicyItem ( + VOID + ) +{ + UINT8 *NewInfo; + EFI_USER_INFO_IDENTITY_POLICY *Policy; + + if (mProviderInfo->Count == 0) { + return ; + } + + if (!mUserInfo.NewIdentityPolicyModified && (mUserInfo.NewIdentityPolicyLen > 0)) { + FreePool (mUserInfo.NewIdentityPolicy); + mUserInfo.NewIdentityPolicy = NULL; + mUserInfo.NewIdentityPolicyLen = 0; + } + // + // Expand the identity policy memory for the newly added policy info. + // + if (mUserInfo.NewIdentityPolicyLen > 0) { + // + // The new policy is not empty, expand space for connetor and provider. + // + if (!CheckIdentityPolicy (&mProviderInfo->Provider[mProviderChoice]->Identifier)) { + return ; + } + NewInfo = AllocateZeroPool ( + mUserInfo.NewIdentityPolicyLen + + sizeof (EFI_USER_INFO_IDENTITY_POLICY) * 2 + + sizeof (EFI_GUID) + ); + } else { + // + // The new policy is empty, only expand space for provider. + // + NewInfo = AllocateZeroPool ( + mUserInfo.NewIdentityPolicyLen + + sizeof (EFI_USER_INFO_IDENTITY_POLICY) + + sizeof (EFI_GUID) + ); + } + + if (NewInfo == NULL) { + return ; + } + + if (mUserInfo.NewIdentityPolicyLen > 0) { + CopyMem (NewInfo, mUserInfo.NewIdentityPolicy, mUserInfo.NewIdentityPolicyLen); + FreePool (mUserInfo.NewIdentityPolicy); + } + mUserInfo.NewIdentityPolicy = NewInfo; + + // + // Save logical connector. + // + if (mUserInfo.NewIdentityPolicyLen > 0) { + Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + + mUserInfo.NewIdentityPolicyLen); + if (mConncetLogical == 0) { + Policy->Type = EFI_USER_INFO_IDENTITY_AND; + } else { + Policy->Type = EFI_USER_INFO_IDENTITY_OR; + } + + Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY); + mUserInfo.NewIdentityPolicyLen += Policy->Length; + } + + // + // Save credential provider. + // + Policy = (EFI_USER_INFO_IDENTITY_POLICY *) (mUserInfo.NewIdentityPolicy + + mUserInfo.NewIdentityPolicyLen); + Policy->Length = sizeof (EFI_USER_INFO_IDENTITY_POLICY) + sizeof (EFI_GUID); + Policy->Type = EFI_USER_INFO_IDENTITY_CREDENTIAL_PROVIDER; + CopyGuid ((EFI_GUID *) (Policy + 1), &mProviderInfo->Provider[mProviderChoice]->Identifier); + mUserInfo.NewIdentityPolicyLen += Policy->Length; + + // + // Update identity policy choice. + // + mUserInfo.NewIdentityPolicyModified = TRUE; + ResolveIdentityPolicy ( + mUserInfo.NewIdentityPolicy, + mUserInfo.NewIdentityPolicyLen, + STRING_TOKEN (STR_IDENTIFY_POLICY_VALUE) + ); +} + + +/** + 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_STATUS Status; + EFI_DEVICE_PATH_PROTOCOL *Next; + EFI_STRING_ID NameID; + EFI_STRING DriverName; + EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevicePathText; + + // + // Locate device path to text protocol. + // + Status = gBS->LocateProtocol ( + &gEfiDevicePathToTextProtocolGuid, + NULL, + (VOID **) &DevicePathText + ); + if (EFI_ERROR (Status)) { + return ; + } + + // + // Get driver file name node. + // + Next = DevicePath; + while (!IsDevicePathEnd (Next)) { + DevicePath = Next; + Next = NextDevicePathNode (Next); + } + + // + // Display the device path in form. + // + DriverName = DevicePathText->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]); + Var = GetEfiGlobalVariable (VarName); + 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 + &mUserProfileManagerGuid, // 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 + &mUserProfileManagerGuid, // 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); + Var = GetEfiGlobalVariable (VarName); + 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); +} + + +/** + 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; +} + + + -- cgit v1.2.3