/** @file | |
Implementation of the HII for the Opal UEFI Driver. | |
Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "OpalHii.h" | |
// | |
// Character definitions | |
// | |
#define UPPER_LOWER_CASE_OFFSET 0x20 | |
// | |
// 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[]; | |
CHAR16 OpalPasswordStorageName[] = L"OpalHiiConfig"; | |
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; | |
// | |
// 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) | |
} | |
} | |
}; | |
/** | |
Get saved OPAL request. | |
@param[in] OpalDisk The disk needs to get the saved OPAL request. | |
@param[out] OpalRequest OPAL request got. | |
**/ | |
VOID | |
GetSavedOpalRequest ( | |
IN OPAL_DISK *OpalDisk, | |
OUT OPAL_REQUEST *OpalRequest | |
) | |
{ | |
EFI_STATUS Status; | |
OPAL_REQUEST_VARIABLE *TempVariable; | |
OPAL_REQUEST_VARIABLE *Variable; | |
UINTN VariableSize; | |
EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable; | |
UINTN DevicePathSizeInVariable; | |
EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
UINTN DevicePathSize; | |
DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); | |
Variable = NULL; | |
VariableSize = 0; | |
Status = GetVariable2 ( | |
OPAL_REQUEST_VARIABLE_NAME, | |
&gHiiSetupVariableGuid, | |
(VOID **) &Variable, | |
&VariableSize | |
); | |
if (EFI_ERROR (Status) || (Variable == NULL)) { | |
return; | |
} | |
TempVariable = Variable; | |
while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) && | |
(VariableSize >= TempVariable->Length) && | |
(TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) { | |
DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE)); | |
DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable); | |
DevicePath = OpalDisk->OpalDevicePath; | |
DevicePathSize = GetDevicePathSize (DevicePath); | |
if ((DevicePathSize == DevicePathSizeInVariable) && | |
(CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) { | |
// | |
// Found the node for the OPAL device. | |
// Get the OPAL request. | |
// | |
CopyMem (OpalRequest, &TempVariable->OpalRequest, sizeof (OPAL_REQUEST)); | |
DEBUG (( | |
DEBUG_INFO, | |
"OpalRequest got: 0x%x\n", | |
*OpalRequest | |
)); | |
break; | |
} | |
VariableSize -= TempVariable->Length; | |
TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length); | |
} | |
FreePool (Variable); | |
DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); | |
} | |
/** | |
Save OPAL request. | |
@param[in] OpalDisk The disk has OPAL request to save. | |
@param[in] OpalRequest OPAL request to save. | |
**/ | |
VOID | |
SaveOpalRequest ( | |
IN OPAL_DISK *OpalDisk, | |
IN OPAL_REQUEST OpalRequest | |
) | |
{ | |
EFI_STATUS Status; | |
OPAL_REQUEST_VARIABLE *TempVariable; | |
UINTN TempVariableSize; | |
OPAL_REQUEST_VARIABLE *Variable; | |
UINTN VariableSize; | |
OPAL_REQUEST_VARIABLE *NewVariable; | |
UINTN NewVariableSize; | |
EFI_DEVICE_PATH_PROTOCOL *DevicePathInVariable; | |
UINTN DevicePathSizeInVariable; | |
EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
UINTN DevicePathSize; | |
DEBUG ((DEBUG_INFO, "%a() - enter\n", __FUNCTION__)); | |
DEBUG (( | |
DEBUG_INFO, | |
"OpalRequest to save: 0x%x\n", | |
OpalRequest | |
)); | |
Variable = NULL; | |
VariableSize = 0; | |
NewVariable = NULL; | |
NewVariableSize = 0; | |
Status = GetVariable2 ( | |
OPAL_REQUEST_VARIABLE_NAME, | |
&gHiiSetupVariableGuid, | |
(VOID **) &Variable, | |
&VariableSize | |
); | |
if (!EFI_ERROR (Status) && (Variable != NULL)) { | |
TempVariable = Variable; | |
TempVariableSize = VariableSize; | |
while ((TempVariableSize > sizeof (OPAL_REQUEST_VARIABLE)) && | |
(TempVariableSize >= TempVariable->Length) && | |
(TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE))) { | |
DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE)); | |
DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable); | |
DevicePath = OpalDisk->OpalDevicePath; | |
DevicePathSize = GetDevicePathSize (DevicePath); | |
if ((DevicePathSize == DevicePathSizeInVariable) && | |
(CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0)) { | |
// | |
// Found the node for the OPAL device. | |
// Update the OPAL request. | |
// | |
CopyMem (&TempVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST)); | |
NewVariable = Variable; | |
NewVariableSize = VariableSize; | |
break; | |
} | |
TempVariableSize -= TempVariable->Length; | |
TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) TempVariable + TempVariable->Length); | |
} | |
if (NewVariable == NULL) { | |
// | |
// The node for the OPAL device is not found. | |
// Create node for the OPAL device. | |
// | |
DevicePath = OpalDisk->OpalDevicePath; | |
DevicePathSize = GetDevicePathSize (DevicePath); | |
NewVariableSize = VariableSize + sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize; | |
NewVariable = AllocatePool (NewVariableSize); | |
ASSERT (NewVariable != NULL); | |
CopyMem (NewVariable, Variable, VariableSize); | |
TempVariable = (OPAL_REQUEST_VARIABLE *) ((UINTN) NewVariable + VariableSize); | |
TempVariable->Length = (UINT32) (sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize); | |
CopyMem (&TempVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST)); | |
DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) TempVariable + sizeof (OPAL_REQUEST_VARIABLE)); | |
CopyMem (DevicePathInVariable, DevicePath, DevicePathSize); | |
} | |
} else { | |
DevicePath = OpalDisk->OpalDevicePath; | |
DevicePathSize = GetDevicePathSize (DevicePath); | |
NewVariableSize = sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize; | |
NewVariable = AllocatePool (NewVariableSize); | |
ASSERT (NewVariable != NULL); | |
NewVariable->Length = (UINT32) (sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize); | |
CopyMem (&NewVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST)); | |
DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *) ((UINTN) NewVariable + sizeof (OPAL_REQUEST_VARIABLE)); | |
CopyMem (DevicePathInVariable, DevicePath, DevicePathSize); | |
} | |
Status = gRT->SetVariable ( | |
OPAL_REQUEST_VARIABLE_NAME, | |
(EFI_GUID *) &gHiiSetupVariableGuid, | |
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, | |
NewVariableSize, | |
NewVariable | |
); | |
if (EFI_ERROR (Status)) { | |
DEBUG ((DEBUG_INFO, "OpalRequest variable set failed (%r)\n", Status)); | |
} | |
if (NewVariable != Variable) { | |
FreePool (NewVariable); | |
} | |
if (Variable != NULL) { | |
FreePool (Variable); | |
} | |
DEBUG ((DEBUG_INFO, "%a() - exit\n", __FUNCTION__)); | |
} | |
/** | |
Sets the current system state of global config variables. | |
**/ | |
VOID | |
HiiSetCurrentConfiguration( | |
VOID | |
) | |
{ | |
UINT32 PpStorageFlag; | |
EFI_STRING NewString; | |
gHiiConfiguration.NumDisks = GetDeviceCount(); | |
// | |
// Update the BlockSID status string. | |
// | |
PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags (); | |
if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) { | |
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_ENABLED), NULL); | |
if (NewString == NULL) { | |
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n")); | |
return; | |
} | |
} else { | |
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISABLED), NULL); | |
if (NewString == NULL) { | |
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n")); | |
return; | |
} | |
} | |
HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS1), NewString, NULL); | |
FreePool (NewString); | |
if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) != 0) { | |
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), NULL); | |
if (NewString == NULL) { | |
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n")); | |
return; | |
} | |
} else { | |
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), NULL); | |
if (NewString == NULL) { | |
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n")); | |
return; | |
} | |
} | |
HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS2), NewString, NULL); | |
FreePool (NewString); | |
if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) != 0) { | |
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), NULL); | |
if (NewString == NULL) { | |
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n")); | |
return; | |
} | |
} else { | |
NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN(STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), NULL); | |
if (NewString == NULL) { | |
DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n")); | |
return; | |
} | |
} | |
HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_BLOCKSID_STATUS3), NewString, NULL); | |
FreePool (NewString); | |
} | |
/** | |
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; | |
// | |
// 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; | |
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; | |
} | |
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; | |
} | |
/** | |
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; | |
} | |
/** | |
Confirm whether user truly want to do the revert action. | |
@param OpalDisk The device which need to perform data removal action. | |
@param ActionString Specifies the action name shown on pop up menu. | |
@retval EFI_SUCCESS Confirmed user want to do the revert action. | |
**/ | |
EFI_STATUS | |
HiiConfirmDataRemovalAction ( | |
IN OPAL_DISK *OpalDisk, | |
IN CHAR16 *ActionString | |
) | |
{ | |
CHAR16 Unicode[512]; | |
EFI_INPUT_KEY Key; | |
CHAR16 ApproveResponse; | |
CHAR16 RejectResponse; | |
// | |
// When the estimate cost time bigger than MAX_ACCEPTABLE_REVERTING_TIME, pop up dialog to let user confirm | |
// the revert action. | |
// | |
if (OpalDisk->EstimateTimeCost < MAX_ACCEPTABLE_REVERTING_TIME) { | |
return EFI_SUCCESS; | |
} | |
ApproveResponse = L'Y'; | |
RejectResponse = L'N'; | |
UnicodeSPrint(Unicode, StrSize(L"WARNING: ############# action needs about ####### seconds"), L"WARNING: %s action needs about %d seconds", ActionString, OpalDisk->EstimateTimeCost); | |
do { | |
CreatePopUp( | |
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, | |
&Key, | |
Unicode, | |
L" System should not be powered off until action completion ", | |
L" ", | |
L" Press 'Y/y' to continue, press 'N/n' to cancel ", | |
NULL | |
); | |
} while ( | |
((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (ApproveResponse | UPPER_LOWER_CASE_OFFSET)) && | |
((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (RejectResponse | UPPER_LOWER_CASE_OFFSET)) | |
); | |
if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (RejectResponse | UPPER_LOWER_CASE_OFFSET)) { | |
return EFI_ABORTED; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
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; | |
UINT32 PpRequest; | |
OPAL_DISK *OpalDisk; | |
if (ActionRequest != NULL) { | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; | |
} else { | |
return EFI_INVALID_PARAMETER; | |
} | |
// | |
// 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: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS\n")); | |
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_REVERT: | |
case HII_KEY_ID_PSID_REVERT: | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
return HiiConfirmDataRemovalAction (OpalDisk, L"Revert"); | |
} else { | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
case HII_KEY_ID_SECURE_ERASE: | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
return HiiConfirmDataRemovalAction (OpalDisk, L"Secure erase"); | |
} else { | |
ASSERT (FALSE); | |
return EFI_SUCCESS; | |
} | |
} | |
} else if (Action == EFI_BROWSER_ACTION_CHANGED) { | |
switch (HiiKeyId) { | |
case HII_KEY_ID_BLOCKSID: | |
switch (Value->u8) { | |
case 0: | |
PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION; | |
break; | |
case 1: | |
PpRequest = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID; | |
break; | |
case 2: | |
PpRequest = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID; | |
break; | |
case 3: | |
PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE; | |
break; | |
case 4: | |
PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE; | |
break; | |
case 5: | |
PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE; | |
break; | |
case 6: | |
PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE; | |
break; | |
default: | |
PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION; | |
DEBUG ((DEBUG_ERROR, "Invalid value input!\n")); | |
break; | |
} | |
HiiSetBlockSidAction(PpRequest); | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
case HII_KEY_ID_SET_ADMIN_PWD: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_SET_ADMIN_PWD\n")); | |
gHiiConfiguration.OpalRequest.SetAdminPwd = Value->b; | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest); | |
} | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
case HII_KEY_ID_SET_USER_PWD: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_SET_USER_PWD\n")); | |
gHiiConfiguration.OpalRequest.SetUserPwd = Value->b; | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest); | |
} | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
case HII_KEY_ID_SECURE_ERASE: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_SECURE_ERASE\n")); | |
gHiiConfiguration.OpalRequest.SecureErase = Value->b; | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest); | |
} | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
case HII_KEY_ID_REVERT: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_REVERT\n")); | |
gHiiConfiguration.OpalRequest.Revert = Value->b; | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest); | |
} | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
case HII_KEY_ID_KEEP_USER_DATA: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_KEEP_USER_DATA\n")); | |
gHiiConfiguration.OpalRequest.KeepUserData = Value->b; | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest); | |
} | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
case HII_KEY_ID_PSID_REVERT: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_PSID_REVERT\n")); | |
gHiiConfiguration.OpalRequest.PsidRevert = Value->b; | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest); | |
} | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
case HII_KEY_ID_DISABLE_USER: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_DISABLE_USER\n")); | |
gHiiConfiguration.OpalRequest.DisableUser = Value->b; | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest); | |
} | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
case HII_KEY_ID_ENABLE_FEATURE: | |
DEBUG ((DEBUG_INFO, "HII_KEY_ID_ENABLE_FEATURE\n")); | |
gHiiConfiguration.OpalRequest.EnableFeature = Value->b; | |
OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex); | |
if (OpalDisk != NULL) { | |
SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest); | |
} | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
return EFI_SUCCESS; | |
default: | |
break; | |
} | |
} | |
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); | |
gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE; | |
ZeroMem (&gHiiConfiguration.OpalRequest, sizeof (OPAL_REQUEST)); | |
gHiiConfiguration.KeepUserDataForced = FALSE; | |
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; | |
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.OpalRequest.KeepUserData = 1; | |
if (AvailActions.RevertKeepDataForced) { | |
gHiiConfiguration.KeepUserDataForced = TRUE; | |
} | |
} | |
} | |
GetSavedOpalRequest (OpalDisk, &gHiiConfiguration.OpalRequest); | |
} | |
// | |
// Pass the current configuration to the BIOS | |
// | |
OpalHiiSetBrowserData (); | |
return EFI_SUCCESS; | |
} | |
/** | |
Send BlockSid request through TPM physical presence module. | |
@param PpRequest TPM physical presence operation request. | |
@retval EFI_SUCCESS Do the required action success. | |
@retval Others Other error occur. | |
**/ | |
EFI_STATUS | |
HiiSetBlockSidAction ( | |
IN UINT32 PpRequest | |
) | |
{ | |
UINT32 ReturnCode; | |
EFI_STATUS Status; | |
ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0); | |
if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) { | |
Status = EFI_SUCCESS; | |
} else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) { | |
Status = EFI_OUT_OF_RESOURCES; | |
} else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) { | |
Status = EFI_UNSUPPORTED; | |
} else { | |
Status = EFI_DEVICE_ERROR; | |
} | |
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 | |
) | |
{ | |
if (Configuration == NULL || Progress == NULL) { | |
return (EFI_INVALID_PARAMETER); | |
} | |
*Progress = Configuration; | |
if (!HiiIsConfigHdrMatch (Configuration, &gHiiSetupVariableGuid, OpalPasswordStorageName)) { | |
return EFI_NOT_FOUND; | |
} | |
*Progress = Configuration + StrLen (Configuration); | |
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; | |
EFI_STRING ConfigRequest; | |
EFI_STRING ConfigRequestHdr; | |
UINTN BufferSize; | |
UINTN Size; | |
BOOLEAN AllocatedRequest; | |
EFI_HANDLE DriverHandle; | |
// | |
// Check for valid parameters | |
// | |
if (Progress == NULL || Results == NULL) { | |
return (EFI_INVALID_PARAMETER); | |
} | |
*Progress = Request; | |
if ((Request != NULL) && | |
!HiiIsConfigHdrMatch (Request, &gHiiSetupVariableGuid, OpalPasswordStorageName)) { | |
return EFI_NOT_FOUND; | |
} | |
AllocatedRequest = FALSE; | |
BufferSize = sizeof (OPAL_HII_CONFIGURATION); | |
ConfigRequest = Request; | |
if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { | |
// | |
// Request has no request element, construct full request string. | |
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template | |
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator | |
// | |
DriverHandle = HiiGetDriverImageHandleCB(); | |
ConfigRequestHdr = HiiConstructConfigHdr (&gHiiSetupVariableGuid, OpalPasswordStorageName, DriverHandle); | |
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); | |
ConfigRequest = AllocateZeroPool (Size); | |
if (ConfigRequest == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
AllocatedRequest = TRUE; | |
UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize); | |
FreePool (ConfigRequestHdr); | |
} | |
// | |
// Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( ) | |
// | |
Status = gHiiConfigRouting->BlockToConfig( | |
gHiiConfigRouting, | |
ConfigRequest, | |
(UINT8*)&gHiiConfiguration, | |
sizeof(OPAL_HII_CONFIGURATION), | |
Results, | |
Progress | |
); | |
// | |
// Free the allocated config request string. | |
// | |
if (AllocatedRequest) { | |
FreePool (ConfigRequest); | |
ConfigRequest = NULL; | |
} | |
// | |
// Set Progress string to the original request string. | |
// | |
if (Request == NULL) { | |
*Progress = NULL; | |
} else if (StrStr (Request, L"OFFSET") == NULL) { | |
*Progress = Request + StrLen (Request); | |
} | |
return (Status); | |
} | |
/** | |
Pass the current system state to the bios via the hii_G_Configuration. | |
**/ | |
VOID | |
OpalHiiSetBrowserData ( | |
VOID | |
) | |
{ | |
HiiSetBrowserData( | |
&gHiiSetupVariableGuid, | |
(CHAR16*)L"OpalHiiConfig", | |
sizeof(gHiiConfiguration), | |
(UINT8*)&gHiiConfiguration, | |
NULL | |
); | |
} | |
/** | |
Populate the hii_g_Configuration with the browser Data. | |
**/ | |
VOID | |
OpalHiiGetBrowserData ( | |
VOID | |
) | |
{ | |
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 need 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; | |
// | |
// 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 | |
// | |
AsciiStrToUnicodeStrS ( SrcAsciiStr, UniStr, Len + 1); | |
// | |
// 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_SUCCESS 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; | |
UINT8 ActiveDataRemovalMechanism; | |
UINT32 RemovalMechanishLists[ResearvedMechanism]; | |
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_LENGTH, &Dev->OpalDisk.MsidLength); | |
if (TcgResult != TcgResultSuccess) { | |
return EFI_DEVICE_ERROR; | |
} | |
if (Dev->OpalDisk.SupportedAttributes.DataRemoval) { | |
TcgResult = OpalUtilGetDataRemovalMechanismLists (&Session, RemovalMechanishLists); | |
if (TcgResult != TcgResultSuccess) { | |
return EFI_DEVICE_ERROR; | |
} | |
TcgResult = OpalUtilGetActiveDataRemovalMechanism (&Session, Dev->OpalDisk.Msid, Dev->OpalDisk.MsidLength, &ActiveDataRemovalMechanism); | |
if (TcgResult != TcgResultSuccess) { | |
return EFI_DEVICE_ERROR; | |
} | |
Dev->OpalDisk.EstimateTimeCost = RemovalMechanishLists[ActiveDataRemovalMechanism]; | |
} | |
return OpalDiskUpdateStatus (&Dev->OpalDisk); | |
} | |
/** | |
Update the device ownship | |
@param OpalDisk The Opal device. | |
@retval EFI_SUCCESS Get ownership success. | |
@retval EFI_ACCESS_DENIED Has send BlockSID command, can't change ownership. | |
@retval EFI_INVALID_PARAMETER Not get Msid info before get ownership info. | |
**/ | |
EFI_STATUS | |
OpalDiskUpdateOwnerShip ( | |
OPAL_DISK *OpalDisk | |
) | |
{ | |
OPAL_SESSION Session; | |
if (OpalDisk->MsidLength == 0) { | |
return EFI_INVALID_PARAMETER; | |
} | |
if (OpalDisk->SentBlockSID) { | |
return EFI_ACCESS_DENIED; | |
} | |
ZeroMem(&Session, sizeof(Session)); | |
Session.Sscp = OpalDisk->Sscp; | |
Session.MediaId = OpalDisk->MediaId; | |
Session.OpalBaseComId = OpalDisk->OpalBaseComId; | |
OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength); | |
return EFI_SUCCESS; | |
} | |
/** | |
Update the device info. | |
@param OpalDisk The Opal device. | |
@retval EFI_SUCCESS 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. | |
@retval EFI_ACCESS_DENIED Has send BlockSID command, can't change ownership. | |
**/ | |
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; | |
} | |
return OpalDiskUpdateOwnerShip (OpalDisk); | |
} | |