Home | History | Annotate | Download | only in OpalPasswordDxe
      1 /** @file
      2   Implementation of the HII for the Opal UEFI Driver.
      3 
      4 Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "OpalHii.h"
     16 #include "OpalDriver.h"
     17 #include "OpalHiiPrivate.h"
     18 
     19 //
     20 // This is the generated IFR binary Data for each formset defined in VFR.
     21 // This Data array is ready to be used as input of HiiAddPackages() to
     22 // create a packagelist (which contains Form packages, String packages, etc).
     23 //
     24 extern UINT8  OpalPasswordFormBin[];
     25 
     26 //
     27 // This is the generated String package Data for all .UNI files.
     28 // This Data array is ready to be used as input of HiiAddPackages() to
     29 // create a packagelist (which contains Form packages, String packages, etc).
     30 //
     31 extern UINT8  OpalPasswordDxeStrings[];
     32 
     33 CHAR16  OpalPasswordStorageName[] = L"OpalHiiConfig";
     34 
     35 EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol;
     36 
     37 //
     38 // Handle to the list of HII packages (forms and strings) for this driver
     39 //
     40 EFI_HII_HANDLE gHiiPackageListHandle = NULL;
     41 
     42 //
     43 // Package List GUID containing all form and string packages
     44 //
     45 const EFI_GUID gHiiPackageListGuid = PACKAGE_LIST_GUID;
     46 const EFI_GUID gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;
     47 
     48 //
     49 // Structure that contains state of the HII
     50 // This structure is updated by Hii.cpp and its contents
     51 // is rendered in the HII.
     52 //
     53 OPAL_HII_CONFIGURATION gHiiConfiguration;
     54 
     55 CHAR8 gHiiOldPassword[MAX_PASSWORD_CHARACTER_LENGTH] = {0};
     56 UINT32 gHiiOldPasswordLength = 0;
     57 
     58 //
     59 // The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL
     60 //
     61 HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath = {
     62     {
     63         {
     64             HARDWARE_DEVICE_PATH,
     65             HW_VENDOR_DP,
     66             {
     67                 (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
     68                 (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)
     69             }
     70         },
     71         OPAL_PASSWORD_CONFIG_GUID
     72     },
     73     {
     74         END_DEVICE_PATH_TYPE,
     75         END_ENTIRE_DEVICE_PATH_SUBTYPE,
     76         {
     77             (UINT8)(END_DEVICE_PATH_LENGTH),
     78             (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
     79         }
     80     }
     81 };
     82 
     83 
     84 /**
     85   Sets the current system state of global config variables.
     86 
     87 **/
     88 VOID
     89 HiiSetCurrentConfiguration(
     90   VOID
     91   )
     92 {
     93   UINT32                                       PpStorageFlag;
     94   EFI_STRING                                   NewString;
     95 
     96   gHiiConfiguration.NumDisks = GetDeviceCount();
     97 
     98   //
     99   // Update the BlockSID status string.
    100   //
    101   PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();
    102 
    103   if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {
    104     NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_ENABLED), NULL);
    105     if (NewString == NULL) {
    106       DEBUG ((DEBUG_INFO,  "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
    107       return;
    108     }
    109   } else {
    110     NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISABLED), NULL);
    111     if (NewString == NULL) {
    112       DEBUG ((DEBUG_INFO,  "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
    113       return;
    114     }
    115   }
    116   HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS1), NewString, NULL);
    117   FreePool (NewString);
    118 
    119   if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) != 0) {
    120     NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), NULL);
    121     if (NewString == NULL) {
    122       DEBUG ((DEBUG_INFO,  "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
    123       return;
    124     }
    125   } else {
    126     NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), NULL);
    127     if (NewString == NULL) {
    128       DEBUG ((DEBUG_INFO,  "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
    129       return;
    130     }
    131   }
    132   HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS2), NewString, NULL);
    133   FreePool (NewString);
    134 
    135   if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) != 0) {
    136     NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), NULL);
    137     if (NewString == NULL) {
    138       DEBUG ((DEBUG_INFO,  "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
    139       return;
    140     }
    141   } else {
    142     NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), NULL);
    143     if (NewString == NULL) {
    144       DEBUG ((DEBUG_INFO,  "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
    145       return;
    146     }
    147   }
    148   HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS3), NewString, NULL);
    149   FreePool (NewString);
    150 }
    151 
    152 /**
    153   Install the HII related resources.
    154 
    155   @retval  EFI_SUCCESS        Install all the resources success.
    156   @retval  other              Error occur when install the resources.
    157 **/
    158 EFI_STATUS
    159 HiiInstall(
    160   VOID
    161   )
    162 {
    163   EFI_STATUS                   Status;
    164   EFI_HANDLE                   DriverHandle;
    165 
    166   //
    167   // Clear the global configuration.
    168   //
    169   ZeroMem(&gHiiConfiguration, sizeof(gHiiConfiguration));
    170 
    171   //
    172   // Obtain the driver handle that the BIOS assigned us
    173   //
    174   DriverHandle = HiiGetDriverImageHandleCB();
    175 
    176   //
    177   // Populate the config access protocol with the three functions we are publishing
    178   //
    179   gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;
    180   gHiiConfigAccessProtocol.RouteConfig = RouteConfig;
    181   gHiiConfigAccessProtocol.Callback = DriverCallback;
    182 
    183   //
    184   // Associate the required protocols with our driver handle
    185   //
    186   Status = gBS->InstallMultipleProtocolInterfaces(
    187                &DriverHandle,
    188                &gEfiHiiConfigAccessProtocolGuid,
    189                &gHiiConfigAccessProtocol,      // HII callback
    190                &gEfiDevicePathProtocolGuid,
    191                &gHiiVendorDevicePath,        // required for HII callback allow all disks to be shown in same hii
    192                NULL
    193            );
    194 
    195   if (EFI_ERROR(Status)) {
    196     return Status;
    197   }
    198 
    199   return OpalHiiAddPackages();
    200 }
    201 
    202 /**
    203   Install the HII form and string packages.
    204 
    205   @retval  EFI_SUCCESS           Install all the resources success.
    206   @retval  EFI_OUT_OF_RESOURCES  Out of resource error.
    207 **/
    208 EFI_STATUS
    209 OpalHiiAddPackages(
    210   VOID
    211   )
    212 {
    213   EFI_HANDLE                   DriverHandle;
    214   CHAR16                       *NewString;
    215 
    216   DriverHandle = HiiGetDriverImageHandleCB();
    217 
    218   //
    219   // Publish the HII form and HII string packages
    220   //
    221   gHiiPackageListHandle = HiiAddPackages(
    222                                 &gHiiPackageListGuid,
    223                                 DriverHandle,
    224                                 OpalPasswordDxeStrings,
    225                                 OpalPasswordFormBin,
    226                                 (VOID*)NULL
    227                                 );
    228 
    229   //
    230   // Make sure the packages installed successfully
    231   //
    232   if (gHiiPackageListHandle == NULL) {
    233     DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));
    234     return EFI_OUT_OF_RESOURCES;
    235   }
    236 
    237   //
    238   // Update Version String in main window
    239   //
    240   NewString = HiiGetDriverNameCB ();
    241   if (HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_MAIN_OPAL_VERSION), NewString, NULL) == 0) {
    242     DEBUG ((DEBUG_INFO,  "OpalHiiAddPackages: HiiSetString( ) failed\n"));
    243     return EFI_OUT_OF_RESOURCES;
    244   }
    245 
    246   return EFI_SUCCESS;
    247 }
    248 
    249 /**
    250   Uninstall the HII capability.
    251 
    252   @retval  EFI_SUCCESS           Uninstall all the resources success.
    253   @retval  others                Other errors occur when unistall the hii resource.
    254 **/
    255 EFI_STATUS
    256 HiiUninstall(
    257   VOID
    258   )
    259 {
    260   EFI_STATUS                   Status;
    261 
    262   //
    263   // Remove the packages we've provided to the BIOS
    264   //
    265   HiiRemovePackages(gHiiPackageListHandle);
    266 
    267   //
    268   // Remove the protocols from our driver handle
    269   //
    270   Status = gBS->UninstallMultipleProtocolInterfaces(
    271                           HiiGetDriverImageHandleCB(),
    272                           &gEfiHiiConfigAccessProtocolGuid,
    273                           &gHiiConfigAccessProtocol,        // HII callback
    274                           &gEfiDevicePathProtocolGuid,
    275                           &gHiiVendorDevicePath,            // required for HII callback
    276                           NULL
    277                       );
    278   if (EFI_ERROR(Status)) {
    279     DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));
    280   }
    281 
    282   return Status;
    283 }
    284 
    285 /**
    286   Updates the main menu form.
    287 
    288   @retval  EFI_SUCCESS           update the main form success.
    289 **/
    290 EFI_STATUS
    291 HiiPopulateMainMenuForm (
    292   VOID
    293   )
    294 {
    295   UINT8         Index;
    296   CHAR8         *DiskName;
    297   EFI_STRING_ID DiskNameId;
    298   OPAL_DISK     *OpalDisk;
    299 
    300   HiiSetCurrentConfiguration();
    301 
    302   gHiiConfiguration.SupportedDisks = 0;
    303 
    304   for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {
    305     OpalDisk = HiiGetOpalDiskCB (Index);
    306     if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {
    307       gHiiConfiguration.SupportedDisks |= (1 << Index);
    308       DiskNameId = GetDiskNameStringId (Index);
    309       DiskName = HiiDiskGetNameCB (Index);
    310       if ((DiskName == NULL) || (DiskNameId == 0)) {
    311         return EFI_UNSUPPORTED;
    312       }
    313       HiiSetFormString(DiskNameId, DiskName);
    314     }
    315   }
    316 
    317   OpalHiiSetBrowserData ();
    318   return EFI_SUCCESS;
    319 }
    320 
    321 /**
    322   Update the disk action info.
    323 
    324   @param     ActionString
    325   @param     SelectedAction
    326 
    327   @retval  EFI_SUCCESS           Uninstall all the resources success.
    328 **/
    329 EFI_STATUS
    330 HiiSelectDiskAction (
    331   CHAR8           *ActionString,
    332   UINT8           SelectedAction
    333   )
    334 {
    335   OPAL_DISK                     *OpalDisk;
    336   OPAL_DISK_ACTIONS              AvailActions;
    337 
    338   OpalHiiGetBrowserData ();
    339 
    340   HiiSetFormString(STRING_TOKEN(STR_DISK_ACTION_LBL), ActionString);
    341   HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), " ");
    342 
    343   gHiiConfiguration.SelectedAction = SelectedAction;
    344   gHiiConfiguration.AvailableFields = 0;
    345 
    346   OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
    347   if (OpalDisk == NULL) {
    348     return EFI_INVALID_PARAMETER;
    349   }
    350 
    351   if (OpalSupportGetAvailableActions (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions) != TcgResultSuccess) {
    352     return EFI_DEVICE_ERROR;
    353   }
    354 
    355   switch (SelectedAction) {
    356     case HII_KEY_ID_GOTO_LOCK:
    357     case HII_KEY_ID_GOTO_UNLOCK:
    358     case HII_KEY_ID_GOTO_SET_ADMIN_PWD:
    359     case HII_KEY_ID_GOTO_SET_USER_PWD:
    360     case HII_KEY_ID_GOTO_SECURE_ERASE:
    361     case HII_KEY_ID_GOTO_DISABLE_USER:
    362     case HII_KEY_ID_GOTO_ENABLE_FEATURE:   // User is required to enter Password to enable Feature
    363       gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;
    364       break;
    365 
    366     case HII_KEY_ID_GOTO_PSID_REVERT:
    367       gHiiConfiguration.AvailableFields |= HII_FIELD_PSID;
    368       break;
    369 
    370     case HII_KEY_ID_GOTO_REVERT:
    371       gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;
    372       gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA;
    373       if (AvailActions.RevertKeepDataForced) {
    374         gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA_FORCED;
    375       }
    376       break;
    377   }
    378 
    379   OpalHiiSetBrowserData ();
    380 
    381   return EFI_SUCCESS;
    382 }
    383 
    384 /**
    385   Get disk name string id.
    386 
    387   @param   DiskIndex             The input disk index info.
    388 
    389   @retval  The disk name string id.
    390 
    391 **/
    392 EFI_STRING_ID
    393 GetDiskNameStringId(
    394   UINT8 DiskIndex
    395   )
    396 {
    397   switch (DiskIndex) {
    398     case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0);
    399     case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1);
    400     case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2);
    401     case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3);
    402     case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4);
    403     case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5);
    404   }
    405   return 0;
    406 }
    407 
    408 /**
    409   This function processes the results of changes in configuration.
    410 
    411   @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    412   @param  Action                 Specifies the type of action taken by the browser.
    413   @param  QuestionId             A unique value which is sent to the original
    414                                  exporting driver so that it can identify the type
    415                                  of data to expect.
    416   @param  Type                   The type of value for the question.
    417   @param  Value                  A pointer to the data being sent to the original
    418                                  exporting driver.
    419   @param  ActionRequest          On return, points to the action requested by the
    420                                  callback function.
    421 
    422   @retval EFI_SUCCESS            The callback successfully handled the action.
    423   @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
    424                                  variable and its data.
    425   @retval EFI_DEVICE_ERROR       The variable could not be saved.
    426   @retval EFI_UNSUPPORTED        The specified Action is not supported by the
    427                                  callback.
    428 
    429 **/
    430 EFI_STATUS
    431 EFIAPI
    432 DriverCallback(
    433   CONST EFI_HII_CONFIG_ACCESS_PROTOCOL    *This,
    434   EFI_BROWSER_ACTION                      Action,
    435   EFI_QUESTION_ID                         QuestionId,
    436   UINT8                                   Type,
    437   EFI_IFR_TYPE_VALUE                      *Value,
    438   EFI_BROWSER_ACTION_REQUEST              *ActionRequest
    439   )
    440 {
    441   HII_KEY    HiiKey;
    442   UINT8      HiiKeyId;
    443   UINT32     PpRequest;
    444 
    445   if (ActionRequest != NULL) {
    446     *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
    447   } else {
    448     return EFI_INVALID_PARAMETER;
    449   }
    450 
    451   //
    452   // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.
    453   //
    454   if ((QuestionId & HII_KEY_FLAG) == 0) {
    455     return EFI_SUCCESS;
    456   }
    457 
    458   HiiKey.Raw = QuestionId;
    459   HiiKeyId   = (UINT8) HiiKey.KeyBits.Id;
    460 
    461   if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
    462     switch (HiiKeyId) {
    463       case HII_KEY_ID_VAR_SUPPORTED_DISKS:
    464         DEBUG ((DEBUG_INFO,  "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
    465         return HiiPopulateMainMenuForm ();
    466 
    467       case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:
    468         return HiiPopulateDiskInfoForm();
    469     }
    470   } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
    471     switch (HiiKeyId) {
    472       case HII_KEY_ID_GOTO_DISK_INFO:
    473         return HiiSelectDisk((UINT8)HiiKey.KeyBits.Index);
    474 
    475       case HII_KEY_ID_GOTO_LOCK:
    476         return HiiSelectDiskAction("Action: Lock", HiiKeyId);
    477 
    478       case HII_KEY_ID_GOTO_UNLOCK:
    479         return HiiSelectDiskAction("Action: Unlock", HiiKeyId);
    480 
    481       case HII_KEY_ID_GOTO_SET_ADMIN_PWD:
    482         return HiiSelectDiskAction("Action: Set Administrator Password", HiiKeyId);
    483 
    484       case HII_KEY_ID_GOTO_SET_USER_PWD:
    485         return HiiSelectDiskAction("Action: Set User Password", HiiKeyId);
    486 
    487       case HII_KEY_ID_GOTO_SECURE_ERASE:
    488         return HiiSelectDiskAction("Action: Secure Erase", HiiKeyId);
    489 
    490       case HII_KEY_ID_GOTO_PSID_REVERT:
    491         return HiiSelectDiskAction("Action: Revert to Factory Defaults with PSID", HiiKeyId);
    492 
    493       case HII_KEY_ID_GOTO_REVERT:
    494         return HiiSelectDiskAction("Action: Revert to Factory Defaults", HiiKeyId);
    495 
    496       case HII_KEY_ID_GOTO_DISABLE_USER:
    497         return HiiSelectDiskAction("Action: Disable User", HiiKeyId);
    498 
    499       case HII_KEY_ID_GOTO_ENABLE_FEATURE:
    500         return HiiSelectDiskAction("Action: Enable Feature", HiiKeyId);
    501 
    502       case HII_KEY_ID_ENTER_PASSWORD:
    503         return HiiPasswordEntered(Value->string);
    504 
    505       case HII_KEY_ID_ENTER_PSID:
    506         return HiiPsidRevert(Value->string);
    507 
    508     }
    509   } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    510     switch (HiiKeyId) {
    511       case HII_KEY_ID_BLOCKSID:
    512         switch (Value->u8) {
    513           case 0:
    514             PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
    515             break;
    516 
    517           case 1:
    518             PpRequest = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID;
    519             break;
    520 
    521           case 2:
    522             PpRequest = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID;
    523             break;
    524 
    525           case 3:
    526             PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE;
    527             break;
    528 
    529           case 4:
    530             PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE;
    531             break;
    532 
    533           case 5:
    534             PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE;
    535             break;
    536 
    537           case 6:
    538             PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE;
    539             break;
    540 
    541           default:
    542             PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
    543             DEBUG ((DEBUG_ERROR, "Invalid value input!\n"));
    544             break;
    545         }
    546         HiiSetBlockSidAction(PpRequest);
    547 
    548         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
    549         return EFI_SUCCESS;
    550 
    551       default:
    552         break;
    553     }
    554   }
    555 
    556   return EFI_UNSUPPORTED;
    557 }
    558 
    559 /**
    560   Update the global Disk index info.
    561 
    562   @param   Index             The input disk index info.
    563 
    564   @retval  EFI_SUCCESS       Update the disk index info success.
    565 
    566 **/
    567 EFI_STATUS
    568 HiiSelectDisk(
    569   UINT8 Index
    570   )
    571 {
    572   OpalHiiGetBrowserData();
    573   gHiiConfiguration.SelectedDiskIndex = Index;
    574   OpalHiiSetBrowserData ();
    575 
    576   return EFI_SUCCESS;
    577 }
    578 
    579 /**
    580   Draws the disk info form.
    581 
    582   @retval  EFI_SUCCESS       Draw the disk info success.
    583 
    584 **/
    585 EFI_STATUS
    586 HiiPopulateDiskInfoForm(
    587   VOID
    588   )
    589 {
    590   OPAL_DISK*                    OpalDisk;
    591   OPAL_DISK_ACTIONS             AvailActions;
    592   TCG_RESULT                    Ret;
    593   CHAR8                         *DiskName;
    594 
    595   OpalHiiGetBrowserData();
    596 
    597   DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);
    598   if (DiskName == NULL) {
    599     return EFI_UNSUPPORTED;
    600   }
    601   HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);
    602 
    603   ZeroMem(gHiiConfiguration.Psid, sizeof(gHiiConfiguration.Psid));
    604 
    605   gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;
    606 
    607   OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
    608 
    609   if (OpalDisk != NULL) {
    610     OpalDiskUpdateStatus (OpalDisk);
    611     Ret = OpalSupportGetAvailableActions(&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);
    612     if (Ret == TcgResultSuccess) {
    613       //
    614       // Update actions, always allow PSID Revert
    615       //
    616       gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;
    617 
    618       //
    619       // Always allow unlock to handle device migration
    620       //
    621       gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;
    622 
    623       if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {
    624         if (OpalDisk->Owner == OpalOwnershipNobody) {
    625           gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;
    626 
    627           //
    628           // Update strings
    629           //
    630           HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");
    631         } else {
    632           DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));
    633         }
    634       } else {
    635         gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;
    636         gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;
    637         gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;
    638         gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;
    639         gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;
    640 
    641         HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");
    642 
    643         //
    644         // Determine revert options for disk
    645         // Default initialize keep user Data to be true
    646         //
    647         gHiiConfiguration.KeepUserData = 1;
    648       }
    649     }
    650   }
    651 
    652   //
    653   // Pass the current configuration to the BIOS
    654   //
    655   OpalHiiSetBrowserData ();
    656 
    657   return EFI_SUCCESS;
    658 }
    659 
    660 /**
    661   Reverts the Opal disk to factory default.
    662 
    663   @param   PsidStringId      The string id for the PSID info.
    664 
    665   @retval  EFI_SUCCESS       Do the required action success.
    666 
    667 **/
    668 EFI_STATUS
    669 HiiPsidRevert(
    670   EFI_STRING_ID         PsidStringId
    671   )
    672 {
    673   CHAR8                         Response[DEFAULT_RESPONSE_SIZE];
    674   TCG_PSID                      Psid;
    675   OPAL_DISK                     *OpalDisk;
    676   TCG_RESULT                    Ret;
    677   OPAL_SESSION                  Session;
    678   CHAR16                        *UnicodeStr;
    679   UINT8                         TmpBuf[PSID_CHARACTER_STRING_END_LENGTH];
    680 
    681   Ret = TcgResultFailure;
    682 
    683   UnicodeStr = HiiGetString (gHiiPackageListHandle, PsidStringId, NULL);
    684   ZeroMem (TmpBuf, sizeof (TmpBuf));
    685   UnicodeStrToAsciiStrS (UnicodeStr, (CHAR8*)TmpBuf, PSID_CHARACTER_STRING_END_LENGTH);
    686   CopyMem (Psid.Psid, TmpBuf, PSID_CHARACTER_LENGTH);
    687   HiiSetString (gHiiPackageListHandle, PsidStringId, L"", NULL);
    688   ZeroMem (TmpBuf, sizeof (TmpBuf));
    689   ZeroMem (UnicodeStr, StrSize (UnicodeStr));
    690   FreePool (UnicodeStr);
    691 
    692   OpalDisk = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
    693   if (OpalDisk != NULL) {
    694     ZeroMem(&Session, sizeof(Session));
    695     Session.Sscp = OpalDisk->Sscp;
    696     Session.MediaId = OpalDisk->MediaId;
    697     Session.OpalBaseComId = OpalDisk->OpalBaseComId;
    698 
    699     Ret = OpalSupportPsidRevert(&Session, Psid.Psid, (UINT32)sizeof(Psid.Psid), OpalDisk->OpalDevicePath);
    700   }
    701 
    702   ZeroMem (Psid.Psid, PSID_CHARACTER_LENGTH);
    703 
    704   if (Ret == TcgResultSuccess) {
    705     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Success" );
    706   } else {
    707     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Failure" );
    708   }
    709 
    710   HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
    711 
    712   return EFI_SUCCESS;
    713 }
    714 
    715 /**
    716   Set password for the disk.
    717 
    718   @param      OpalDisk       The disk need to set the password.
    719   @param      Password       The input password.
    720   @param      PassLength     The input password length.
    721 
    722   @retval  EFI_SUCCESS       Do the required action success.
    723 
    724 **/
    725 EFI_STATUS
    726 HiiSetPassword(
    727   OPAL_DISK          *OpalDisk,
    728   VOID               *Password,
    729   UINT32             PassLength
    730   )
    731 {
    732   CHAR8                         Response[DEFAULT_RESPONSE_SIZE];
    733   TCG_RESULT                    Ret;
    734   BOOLEAN                       ExistingPassword;
    735   OPAL_SESSION                  Session;
    736 
    737   ExistingPassword = FALSE;
    738 
    739   //
    740   // PassLength = 0 means check whether exist old password.
    741   //
    742   if (PassLength == 0) {
    743     ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
    744     gHiiOldPasswordLength = 0;
    745 
    746     if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_ENABLE_FEATURE) {
    747       ExistingPassword = FALSE;
    748     } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_ADMIN_PWD) {
    749       ExistingPassword = OpalUtilAdminPasswordExists(OpalDisk->Owner, &OpalDisk->LockingFeature);
    750     } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
    751       //
    752       // Set user Password option shall only be shown if an Admin Password exists
    753       // so a Password is always required (Admin or Existing User Password)
    754       //
    755       ExistingPassword = TRUE;
    756     }
    757 
    758     //
    759     // Return error if there is a previous Password
    760     // see UEFI 2.4 errata B, Figure 121. Password Flowchart
    761     //
    762     return ExistingPassword ? EFI_DEVICE_ERROR : EFI_SUCCESS;
    763   }
    764 
    765   ZeroMem(&Session, sizeof(Session));
    766   Session.Sscp = OpalDisk->Sscp;
    767   Session.MediaId = OpalDisk->MediaId;
    768   Session.OpalBaseComId = OpalDisk->OpalBaseComId;
    769 
    770   AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Failure");
    771   //
    772   // Password entered.
    773   // No current Owner, so set new Password, must be admin Password
    774   //
    775   if (OpalDisk->Owner == OpalOwnershipNobody) {
    776     Ret = OpalSupportEnableOpalFeature (&Session, OpalDisk->Msid, OpalDisk->MsidLength,Password, PassLength, OpalDisk->OpalDevicePath);
    777     if (Ret == TcgResultSuccess) {
    778       AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");
    779     }
    780 
    781     HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
    782     return EFI_SUCCESS;
    783   }
    784 
    785   //
    786   // 1st Password entered
    787   //
    788   if (OpalDisk->Owner == OpalOwnershipUnknown && gHiiOldPasswordLength == 0) {
    789 
    790     //
    791     // Unknown ownership - prompt for old Password, then new
    792     // old Password is not set yet - first time through
    793     // assume authority provided is admin1, overwritten if user1 authority works below
    794     //
    795     if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
    796       //
    797       // First try to login as USER1 to Locking SP to see if we're simply updating its Password
    798       //
    799       Ret =  OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_USER1_AUTHORITY);
    800       if (Ret == TcgResultSuccess) {
    801         //
    802         // User1 worked so authority 1 means user 1
    803         //
    804         CopyMem(gHiiOldPassword, Password, PassLength);
    805         gHiiOldPasswordLength = PassLength;
    806 
    807         return EFI_SUCCESS;
    808       }
    809     }
    810 
    811     //
    812     // Else try admin1 below
    813     //
    814     Ret =  OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);
    815     if (Ret == TcgResultSuccess) {
    816       CopyMem(gHiiOldPassword, Password, PassLength);
    817       gHiiOldPasswordLength = PassLength;
    818 
    819       return EFI_SUCCESS;
    820     } else {
    821       DEBUG ((DEBUG_INFO, "start session with old PW failed - return EFI_NOT_READY - mistyped old PW\n"));
    822       HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Authentication Failure");
    823 
    824       ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
    825       gHiiOldPasswordLength = 0;
    826 
    827       return EFI_NOT_READY;
    828     }
    829   }
    830 
    831   //
    832   // New Password entered
    833   //
    834   if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {
    835     Ret = OpalSupportSetPassword(
    836                             &Session,
    837                             gHiiOldPassword,
    838                             gHiiOldPasswordLength,
    839                             Password,
    840                             PassLength,
    841                             OpalDisk->OpalDevicePath,
    842                             FALSE
    843                             );
    844   } else {
    845     Ret = OpalSupportSetPassword(
    846                             &Session,
    847                             gHiiOldPassword,
    848                             gHiiOldPasswordLength,
    849                             Password,
    850                             PassLength,
    851                             OpalDisk->OpalDevicePath,
    852                             TRUE
    853                             );
    854   }
    855 
    856   if (Ret == TcgResultSuccess) {
    857     AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");
    858   }
    859 
    860   //
    861   // Reset old Password storage
    862   //
    863   ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));
    864   gHiiOldPasswordLength = 0;
    865 
    866   HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
    867   return Ret == TcgResultSuccess ? EFI_SUCCESS : EFI_NOT_READY;
    868 }
    869 
    870 /**
    871   Secure Erases Opal Disk.
    872 
    873   @param      OpalDisk       The disk need to erase data.
    874   @param      Password       The input password.
    875   @param      PassLength     The input password length.
    876 
    877   @retval  EFI_SUCCESS       Do the required action success.
    878 
    879 **/
    880 EFI_STATUS
    881 HiiSecureErase(
    882   OPAL_DISK       *OpalDisk,
    883   const VOID      *Password,
    884   UINT32          PassLength
    885   )
    886 {
    887   CHAR8                        Response[DEFAULT_RESPONSE_SIZE];
    888   BOOLEAN                      PasswordFailed;
    889   TCG_RESULT                   Ret;
    890   OPAL_SESSION                 AdminSpSession;
    891 
    892   if (PassLength == 0) {
    893     return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
    894   }
    895 
    896   ZeroMem(&AdminSpSession, sizeof(AdminSpSession));
    897   AdminSpSession.Sscp = OpalDisk->Sscp;
    898   AdminSpSession.MediaId = OpalDisk->MediaId;
    899   AdminSpSession.OpalBaseComId = OpalDisk->OpalBaseComId;
    900 
    901   Ret = OpalUtilSecureErase(&AdminSpSession, Password, PassLength, &PasswordFailed);
    902   if (Ret == TcgResultSuccess) {
    903     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Success" );
    904   } else {
    905     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Failure" );
    906   }
    907   HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
    908 
    909   //
    910   // If Password failed, return invalid passowrd
    911   //
    912   if (PasswordFailed) {
    913     DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
    914     return EFI_NOT_READY;
    915   }
    916 
    917   //
    918   // Indicates Password was valid and is not changing to UEFI
    919   // Response string will indicate action error
    920   //
    921   return EFI_DEVICE_ERROR;
    922 }
    923 
    924 
    925 /**
    926   Disables User for Opal Disk.
    927 
    928   @param      OpalDisk       The disk need to the action.
    929   @param      Password       The input password.
    930   @param      PassLength     The input password length.
    931 
    932   @retval  EFI_SUCCESS       Do the required action success.
    933 
    934 **/
    935 EFI_STATUS
    936 HiiDisableUser(
    937   OPAL_DISK      *OpalDisk,
    938   VOID           *Password,
    939   UINT32         PassLength
    940   )
    941 {
    942   CHAR8                        Response[ DEFAULT_RESPONSE_SIZE ];
    943   BOOLEAN                      PasswordFailed;
    944   TCG_RESULT                   Ret;
    945   OPAL_SESSION                 Session;
    946 
    947   if (PassLength == 0) {
    948     return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
    949   }
    950 
    951   ZeroMem(&Session, sizeof(Session));
    952   Session.Sscp = OpalDisk->Sscp;
    953   Session.MediaId = OpalDisk->MediaId;
    954   Session.OpalBaseComId = OpalDisk->OpalBaseComId;
    955 
    956   Ret = OpalSupportDisableUser(&Session, Password, PassLength, &PasswordFailed, OpalDisk->OpalDevicePath);
    957   if (Ret == TcgResultSuccess) {
    958     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Success" );
    959   } else {
    960     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Failure" );
    961   }
    962   HiiSetFormString (STRING_TOKEN(STR_ACTION_STATUS), Response);
    963 
    964   //
    965   // If Password failed, return invalid passowrd
    966   //
    967   if (PasswordFailed) {
    968     DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
    969     return EFI_NOT_READY;
    970   }
    971 
    972   //
    973   // Indicates Password was valid and is not changing to UEFI
    974   // Response string will indicate action error
    975   //
    976   return EFI_DEVICE_ERROR;
    977 }
    978 
    979 /**
    980   Revert Opal Disk as Admin1.
    981 
    982   @param      OpalDisk       The disk need to the action.
    983   @param      Password       The input password.
    984   @param      PassLength     The input password length.
    985   @param      KeepUserData   Whether need to keey user data.
    986 
    987   @retval  EFI_SUCCESS       Do the required action success.
    988 
    989 **/
    990 EFI_STATUS
    991 HiiRevert(
    992   OPAL_DISK       *OpalDisk,
    993   VOID            *Password,
    994   UINT32          PassLength,
    995   BOOLEAN         KeepUserData
    996   )
    997 {
    998   CHAR8                         Response[ DEFAULT_RESPONSE_SIZE ];
    999   BOOLEAN                      PasswordFailed;
   1000   TCG_RESULT                    Ret;
   1001   OPAL_SESSION                  Session;
   1002 
   1003   if (PassLength == 0) {
   1004     DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));
   1005     // return error to indicate there is an existing Password
   1006     return EFI_DEVICE_ERROR;
   1007   }
   1008 
   1009   ZeroMem(&Session, sizeof(Session));
   1010   Session.Sscp = OpalDisk->Sscp;
   1011   Session.MediaId = OpalDisk->MediaId;
   1012   Session.OpalBaseComId = OpalDisk->OpalBaseComId;
   1013 
   1014   Ret = OpalSupportRevert(
   1015                       &Session,
   1016                       KeepUserData,
   1017                       Password,
   1018                       PassLength,
   1019                       OpalDisk->Msid,
   1020                       OpalDisk->MsidLength,
   1021                       &PasswordFailed,
   1022                       OpalDisk->OpalDevicePath
   1023                       );
   1024   if (Ret == TcgResultSuccess) {
   1025     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Success" );
   1026   } else {
   1027     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Failure" );
   1028   }
   1029   HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
   1030 
   1031   //
   1032   // If Password failed, return invalid passowrd
   1033   //
   1034   if (PasswordFailed) {
   1035     DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
   1036     return EFI_NOT_READY;
   1037   }
   1038 
   1039   //
   1040   // Indicates Password was valid and is not changing to UEFI
   1041   // Response string will indicate action error
   1042   //
   1043   return EFI_DEVICE_ERROR;
   1044 }
   1045 
   1046 /**
   1047   Unlocks Opal Disk.
   1048 
   1049   @param      OpalDisk       The disk need to the action.
   1050   @param      Password       The input password.
   1051   @param      PassLength     The input password length.
   1052 
   1053   @retval  EFI_SUCCESS       Do the required action success.
   1054 
   1055 **/
   1056 EFI_STATUS
   1057 HiiUnlock(
   1058   OPAL_DISK         *OpalDisk,
   1059   VOID              *Password,
   1060   UINT32            PassLength
   1061   )
   1062 {
   1063   CHAR8                         Response[DEFAULT_RESPONSE_SIZE];
   1064   TCG_RESULT                    Ret;
   1065   OPAL_SESSION                  Session;
   1066 
   1067   if (PassLength == 0) {
   1068     DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));
   1069     return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password
   1070   }
   1071 
   1072   ZeroMem(&Session, sizeof(Session));
   1073   Session.Sscp = OpalDisk->Sscp;
   1074   Session.MediaId = OpalDisk->MediaId;
   1075   Session.OpalBaseComId = OpalDisk->OpalBaseComId;
   1076 
   1077   Ret = OpalSupportUnlock(&Session, Password, PassLength, OpalDisk->OpalDevicePath);
   1078   if (Ret == TcgResultSuccess) {
   1079     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Success" );
   1080   } else {
   1081     AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Failure" );
   1082   }
   1083 
   1084   HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);
   1085 
   1086   if (Ret == TcgResultSuccess) {
   1087     DEBUG ((DEBUG_INFO, "returning error to indicate Password was correct but is not changing\n"));
   1088     return EFI_DEVICE_ERROR;
   1089   } else {
   1090     DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));
   1091     return EFI_NOT_READY;
   1092   }
   1093 }
   1094 
   1095 /**
   1096   Use the input password to do the specified action.
   1097 
   1098   @param      Str            The input password saved in.
   1099 
   1100   @retval  EFI_SUCCESS       Do the required action success.
   1101   @retval  Others            Other error occur.
   1102 
   1103 **/
   1104 EFI_STATUS
   1105 HiiPasswordEntered(
   1106   EFI_STRING_ID            Str
   1107   )
   1108 {
   1109   OPAL_DISK*                   OpalDisk;
   1110   CHAR8                        Password[MAX_PASSWORD_CHARACTER_LENGTH + 1];
   1111   CHAR16*                      UniStr;
   1112   UINT32                       PassLength;
   1113   EFI_STATUS                   Status;
   1114 
   1115   OpalHiiGetBrowserData();
   1116 
   1117   OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);
   1118   if (OpalDisk == NULL) {
   1119     DEBUG ((DEBUG_INFO, "ERROR: disk %u not found\n", gHiiConfiguration.SelectedDiskIndex));
   1120     return EFI_NOT_FOUND;
   1121   }
   1122 
   1123   if (Str == 0) {
   1124     DEBUG ((DEBUG_INFO, "ERROR: str=NULL\n"));
   1125     return EFI_INVALID_PARAMETER;
   1126   }
   1127 
   1128   ZeroMem(Password, sizeof(Password));
   1129 
   1130   UniStr = HiiGetString(gHiiPackageListHandle, Str, NULL);
   1131   if (UniStr == NULL) {
   1132     return EFI_NOT_FOUND;
   1133   }
   1134 
   1135   HiiSetString(gHiiPackageListHandle, Str, L"", NULL);
   1136 
   1137   PassLength = (UINT32) StrLen (UniStr);
   1138   if (PassLength >= sizeof(Password)) {
   1139     HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Password too long");
   1140     ZeroMem (UniStr, StrSize (UniStr));
   1141     FreePool(UniStr);
   1142     return EFI_BUFFER_TOO_SMALL;
   1143   }
   1144 
   1145   UnicodeStrToAsciiStrS (UniStr, Password, sizeof (Password));
   1146   ZeroMem (UniStr, StrSize (UniStr));
   1147   FreePool(UniStr);
   1148 
   1149   if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_UNLOCK) {
   1150     Status = HiiUnlock (OpalDisk, Password, PassLength);
   1151   } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SECURE_ERASE) {
   1152     Status = HiiSecureErase (OpalDisk, Password, PassLength);
   1153   } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_DISABLE_USER) {
   1154     Status = HiiDisableUser (OpalDisk, Password, PassLength);
   1155   } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_REVERT) {
   1156     if (OpalDisk->SupportedAttributes.PyriteSsc == 1 && OpalDisk->LockingFeature.MediaEncryption == 0) {
   1157       //
   1158       // For pyrite type device which also not supports media encryption, it not accept "Keep User Data" parameter.
   1159       // So here hardcode a FALSE for this case.
   1160       //
   1161       Status = HiiRevert(OpalDisk, Password, PassLength, FALSE);
   1162     } else {
   1163       Status = HiiRevert(OpalDisk, Password, PassLength, gHiiConfiguration.KeepUserData);
   1164     }
   1165   } else {
   1166     Status = HiiSetPassword(OpalDisk, Password, PassLength);
   1167   }
   1168 
   1169   ZeroMem (Password, sizeof (Password));
   1170 
   1171   OpalHiiSetBrowserData ();
   1172 
   1173   return Status;
   1174 }
   1175 
   1176 /**
   1177   Send BlockSid request through TPM physical presence module.
   1178 
   1179   @param   PpRequest         TPM physical presence operation request.
   1180 
   1181   @retval  EFI_SUCCESS       Do the required action success.
   1182   @retval  Others            Other error occur.
   1183 
   1184 **/
   1185 EFI_STATUS
   1186 HiiSetBlockSidAction (
   1187   IN UINT32          PpRequest
   1188   )
   1189 {
   1190   UINT32                           ReturnCode;
   1191   EFI_STATUS                       Status;
   1192 
   1193   ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);
   1194   if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
   1195     Status = EFI_SUCCESS;
   1196   } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
   1197     Status = EFI_OUT_OF_RESOURCES;
   1198   } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
   1199     Status = EFI_UNSUPPORTED;
   1200   } else {
   1201     Status = EFI_DEVICE_ERROR;
   1202   }
   1203 
   1204   return Status;
   1205 }
   1206 
   1207 /**
   1208   This function processes the results of changes in configuration.
   1209 
   1210   @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
   1211   @param  Configuration          A null-terminated Unicode string in <ConfigResp>
   1212                                  format.
   1213   @param  Progress               A pointer to a string filled in with the offset of
   1214                                  the most recent '&' before the first failing
   1215                                  name/value pair (or the beginning of the string if
   1216                                  the failure is in the first name/value pair) or
   1217                                  the terminating NULL if all was successful.
   1218 
   1219   @retval EFI_SUCCESS            The Results is processed successfully.
   1220   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
   1221   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
   1222                                  driver.
   1223 
   1224 **/
   1225 EFI_STATUS
   1226 EFIAPI
   1227 RouteConfig(
   1228   CONST EFI_HII_CONFIG_ACCESS_PROTOCOL    *This,
   1229   CONST EFI_STRING                        Configuration,
   1230   EFI_STRING                              *Progress
   1231   )
   1232 {
   1233   if (Configuration == NULL || Progress == NULL) {
   1234     return (EFI_INVALID_PARAMETER);
   1235   }
   1236 
   1237   *Progress = Configuration;
   1238   if (!HiiIsConfigHdrMatch (Configuration, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
   1239     return EFI_NOT_FOUND;
   1240   }
   1241 
   1242   *Progress = Configuration + StrLen (Configuration);
   1243 
   1244   return EFI_SUCCESS;
   1245 }
   1246 
   1247 /**
   1248   This function allows a caller to extract the current configuration for one
   1249   or more named elements from the target driver.
   1250 
   1251   @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
   1252   @param  Request                A null-terminated Unicode string in
   1253                                  <ConfigRequest> format.
   1254   @param  Progress               On return, points to a character in the Request
   1255                                  string. Points to the string's null terminator if
   1256                                  request was successful. Points to the most recent
   1257                                  '&' before the first failing name/value pair (or
   1258                                  the beginning of the string if the failure is in
   1259                                  the first name/value pair) if the request was not
   1260                                  successful.
   1261   @param  Results                A null-terminated Unicode string in
   1262                                  <ConfigAltResp> format which has all values filled
   1263                                  in for the names in the Request string. String to
   1264                                  be allocated by the called function.
   1265 
   1266   @retval EFI_SUCCESS            The Results is filled with the requested values.
   1267   @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
   1268   @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
   1269   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
   1270                                  driver.
   1271 
   1272 **/
   1273 EFI_STATUS
   1274 EFIAPI
   1275 ExtractConfig(
   1276   CONST EFI_HII_CONFIG_ACCESS_PROTOCOL    *This,
   1277   CONST EFI_STRING                        Request,
   1278   EFI_STRING                              *Progress,
   1279   EFI_STRING                              *Results
   1280   )
   1281 {
   1282   EFI_STATUS                              Status;
   1283 
   1284   //
   1285   // Check for valid parameters
   1286   //
   1287   if (Progress == NULL || Results == NULL) {
   1288     return (EFI_INVALID_PARAMETER);
   1289   }
   1290 
   1291   *Progress = Request;
   1292   if ((Request != NULL) &&
   1293     !HiiIsConfigHdrMatch (Request, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
   1294     return EFI_NOT_FOUND;
   1295   }
   1296 
   1297   //
   1298   // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )
   1299   //
   1300   Status = gHiiConfigRouting->BlockToConfig(
   1301                gHiiConfigRouting,
   1302                Request,
   1303                (UINT8*)&gHiiConfiguration,
   1304                sizeof(OPAL_HII_CONFIGURATION),
   1305                Results,
   1306                Progress
   1307            );
   1308 
   1309   return (Status);
   1310 }
   1311 
   1312 
   1313 /**
   1314 
   1315   Pass the current system state to the bios via the hii_G_Configuration.
   1316 
   1317 **/
   1318 VOID
   1319 OpalHiiSetBrowserData (
   1320   VOID
   1321   )
   1322 {
   1323   HiiSetBrowserData(
   1324       &gHiiSetupVariableGuid,
   1325       (CHAR16*)L"OpalHiiConfig",
   1326       sizeof(gHiiConfiguration),
   1327       (UINT8*)&gHiiConfiguration,
   1328       NULL
   1329   );
   1330 }
   1331 
   1332 
   1333 /**
   1334 
   1335   Populate the hii_g_Configuraton with the browser Data.
   1336 
   1337 **/
   1338 VOID
   1339 OpalHiiGetBrowserData (
   1340   VOID
   1341   )
   1342 {
   1343   HiiGetBrowserData(
   1344       &gHiiSetupVariableGuid,
   1345       (CHAR16*)L"OpalHiiConfig",
   1346       sizeof(gHiiConfiguration),
   1347       (UINT8*)&gHiiConfiguration
   1348   );
   1349 }
   1350 
   1351 /**
   1352   Set a string Value in a form.
   1353 
   1354   @param      DestStringId   The stringid which need to update.
   1355   @param      SrcAsciiStr    The string nned to update.
   1356 
   1357   @retval  EFI_SUCCESS       Do the required action success.
   1358   @retval  Others            Other error occur.
   1359 
   1360 **/
   1361 EFI_STATUS
   1362 HiiSetFormString(
   1363   EFI_STRING_ID       DestStringId,
   1364   CHAR8               *SrcAsciiStr
   1365   )
   1366 {
   1367   UINT32                    Len;
   1368   UINT32                    UniSize;
   1369   CHAR16*                   UniStr;
   1370 
   1371   //
   1372   // Determine the Length of the sting
   1373   //
   1374   Len = ( UINT32 )AsciiStrLen( SrcAsciiStr );
   1375 
   1376   //
   1377   // Allocate space for the unicode string, including terminator
   1378   //
   1379   UniSize = (Len + 1) * sizeof(CHAR16);
   1380   UniStr = (CHAR16*)AllocateZeroPool(UniSize);
   1381 
   1382   //
   1383   // Copy into unicode string, then copy into string id
   1384   //
   1385   AsciiStrToUnicodeStrS ( SrcAsciiStr, UniStr, Len + 1);
   1386 
   1387   //
   1388   // Update the string in the form
   1389   //
   1390   if (HiiSetString(gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {
   1391     DEBUG ((DEBUG_INFO,  "HiiSetFormString( ) failed\n"));
   1392     FreePool(UniStr);
   1393     return (EFI_OUT_OF_RESOURCES);
   1394   }
   1395 
   1396   //
   1397   // Free the memory
   1398   //
   1399   FreePool(UniStr);
   1400 
   1401   return (EFI_SUCCESS);
   1402 }
   1403 
   1404 /**
   1405   Initialize the Opal disk base on the hardware info get from device.
   1406 
   1407   @param Dev                  The Opal device.
   1408 
   1409   @retval EFI_SUCESS          Initialize the device success.
   1410   @retval EFI_DEVICE_ERROR    Get info from device failed.
   1411 
   1412 **/
   1413 EFI_STATUS
   1414 OpalDiskInitialize (
   1415   IN OPAL_DRIVER_DEVICE          *Dev
   1416   )
   1417 {
   1418   TCG_RESULT                  TcgResult;
   1419   OPAL_SESSION                Session;
   1420 
   1421   ZeroMem(&Dev->OpalDisk, sizeof(OPAL_DISK));
   1422   Dev->OpalDisk.Sscp = Dev->Sscp;
   1423   Dev->OpalDisk.MediaId = Dev->MediaId;
   1424   Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;
   1425 
   1426   ZeroMem(&Session, sizeof(Session));
   1427   Session.Sscp = Dev->Sscp;
   1428   Session.MediaId = Dev->MediaId;
   1429 
   1430   TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);
   1431   if (TcgResult != TcgResultSuccess) {
   1432     return EFI_DEVICE_ERROR;
   1433   }
   1434   Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;
   1435 
   1436   TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGHT, &Dev->OpalDisk.MsidLength);
   1437   if (TcgResult != TcgResultSuccess) {
   1438     return EFI_DEVICE_ERROR;
   1439   }
   1440 
   1441   return OpalDiskUpdateStatus (&Dev->OpalDisk);
   1442 }
   1443 
   1444 /**
   1445   Update the device info.
   1446 
   1447   @param OpalDisk                The Opal device.
   1448 
   1449   @retval EFI_SUCESS             Initialize the device success.
   1450   @retval EFI_DEVICE_ERROR       Get info from device failed.
   1451   @retval EFI_INVALID_PARAMETER  Not get Msid info before get ownership info.
   1452 
   1453 **/
   1454 EFI_STATUS
   1455 OpalDiskUpdateStatus (
   1456   OPAL_DISK        *OpalDisk
   1457   )
   1458 {
   1459   TCG_RESULT                  TcgResult;
   1460   OPAL_SESSION                Session;
   1461 
   1462   ZeroMem(&Session, sizeof(Session));
   1463   Session.Sscp = OpalDisk->Sscp;
   1464   Session.MediaId = OpalDisk->MediaId;
   1465   Session.OpalBaseComId = OpalDisk->OpalBaseComId;
   1466 
   1467   TcgResult = OpalGetLockingInfo(&Session, &OpalDisk->LockingFeature);
   1468   if (TcgResult != TcgResultSuccess) {
   1469     return EFI_DEVICE_ERROR;
   1470   }
   1471 
   1472   if (OpalDisk->MsidLength == 0) {
   1473     return EFI_INVALID_PARAMETER;
   1474   } else {
   1475     //
   1476     // Base on the Msid info to get the ownership, so Msid info must get first.
   1477     //
   1478     OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength);
   1479   }
   1480 
   1481   return EFI_SUCCESS;
   1482 }
   1483 
   1484