summaryrefslogtreecommitdiffstats
path: root/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
diff options
context:
space:
mode:
Diffstat (limited to 'SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c')
-rw-r--r--SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c1424
1 files changed, 1424 insertions, 0 deletions
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
new file mode 100644
index 0000000000..250cb438e9
--- /dev/null
+++ b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
@@ -0,0 +1,1424 @@
+/** @file
+ Implementation of the HII for the Opal UEFI Driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "OpalHii.h"
+#include "OpalDriver.h"
+#include "OpalHiiPrivate.h"
+
+//
+// This is the generated IFR binary Data for each formset defined in VFR.
+// This Data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 OpalPasswordFormBin[];
+
+//
+// This is the generated String package Data for all .UNI files.
+// This Data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 OpalPasswordDxeStrings[];
+
+EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol;
+
+//
+// Handle to the list of HII packages (forms and strings) for this driver
+//
+EFI_HII_HANDLE gHiiPackageListHandle = NULL;
+
+//
+// Package List GUID containing all form and string packages
+//
+const EFI_GUID gHiiPackageListGuid = PACKAGE_LIST_GUID;
+const EFI_GUID gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;
+
+//
+// Structure that contains state of the HII
+// This structure is updated by Hii.cpp and its contents
+// is rendered in the HII.
+//
+OPAL_HII_CONFIGURATION gHiiConfiguration;
+
+CHAR8 gHiiOldPassword[MAX_PASSWORD_CHARACTER_LENGTH] = {0};
+UINT32 gHiiOldPasswordLength = 0;
+
+//
+// The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL
+//
+HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+ (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ OPAL_PASSWORD_CONFIG_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8)(END_DEVICE_PATH_LENGTH),
+ (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+
+/**
+ Sets the current system state of global config variables.
+
+**/
+VOID
+HiiSetCurrentConfiguration(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ OPAL_EXTRA_INFO_VAR OpalExtraInfo;
+ UINTN DataSize;
+
+ gHiiConfiguration.NumDisks = GetDeviceCount();
+
+ DataSize = sizeof (OPAL_EXTRA_INFO_VAR);
+ Status = gRT->GetVariable (
+ OPAL_EXTRA_INFO_VAR_NAME,
+ &gOpalExtraInfoVariableGuid,
+ NULL,
+ &DataSize,
+ &OpalExtraInfo
+ );
+ DEBUG ((DEBUG_INFO, "GetVariable for OpalExtraInfo @ HiiSetCurrentConfiguration, Status: %r\n", Status));
+ if (!EFI_ERROR (Status)) {
+ gHiiConfiguration.EnableBlockSid = OpalExtraInfo.EnableBlockSid;
+ }
+}
+
+/**
+ Check that all required protocols for HII are available.
+
+ @retval EFI_SUCCESS All required protocols are installed.
+ @retval EFI_NOT_FOUND One or more protocol are not installed.
+**/
+EFI_STATUS
+HiiCheckForRequiredProtocols (
+ VOID
+ )
+{
+ VOID* TempProtocol;
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, (VOID**)&TempProtocol );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = gBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, (VOID**)&TempProtocol );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = gBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID**)&TempProtocol );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = gBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, (VOID**)&TempProtocol );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Install the HII related resources.
+
+ @retval EFI_SUCCESS Install all the resources success.
+ @retval other Error occur when install the resources.
+**/
+EFI_STATUS
+HiiInstall(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DriverHandle;
+
+ //
+ // Check that all required protocols are available for HII.
+ // If not, fail the install
+ //
+ Status = HiiCheckForRequiredProtocols();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Clear the global configuration.
+ //
+ ZeroMem(&gHiiConfiguration, sizeof(gHiiConfiguration));
+
+ //
+ // Obtain the driver handle that the BIOS assigned us
+ //
+ DriverHandle = HiiGetDriverImageHandleCB();
+
+ //
+ // Populate the config access protocol with the three functions we are publishing
+ //
+ gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;
+ gHiiConfigAccessProtocol.RouteConfig = RouteConfig;
+ gHiiConfigAccessProtocol.Callback = DriverCallback;
+
+ //
+ // Associate the required protocols with our driver handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &DriverHandle,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &gHiiConfigAccessProtocol, // HII callback
+ &gEfiDevicePathProtocolGuid,
+ &gHiiVendorDevicePath, // required for HII callback allow all disks to be shown in same hii
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ return OpalHiiAddPackages();
+}
+
+/**
+ Install the HII form and string packages.
+
+ @retval EFI_SUCCESS Install all the resources success.
+ @retval EFI_OUT_OF_RESOURCES Out of resource error.
+**/
+EFI_STATUS
+OpalHiiAddPackages(
+ VOID
+ )
+{
+ EFI_HANDLE DriverHandle;
+ CHAR16 *NewString;
+
+ DriverHandle = HiiGetDriverImageHandleCB();
+
+ //
+ // Publish the HII form and HII string packages
+ //
+ gHiiPackageListHandle = HiiAddPackages(
+ &gHiiPackageListGuid,
+ DriverHandle,
+ OpalPasswordDxeStrings,
+ OpalPasswordFormBin,
+ (VOID*)NULL
+ );
+
+ //
+ // Make sure the packages installed successfully
+ //
+ if (gHiiPackageListHandle == NULL) {
+ DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Update Version String in main window
+ //
+ NewString = HiiGetDriverNameCB ();
+ if (HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_MAIN_OPAL_VERSION), NewString, NULL) == 0) {
+ DEBUG ((DEBUG_INFO, "OpalHiiAddPackages: HiiSetString( ) failed\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Uninstall the HII capability.
+
+ @retval EFI_SUCCESS Uninstall all the resources success.
+ @retval others Other errors occur when unistall the hii resource.
+**/
+EFI_STATUS
+HiiUninstall(
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Remove the packages we've provided to the BIOS
+ //
+ HiiRemovePackages(gHiiPackageListHandle);
+
+ //
+ // Remove the protocols from our driver handle
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces(
+ HiiGetDriverImageHandleCB(),
+ &gEfiHiiConfigAccessProtocolGuid,
+ &gHiiConfigAccessProtocol, // HII callback
+ &gEfiDevicePathProtocolGuid,
+ &gHiiVendorDevicePath, // required for HII callback
+ NULL
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));
+ }
+
+ return Status;
+}
+
+/**
+ Updates the main menu form.
+
+ @retval EFI_SUCCESS update the main form success.
+**/
+EFI_STATUS
+HiiPopulateMainMenuForm (
+ VOID
+ )
+{
+ UINT8 Index;
+ CHAR8 *DiskName;
+ EFI_STRING_ID DiskNameId;
+ OPAL_DISK *OpalDisk;
+
+ HiiSetCurrentConfiguration();
+
+ gHiiConfiguration.SupportedDisks = 0;
+
+ for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {
+ OpalDisk = HiiGetOpalDiskCB (Index);
+ if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {
+ gHiiConfiguration.SupportedDisks |= (1 << Index);
+ DiskNameId = GetDiskNameStringId (Index);
+ DiskName = HiiDiskGetNameCB (Index);
+ if ((DiskName == NULL) || (DiskNameId == 0)) {
+ return EFI_UNSUPPORTED;
+ }
+ HiiSetFormString(DiskNameId, DiskName);
+ }
+ }
+
+ OpalHiiSetBrowserData ();
+ return EFI_SUCCESS;
+}
+
+/**
+ Update the disk action info.
+
+ @param ActionString
+ @param SelectedAction
+
+ @retval EFI_SUCCESS Uninstall all the resources success.
+**/
+EFI_STATUS
+HiiSelectDiskAction (
+ CHAR8 *ActionString,
+ UINT8 SelectedAction
+ )
+{
+ OPAL_DISK *OpalDisk;
+ OPAL_DISK_ACTIONS AvailActions;
+
+ OpalHiiGetBrowserData ();
+
+ HiiSetFormString(STRING_TOKEN(STR_DISK_ACTION_LBL), ActionString);
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), " ");
+
+ gHiiConfiguration.SelectedAction = SelectedAction;
+ gHiiConfiguration.AvailableFields = 0;
+
+ OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
+ if (OpalDisk == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (OpalSupportGetAvailableActions (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions) != TcgResultSuccess) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ switch (SelectedAction) {
+ case HII_KEY_ID_GOTO_LOCK:
+ case HII_KEY_ID_GOTO_UNLOCK:
+ case HII_KEY_ID_GOTO_SET_ADMIN_PWD:
+ case HII_KEY_ID_GOTO_SET_USER_PWD:
+ case HII_KEY_ID_GOTO_SECURE_ERASE:
+ case HII_KEY_ID_GOTO_DISABLE_USER:
+ case HII_KEY_ID_GOTO_ENABLE_FEATURE: // User is required to enter Password to enable Feature
+ gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;
+ break;
+
+ case HII_KEY_ID_GOTO_PSID_REVERT:
+ gHiiConfiguration.AvailableFields |= HII_FIELD_PSID;
+ break;
+
+ case HII_KEY_ID_GOTO_REVERT:
+ gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;
+ gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA;
+ if (AvailActions.RevertKeepDataForced) {
+ gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA_FORCED;
+ }
+ break;
+ }
+
+ OpalHiiSetBrowserData ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get disk name string id.
+
+ @param DiskIndex The input disk index info.
+
+ @retval The disk name string id.
+
+**/
+EFI_STRING_ID
+GetDiskNameStringId(
+ UINT8 DiskIndex
+ )
+{
+ switch (DiskIndex) {
+ case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0);
+ case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1);
+ case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2);
+ case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3);
+ case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4);
+ case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5);
+ }
+ return 0;
+}
+
+/**
+ This function processes the results of changes in 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 EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverCallback(
+ CONST EFI_HII_CONFIG_ACCESS_PROTOCOL* This,
+ EFI_BROWSER_ACTION Action,
+ EFI_QUESTION_ID QuestionId,
+ UINT8 Type,
+ EFI_IFR_TYPE_VALUE* Value,
+ EFI_BROWSER_ACTION_REQUEST* ActionRequest
+ )
+{
+ HII_KEY HiiKey;
+ UINT8 HiiKeyId;
+
+ if (ActionRequest != NULL) {
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
+ }
+
+ //
+ // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.
+ //
+ if ((QuestionId & HII_KEY_FLAG) == 0) {
+ return EFI_SUCCESS;
+ }
+
+ HiiKey.Raw = QuestionId;
+ HiiKeyId = (UINT8) HiiKey.KeyBits.Id;
+
+ if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
+ switch (HiiKeyId) {
+ case HII_KEY_ID_VAR_SUPPORTED_DISKS:
+ DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
+ return HiiPopulateMainMenuForm ();
+
+ case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:
+ return HiiPopulateDiskInfoForm();
+ }
+ } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
+ switch (HiiKeyId) {
+ case HII_KEY_ID_GOTO_DISK_INFO:
+ return HiiSelectDisk((UINT8)HiiKey.KeyBits.Index);
+
+ case HII_KEY_ID_GOTO_LOCK:
+ return HiiSelectDiskAction("Action: Lock", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_UNLOCK:
+ return HiiSelectDiskAction("Action: Unlock", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_SET_ADMIN_PWD:
+ return HiiSelectDiskAction("Action: Set Administrator Password", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_SET_USER_PWD:
+ return HiiSelectDiskAction("Action: Set User Password", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_SECURE_ERASE:
+ return HiiSelectDiskAction("Action: Secure Erase", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_PSID_REVERT:
+ return HiiSelectDiskAction("Action: Revert to Factory Defaults with PSID", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_REVERT:
+ return HiiSelectDiskAction("Action: Revert to Factory Defaults", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_DISABLE_USER:
+ return HiiSelectDiskAction("Action: Disable User", HiiKeyId);
+
+ case HII_KEY_ID_GOTO_ENABLE_FEATURE:
+ return HiiSelectDiskAction("Action: Enable Feature", HiiKeyId);
+
+ case HII_KEY_ID_ENTER_PASSWORD:
+ return HiiPasswordEntered(Value->string);
+
+ case HII_KEY_ID_BLOCKSID:
+ return HiiSetBlockSid(Value->b);
+ }
+ } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
+ switch (HiiKeyId) {
+ case HII_KEY_ID_ENTER_PSID:
+ HiiPsidRevert();
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Update the global Disk index info.
+
+ @param Index The input disk index info.
+
+ @retval EFI_SUCCESS Update the disk index info success.
+
+**/
+EFI_STATUS
+HiiSelectDisk(
+ UINT8 Index
+ )
+{
+ OpalHiiGetBrowserData();
+ gHiiConfiguration.SelectedDiskIndex = Index;
+ OpalHiiSetBrowserData ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Draws the disk info form.
+
+ @retval EFI_SUCCESS Draw the disk info success.
+
+**/
+EFI_STATUS
+HiiPopulateDiskInfoForm(
+ VOID
+ )
+{
+ OPAL_DISK* OpalDisk;
+ OPAL_DISK_ACTIONS AvailActions;
+ TCG_RESULT Ret;
+ CHAR8 *DiskName;
+
+ OpalHiiGetBrowserData();
+
+ DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);
+ if (DiskName == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);
+
+ ZeroMem(gHiiConfiguration.Psid, sizeof(gHiiConfiguration.Psid));
+
+ gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;
+
+ OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
+
+ if (OpalDisk != NULL) {
+ OpalDiskUpdateStatus (OpalDisk);
+ Ret = OpalSupportGetAvailableActions(&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);
+ if (Ret == TcgResultSuccess) {
+ //
+ // Update actions, always allow PSID Revert
+ //
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;
+
+ //
+ // Always allow unlock to handle device migration
+ //
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;
+
+ if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {
+ if (OpalDisk->Owner == OpalOwnershipNobody) {
+ gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;
+
+ //
+ // Update strings
+ //
+ HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");
+ } else {
+ DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));
+ }
+ } else {
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;
+ gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_BLOCKSID;
+
+ HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");
+
+ //
+ // Determine revert options for disk
+ // Default initialize keep user Data to be true
+ //
+ gHiiConfiguration.KeepUserData = 1;
+ }
+ }
+ }
+
+ //
+ // Pass the current configuration to the BIOS
+ //
+ OpalHiiSetBrowserData ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Reverts the Opal disk to factory default.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiPsidRevert(
+ VOID
+ )
+{
+ CHAR8 Response[DEFAULT_RESPONSE_SIZE];
+ TCG_PSID Psid;
+ OPAL_DISK *OpalDisk;
+ TCG_RESULT Ret;
+ OPAL_SESSION Session;
+
+ Ret = TcgResultFailure;
+
+ OpalHiiGetBrowserData();
+
+ UnicodeStrToAsciiStr(gHiiConfiguration.Psid, (CHAR8*)Psid.Psid);
+
+ OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ if (OpalDisk != NULL) {
+ Ret = OpalSupportPsidRevert(&Session, Psid.Psid, (UINT32)sizeof(Psid.Psid), OpalDisk->OpalDevicePath);
+ }
+
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Failure" );
+ }
+
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set password for the disk.
+
+ @param OpalDisk The disk need to set the password.
+ @param Password The input password.
+ @param PassLength The input password length.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiSetPassword(
+ OPAL_DISK *OpalDisk,
+ VOID *Password,
+ UINT32 PassLength
+ )
+{
+ CHAR8 Response[DEFAULT_RESPONSE_SIZE];
+ TCG_RESULT Ret;
+ BOOLEAN ExistingPassword;
+ OPAL_SESSION Session;
+
+ ExistingPassword = FALSE;
+
+ //
+ // PassLength = 0 means check whether exist old password.
+ //
+ if (PassLength == 0) {
+ ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
+ gHiiOldPasswordLength = 0;
+
+ if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_ENABLE_FEATURE) {
+ ExistingPassword = FALSE;
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_ADMIN_PWD) {
+ ExistingPassword = OpalUtilAdminPasswordExists(OpalDisk->Owner, &OpalDisk->LockingFeature);
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
+ //
+ // Set user Password option shall only be shown if an Admin Password exists
+ // so a Password is always required (Admin or Existing User Password)
+ //
+ ExistingPassword = TRUE;
+ }
+
+ //
+ // Return error if there is a previous Password
+ // see UEFI 2.4 errata B, Figure 121. Password Flowchart
+ //
+ return ExistingPassword ? EFI_DEVICE_ERROR : EFI_SUCCESS;
+ }
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Failure");
+ //
+ // Password entered.
+ // No current Owner, so set new Password, must be admin Password
+ //
+ if (OpalDisk->Owner == OpalOwnershipNobody) {
+ Ret = OpalSupportEnableOpalFeature (&Session, OpalDisk->Msid, OpalDisk->MsidLength,Password, PassLength, OpalDisk->OpalDevicePath);
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");
+ }
+
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // 1st Password entered
+ //
+ if (OpalDisk->Owner == OpalOwnershipUnknown && gHiiOldPasswordLength == 0) {
+
+ //
+ // Unknown ownership - prompt for old Password, then new
+ // old Password is not set yet - first time through
+ // assume authority provided is admin1, overwritten if user1 authority works below
+ //
+ if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
+ //
+ // First try to login as USER1 to Locking SP to see if we're simply updating its Password
+ //
+ Ret = OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_USER1_AUTHORITY);
+ if (Ret == TcgResultSuccess) {
+ //
+ // User1 worked so authority 1 means user 1
+ //
+ CopyMem(gHiiOldPassword, Password, PassLength);
+ gHiiOldPasswordLength = PassLength;
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Else try admin1 below
+ //
+ Ret = OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);
+ if (Ret == TcgResultSuccess) {
+ CopyMem(gHiiOldPassword, Password, PassLength);
+ gHiiOldPasswordLength = PassLength;
+
+ return EFI_SUCCESS;
+ } else {
+ DEBUG ((DEBUG_INFO, "start session with old PW failed - return EFI_NOT_READY - mistyped old PW\n"));
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Authentication Failure");
+
+ ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
+ gHiiOldPasswordLength = 0;
+
+ return EFI_NOT_READY;
+ }
+ }
+
+ //
+ // New Password entered
+ //
+ if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
+ Ret = OpalSupportSetPassword(
+ &Session,
+ gHiiOldPassword,
+ gHiiOldPasswordLength,
+ Password,
+ PassLength,
+ OpalDisk->OpalDevicePath,
+ FALSE
+ );
+ } else {
+ Ret = OpalSupportSetPassword(
+ &Session,
+ gHiiOldPassword,
+ gHiiOldPasswordLength,
+ Password,
+ PassLength,
+ OpalDisk->OpalDevicePath,
+ TRUE
+ );
+ }
+
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");
+ }
+
+ //
+ // Reset old Password storage
+ //
+ ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
+ gHiiOldPasswordLength = 0;
+
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+ return Ret == TcgResultSuccess ? EFI_SUCCESS : EFI_NOT_READY;
+}
+
+/**
+ Secure Erases Opal Disk.
+
+ @param OpalDisk The disk need to erase data.
+ @param Password The input password.
+ @param PassLength The input password length.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiSecureErase(
+ OPAL_DISK *OpalDisk,
+ const VOID *Password,
+ UINT32 PassLength
+ )
+{
+ CHAR8 Response[DEFAULT_RESPONSE_SIZE];
+ BOOLEAN PasswordFailed;
+ TCG_RESULT Ret;
+ OPAL_SESSION AdminSpSession;
+
+ if (PassLength == 0) {
+ return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
+ }
+
+ ZeroMem(&AdminSpSession, sizeof(AdminSpSession));
+ AdminSpSession.Sscp = OpalDisk->Sscp;
+ AdminSpSession.MediaId = OpalDisk->MediaId;
+ AdminSpSession.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalUtilSecureErase(&AdminSpSession, Password, PassLength, &PasswordFailed);
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Failure" );
+ }
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ //
+ // If Password failed, return invalid passowrd
+ //
+ if (PasswordFailed) {
+ DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Indicates Password was valid and is not changing to UEFI
+ // Response string will indicate action error
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+
+/**
+ Disables User for Opal Disk.
+
+ @param OpalDisk The disk need to the action.
+ @param Password The input password.
+ @param PassLength The input password length.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiDisableUser(
+ OPAL_DISK *OpalDisk,
+ VOID *Password,
+ UINT32 PassLength
+ )
+{
+ CHAR8 Response[ DEFAULT_RESPONSE_SIZE ];
+ BOOLEAN PasswordFailed;
+ TCG_RESULT Ret;
+ OPAL_SESSION Session;
+
+ if (PassLength == 0) {
+ return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
+ }
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalSupportDisableUser(&Session, Password, PassLength, &PasswordFailed, OpalDisk->OpalDevicePath);
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Failure" );
+ }
+ HiiSetFormString (STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ //
+ // If Password failed, return invalid passowrd
+ //
+ if (PasswordFailed) {
+ DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Indicates Password was valid and is not changing to UEFI
+ // Response string will indicate action error
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Revert Opal Disk as Admin1.
+
+ @param OpalDisk The disk need to the action.
+ @param Password The input password.
+ @param PassLength The input password length.
+ @param KeepUserData Whether need to keey user data.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiRevert(
+ OPAL_DISK *OpalDisk,
+ VOID *Password,
+ UINT32 PassLength,
+ BOOLEAN KeepUserData
+ )
+{
+ CHAR8 Response[ DEFAULT_RESPONSE_SIZE ];
+ BOOLEAN PasswordFailed;
+ TCG_RESULT Ret;
+ OPAL_SESSION Session;
+
+ if (PassLength == 0) {
+ DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));
+ // return error to indicate there is an existing Password
+ return EFI_DEVICE_ERROR;
+ }
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalSupportRevert(
+ &Session,
+ KeepUserData,
+ Password,
+ PassLength,
+ OpalDisk->Msid,
+ OpalDisk->MsidLength,
+ &PasswordFailed,
+ OpalDisk->OpalDevicePath
+ );
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Failure" );
+ }
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ //
+ // If Password failed, return invalid passowrd
+ //
+ if (PasswordFailed) {
+ DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Indicates Password was valid and is not changing to UEFI
+ // Response string will indicate action error
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Unlocks Opal Disk.
+
+ @param OpalDisk The disk need to the action.
+ @param Password The input password.
+ @param PassLength The input password length.
+
+ @retval EFI_SUCCESS Do the required action success.
+
+**/
+EFI_STATUS
+HiiUnlock(
+ OPAL_DISK *OpalDisk,
+ VOID *Password,
+ UINT32 PassLength
+ )
+{
+ CHAR8 Response[DEFAULT_RESPONSE_SIZE];
+ TCG_RESULT Ret;
+ OPAL_SESSION Session;
+
+ if (PassLength == 0) {
+ DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));
+ return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
+ }
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ Ret = OpalSupportUnlock(&Session, Password, PassLength, OpalDisk->OpalDevicePath);
+ if (Ret == TcgResultSuccess) {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Success" );
+ } else {
+ AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Failure" );
+ }
+
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
+
+ if (Ret == TcgResultSuccess) {
+ DEBUG ((DEBUG_INFO, "returning error to indicate Password was correct but is not changing\n"));
+ return EFI_DEVICE_ERROR;
+ } else {
+ DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
+ return EFI_NOT_READY;
+ }
+}
+
+/**
+ Use the input password to do the specified action.
+
+ @param Str The input password saved in.
+
+ @retval EFI_SUCCESS Do the required action success.
+ @retval Others Other error occur.
+
+**/
+EFI_STATUS
+HiiPasswordEntered(
+ EFI_STRING_ID Str
+ )
+{
+ OPAL_DISK* OpalDisk;
+ CHAR8 Password[MAX_PASSWORD_CHARACTER_LENGTH + 1];
+ CHAR16* UniStr;
+ UINT32 PassLength;
+ EFI_STATUS Status;
+
+ OpalHiiGetBrowserData();
+
+ OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
+ if (OpalDisk == NULL) {
+ DEBUG ((DEBUG_INFO, "ERROR: disk %u not found\n", gHiiConfiguration.SelectedDiskIndex));
+ return EFI_NOT_FOUND;
+ }
+
+ if (Str == 0) {
+ DEBUG ((DEBUG_INFO, "ERROR: str=NULL\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ZeroMem(Password, sizeof(Password));
+
+ UniStr = HiiGetString(gHiiPackageListHandle, Str, NULL);
+ if (UniStr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ PassLength = (UINT32) StrLen (UniStr);
+ if (PassLength >= sizeof(Password)) {
+ HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Password too long");
+ gBS->FreePool(UniStr);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ UnicodeStrToAsciiStr(UniStr, Password);
+ gBS->FreePool(UniStr);
+
+ DEBUG ((DEBUG_INFO, "Password: '%s'\n", Password));
+
+ if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_UNLOCK) {
+ Status = HiiUnlock (OpalDisk, Password, PassLength);
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SECURE_ERASE) {
+ Status = HiiSecureErase (OpalDisk, Password, PassLength);
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_DISABLE_USER) {
+ Status = HiiDisableUser (OpalDisk, Password, PassLength);
+ } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_REVERT) {
+ DEBUG ((DEBUG_INFO, "gHiiConfiguration.KeepUserData %u\n", gHiiConfiguration.KeepUserData));
+ Status = HiiRevert(OpalDisk, Password, PassLength, gHiiConfiguration.KeepUserData);
+ } else {
+ Status = HiiSetPassword(OpalDisk, Password, PassLength);
+ }
+
+ OpalHiiSetBrowserData ();
+
+ return Status;
+}
+
+/**
+ Update block sid info.
+
+ @param Enable Enable/disable BlockSid.
+
+ @retval EFI_SUCCESS Do the required action success.
+ @retval Others Other error occur.
+
+**/
+EFI_STATUS
+HiiSetBlockSid (
+ BOOLEAN Enable
+ )
+{
+ EFI_STATUS Status;
+ OPAL_EXTRA_INFO_VAR OpalExtraInfo;
+ UINTN DataSize;
+
+ Status = EFI_SUCCESS;
+
+ DEBUG ((DEBUG_INFO, "HiiSetBlockSid(enable: %x)\n", Enable));
+
+ OpalExtraInfo.EnableBlockSid = Enable;
+ DataSize = sizeof (OPAL_EXTRA_INFO_VAR);
+ Status = gRT->SetVariable (
+ OPAL_EXTRA_INFO_VAR_NAME,
+ &gOpalExtraInfoVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DataSize,
+ &OpalExtraInfo
+ );
+ DEBUG ((DEBUG_INFO, "SetVariable, Status: %r\n", Status));
+
+ return Status;
+}
+
+/**
+ 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 <ConfigResp>
+ 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
+RouteConfig(
+ CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ CONST EFI_STRING Configuration,
+ EFI_STRING *Progress
+ )
+{
+ DEBUG ((DEBUG_INFO, "RouteConfig( )\n"));
+ if (Configuration == NULL || Progress == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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
+ <ConfigRequest> 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
+ <ConfigAltResp> 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
+ExtractConfig(
+ CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ CONST EFI_STRING Request,
+ EFI_STRING *Progress,
+ EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((DEBUG_INFO, "ExtractConfig( )\n"));
+
+ //
+ // Check for valid parameters
+ //
+ if (Progress == NULL || Results == NULL) {
+ return (EFI_INVALID_PARAMETER);
+ }
+
+ //
+ // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )
+ //
+ Status = gHiiConfigRouting->BlockToConfig(
+ gHiiConfigRouting,
+ Request,
+ (UINT8*)&gHiiConfiguration,
+ sizeof(OPAL_HII_CONFIGURATION),
+ Results,
+ Progress
+ );
+
+ return (Status);
+}
+
+
+/**
+
+ Pass the current system state to the bios via the hii_G_Configuration.
+
+**/
+VOID
+OpalHiiSetBrowserData (
+ VOID
+ )
+{
+ DEBUG ((DEBUG_INFO, "OpalHiiSetBrowserData( )\n"));
+ HiiSetBrowserData(
+ &gHiiSetupVariableGuid,
+ (CHAR16*)L"OpalHiiConfig",
+ sizeof(gHiiConfiguration),
+ (UINT8*)&gHiiConfiguration,
+ NULL
+ );
+}
+
+
+/**
+
+ Populate the hii_g_Configuraton with the browser Data.
+
+**/
+VOID
+OpalHiiGetBrowserData (
+ VOID
+ )
+{
+ DEBUG ((DEBUG_INFO, "OpalHiiGetBrowserData( )\n"));
+ HiiGetBrowserData(
+ &gHiiSetupVariableGuid,
+ (CHAR16*)L"OpalHiiConfig",
+ sizeof(gHiiConfiguration),
+ (UINT8*)&gHiiConfiguration
+ );
+}
+
+/**
+ Set a string Value in a form.
+
+ @param DestStringId The stringid which need to update.
+ @param SrcAsciiStr The string nned to update.
+
+ @retval EFI_SUCCESS Do the required action success.
+ @retval Others Other error occur.
+
+**/
+EFI_STATUS
+HiiSetFormString(
+ EFI_STRING_ID DestStringId,
+ CHAR8 *SrcAsciiStr
+ )
+{
+ UINT32 Len;
+ UINT32 UniSize;
+ CHAR16* UniStr;
+
+ DEBUG ((DEBUG_INFO, "HiiSetFormString( )\n"));
+
+ //
+ // Determine the Length of the sting
+ //
+ Len = ( UINT32 )AsciiStrLen( SrcAsciiStr );
+
+ //
+ // Allocate space for the unicode string, including terminator
+ //
+ UniSize = (Len + 1) * sizeof(CHAR16);
+ UniStr = (CHAR16*)AllocateZeroPool(UniSize);
+
+ //
+ // Copy into unicode string, then copy into string id
+ //
+ AsciiStrToUnicodeStr( SrcAsciiStr, UniStr );
+
+ //
+ // Update the string in the form
+ //
+ if (HiiSetString(gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {
+ DEBUG ((DEBUG_INFO, "HiiSetFormString( ) failed\n"));
+ FreePool(UniStr);
+ return (EFI_OUT_OF_RESOURCES);
+ }
+
+ //
+ // Free the memory
+ //
+ FreePool(UniStr);
+
+ return (EFI_SUCCESS);
+}
+
+/**
+ Initialize the Opal disk base on the hardware info get from device.
+
+ @param Dev The Opal device.
+
+ @retval EFI_SUCESS Initialize the device success.
+ @retval EFI_DEVICE_ERROR Get info from device failed.
+
+**/
+EFI_STATUS
+OpalDiskInitialize (
+ IN OPAL_DRIVER_DEVICE *Dev
+ )
+{
+ TCG_RESULT TcgResult;
+ OPAL_SESSION Session;
+
+ ZeroMem(&Dev->OpalDisk, sizeof(OPAL_DISK));
+ Dev->OpalDisk.Sscp = Dev->Sscp;
+ Dev->OpalDisk.MediaId = Dev->MediaId;
+ Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = Dev->Sscp;
+ Session.MediaId = Dev->MediaId;
+
+ TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);
+ if (TcgResult != TcgResultSuccess) {
+ return EFI_DEVICE_ERROR;
+ }
+ Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
+
+ TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGHT, &Dev->OpalDisk.MsidLength);
+ if (TcgResult != TcgResultSuccess) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return OpalDiskUpdateStatus (&Dev->OpalDisk);
+}
+
+/**
+ Update the device info.
+
+ @param OpalDisk The Opal device.
+
+ @retval EFI_SUCESS Initialize the device success.
+ @retval EFI_DEVICE_ERROR Get info from device failed.
+ @retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info.
+
+**/
+EFI_STATUS
+OpalDiskUpdateStatus (
+ OPAL_DISK *OpalDisk
+ )
+{
+ TCG_RESULT TcgResult;
+ OPAL_SESSION Session;
+
+ ZeroMem(&Session, sizeof(Session));
+ Session.Sscp = OpalDisk->Sscp;
+ Session.MediaId = OpalDisk->MediaId;
+ Session.OpalBaseComId = OpalDisk->OpalBaseComId;
+
+ TcgResult = OpalGetLockingInfo(&Session, &OpalDisk->LockingFeature);
+ if (TcgResult != TcgResultSuccess) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (OpalDisk->MsidLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ //
+ // Base on the Msid info to get the ownership, so Msid info must get first.
+ //
+ OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength);
+ }
+
+ return EFI_SUCCESS;
+}
+