]> git.proxmox.com Git - mirror_edk2.git/commitdiff
SecurityPkg: OpalPasswordDxe: Add Opal password dxe driver.
authorEric Dong <eric.dong@intel.com>
Tue, 29 Mar 2016 06:48:20 +0000 (14:48 +0800)
committerFeng Tian <feng.tian@intel.com>
Tue, 29 Mar 2016 07:37:30 +0000 (15:37 +0800)
This driver used to enables opal feature in bios.
It adds setup menu and unlock device process in boot phase.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
12 files changed:
SecurityPkg/Tcg/Opal/OpalPasswordDxe/ComponentName.c [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.c [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.h [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriverPrivate.h [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.h [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiCallbacks.c [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormStrings.uni [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormValues.h [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiPrivate.h [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordDxe.inf [new file with mode: 0644]
SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordForm.vfr [new file with mode: 0644]

diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/ComponentName.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..ef963d0
--- /dev/null
@@ -0,0 +1,398 @@
+/** @file\r
+  UEFI Component Name(2) protocol implementation for Opal driver.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "OpalDriver.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gOpalComponentName = {\r
+  OpalEfiDriverComponentNameGetDriverName,\r
+  OpalEfiDriverComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+//\r
+// EFI Component Name 2 Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gOpalComponentName2 = {\r
+  OpalEfiDriverComponentName2GetDriverName,\r
+  OpalEfiDriverComponentName2GetControllerName,\r
+  "en"\r
+};\r
+\r
+\r
+/// The name of the driver in all the languages we support.\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mOpalDriverNameTable[] = {\r
+    { LANGUAGE_RFC_3066_ENGLISH, (CHAR16*)EFI_DRIVER_NAME_UNICODE },\r
+    { LANGUAGE_ISO_639_2_ENGLISH, (CHAR16*)EFI_DRIVER_NAME_UNICODE },\r
+    { 0, 0 }\r
+};\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverComponentNameGetDriverName(\r
+  EFI_COMPONENT_NAME_PROTOCOL*    This,\r
+  CHAR8*                          Language,\r
+  CHAR16**                        DriverName\r
+  )\r
+{\r
+  return LookupUnicodeString2(\r
+    Language,\r
+    This->SupportedLanguages,\r
+    mOpalDriverNameTable,\r
+    DriverName,\r
+    TRUE\r
+    );\r
+}\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverComponentName2GetDriverName(\r
+  EFI_COMPONENT_NAME2_PROTOCOL*   This,\r
+  CHAR8*                          Language,\r
+  CHAR16**                        DriverName\r
+  )\r
+{\r
+  return LookupUnicodeString2(\r
+    Language,\r
+    This->SupportedLanguages,\r
+    mOpalDriverNameTable,\r
+    DriverName,\r
+    FALSE\r
+    );\r
+}\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+GetControllerName(\r
+  EFI_HANDLE  ControllerHandle,\r
+  EFI_HANDLE  ChildHandle,\r
+  CHAR8*      Language,\r
+  CHAR16**    ControllerName\r
+  )\r
+{\r
+  if (Language == NULL || ControllerName == NULL || ControllerHandle == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  // don't support any controller or children names\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverComponentNameGetControllerName(\r
+  EFI_COMPONENT_NAME_PROTOCOL*    This,\r
+  EFI_HANDLE                      ControllerHandle,\r
+  EFI_HANDLE                      ChildHandle,\r
+  CHAR8*                          Language,\r
+  CHAR16**                        ControllerName\r
+  )\r
+{\r
+  return (GetControllerName( ControllerHandle, ChildHandle, Language, ControllerName));\r
+}\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverComponentName2GetControllerName(\r
+  EFI_COMPONENT_NAME2_PROTOCOL*   This,\r
+  EFI_HANDLE                      ControllerHandle,\r
+  EFI_HANDLE                      ChildHandle,\r
+  CHAR8*                          Language,\r
+  CHAR16**                        ControllerName\r
+  )\r
+{\r
+  return (GetControllerName(ControllerHandle, ChildHandle, Language, ControllerName));\r
+}\r
+\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.c
new file mode 100644 (file)
index 0000000..e06ce4a
--- /dev/null
@@ -0,0 +1,1083 @@
+/** @file\r
+  Entrypoint of Opal UEFI Driver and contains all the logic to\r
+  register for new Opal device instances.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+// This UEFI driver consumes EFI_STORAGE_SECURITY_PROTOCOL instances and installs an\r
+// HII GUI to manage Opal features if the device is Opal capable\r
+// If the Opal device is being managed by the UEFI Driver, it shall provide a popup\r
+// window during boot requesting a user password\r
+\r
+#include "OpalDriver.h"\r
+#include "OpalDriverPrivate.h"\r
+#include "OpalHii.h"\r
+\r
+OPAL_DRIVER mOpalDriver;\r
+\r
+// flag to track hii installation\r
+BOOLEAN gHiiInstalled = FALSE;\r
+\r
+\r
+#define MAX_PASSWORD_SIZE        32\r
+#define MAX_PASSWORD_TRY_COUNT   5\r
+\r
+//\r
+// Globals\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL gOpalDriverBinding = {\r
+  OpalEfiDriverBindingSupported,\r
+  OpalEfiDriverBindingStart,\r
+  OpalEfiDriverBindingStop,\r
+  0x1b,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+\r
+/**\r
+  Add new device to the global device list.\r
+\r
+  @param Dev             New create device.\r
+\r
+**/\r
+VOID\r
+AddDeviceToTail(\r
+  IN OPAL_DRIVER_DEVICE    *Dev\r
+  )\r
+{\r
+  OPAL_DRIVER_DEVICE                *TmpDev;\r
+\r
+  if (mOpalDriver.DeviceList == NULL) {\r
+    mOpalDriver.DeviceList = Dev;\r
+  } else {\r
+    TmpDev = mOpalDriver.DeviceList;\r
+    while (TmpDev->Next != NULL) {\r
+      TmpDev = TmpDev->Next;\r
+    }\r
+\r
+    TmpDev->Next = Dev;\r
+  }\r
+}\r
+\r
+/**\r
+  Remove one device in the global device list.\r
+\r
+  @param Dev             The device need to be removed.\r
+\r
+**/\r
+VOID\r
+RemoveDevice (\r
+  IN OPAL_DRIVER_DEVICE    *Dev\r
+  )\r
+{\r
+  OPAL_DRIVER_DEVICE                *TmpDev;\r
+\r
+  if (mOpalDriver.DeviceList == NULL) {\r
+    return;\r
+  }\r
+\r
+  if (mOpalDriver.DeviceList == Dev) {\r
+    mOpalDriver.DeviceList = NULL;\r
+    return;\r
+  }\r
+\r
+  TmpDev = mOpalDriver.DeviceList;\r
+  while (TmpDev->Next != NULL) {\r
+    if (TmpDev->Next == Dev) {\r
+      TmpDev->Next = Dev->Next;\r
+      break;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Get current device count.\r
+\r
+  @retval  return the current created device count.\r
+\r
+**/\r
+UINT8\r
+GetDeviceCount (\r
+  VOID\r
+  )\r
+{\r
+  UINT8                Count;\r
+  OPAL_DRIVER_DEVICE   *TmpDev;\r
+\r
+  Count = 0;\r
+  TmpDev = mOpalDriver.DeviceList;\r
+\r
+  while (TmpDev != NULL) {\r
+    Count++;\r
+    TmpDev = TmpDev->Next;\r
+  }\r
+\r
+  return Count;\r
+}\r
+\r
+/**\r
+  Get password input from the popup windows, and unlock the device.\r
+\r
+  @param[in]       Dev          The device which need to be unlock.\r
+  @param[out]      PressEsc     Whether user escape function through Press ESC.\r
+\r
+  @retval   Password string if success. NULL if failed.\r
+\r
+**/\r
+CHAR8 *\r
+OpalDriverPopUpHddPassword (\r
+  IN  OPAL_DRIVER_DEVICE         *Dev,\r
+  OUT BOOLEAN                    *PressEsc\r
+  )\r
+{\r
+  EFI_INPUT_KEY                InputKey;\r
+  UINTN                        InputLength;\r
+  CHAR16                       Mask[MAX_PASSWORD_SIZE + 1];\r
+  CHAR16                       Unicode[MAX_PASSWORD_SIZE + 1];\r
+  CHAR8                        *Ascii;\r
+  CHAR16                       *PopUpString;\r
+  UINTN                        StrLength;\r
+\r
+  ZeroMem(Unicode, sizeof(Unicode));\r
+  ZeroMem(Mask, sizeof(Mask));\r
+\r
+  StrLength = StrLen(Dev->Name16);\r
+  PopUpString = (CHAR16*) AllocateZeroPool ((8 + StrLength) * 2);\r
+  *PressEsc = FALSE;\r
+\r
+  if (Dev->Name16 == NULL) {\r
+    UnicodeSPrint(PopUpString, StrLen(L"Unlock Disk") + 1, L"Unlock Disk");\r
+  } else {\r
+    UnicodeSPrint(PopUpString, StrLen(L"Unlock ") + StrLength + 1, L"Unlock %s", Dev->Name16);\r
+  }\r
+\r
+  gST->ConOut->ClearScreen(gST->ConOut);\r
+\r
+  InputLength = 0;\r
+  while (TRUE) {\r
+    Mask[InputLength] = L'_';\r
+    CreatePopUp(\r
+        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+        &InputKey,\r
+        PopUpString,\r
+        L"---------------------",\r
+        Mask,\r
+        NULL\r
+    );\r
+\r
+    //\r
+    // Check key.\r
+    //\r
+    if (InputKey.ScanCode == SCAN_NULL) {\r
+      //\r
+      // password finished\r
+      //\r
+      if (InputKey.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
+        //\r
+        // Add the null terminator.\r
+        //\r
+        Unicode[InputLength] = 0;\r
+        InputLength++;\r
+        break;\r
+      } else if ((InputKey.UnicodeChar == CHAR_NULL) ||\r
+                 (InputKey.UnicodeChar == CHAR_TAB) ||\r
+                 (InputKey.UnicodeChar == CHAR_LINEFEED)\r
+                ) {\r
+        continue;\r
+      } else {\r
+        //\r
+        // delete last key entered\r
+        //\r
+        if (InputKey.UnicodeChar == CHAR_BACKSPACE) {\r
+          if (InputLength > 0) {\r
+            Unicode[InputLength] = 0;\r
+            Mask[InputLength] = 0;\r
+            InputLength--;\r
+          }\r
+        } else {\r
+          //\r
+          // add Next key entry\r
+          //\r
+          Unicode[InputLength] = InputKey.UnicodeChar;\r
+          Mask[InputLength] = L'*';\r
+          InputLength++;\r
+          if (InputLength == MAX_PASSWORD_SIZE) {\r
+            //\r
+            // Add the null terminator.\r
+            //\r
+            Unicode[InputLength] = 0;\r
+            Mask[InputLength] = 0;\r
+            break;\r
+          }\r
+        }\r
+      }\r
+    }\r
+\r
+    //\r
+    // exit on ESC\r
+    //\r
+    if (InputKey.ScanCode == SCAN_ESC) {\r
+      *PressEsc = TRUE;\r
+      break;\r
+    }\r
+  }\r
+\r
+  gST->ConOut->ClearScreen(gST->ConOut);\r
+\r
+  if (InputLength == 0 || InputKey.ScanCode == SCAN_ESC) {\r
+    return NULL;\r
+  }\r
+\r
+  Ascii = AllocateZeroPool (MAX_PASSWORD_SIZE + 1);\r
+  if (Ascii == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  UnicodeStrToAsciiStr(Unicode, Ascii);\r
+\r
+  return Ascii;\r
+}\r
+\r
+/**\r
+  Check if disk is locked, show popup window and ask for password if it is\r
+\r
+  @param[in]       Dev          The device which need to be unlock.\r
+\r
+**/\r
+VOID\r
+OpalDriverRequestPassword (\r
+  OPAL_DRIVER_DEVICE       *Dev\r
+  )\r
+{\r
+  UINT8               Count;\r
+  BOOLEAN             IsEnabled;\r
+  CHAR8               *Password;\r
+  UINT32              PasswordLen;\r
+  TCG_RESULT          Ret;\r
+  EFI_INPUT_KEY       Key;\r
+  OPAL_SESSION        Session;\r
+  BOOLEAN             PressEsc;\r
+\r
+  if (Dev == NULL) {\r
+    return;\r
+  }\r
+\r
+  Count = 0;\r
+\r
+  IsEnabled = OpalFeatureEnabled (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature);\r
+  if (IsEnabled) {\r
+    ZeroMem(&Session, sizeof(Session));\r
+    Session.Sscp = Dev->OpalDisk.Sscp;\r
+    Session.MediaId = Dev->OpalDisk.MediaId;\r
+    Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
+\r
+    while (Count < MAX_PASSWORD_TRY_COUNT) {\r
+      Password = OpalDriverPopUpHddPassword (Dev, &PressEsc);\r
+      if (PressEsc) {\r
+        //\r
+        // User not input password and press ESC, keep device in lock status and continue boot.\r
+        //\r
+        do {\r
+          CreatePopUp (\r
+                  EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+                  &Key,\r
+                  L"Confirm: Not unlock device and continue boot?.",\r
+                  L"Press ENTER to confirm, Press Esc to input password",\r
+                  NULL\r
+                  );\r
+        } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
+\r
+        if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {\r
+          gST->ConOut->ClearScreen(gST->ConOut);\r
+          //\r
+          // Keep lock and continue boot.\r
+          //\r
+          return;\r
+        } else {\r
+          //\r
+          // Let user input password again.\r
+          //\r
+          continue;\r
+        }\r
+      }\r
+\r
+      if (Password == NULL) {\r
+        Count ++;\r
+        continue;\r
+      }\r
+      PasswordLen = (UINT32) AsciiStrLen(Password);\r
+\r
+      if (OpalDeviceLocked (&Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.LockingFeature)) {\r
+        Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath);\r
+      } else {\r
+        Ret = OpalSupportLock(&Session, Password, PasswordLen, Dev->OpalDevicePath);\r
+        if (Ret == TcgResultSuccess) {\r
+          Ret = OpalSupportUnlock(&Session, Password, PasswordLen, Dev->OpalDevicePath);\r
+        }\r
+      }\r
+\r
+      if (Password != NULL) {\r
+        ZeroMem (Password, PasswordLen);\r
+        FreePool (Password);\r
+      }\r
+\r
+      if (Ret == TcgResultSuccess) {\r
+        break;\r
+      }\r
+\r
+      Count++;\r
+\r
+      do {\r
+        CreatePopUp (\r
+                  EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+                  &Key,\r
+                  L"Invalid password.",\r
+                  L"Press ENTER to retry",\r
+                  NULL\r
+                  );\r
+      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+    }\r
+\r
+    if (Count >= MAX_PASSWORD_TRY_COUNT) {\r
+      do {\r
+        CreatePopUp (\r
+                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+                &Key,\r
+                L"Opal password retry count is expired. Keep lock and continue boot.",\r
+                L"Press ENTER to continue",\r
+                NULL\r
+                );\r
+      } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
+      gST->ConOut->ClearScreen(gST->ConOut);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Get devcie list info.\r
+\r
+  @retval     return the device list pointer.\r
+**/\r
+OPAL_DRIVER_DEVICE*\r
+OpalDriverGetDeviceList(\r
+  VOID\r
+  )\r
+{\r
+  return mOpalDriver.DeviceList;\r
+}\r
+\r
+/**\r
+  ReadyToBoot callback to send BlockSid command.\r
+\r
+  @param  Event   Pointer to this event\r
+  @param  Context Event hanlder private Data\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ReadyToBootCallback (\r
+  IN EFI_EVENT        Event,\r
+  IN VOID             *Context\r
+  )\r
+{\r
+  EFI_STATUS          Status;\r
+  OPAL_DRIVER_DEVICE* Itr;\r
+  UINT8               Count;\r
+  TCG_RESULT          Result;\r
+  OPAL_EXTRA_INFO_VAR OpalExtraInfo;\r
+  UINTN               DataSize;\r
+  OPAL_SESSION        Session;\r
+\r
+  Count = 0;\r
+\r
+  gBS->CloseEvent (Event);\r
+\r
+  DataSize = sizeof (OPAL_EXTRA_INFO_VAR);\r
+  Status = gRT->GetVariable (\r
+                  OPAL_EXTRA_INFO_VAR_NAME,\r
+                  &gOpalExtraInfoVariableGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &OpalExtraInfo\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return;\r
+  }\r
+\r
+  if (OpalExtraInfo.EnableBlockSid == TRUE) {\r
+    //\r
+    // Send BlockSID command to each Opal disk\r
+    //\r
+    Itr = mOpalDriver.DeviceList;\r
+    Count = 0;\r
+    while (Itr != NULL) {\r
+      ZeroMem(&Session, sizeof(Session));\r
+      Session.Sscp = Itr->OpalDisk.Sscp;\r
+      Session.MediaId = Itr->OpalDisk.MediaId;\r
+      Session.OpalBaseComId = Itr->OpalDisk.OpalBaseComId;\r
+\r
+      Result = OpalBlockSid (&Session, TRUE);  // HardwareReset must always be TRUE\r
+      if (Result != TcgResultSuccess) {\r
+        DEBUG ((DEBUG_ERROR, "OpalBlockSid fail\n"));\r
+        break;\r
+      }\r
+\r
+      Itr = Itr->Next;\r
+      Count++;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Stop this Controller.\r
+\r
+  @param  Dev               The device need to be stopped.\r
+\r
+**/\r
+VOID\r
+OpalDriverStopDevice (\r
+  OPAL_DRIVER_DEVICE     *Dev\r
+  )\r
+{\r
+  //\r
+  // free each name\r
+  //\r
+  FreePool(Dev->Name16);\r
+\r
+  //\r
+  // remove OPAL_DRIVER_DEVICE from the list\r
+  // it updates the controllerList pointer\r
+  //\r
+  RemoveDevice(Dev);\r
+\r
+  //\r
+  // close protocols that were opened\r
+  //\r
+  gBS->CloseProtocol(\r
+    Dev->Handle,\r
+    &gEfiStorageSecurityCommandProtocolGuid,\r
+    gOpalDriverBinding.DriverBindingHandle,\r
+    Dev->Handle\r
+    );\r
+\r
+  gBS->CloseProtocol(\r
+    Dev->Handle,\r
+    &gEfiBlockIoProtocolGuid,\r
+    gOpalDriverBinding.DriverBindingHandle,\r
+    Dev->Handle\r
+    );\r
+\r
+  FreePool(Dev);\r
+}\r
+\r
+/**\r
+  Get devcie name through the component name protocol.\r
+\r
+  @param[in]       AllHandlesBuffer   The handle buffer for current system.\r
+  @param[in]       NumAllHandles      The number of handles for the handle buffer.\r
+  @param[in]       Dev                The device which need to get name.\r
+  @param[in]       UseComp1           Whether use component name or name2 protocol.\r
+\r
+  @retval     TRUE        Find the name for this device.\r
+  @retval     FALSE       Not found the name for this device.\r
+**/\r
+BOOLEAN\r
+OpalDriverGetDeviceNameByProtocol(\r
+  EFI_HANDLE             *AllHandlesBuffer,\r
+  UINTN                  NumAllHandles,\r
+  OPAL_DRIVER_DEVICE     *Dev,\r
+  BOOLEAN                UseComp1\r
+  )\r
+{\r
+  EFI_HANDLE*                   ProtocolHandlesBuffer;\r
+  UINTN                         NumProtocolHandles;\r
+  EFI_STATUS                    Status;\r
+  EFI_COMPONENT_NAME2_PROTOCOL* Cnp1_2; // efi component name and componentName2 have same layout\r
+  EFI_GUID                      Protocol;\r
+  UINTN                         StrLength;\r
+  EFI_DEVICE_PATH_PROTOCOL*     TmpDevPath;\r
+  UINTN                         Index1;\r
+  UINTN                         Index2;\r
+  EFI_HANDLE                    TmpHandle;\r
+  CHAR16                        *DevName;\r
+\r
+  if (Dev == NULL || AllHandlesBuffer == NULL || NumAllHandles == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  Protocol = UseComp1 ? gEfiComponentNameProtocolGuid : gEfiComponentName2ProtocolGuid;\r
+\r
+  //\r
+  // Find all EFI_HANDLES with protocol\r
+  //\r
+  Status = gBS->LocateHandleBuffer(\r
+               ByProtocol,\r
+               &Protocol,\r
+               NULL,\r
+               &NumProtocolHandles,\r
+               &ProtocolHandlesBuffer\r
+               );\r
+  if (EFI_ERROR(Status)) {\r
+    return FALSE;\r
+  }\r
+\r
+\r
+  //\r
+  // Exit early if no supported devices\r
+  //\r
+  if (NumProtocolHandles == 0) {\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Get printable name by iterating through all protocols\r
+  // using the handle as the child, and iterate through all handles for the controller\r
+  // exit loop early once found, if not found, then delete device\r
+  // storage security protocol instances already exist, add them to internal list\r
+  //\r
+  Status = EFI_DEVICE_ERROR;\r
+  for (Index1 = 0; Index1 < NumProtocolHandles; Index1++) {\r
+    DevName = NULL;\r
+\r
+    if (Dev->Name16 != NULL) {\r
+      return TRUE;\r
+    }\r
+\r
+    TmpHandle = ProtocolHandlesBuffer[Index1];\r
+\r
+    Status = gBS->OpenProtocol(\r
+                 TmpHandle,\r
+                 &Protocol,\r
+                 (VOID**)&Cnp1_2,\r
+                 gImageHandle,\r
+                 NULL,\r
+                 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                 );\r
+    if (EFI_ERROR(Status) || Cnp1_2 == NULL) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Use all handles array as controller handle\r
+    //\r
+    for (Index2 = 0; Index2 < NumAllHandles; Index2++) {\r
+      Status = Cnp1_2->GetControllerName(\r
+                   Cnp1_2,\r
+                   AllHandlesBuffer[Index2],\r
+                   Dev->Handle,\r
+                   LANGUAGE_ISO_639_2_ENGLISH,\r
+                   &DevName\r
+                   );\r
+      if (EFI_ERROR(Status)) {\r
+        Status = Cnp1_2->GetControllerName(\r
+                     Cnp1_2,\r
+                     AllHandlesBuffer[Index2],\r
+                     Dev->Handle,\r
+                     LANGUAGE_RFC_3066_ENGLISH,\r
+                     &DevName\r
+                     );\r
+      }\r
+      if (!EFI_ERROR(Status) && DevName != NULL) {\r
+        StrLength = StrLen(DevName) + 1;        // Add one for NULL terminator\r
+        Dev->Name16 = AllocateZeroPool(StrLength * sizeof (CHAR16));\r
+        ASSERT (Dev->Name16 != NULL);\r
+        StrCpyS (Dev->Name16, StrLength, DevName);\r
+        Dev->NameZ = (CHAR8*)AllocateZeroPool(StrLength);\r
+        UnicodeStrToAsciiStr(DevName, Dev->NameZ);\r
+\r
+        //\r
+        // Retrieve bridge BDF info and port number or namespace depending on type\r
+        //\r
+        TmpDevPath = NULL;\r
+        Status = gBS->OpenProtocol(\r
+            Dev->Handle,\r
+            &gEfiDevicePathProtocolGuid,\r
+            (VOID**)&TmpDevPath,\r
+            gImageHandle,\r
+            NULL,\r
+            EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+            );\r
+        if (!EFI_ERROR(Status)) {\r
+          Dev->OpalDevicePath = DuplicateDevicePath (TmpDevPath);\r
+          return TRUE;\r
+        }\r
+\r
+        if (Dev->Name16 != NULL) {\r
+          FreePool(Dev->Name16);\r
+          Dev->Name16 = NULL;\r
+        }\r
+        if (Dev->NameZ != NULL) {\r
+          FreePool(Dev->NameZ);\r
+          Dev->NameZ = NULL;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+/**\r
+  Get devcie name through the component name protocol.\r
+\r
+  @param[in]       Dev                The device which need to get name.\r
+\r
+  @retval     TRUE        Find the name for this device.\r
+  @retval     FALSE       Not found the name for this device.\r
+**/\r
+BOOLEAN\r
+OpalDriverGetDriverDeviceName(\r
+  OPAL_DRIVER_DEVICE          *Dev\r
+  )\r
+{\r
+  EFI_HANDLE*                  AllHandlesBuffer;\r
+  UINTN                        NumAllHandles;\r
+  EFI_STATUS                   Status;\r
+\r
+  if (Dev == NULL) {\r
+    DEBUG((DEBUG_ERROR | DEBUG_INIT, "OpalDriverGetDriverDeviceName Exiting, Dev=NULL\n"));\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Iterate through ComponentName2 handles to get name, if fails, try ComponentName\r
+  //\r
+  if (Dev->Name16 == NULL) {\r
+    DEBUG((DEBUG_ERROR | DEBUG_INIT, "Name is null, update it\n"));\r
+    //\r
+    // Find all EFI_HANDLES\r
+    //\r
+    Status = gBS->LocateHandleBuffer(\r
+                 AllHandles,\r
+                 NULL,\r
+                 NULL,\r
+                 &NumAllHandles,\r
+                 &AllHandlesBuffer\r
+                 );\r
+    if (EFI_ERROR(Status)) {\r
+      DEBUG ((DEBUG_INFO, "LocateHandleBuffer for AllHandles failed %r\n", Status ));\r
+      return FALSE;\r
+    }\r
+\r
+    //\r
+    // Try component Name2\r
+    //\r
+    if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, FALSE)) {\r
+      DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName2 failed to get device name, try ComponentName\n"));\r
+      if (!OpalDriverGetDeviceNameByProtocol(AllHandlesBuffer, NumAllHandles, Dev, TRUE)) {\r
+        DEBUG((DEBUG_ERROR | DEBUG_INIT, "ComponentName failed to get device name, skip device\n"));\r
+        return FALSE;\r
+      }\r
+    }\r
+  }\r
+\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Main entry for this driver.\r
+\r
+  @param ImageHandle     Image Handle this driver.\r
+  @param SystemTable     Pointer to SystemTable.\r
+\r
+  @retval EFI_SUCESS     This function always complete successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiDriverEntryPoint(\r
+  IN EFI_HANDLE         ImageHandle,\r
+  IN EFI_SYSTEM_TABLE*  SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  EFI_EVENT                      ReadyToBootEvent;\r
+\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &gOpalDriverBinding,\r
+             ImageHandle,\r
+             &gOpalComponentName,\r
+             &gOpalComponentName2\r
+             );\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    DEBUG((DEBUG_ERROR, "Install protocols to Opal driver Handle failed\n"));\r
+    return Status ;\r
+  }\r
+\r
+  //\r
+  // Initialize Driver object\r
+  //\r
+  ZeroMem(&mOpalDriver, sizeof(mOpalDriver));\r
+  mOpalDriver.Handle = ImageHandle;\r
+\r
+  //\r
+  // register a ReadyToBoot event callback for sending BlockSid command\r
+  //\r
+  Status = EfiCreateEventReadyToBootEx (\r
+                  TPL_CALLBACK,\r
+                  ReadyToBootCallback,\r
+                  (VOID *) &ImageHandle,\r
+                  &ReadyToBootEvent\r
+                  );\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Tests to see if this driver supports a given controller.\r
+\r
+  This function checks to see if the controller contains an instance of the\r
+  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL and the EFI_BLOCK_IO_PROTOCL\r
+  and returns EFI_SUCCESS if it does.\r
+\r
+  @param[in]  This                  A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle      The Handle of the controller to test. This Handle\r
+                                    must support a protocol interface that supplies\r
+                                    an I/O abstraction to the driver.\r
+  @param[in]  RemainingDevicePath  This parameter is ignored.\r
+\r
+  @retval EFI_SUCCESS               The device contains required protocols\r
+  @retval EFI_ALREADY_STARTED       The device specified by ControllerHandle and\r
+                                    RemainingDevicePath is already being managed by the driver\r
+                                    specified by This.\r
+  @retval EFI_ACCESS_DENIED         The device specified by ControllerHandle and\r
+                                    RemainingDevicePath is already being managed by a different\r
+                                    driver or an application that requires exclusive access.\r
+                                    Currently not implemented.\r
+  @retval EFI_UNSUPPORTED           The device does not contain requires protocols\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverBindingSupported(\r
+  IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL*    RemainingDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                              Status;\r
+  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL*  SecurityCommand;\r
+  EFI_BLOCK_IO_PROTOCOL*                  BlkIo;\r
+\r
+  //\r
+  // Test EFI_STORAGE_SECURITY_COMMAND_PROTOCOL on controller Handle.\r
+  //\r
+  Status = gBS->OpenProtocol(\r
+    Controller,\r
+    &gEfiStorageSecurityCommandProtocolGuid,\r
+    ( VOID ** )&SecurityCommand,\r
+    This->DriverBindingHandle,\r
+    Controller,\r
+    EFI_OPEN_PROTOCOL_BY_DRIVER\r
+    );\r
+\r
+  if (Status == EFI_ALREADY_STARTED) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Close protocol and reopen in Start call\r
+  //\r
+  gBS->CloseProtocol(\r
+      Controller,\r
+      &gEfiStorageSecurityCommandProtocolGuid,\r
+      This->DriverBindingHandle,\r
+      Controller\r
+      );\r
+\r
+  //\r
+  // Test EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
+  // function APIs\r
+  //\r
+  Status = gBS->OpenProtocol(\r
+    Controller,\r
+    &gEfiBlockIoProtocolGuid,\r
+    (VOID **)&BlkIo,\r
+    This->DriverBindingHandle,\r
+    Controller,\r
+    EFI_OPEN_PROTOCOL_BY_DRIVER\r
+    );\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    DEBUG((DEBUG_INFO, "No EFI_BLOCK_IO_PROTOCOL on controller\n"));\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Close protocol and reopen in Start call\r
+  //\r
+  gBS->CloseProtocol(\r
+    Controller,\r
+    &gEfiBlockIoProtocolGuid,\r
+    This->DriverBindingHandle,\r
+    Controller\r
+    );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Enables Opal Management on a supported device if available.\r
+\r
+  The start function is designed to be called after the Opal UEFI Driver has confirmed the\r
+  "controller", which is a child Handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.\r
+  This function will complete the other necessary checks, such as verifying the device supports\r
+  the correct version of Opal.  Upon verification, it will add the device to the\r
+  Opal HII list in order to expose Opal managmeent options.\r
+\r
+  @param[in]  This                  A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle      The Handle of the controller to start. This Handle\r
+                                    must support a protocol interface that supplies\r
+                                    an I/O abstraction to the driver.\r
+  @param[in]  RemainingDevicePath   A pointer to the remaining portion of a device path.  This\r
+                                    parameter is ignored by device drivers, and is optional for bus\r
+                                    drivers. For a bus driver, if this parameter is NULL, then handles\r
+                                    for all the children of Controller are created by this driver.\r
+                                    If this parameter is not NULL and the first Device Path Node is\r
+                                    not the End of Device Path Node, then only the Handle for the\r
+                                    child device specified by the first Device Path Node of\r
+                                    RemainingDevicePath is created by this driver.\r
+                                    If the first Device Path Node of RemainingDevicePath is\r
+                                    the End of Device Path Node, no child Handle is created by this\r
+                                    driver.\r
+\r
+  @retval EFI_SUCCESS               Opal management was enabled.\r
+  @retval EFI_DEVICE_ERROR          The device could not be started due to a device error.Currently not implemented.\r
+  @retval EFI_OUT_OF_RESOURCES      The request could not be completed due to a lack of resources.\r
+  @retval Others                    The driver failed to start the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverBindingStart(\r
+  IN EFI_DRIVER_BINDING_PROTOCOL* This,\r
+  IN EFI_HANDLE                   Controller,\r
+  IN EFI_DEVICE_PATH_PROTOCOL*    RemainingDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_BLOCK_IO_PROTOCOL       *BlkIo;\r
+  OPAL_DRIVER_DEVICE          *Dev;\r
+  OPAL_DRIVER_DEVICE          *Itr;\r
+  BOOLEAN                     Result;\r
+\r
+  Itr = mOpalDriver.DeviceList;\r
+  while (Itr != NULL) {\r
+    if (Controller == Itr->Handle) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    Itr = Itr->Next;\r
+  }\r
+\r
+  //\r
+  // Create internal device for tracking.  This allows all disks to be tracked\r
+  // by same HII form\r
+  //\r
+  Dev = (OPAL_DRIVER_DEVICE*)AllocateZeroPool(sizeof(OPAL_DRIVER_DEVICE));\r
+  if (Dev == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  Dev->Handle = Controller;\r
+\r
+  //\r
+  // Open EFI_STORAGE_SECURITY_COMMAND_PROTOCOL to perform Opal supported checks\r
+  //\r
+  Status = gBS->OpenProtocol(\r
+    Controller,\r
+    &gEfiStorageSecurityCommandProtocolGuid,\r
+    (VOID **)&Dev->Sscp,\r
+    This->DriverBindingHandle,\r
+    Controller,\r
+    EFI_OPEN_PROTOCOL_BY_DRIVER\r
+    );\r
+  if (EFI_ERROR(Status)) {\r
+    FreePool(Dev);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Open EFI_BLOCK_IO_PROTOCOL on controller Handle, required by EFI_STORAGE_SECURITY_COMMAND_PROTOCOL\r
+  // function APIs\r
+  //\r
+  Status = gBS->OpenProtocol(\r
+    Controller,\r
+    &gEfiBlockIoProtocolGuid,\r
+    (VOID **)&BlkIo,\r
+    This->DriverBindingHandle,\r
+    Controller,\r
+    EFI_OPEN_PROTOCOL_BY_DRIVER\r
+    );\r
+  if (EFI_ERROR(Status)) {\r
+    //\r
+    // Close storage security that was opened\r
+    //\r
+    gBS->CloseProtocol(\r
+        Controller,\r
+        &gEfiStorageSecurityCommandProtocolGuid,\r
+        This->DriverBindingHandle,\r
+        Controller\r
+        );\r
+\r
+    FreePool(Dev);\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Save mediaId\r
+  //\r
+  Dev->MediaId = BlkIo->Media->MediaId;\r
+\r
+  gBS->CloseProtocol(\r
+    Controller,\r
+    &gEfiBlockIoProtocolGuid,\r
+    This->DriverBindingHandle,\r
+    Controller\r
+    );\r
+\r
+  //\r
+  // Acquire Ascii printable name of child, if not found, then ignore device\r
+  //\r
+  Result = OpalDriverGetDriverDeviceName (Dev);\r
+  if (!Result) {\r
+    goto Done;\r
+  }\r
+\r
+  Status = OpalDiskInitialize (Dev);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  AddDeviceToTail(Dev);\r
+\r
+  //\r
+  // Install Hii if it hasn't already been installed\r
+  //\r
+  if (!gHiiInstalled) {\r
+    HiiInstall();\r
+    gHiiInstalled = TRUE;\r
+  }\r
+\r
+  //\r
+  // check if device is locked and prompt for password\r
+  //\r
+  OpalDriverRequestPassword (Dev);\r
+\r
+  return EFI_SUCCESS;\r
+\r
+Done:\r
+  //\r
+  // free device, close protocols and exit\r
+  //\r
+  gBS->CloseProtocol(\r
+      Controller,\r
+      &gEfiStorageSecurityCommandProtocolGuid,\r
+      This->DriverBindingHandle,\r
+      Controller\r
+      );\r
+\r
+  FreePool(Dev);\r
+\r
+  return EFI_DEVICE_ERROR;\r
+}\r
+\r
+/**\r
+  Stop this driver on Controller.\r
+\r
+  @param  This              Protocol instance pointer.\r
+  @param  Controller        Handle of device to stop driver on\r
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
+                            children is zero stop the entire bus driver.\r
+  @param  ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+  @retval EFI_SUCCESS       This driver is removed Controller.\r
+  @retval other             This driver could not be removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverBindingStop(\r
+  EFI_DRIVER_BINDING_PROTOCOL*    This,\r
+  EFI_HANDLE                      Controller,\r
+  UINTN                           NumberOfChildren,\r
+  EFI_HANDLE*                     ChildHandleBuffer\r
+  )\r
+{\r
+  OPAL_DRIVER_DEVICE*   Itr;\r
+\r
+  Itr = mOpalDriver.DeviceList;\r
+\r
+  //\r
+  // does Controller match any of the devices we are managing for Opal\r
+  //\r
+  while (Itr != NULL) {\r
+    if (Itr->Handle == Controller) {\r
+      OpalDriverStopDevice (Itr);\r
+      return EFI_SUCCESS;\r
+    }\r
+\r
+    Itr = Itr->Next;\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+\r
+/**\r
+  Unloads UEFI Driver.  Very useful for debugging and testing.\r
+\r
+  @param ImageHandle            Image Handle this driver.\r
+\r
+  @retval EFI_SUCCESS           This function always complete successfully.\r
+  @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverUnload (\r
+  IN EFI_HANDLE ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  OPAL_DRIVER_DEVICE                   *Itr;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (ImageHandle != gImageHandle) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // Uninstall any interface added to each device by us\r
+  //\r
+  while (mOpalDriver.DeviceList) {\r
+    Itr = mOpalDriver.DeviceList;\r
+    //\r
+    // Remove OPAL_DRIVER_DEVICE from the list\r
+    // it updates the controllerList pointer\r
+    //\r
+    OpalDriverStopDevice(Itr);\r
+  }\r
+\r
+  //\r
+  // Uninstall the HII capability\r
+  //\r
+  Status = HiiUninstall();\r
+\r
+  return Status;\r
+}\r
+\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriver.h
new file mode 100644 (file)
index 0000000..213c139
--- /dev/null
@@ -0,0 +1,413 @@
+/** @file\r
+  Values defined and used by the Opal UEFI Driver.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _OPAL_DRIVER_H_\r
+#define _OPAL_DRIVER_H_\r
+\r
+#include <PiDxe.h>\r
+\r
+#include <Guid/OpalPasswordExtraInfoVariable.h>\r
+\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/SmmCommunication.h>\r
+#include <Protocol/BlockIo.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/DevicePathToText.h>\r
+#include <Protocol/StorageSecurityCommand.h>\r
+\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/UefiHiiServicesLib.h>\r
+#include <Library/TcgStorageOpalLib.h>\r
+#include <Library/OpalPasswordSupportLib.h>\r
+\r
+#define EFI_DRIVER_NAME_UNICODE L"1.0 UEFI Opal Driver"\r
+\r
+// UEFI 2.1\r
+#define LANGUAGE_RFC_3066_ENGLISH ((CHAR8*)"en")\r
+\r
+// UEFI/EFI < 2.1\r
+#define LANGUAGE_ISO_639_2_ENGLISH ((CHAR8*)"eng")\r
+\r
+\r
+#define UNLOCK_VAR_NAME                 (const CHAR16*)L"UNLOCK"\r
+#define OPAL_FILTER_DRIVER_VAR_NAME     L"FILTER_DRIVER"\r
+\r
+\r
+#define CONCAT_(x, y) x ## y\r
+#define CONCAT(x, y) CONCAT_(x, y)\r
+\r
+#define UNICODE_STR(x) CONCAT( L, x )\r
+\r
+extern EFI_DRIVER_BINDING_PROTOCOL   gOpalDriverBinding;\r
+extern EFI_COMPONENT_NAME_PROTOCOL   gOpalComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL  gOpalComponentName2;\r
+\r
+/**\r
+  Unloads UEFI Driver.  Very useful for debugging and testing.\r
+\r
+  @param ImageHandle            Image handle this driver.\r
+\r
+  @retval EFI_SUCCESS           This function always complete successfully.\r
+  @retval EFI_INVALID_PARAMETER The input ImageHandle is not valid.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiDriverUnload(\r
+  EFI_HANDLE ImageHandle\r
+  );\r
+\r
+\r
+/**\r
+  Test to see if this driver supports Controller.\r
+\r
+  @param  This                Protocol instance pointer.\r
+  @param  ControllerHandle    Handle of device to test\r
+  @param  RemainingDevicePath Optional parameter use to pick a specific child\r
+                              device to start.\r
+\r
+  @retval EFI_SUCCESS         This driver supports this device.\r
+  @retval EFI_ALREADY_STARTED This driver is already running on this device.\r
+  @retval other               This driver does not support this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverBindingSupported(\r
+  EFI_DRIVER_BINDING_PROTOCOL*    This,\r
+  EFI_HANDLE                      Controller,\r
+  EFI_DEVICE_PATH_PROTOCOL*       RemainingDevicePath\r
+  );\r
+\r
+/**\r
+  Enables Opal Management on a supported device if available.\r
+\r
+  The start function is designed to be called after the Opal UEFI Driver has confirmed the\r
+  "controller", which is a child handle, contains the EF_STORAGE_SECURITY_COMMAND protocols.\r
+  This function will complete the other necessary checks, such as verifying the device supports\r
+  the correct version of Opal.  Upon verification, it will add the device to the\r
+  Opal HII list in order to expose Opal managmeent options.\r
+\r
+  @param[in]  This                  A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.\r
+  @param[in]  ControllerHandle      The handle of the controller to start. This handle\r
+                                    must support a protocol interface that supplies\r
+                                    an I/O abstraction to the driver.\r
+  @param[in]  RemainingDevicePath   A pointer to the remaining portion of a device path.  This\r
+                                    parameter is ignored by device drivers, and is optional for bus\r
+                                    drivers. For a bus driver, if this parameter is NULL, then handles\r
+                                    for all the children of Controller are created by this driver.\r
+                                    If this parameter is not NULL and the first Device Path Node is\r
+                                    not the End of Device Path Node, then only the handle for the\r
+                                    child device specified by the first Device Path Node of\r
+                                    RemainingDevicePath is created by this driver.\r
+                                    If the first Device Path Node of RemainingDevicePath is\r
+                                    the End of Device Path Node, no child handle is created by this\r
+                                    driver.\r
+\r
+  @retval EFI_SUCCESS               Opal management was enabled.\r
+  @retval EFI_DEVICE_ERROR          The device could not be started due to a device error.Currently not implemented.\r
+  @retval EFI_OUT_OF_RESOURCES      The request could not be completed due to a lack of resources.\r
+  @retval Others                    The driver failed to start the device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverBindingStart(\r
+  EFI_DRIVER_BINDING_PROTOCOL*    This,\r
+  EFI_HANDLE                      Controller,\r
+  EFI_DEVICE_PATH_PROTOCOL*       RemainingDevicePath\r
+  );\r
+\r
+/**\r
+  Stop this driver on Controller.\r
+\r
+  @param  This              Protocol instance pointer.\r
+  @param  Controller        Handle of device to stop driver on\r
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
+                            children is zero stop the entire bus driver.\r
+  @param  ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+  @retval EFI_SUCCESS       This driver is removed Controller.\r
+  @retval other             This driver could not be removed from this device.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverBindingStop(\r
+  EFI_DRIVER_BINDING_PROTOCOL*    This,\r
+  EFI_HANDLE                      Controller,\r
+  UINTN                           NumberOfChildren,\r
+  EFI_HANDLE*                     ChildHandleBuffer\r
+  );\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverComponentNameGetDriverName(\r
+  EFI_COMPONENT_NAME_PROTOCOL*    This,\r
+  CHAR8*                          Language,\r
+  CHAR16**                        DriverName\r
+  );\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverComponentNameGetControllerName(\r
+  EFI_COMPONENT_NAME_PROTOCOL*    This,\r
+  EFI_HANDLE                      ControllerHandle,\r
+  EFI_HANDLE                      ChildHandle,\r
+  CHAR8*                          Language,\r
+  CHAR16**                        ControllerName\r
+  );\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverComponentName2GetDriverName(\r
+  EFI_COMPONENT_NAME2_PROTOCOL*   This,\r
+  CHAR8*                          Language,\r
+  CHAR16**                        DriverName\r
+  );\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+OpalEfiDriverComponentName2GetControllerName(\r
+  EFI_COMPONENT_NAME2_PROTOCOL*   This,\r
+  EFI_HANDLE                      ControllerHandle,\r
+  EFI_HANDLE                      ChildHandle,\r
+  CHAR8*                          Language,\r
+  CHAR16**                        ControllerName\r
+  );\r
+\r
+#endif //_OPAL_DRIVER_H_\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriverPrivate.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalDriverPrivate.h
new file mode 100644 (file)
index 0000000..19ebc32
--- /dev/null
@@ -0,0 +1,102 @@
+/** @file\r
+  Private structures and functions used within OPAL_DRIVER\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _OPAL_DRIVER_PRIVATE_H_\r
+#define _OPAL_DRIVER_PRIVATE_H_\r
+#include "OpalDriver.h"\r
+\r
+#define OPAL_MSID_LENGHT    128\r
+\r
+#pragma pack(1)\r
+//\r
+// Structure that is used to represent an OPAL_DISK.\r
+//\r
+typedef struct {\r
+  UINT32                                          MsidLength;             // Byte length of MSID Pin for device\r
+  UINT8                                           Msid[OPAL_MSID_LENGHT]; // MSID Pin for device\r
+  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL           *Sscp;\r
+  UINT32                                          MediaId;                // MediaId is used by Ssc Protocol.\r
+  EFI_DEVICE_PATH_PROTOCOL                        *OpalDevicePath;\r
+  UINT16                                          OpalBaseComId;          // Opal SSC 1 base com id.\r
+  OPAL_OWNER_SHIP                                 Owner;\r
+  OPAL_DISK_SUPPORT_ATTRIBUTE                     SupportedAttributes;\r
+  TCG_LOCKING_FEATURE_DESCRIPTOR                  LockingFeature;         // Locking Feature Descriptor retrieved from performing a Level 0 Discovery\r
+} OPAL_DISK;\r
+\r
+//\r
+// Device with block IO protocol\r
+//\r
+typedef struct _OPAL_DRIVER_DEVICE OPAL_DRIVER_DEVICE;\r
+\r
+struct _OPAL_DRIVER_DEVICE {\r
+  OPAL_DRIVER_DEVICE                              *Next;              ///< Linked list pointer\r
+  EFI_HANDLE                                      Handle;             ///< Device handle\r
+  OPAL_DISK                                       OpalDisk;           ///< User context\r
+  CHAR16                                          *Name16;            ///< Allocated/freed by UEFI Filter Driver at device creation/removal\r
+  CHAR8                                           *NameZ;             ///< Allocated/freed by UEFI Filter Driver at device creation/removal\r
+  UINT32                                          MediaId;            ///< Required parameter for EFI_STORAGE_SECURITY_COMMAND_PROTOCOL, from BLOCK_IO_MEDIA\r
+\r
+  EFI_STORAGE_SECURITY_COMMAND_PROTOCOL           *Sscp;              /// Device protocols consumed\r
+  EFI_DEVICE_PATH_PROTOCOL                        *OpalDevicePath;\r
+};\r
+\r
+//\r
+// Opal Driver UEFI Driver Model\r
+//\r
+typedef struct {\r
+  EFI_HANDLE           Handle;              ///< Driver image handle\r
+  OPAL_DRIVER_DEVICE   *DeviceList;         ///< Linked list of controllers owned by this Driver\r
+} OPAL_DRIVER;\r
+#pragma pack()\r
+\r
+//\r
+// Retrieves a OPAL_DRIVER_DEVICE based on the pointer to its StorageSecurity protocol.\r
+//\r
+#define DRIVER_DEVICE_FROM_OPALDISK(OpalDiskPointer) (OPAL_DRIVER_DEVICE*)(BASE_CR(OpalDiskPointer, OPAL_DRIVER_DEVICE, OpalDisk))\r
+\r
+/**\r
+  Get devcie list info.\r
+\r
+  @retval     return the device list pointer.\r
+**/\r
+OPAL_DRIVER_DEVICE*\r
+OpalDriverGetDeviceList(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get devcie name through the component name protocol.\r
+\r
+  @param[in]       Dev                The device which need to get name.\r
+\r
+  @retval     TRUE        Find the name for this device.\r
+  @retval     FALSE       Not found the name for this device.\r
+**/\r
+BOOLEAN\r
+OpalDriverGetDriverDeviceName(\r
+  OPAL_DRIVER_DEVICE          *Dev\r
+  );\r
+\r
+/**\r
+  Get current device count.\r
+\r
+  @retval  return the current created device count.\r
+\r
+**/\r
+UINT8\r
+GetDeviceCount (\r
+  VOID\r
+  );\r
+\r
+#endif // _OPAL_DRIVER_P_H_\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.c
new file mode 100644 (file)
index 0000000..250cb43
--- /dev/null
@@ -0,0 +1,1424 @@
+/** @file\r
+  Implementation of the HII for the Opal UEFI Driver.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "OpalHii.h"\r
+#include "OpalDriver.h"\r
+#include "OpalHiiPrivate.h"\r
+\r
+//\r
+// This is the generated IFR binary Data for each formset defined in VFR.\r
+// This Data array is ready to be used as input of HiiAddPackages() to\r
+// create a packagelist (which contains Form packages, String packages, etc).\r
+//\r
+extern UINT8  OpalPasswordFormBin[];\r
+\r
+//\r
+// This is the generated String package Data for all .UNI files.\r
+// This Data array is ready to be used as input of HiiAddPackages() to\r
+// create a packagelist (which contains Form packages, String packages, etc).\r
+//\r
+extern UINT8  OpalPasswordDxeStrings[];\r
+\r
+EFI_HII_CONFIG_ACCESS_PROTOCOL gHiiConfigAccessProtocol;\r
+\r
+//\r
+// Handle to the list of HII packages (forms and strings) for this driver\r
+//\r
+EFI_HII_HANDLE gHiiPackageListHandle = NULL;\r
+\r
+//\r
+// Package List GUID containing all form and string packages\r
+//\r
+const EFI_GUID gHiiPackageListGuid = PACKAGE_LIST_GUID;\r
+const EFI_GUID gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;\r
+\r
+//\r
+// Structure that contains state of the HII\r
+// This structure is updated by Hii.cpp and its contents\r
+// is rendered in the HII.\r
+//\r
+OPAL_HII_CONFIGURATION gHiiConfiguration;\r
+\r
+CHAR8 gHiiOldPassword[MAX_PASSWORD_CHARACTER_LENGTH] = {0};\r
+UINT32 gHiiOldPasswordLength = 0;\r
+\r
+//\r
+// The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL\r
+//\r
+HII_VENDOR_DEVICE_PATH gHiiVendorDevicePath = {\r
+    {\r
+        {\r
+            HARDWARE_DEVICE_PATH,\r
+            HW_VENDOR_DP,\r
+            {\r
+                (UINT8)(sizeof(VENDOR_DEVICE_PATH)),\r
+                (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8)\r
+            }\r
+        },\r
+        OPAL_PASSWORD_CONFIG_GUID\r
+    },\r
+    {\r
+        END_DEVICE_PATH_TYPE,\r
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+        {\r
+            (UINT8)(END_DEVICE_PATH_LENGTH),\r
+            (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)\r
+        }\r
+    }\r
+};\r
+\r
+\r
+/**\r
+  Sets the current system state of global config variables.\r
+\r
+**/\r
+VOID\r
+HiiSetCurrentConfiguration(\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  OPAL_EXTRA_INFO_VAR                   OpalExtraInfo;\r
+  UINTN                                 DataSize;\r
+\r
+  gHiiConfiguration.NumDisks = GetDeviceCount();\r
+\r
+  DataSize = sizeof (OPAL_EXTRA_INFO_VAR);\r
+  Status = gRT->GetVariable (\r
+                  OPAL_EXTRA_INFO_VAR_NAME,\r
+                  &gOpalExtraInfoVariableGuid,\r
+                  NULL,\r
+                  &DataSize,\r
+                  &OpalExtraInfo\r
+                  );\r
+  DEBUG ((DEBUG_INFO, "GetVariable for OpalExtraInfo @ HiiSetCurrentConfiguration, Status: %r\n", Status));\r
+  if (!EFI_ERROR (Status)) {\r
+    gHiiConfiguration.EnableBlockSid = OpalExtraInfo.EnableBlockSid;\r
+  }\r
+}\r
+\r
+/**\r
+  Check that all required protocols for HII are available.\r
+\r
+  @retval  EFI_SUCCESS        All required protocols are installed.\r
+  @retval  EFI_NOT_FOUND      One or more protocol are not installed.\r
+**/\r
+EFI_STATUS\r
+HiiCheckForRequiredProtocols (\r
+  VOID\r
+  )\r
+{\r
+  VOID*       TempProtocol;\r
+  EFI_STATUS  Status;\r
+\r
+  Status = gBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, (VOID**)&TempProtocol );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, (VOID**)&TempProtocol );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID**)&TempProtocol );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, (VOID**)&TempProtocol );\r
+  if (EFI_ERROR (Status)) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Install the HII related resources.\r
+\r
+  @retval  EFI_SUCCESS        Install all the resources success.\r
+  @retval  other              Error occur when install the resources.\r
+**/\r
+EFI_STATUS\r
+HiiInstall(\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+  EFI_HANDLE                   DriverHandle;\r
+\r
+  //\r
+  // Check that all required protocols are available for HII.\r
+  // If not, fail the install\r
+  //\r
+  Status = HiiCheckForRequiredProtocols();\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Clear the global configuration.\r
+  //\r
+  ZeroMem(&gHiiConfiguration, sizeof(gHiiConfiguration));\r
+\r
+  //\r
+  // Obtain the driver handle that the BIOS assigned us\r
+  //\r
+  DriverHandle = HiiGetDriverImageHandleCB();\r
+\r
+  //\r
+  // Populate the config access protocol with the three functions we are publishing\r
+  //\r
+  gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;\r
+  gHiiConfigAccessProtocol.RouteConfig = RouteConfig;\r
+  gHiiConfigAccessProtocol.Callback = DriverCallback;\r
+\r
+  //\r
+  // Associate the required protocols with our driver handle\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces(\r
+               &DriverHandle,\r
+               &gEfiHiiConfigAccessProtocolGuid,\r
+               &gHiiConfigAccessProtocol,      // HII callback\r
+               &gEfiDevicePathProtocolGuid,\r
+               &gHiiVendorDevicePath,        // required for HII callback allow all disks to be shown in same hii\r
+               NULL\r
+           );\r
+\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  return OpalHiiAddPackages();\r
+}\r
+\r
+/**\r
+  Install the HII form and string packages.\r
+\r
+  @retval  EFI_SUCCESS           Install all the resources success.\r
+  @retval  EFI_OUT_OF_RESOURCES  Out of resource error.\r
+**/\r
+EFI_STATUS\r
+OpalHiiAddPackages(\r
+  VOID\r
+  )\r
+{\r
+  EFI_HANDLE                   DriverHandle;\r
+  CHAR16                       *NewString;\r
+\r
+  DriverHandle = HiiGetDriverImageHandleCB();\r
+\r
+  //\r
+  // Publish the HII form and HII string packages\r
+  //\r
+  gHiiPackageListHandle = HiiAddPackages(\r
+                                &gHiiPackageListGuid,\r
+                                DriverHandle,\r
+                                OpalPasswordDxeStrings,\r
+                                OpalPasswordFormBin,\r
+                                (VOID*)NULL\r
+                                );\r
+\r
+  //\r
+  // Make sure the packages installed successfully\r
+  //\r
+  if (gHiiPackageListHandle == NULL) {\r
+    DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Update Version String in main window\r
+  //\r
+  NewString = HiiGetDriverNameCB ();\r
+  if (HiiSetString(gHiiPackageListHandle, STRING_TOKEN(STR_MAIN_OPAL_VERSION), NewString, NULL) == 0) {\r
+    DEBUG ((DEBUG_INFO,  "OpalHiiAddPackages: HiiSetString( ) failed\n"));\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Uninstall the HII capability.\r
+\r
+  @retval  EFI_SUCCESS           Uninstall all the resources success.\r
+  @retval  others                Other errors occur when unistall the hii resource.\r
+**/\r
+EFI_STATUS\r
+HiiUninstall(\r
+  VOID\r
+  )\r
+{\r
+  EFI_STATUS                   Status;\r
+\r
+  //\r
+  // Remove the packages we've provided to the BIOS\r
+  //\r
+  HiiRemovePackages(gHiiPackageListHandle);\r
+\r
+  //\r
+  // Remove the protocols from our driver handle\r
+  //\r
+  Status = gBS->UninstallMultipleProtocolInterfaces(\r
+                          HiiGetDriverImageHandleCB(),\r
+                          &gEfiHiiConfigAccessProtocolGuid,\r
+                          &gHiiConfigAccessProtocol,        // HII callback\r
+                          &gEfiDevicePathProtocolGuid,\r
+                          &gHiiVendorDevicePath,            // required for HII callback\r
+                          NULL\r
+                      );\r
+  if (EFI_ERROR(Status)) {\r
+    DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Updates the main menu form.\r
+\r
+  @retval  EFI_SUCCESS           update the main form success.\r
+**/\r
+EFI_STATUS\r
+HiiPopulateMainMenuForm (\r
+  VOID\r
+  )\r
+{\r
+  UINT8         Index;\r
+  CHAR8         *DiskName;\r
+  EFI_STRING_ID DiskNameId;\r
+  OPAL_DISK     *OpalDisk;\r
+\r
+  HiiSetCurrentConfiguration();\r
+\r
+  gHiiConfiguration.SupportedDisks = 0;\r
+\r
+  for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {\r
+    OpalDisk = HiiGetOpalDiskCB (Index);\r
+    if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {\r
+      gHiiConfiguration.SupportedDisks |= (1 << Index);\r
+      DiskNameId = GetDiskNameStringId (Index);\r
+      DiskName = HiiDiskGetNameCB (Index);\r
+      if ((DiskName == NULL) || (DiskNameId == 0)) {\r
+        return EFI_UNSUPPORTED;\r
+      }\r
+      HiiSetFormString(DiskNameId, DiskName);\r
+    }\r
+  }\r
+\r
+  OpalHiiSetBrowserData ();\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Update the disk action info.\r
+\r
+  @param     ActionString\r
+  @param     SelectedAction\r
+\r
+  @retval  EFI_SUCCESS           Uninstall all the resources success.\r
+**/\r
+EFI_STATUS\r
+HiiSelectDiskAction (\r
+  CHAR8           *ActionString,\r
+  UINT8           SelectedAction\r
+  )\r
+{\r
+  OPAL_DISK                     *OpalDisk;\r
+  OPAL_DISK_ACTIONS              AvailActions;\r
+\r
+  OpalHiiGetBrowserData ();\r
+\r
+  HiiSetFormString(STRING_TOKEN(STR_DISK_ACTION_LBL), ActionString);\r
+  HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), " ");\r
+\r
+  gHiiConfiguration.SelectedAction = SelectedAction;\r
+  gHiiConfiguration.AvailableFields = 0;\r
+\r
+  OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);\r
+  if (OpalDisk == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  if (OpalSupportGetAvailableActions (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions) != TcgResultSuccess) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  switch (SelectedAction) {\r
+    case HII_KEY_ID_GOTO_LOCK:\r
+    case HII_KEY_ID_GOTO_UNLOCK:\r
+    case HII_KEY_ID_GOTO_SET_ADMIN_PWD:\r
+    case HII_KEY_ID_GOTO_SET_USER_PWD:\r
+    case HII_KEY_ID_GOTO_SECURE_ERASE:\r
+    case HII_KEY_ID_GOTO_DISABLE_USER:\r
+    case HII_KEY_ID_GOTO_ENABLE_FEATURE:   // User is required to enter Password to enable Feature\r
+      gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;\r
+      break;\r
+\r
+    case HII_KEY_ID_GOTO_PSID_REVERT:\r
+      gHiiConfiguration.AvailableFields |= HII_FIELD_PSID;\r
+      break;\r
+\r
+    case HII_KEY_ID_GOTO_REVERT:\r
+      gHiiConfiguration.AvailableFields |= HII_FIELD_PASSWORD;\r
+      gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA;\r
+      if (AvailActions.RevertKeepDataForced) {\r
+        gHiiConfiguration.AvailableFields |= HII_FIELD_KEEP_USER_DATA_FORCED;\r
+      }\r
+      break;\r
+  }\r
+\r
+  OpalHiiSetBrowserData ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Get disk name string id.\r
+\r
+  @param   DiskIndex             The input disk index info.\r
+\r
+  @retval  The disk name string id.\r
+\r
+**/\r
+EFI_STRING_ID\r
+GetDiskNameStringId(\r
+  UINT8 DiskIndex\r
+  )\r
+{\r
+  switch (DiskIndex) {\r
+    case 0: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0);\r
+    case 1: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1);\r
+    case 2: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2);\r
+    case 3: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3);\r
+    case 4: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4);\r
+    case 5: return STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5);\r
+  }\r
+  return 0;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Action                 Specifies the type of action taken by the browser.\r
+  @param  QuestionId             A unique value which is sent to the original\r
+                                 exporting driver so that it can identify the type\r
+                                 of data to expect.\r
+  @param  Type                   The type of value for the question.\r
+  @param  Value                  A pointer to the data being sent to the original\r
+                                 exporting driver.\r
+  @param  ActionRequest          On return, points to the action requested by the\r
+                                 callback function.\r
+\r
+  @retval EFI_SUCCESS            The callback successfully handled the action.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the\r
+                                 variable and its data.\r
+  @retval EFI_DEVICE_ERROR       The variable could not be saved.\r
+  @retval EFI_UNSUPPORTED        The specified Action is not supported by the\r
+                                 callback.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverCallback(\r
+  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL*   This,\r
+  EFI_BROWSER_ACTION                      Action,\r
+  EFI_QUESTION_ID                         QuestionId,\r
+  UINT8                                   Type,\r
+  EFI_IFR_TYPE_VALUE*                     Value,\r
+  EFI_BROWSER_ACTION_REQUEST*             ActionRequest\r
+  )\r
+{\r
+  HII_KEY    HiiKey;\r
+  UINT8      HiiKeyId;\r
+\r
+  if (ActionRequest != NULL) {\r
+    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+  }\r
+\r
+  //\r
+  // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.\r
+  //\r
+  if ((QuestionId & HII_KEY_FLAG) == 0) {\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  HiiKey.Raw = QuestionId;\r
+  HiiKeyId   = (UINT8) HiiKey.KeyBits.Id;\r
+\r
+  if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
+    switch (HiiKeyId) {\r
+      case HII_KEY_ID_VAR_SUPPORTED_DISKS:\r
+        DEBUG ((DEBUG_INFO,  "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));\r
+        return HiiPopulateMainMenuForm ();\r
+\r
+      case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:\r
+        return HiiPopulateDiskInfoForm();\r
+    }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+    switch (HiiKeyId) {\r
+      case HII_KEY_ID_GOTO_DISK_INFO:\r
+        return HiiSelectDisk((UINT8)HiiKey.KeyBits.Index);\r
+\r
+      case HII_KEY_ID_GOTO_LOCK:\r
+        return HiiSelectDiskAction("Action: Lock", HiiKeyId);\r
+\r
+      case HII_KEY_ID_GOTO_UNLOCK:\r
+        return HiiSelectDiskAction("Action: Unlock", HiiKeyId);\r
+\r
+      case HII_KEY_ID_GOTO_SET_ADMIN_PWD:\r
+        return HiiSelectDiskAction("Action: Set Administrator Password", HiiKeyId);\r
+\r
+      case HII_KEY_ID_GOTO_SET_USER_PWD:\r
+        return HiiSelectDiskAction("Action: Set User Password", HiiKeyId);\r
+\r
+      case HII_KEY_ID_GOTO_SECURE_ERASE:\r
+        return HiiSelectDiskAction("Action: Secure Erase", HiiKeyId);\r
+\r
+      case HII_KEY_ID_GOTO_PSID_REVERT:\r
+        return HiiSelectDiskAction("Action: Revert to Factory Defaults with PSID", HiiKeyId);\r
+\r
+      case HII_KEY_ID_GOTO_REVERT:\r
+        return HiiSelectDiskAction("Action: Revert to Factory Defaults", HiiKeyId);\r
+\r
+      case HII_KEY_ID_GOTO_DISABLE_USER:\r
+        return HiiSelectDiskAction("Action: Disable User", HiiKeyId);\r
+\r
+      case HII_KEY_ID_GOTO_ENABLE_FEATURE:\r
+        return HiiSelectDiskAction("Action: Enable Feature", HiiKeyId);\r
+\r
+      case HII_KEY_ID_ENTER_PASSWORD:\r
+        return HiiPasswordEntered(Value->string);\r
+\r
+      case HII_KEY_ID_BLOCKSID:\r
+        return HiiSetBlockSid(Value->b);\r
+    }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+    switch (HiiKeyId) {\r
+      case HII_KEY_ID_ENTER_PSID:\r
+        HiiPsidRevert();\r
+        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
+        return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
+/**\r
+  Update the global Disk index info.\r
+\r
+  @param   Index             The input disk index info.\r
+\r
+  @retval  EFI_SUCCESS       Update the disk index info success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiSelectDisk(\r
+  UINT8 Index\r
+  )\r
+{\r
+  OpalHiiGetBrowserData();\r
+  gHiiConfiguration.SelectedDiskIndex = Index;\r
+  OpalHiiSetBrowserData ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Draws the disk info form.\r
+\r
+  @retval  EFI_SUCCESS       Draw the disk info success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiPopulateDiskInfoForm(\r
+  VOID\r
+  )\r
+{\r
+  OPAL_DISK*                    OpalDisk;\r
+  OPAL_DISK_ACTIONS             AvailActions;\r
+  TCG_RESULT                    Ret;\r
+  CHAR8                         *DiskName;\r
+\r
+  OpalHiiGetBrowserData();\r
+\r
+  DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);\r
+  if (DiskName == NULL) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  HiiSetFormString(STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);\r
+\r
+  ZeroMem(gHiiConfiguration.Psid, sizeof(gHiiConfiguration.Psid));\r
+\r
+  gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;\r
+\r
+  OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);\r
+\r
+  if (OpalDisk != NULL) {\r
+    OpalDiskUpdateStatus (OpalDisk);\r
+    Ret = OpalSupportGetAvailableActions(&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);\r
+    if (Ret == TcgResultSuccess) {\r
+      //\r
+      // Update actions, always allow PSID Revert\r
+      //\r
+      gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;\r
+\r
+      //\r
+      // Always allow unlock to handle device migration\r
+      //\r
+      gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;\r
+\r
+      if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {\r
+        if (OpalDisk->Owner == OpalOwnershipNobody) {\r
+          gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;\r
+\r
+          //\r
+          // Update strings\r
+          //\r
+          HiiSetFormString( STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");\r
+        } else {\r
+          DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));\r
+        }\r
+      } else {\r
+        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;\r
+        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;\r
+        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;\r
+        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;\r
+        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;\r
+        gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_BLOCKSID;\r
+\r
+        HiiSetFormString (STRING_TOKEN(STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");\r
+\r
+        //\r
+        // Determine revert options for disk\r
+        // Default initialize keep user Data to be true\r
+        //\r
+        gHiiConfiguration.KeepUserData = 1;\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Pass the current configuration to the BIOS\r
+  //\r
+  OpalHiiSetBrowserData ();\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Reverts the Opal disk to factory default.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiPsidRevert(\r
+  VOID\r
+  )\r
+{\r
+  CHAR8                         Response[DEFAULT_RESPONSE_SIZE];\r
+  TCG_PSID                      Psid;\r
+  OPAL_DISK                     *OpalDisk;\r
+  TCG_RESULT                    Ret;\r
+  OPAL_SESSION                  Session;\r
+\r
+  Ret = TcgResultFailure;\r
+\r
+  OpalHiiGetBrowserData();\r
+\r
+  UnicodeStrToAsciiStr(gHiiConfiguration.Psid, (CHAR8*)Psid.Psid);\r
+\r
+  OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);\r
+\r
+  ZeroMem(&Session, sizeof(Session));\r
+  Session.Sscp = OpalDisk->Sscp;\r
+  Session.MediaId = OpalDisk->MediaId;\r
+  Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
+\r
+  if (OpalDisk != NULL) {\r
+    Ret = OpalSupportPsidRevert(&Session, Psid.Psid, (UINT32)sizeof(Psid.Psid), OpalDisk->OpalDevicePath);\r
+  }\r
+\r
+  if (Ret == TcgResultSuccess) {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Success" );\r
+  } else {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "PSID Revert: Failure" );\r
+  }\r
+\r
+  HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Set password for the disk.\r
+\r
+  @param      OpalDisk       The disk need to set the password.\r
+  @param      Password       The input password.\r
+  @param      PassLength     The input password length.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiSetPassword(\r
+  OPAL_DISK          *OpalDisk,\r
+  VOID               *Password,\r
+  UINT32             PassLength\r
+  )\r
+{\r
+  CHAR8                         Response[DEFAULT_RESPONSE_SIZE];\r
+  TCG_RESULT                    Ret;\r
+  BOOLEAN                       ExistingPassword;\r
+  OPAL_SESSION                  Session;\r
+\r
+  ExistingPassword = FALSE;\r
+\r
+  //\r
+  // PassLength = 0 means check whether exist old password.\r
+  //\r
+  if (PassLength == 0) {\r
+    ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));\r
+    gHiiOldPasswordLength = 0;\r
+\r
+    if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_ENABLE_FEATURE) {\r
+      ExistingPassword = FALSE;\r
+    } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_ADMIN_PWD) {\r
+      ExistingPassword = OpalUtilAdminPasswordExists(OpalDisk->Owner, &OpalDisk->LockingFeature);\r
+    } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {\r
+      //\r
+      // Set user Password option shall only be shown if an Admin Password exists\r
+      // so a Password is always required (Admin or Existing User Password)\r
+      //\r
+      ExistingPassword = TRUE;\r
+    }\r
+\r
+    //\r
+    // Return error if there is a previous Password\r
+    // see UEFI 2.4 errata B, Figure 121. Password Flowchart\r
+    //\r
+    return ExistingPassword ? EFI_DEVICE_ERROR : EFI_SUCCESS;\r
+  }\r
+\r
+  ZeroMem(&Session, sizeof(Session));\r
+  Session.Sscp = OpalDisk->Sscp;\r
+  Session.MediaId = OpalDisk->MediaId;\r
+  Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
+\r
+  AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Failure");\r
+  //\r
+  // Password entered.\r
+  // No current Owner, so set new Password, must be admin Password\r
+  //\r
+  if (OpalDisk->Owner == OpalOwnershipNobody) {\r
+    Ret = OpalSupportEnableOpalFeature (&Session, OpalDisk->Msid, OpalDisk->MsidLength,Password, PassLength, OpalDisk->OpalDevicePath);\r
+    if (Ret == TcgResultSuccess) {\r
+      AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");\r
+    }\r
+\r
+    HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // 1st Password entered\r
+  //\r
+  if (OpalDisk->Owner == OpalOwnershipUnknown && gHiiOldPasswordLength == 0) {\r
+\r
+    //\r
+    // Unknown ownership - prompt for old Password, then new\r
+    // old Password is not set yet - first time through\r
+    // assume authority provided is admin1, overwritten if user1 authority works below\r
+    //\r
+    if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {\r
+      //\r
+      // First try to login as USER1 to Locking SP to see if we're simply updating its Password\r
+      //\r
+      Ret =  OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_USER1_AUTHORITY);\r
+      if (Ret == TcgResultSuccess) {\r
+        //\r
+        // User1 worked so authority 1 means user 1\r
+        //\r
+        CopyMem(gHiiOldPassword, Password, PassLength);\r
+        gHiiOldPasswordLength = PassLength;\r
+\r
+        return EFI_SUCCESS;\r
+      }\r
+    }\r
+\r
+    //\r
+    // Else try admin1 below\r
+    //\r
+    Ret =  OpalUtilVerifyPassword (&Session, Password, PassLength, OPAL_LOCKING_SP_ADMIN1_AUTHORITY);\r
+    if (Ret == TcgResultSuccess) {\r
+      CopyMem(gHiiOldPassword, Password, PassLength);\r
+      gHiiOldPasswordLength = PassLength;\r
+\r
+      return EFI_SUCCESS;\r
+    } else {\r
+      DEBUG ((DEBUG_INFO, "start session with old PW failed - return EFI_NOT_READY - mistyped old PW\n"));\r
+      HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Authentication Failure");\r
+\r
+      ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));\r
+      gHiiOldPasswordLength = 0;\r
+\r
+      return EFI_NOT_READY;\r
+    }\r
+  }\r
+\r
+  //\r
+  // New Password entered\r
+  //\r
+  if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SET_USER_PWD) {\r
+    Ret = OpalSupportSetPassword(\r
+                            &Session,\r
+                            gHiiOldPassword,\r
+                            gHiiOldPasswordLength,\r
+                            Password,\r
+                            PassLength,\r
+                            OpalDisk->OpalDevicePath,\r
+                            FALSE\r
+                            );\r
+  } else {\r
+    Ret = OpalSupportSetPassword(\r
+                            &Session,\r
+                            gHiiOldPassword,\r
+                            gHiiOldPasswordLength,\r
+                            Password,\r
+                            PassLength,\r
+                            OpalDisk->OpalDevicePath,\r
+                            TRUE\r
+                            );\r
+  }\r
+\r
+  if (Ret == TcgResultSuccess) {\r
+    AsciiSPrint(Response, DEFAULT_RESPONSE_SIZE, "%a", "Set Password: Success");\r
+  }\r
+\r
+  //\r
+  // Reset old Password storage\r
+  //\r
+  ZeroMem(gHiiOldPassword, sizeof(gHiiOldPassword));\r
+  gHiiOldPasswordLength = 0;\r
+\r
+  HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
+  return Ret == TcgResultSuccess ? EFI_SUCCESS : EFI_NOT_READY;\r
+}\r
+\r
+/**\r
+  Secure Erases Opal Disk.\r
+\r
+  @param      OpalDisk       The disk need to erase data.\r
+  @param      Password       The input password.\r
+  @param      PassLength     The input password length.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiSecureErase(\r
+  OPAL_DISK       *OpalDisk,\r
+  const VOID      *Password,\r
+  UINT32          PassLength\r
+  )\r
+{\r
+  CHAR8                        Response[DEFAULT_RESPONSE_SIZE];\r
+  BOOLEAN                      PasswordFailed;\r
+  TCG_RESULT                   Ret;\r
+  OPAL_SESSION                 AdminSpSession;\r
+\r
+  if (PassLength == 0) {\r
+    return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password\r
+  }\r
+\r
+  ZeroMem(&AdminSpSession, sizeof(AdminSpSession));\r
+  AdminSpSession.Sscp = OpalDisk->Sscp;\r
+  AdminSpSession.MediaId = OpalDisk->MediaId;\r
+  AdminSpSession.OpalBaseComId = OpalDisk->OpalBaseComId;\r
+\r
+  Ret = OpalUtilSecureErase(&AdminSpSession, Password, PassLength, &PasswordFailed);\r
+  if (Ret == TcgResultSuccess) {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Success" );\r
+  } else {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Secure Erase: Failure" );\r
+  }\r
+  HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
+\r
+  //\r
+  // If Password failed, return invalid passowrd\r
+  //\r
+  if (PasswordFailed) {\r
+    DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  //\r
+  // Indicates Password was valid and is not changing to UEFI\r
+  // Response string will indicate action error\r
+  //\r
+  return EFI_DEVICE_ERROR;\r
+}\r
+\r
+\r
+/**\r
+  Disables User for Opal Disk.\r
+\r
+  @param      OpalDisk       The disk need to the action.\r
+  @param      Password       The input password.\r
+  @param      PassLength     The input password length.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiDisableUser(\r
+  OPAL_DISK      *OpalDisk,\r
+  VOID           *Password,\r
+  UINT32         PassLength\r
+  )\r
+{\r
+  CHAR8                        Response[ DEFAULT_RESPONSE_SIZE ];\r
+  BOOLEAN                      PasswordFailed;\r
+  TCG_RESULT                   Ret;\r
+  OPAL_SESSION                 Session;\r
+\r
+  if (PassLength == 0) {\r
+    return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password\r
+  }\r
+\r
+  ZeroMem(&Session, sizeof(Session));\r
+  Session.Sscp = OpalDisk->Sscp;\r
+  Session.MediaId = OpalDisk->MediaId;\r
+  Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
+\r
+  Ret = OpalSupportDisableUser(&Session, Password, PassLength, &PasswordFailed, OpalDisk->OpalDevicePath);\r
+  if (Ret == TcgResultSuccess) {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Success" );\r
+  } else {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Disable User: Failure" );\r
+  }\r
+  HiiSetFormString (STRING_TOKEN(STR_ACTION_STATUS), Response);\r
+\r
+  //\r
+  // If Password failed, return invalid passowrd\r
+  //\r
+  if (PasswordFailed) {\r
+    DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  //\r
+  // Indicates Password was valid and is not changing to UEFI\r
+  // Response string will indicate action error\r
+  //\r
+  return EFI_DEVICE_ERROR;\r
+}\r
+\r
+/**\r
+  Revert Opal Disk as Admin1.\r
+\r
+  @param      OpalDisk       The disk need to the action.\r
+  @param      Password       The input password.\r
+  @param      PassLength     The input password length.\r
+  @param      KeepUserData   Whether need to keey user data.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiRevert(\r
+  OPAL_DISK       *OpalDisk,\r
+  VOID            *Password,\r
+  UINT32          PassLength,\r
+  BOOLEAN         KeepUserData\r
+  )\r
+{\r
+  CHAR8                         Response[ DEFAULT_RESPONSE_SIZE ];\r
+  BOOLEAN                      PasswordFailed;\r
+  TCG_RESULT                    Ret;\r
+  OPAL_SESSION                  Session;\r
+\r
+  if (PassLength == 0) {\r
+    DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));\r
+    // return error to indicate there is an existing Password\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  ZeroMem(&Session, sizeof(Session));\r
+  Session.Sscp = OpalDisk->Sscp;\r
+  Session.MediaId = OpalDisk->MediaId;\r
+  Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
+\r
+  Ret = OpalSupportRevert(\r
+                      &Session,\r
+                      KeepUserData,\r
+                      Password,\r
+                      PassLength,\r
+                      OpalDisk->Msid,\r
+                      OpalDisk->MsidLength,\r
+                      &PasswordFailed,\r
+                      OpalDisk->OpalDevicePath\r
+                      );\r
+  if (Ret == TcgResultSuccess) {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Success" );\r
+  } else {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Revert: Failure" );\r
+  }\r
+  HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
+\r
+  //\r
+  // If Password failed, return invalid passowrd\r
+  //\r
+  if (PasswordFailed) {\r
+    DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));\r
+    return EFI_NOT_READY;\r
+  }\r
+\r
+  //\r
+  // Indicates Password was valid and is not changing to UEFI\r
+  // Response string will indicate action error\r
+  //\r
+  return EFI_DEVICE_ERROR;\r
+}\r
+\r
+/**\r
+  Unlocks Opal Disk.\r
+\r
+  @param      OpalDisk       The disk need to the action.\r
+  @param      Password       The input password.\r
+  @param      PassLength     The input password length.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiUnlock(\r
+  OPAL_DISK         *OpalDisk,\r
+  VOID              *Password,\r
+  UINT32            PassLength\r
+  )\r
+{\r
+  CHAR8                         Response[DEFAULT_RESPONSE_SIZE];\r
+  TCG_RESULT                    Ret;\r
+  OPAL_SESSION                  Session;\r
+\r
+  if (PassLength == 0) {\r
+    DEBUG ((DEBUG_INFO, "Returning error to indicate there is an existing Password\n"));\r
+    return EFI_DEVICE_ERROR; // return error to indicate there is an existing Password\r
+  }\r
+\r
+  ZeroMem(&Session, sizeof(Session));\r
+  Session.Sscp = OpalDisk->Sscp;\r
+  Session.MediaId = OpalDisk->MediaId;\r
+  Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
+\r
+  Ret = OpalSupportUnlock(&Session, Password, PassLength, OpalDisk->OpalDevicePath);\r
+  if (Ret == TcgResultSuccess) {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Success" );\r
+  } else {\r
+    AsciiSPrint( Response, DEFAULT_RESPONSE_SIZE, "%a", "Unlock: Failure" );\r
+  }\r
+\r
+  HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), Response);\r
+\r
+  if (Ret == TcgResultSuccess) {\r
+    DEBUG ((DEBUG_INFO, "returning error to indicate Password was correct but is not changing\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  } else {\r
+    DEBUG ((DEBUG_INFO, "returning EFI_NOT_READY to indicate Password was not correct\n"));\r
+    return EFI_NOT_READY;\r
+  }\r
+}\r
+\r
+/**\r
+  Use the input password to do the specified action.\r
+\r
+  @param      Str            The input password saved in.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+  @retval  Others            Other error occur.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiPasswordEntered(\r
+  EFI_STRING_ID            Str\r
+  )\r
+{\r
+  OPAL_DISK*                    OpalDisk;\r
+  CHAR8                         Password[MAX_PASSWORD_CHARACTER_LENGTH + 1];\r
+  CHAR16*                      UniStr;\r
+  UINT32                       PassLength;\r
+  EFI_STATUS                   Status;\r
+\r
+  OpalHiiGetBrowserData();\r
+\r
+  OpalDisk = HiiGetOpalDiskCB(gHiiConfiguration.SelectedDiskIndex);\r
+  if (OpalDisk == NULL) {\r
+    DEBUG ((DEBUG_INFO, "ERROR: disk %u not found\n", gHiiConfiguration.SelectedDiskIndex));\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  if (Str == 0) {\r
+    DEBUG ((DEBUG_INFO, "ERROR: str=NULL\n"));\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  ZeroMem(Password, sizeof(Password));\r
+\r
+  UniStr = HiiGetString(gHiiPackageListHandle, Str, NULL);\r
+  if (UniStr == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  PassLength = (UINT32) StrLen (UniStr);\r
+  if (PassLength >= sizeof(Password)) {\r
+    HiiSetFormString(STRING_TOKEN(STR_ACTION_STATUS), "Password too long");\r
+    gBS->FreePool(UniStr);\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  UnicodeStrToAsciiStr(UniStr, Password);\r
+  gBS->FreePool(UniStr);\r
+\r
+  DEBUG ((DEBUG_INFO, "Password: '%s'\n", Password));\r
+\r
+  if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_UNLOCK) {\r
+    Status = HiiUnlock (OpalDisk, Password, PassLength);\r
+  } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_SECURE_ERASE) {\r
+    Status = HiiSecureErase (OpalDisk, Password, PassLength);\r
+  } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_DISABLE_USER) {\r
+    Status = HiiDisableUser (OpalDisk, Password, PassLength);\r
+  } else if (gHiiConfiguration.SelectedAction == HII_KEY_ID_GOTO_REVERT) {\r
+    DEBUG ((DEBUG_INFO, "gHiiConfiguration.KeepUserData %u\n", gHiiConfiguration.KeepUserData));\r
+    Status = HiiRevert(OpalDisk, Password, PassLength, gHiiConfiguration.KeepUserData);\r
+  } else {\r
+    Status = HiiSetPassword(OpalDisk, Password, PassLength);\r
+  }\r
+\r
+  OpalHiiSetBrowserData ();\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Update block sid info.\r
+\r
+  @param      Enable         Enable/disable BlockSid.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+  @retval  Others            Other error occur.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiSetBlockSid (\r
+  BOOLEAN          Enable\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  OPAL_EXTRA_INFO_VAR                   OpalExtraInfo;\r
+  UINTN                                 DataSize;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+  DEBUG ((DEBUG_INFO, "HiiSetBlockSid(enable: %x)\n", Enable));\r
+\r
+  OpalExtraInfo.EnableBlockSid = Enable;\r
+  DataSize = sizeof (OPAL_EXTRA_INFO_VAR);\r
+  Status = gRT->SetVariable (\r
+                 OPAL_EXTRA_INFO_VAR_NAME,\r
+                 &gOpalExtraInfoVariableGuid,\r
+                 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
+                 DataSize,\r
+                 &OpalExtraInfo\r
+                 );\r
+  DEBUG ((DEBUG_INFO, "SetVariable, Status: %r\n", Status));\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>\r
+                                 format.\r
+  @param  Progress               A pointer to a string filled in with the offset of\r
+                                 the most recent '&' before the first failing\r
+                                 name/value pair (or the beginning of the string if\r
+                                 the failure is in the first name/value pair) or\r
+                                 the terminating NULL if all was successful.\r
+\r
+  @retval EFI_SUCCESS            The Results is processed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RouteConfig(\r
+  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL    *This,\r
+  CONST EFI_STRING                        Configuration,\r
+  EFI_STRING                              *Progress\r
+  )\r
+{\r
+  DEBUG ((DEBUG_INFO,  "RouteConfig( )\n"));\r
+  if (Configuration == NULL || Progress == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Request                A null-terminated Unicode string in\r
+                                 <ConfigRequest> format.\r
+  @param  Progress               On return, points to a character in the Request\r
+                                 string. Points to the string's null terminator if\r
+                                 request was successful. Points to the most recent\r
+                                 '&' before the first failing name/value pair (or\r
+                                 the beginning of the string if the failure is in\r
+                                 the first name/value pair) if the request was not\r
+                                 successful.\r
+  @param  Results                A null-terminated Unicode string in\r
+                                 <ConfigAltResp> format which has all values filled\r
+                                 in for the names in the Request string. String to\r
+                                 be allocated by the called function.\r
+\r
+  @retval EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ExtractConfig(\r
+  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL    *This,\r
+  CONST EFI_STRING                        Request,\r
+  EFI_STRING                              *Progress,\r
+  EFI_STRING                              *Results\r
+  )\r
+{\r
+  EFI_STATUS                              Status;\r
+\r
+  DEBUG ((DEBUG_INFO,  "ExtractConfig( )\n"));\r
+\r
+  //\r
+  // Check for valid parameters\r
+  //\r
+  if (Progress == NULL || Results == NULL) {\r
+    return (EFI_INVALID_PARAMETER);\r
+  }\r
+\r
+  //\r
+  // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )\r
+  //\r
+  Status = gHiiConfigRouting->BlockToConfig(\r
+               gHiiConfigRouting,\r
+               Request,\r
+               (UINT8*)&gHiiConfiguration,\r
+               sizeof(OPAL_HII_CONFIGURATION),\r
+               Results,\r
+               Progress\r
+           );\r
+\r
+  return (Status);\r
+}\r
+\r
+\r
+/**\r
+\r
+  Pass the current system state to the bios via the hii_G_Configuration.\r
+\r
+**/\r
+VOID\r
+OpalHiiSetBrowserData (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG ((DEBUG_INFO,  "OpalHiiSetBrowserData( )\n"));\r
+  HiiSetBrowserData(\r
+      &gHiiSetupVariableGuid,\r
+      (CHAR16*)L"OpalHiiConfig",\r
+      sizeof(gHiiConfiguration),\r
+      (UINT8*)&gHiiConfiguration,\r
+      NULL\r
+  );\r
+}\r
+\r
+\r
+/**\r
+\r
+  Populate the hii_g_Configuraton with the browser Data.\r
+\r
+**/\r
+VOID\r
+OpalHiiGetBrowserData (\r
+  VOID\r
+  )\r
+{\r
+  DEBUG ((DEBUG_INFO,  "OpalHiiGetBrowserData( )\n"));\r
+  HiiGetBrowserData(\r
+      &gHiiSetupVariableGuid,\r
+      (CHAR16*)L"OpalHiiConfig",\r
+      sizeof(gHiiConfiguration),\r
+      (UINT8*)&gHiiConfiguration\r
+  );\r
+}\r
+\r
+/**\r
+  Set a string Value in a form.\r
+\r
+  @param      DestStringId   The stringid which need to update.\r
+  @param      SrcAsciiStr    The string nned to update.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+  @retval  Others            Other error occur.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiSetFormString(\r
+  EFI_STRING_ID       DestStringId,\r
+  CHAR8               *SrcAsciiStr\r
+  )\r
+{\r
+  UINT32                    Len;\r
+  UINT32                    UniSize;\r
+  CHAR16*                   UniStr;\r
+\r
+  DEBUG ((DEBUG_INFO,  "HiiSetFormString( )\n"));\r
+\r
+  //\r
+  // Determine the Length of the sting\r
+  //\r
+  Len = ( UINT32 )AsciiStrLen( SrcAsciiStr );\r
+\r
+  //\r
+  // Allocate space for the unicode string, including terminator\r
+  //\r
+  UniSize = (Len + 1) * sizeof(CHAR16);\r
+  UniStr = (CHAR16*)AllocateZeroPool(UniSize);\r
+\r
+  //\r
+  // Copy into unicode string, then copy into string id\r
+  //\r
+  AsciiStrToUnicodeStr( SrcAsciiStr, UniStr );\r
+\r
+  //\r
+  // Update the string in the form\r
+  //\r
+  if (HiiSetString(gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {\r
+    DEBUG ((DEBUG_INFO,  "HiiSetFormString( ) failed\n"));\r
+    FreePool(UniStr);\r
+    return (EFI_OUT_OF_RESOURCES);\r
+  }\r
+\r
+  //\r
+  // Free the memory\r
+  //\r
+  FreePool(UniStr);\r
+\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  Initialize the Opal disk base on the hardware info get from device.\r
+\r
+  @param Dev                  The Opal device.\r
+\r
+  @retval EFI_SUCESS          Initialize the device success.\r
+  @retval EFI_DEVICE_ERROR    Get info from device failed.\r
+\r
+**/\r
+EFI_STATUS\r
+OpalDiskInitialize (\r
+  IN OPAL_DRIVER_DEVICE          *Dev\r
+  )\r
+{\r
+  TCG_RESULT                  TcgResult;\r
+  OPAL_SESSION                Session;\r
+\r
+  ZeroMem(&Dev->OpalDisk, sizeof(OPAL_DISK));\r
+  Dev->OpalDisk.Sscp = Dev->Sscp;\r
+  Dev->OpalDisk.MediaId = Dev->MediaId;\r
+  Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;\r
+\r
+  ZeroMem(&Session, sizeof(Session));\r
+  Session.Sscp = Dev->Sscp;\r
+  Session.MediaId = Dev->MediaId;\r
+\r
+  TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);\r
+  if (TcgResult != TcgResultSuccess) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+  Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;\r
+\r
+  TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGHT, &Dev->OpalDisk.MsidLength);\r
+  if (TcgResult != TcgResultSuccess) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  return OpalDiskUpdateStatus (&Dev->OpalDisk);\r
+}\r
+\r
+/**\r
+  Update the device info.\r
+\r
+  @param OpalDisk                The Opal device.\r
+\r
+  @retval EFI_SUCESS             Initialize the device success.\r
+  @retval EFI_DEVICE_ERROR       Get info from device failed.\r
+  @retval EFI_INVALID_PARAMETER  Not get Msid info before get ownership info.\r
+\r
+**/\r
+EFI_STATUS\r
+OpalDiskUpdateStatus (\r
+  OPAL_DISK        *OpalDisk\r
+  )\r
+{\r
+  TCG_RESULT                  TcgResult;\r
+  OPAL_SESSION                Session;\r
+\r
+  ZeroMem(&Session, sizeof(Session));\r
+  Session.Sscp = OpalDisk->Sscp;\r
+  Session.MediaId = OpalDisk->MediaId;\r
+  Session.OpalBaseComId = OpalDisk->OpalBaseComId;\r
+\r
+  TcgResult = OpalGetLockingInfo(&Session, &OpalDisk->LockingFeature);\r
+  if (TcgResult != TcgResultSuccess) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  if (OpalDisk->MsidLength == 0) {\r
+    return EFI_INVALID_PARAMETER;\r
+  } else {\r
+    //\r
+    // Base on the Msid info to get the ownership, so Msid info must get first.\r
+    //\r
+    OpalDisk->Owner = OpalUtilDetermineOwnership(&Session, OpalDisk->Msid, OpalDisk->MsidLength);\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHii.h
new file mode 100644 (file)
index 0000000..c03f082
--- /dev/null
@@ -0,0 +1,146 @@
+/** @file\r
+  Public Header file of HII library used by Opal UEFI Driver.\r
+  Defines required callbacks of Opal HII library.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _OPAL_HII_H_\r
+#define _OPAL_HII_H_\r
+\r
+#include <Library/OpalPasswordSupportLib.h>\r
+#include <OpalDriverPrivate.h>\r
+\r
+#define DEFAULT_RESPONSE_SIZE 200\r
+\r
+/**\r
+  Get the driver image handle.\r
+\r
+  @retval  the driver image handle.\r
+\r
+**/\r
+EFI_HANDLE\r
+HiiGetDriverImageHandleCB(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Install the HII form and string packages.\r
+\r
+  @retval  EFI_SUCCESS           Install all the resources success.\r
+  @retval  EFI_OUT_OF_RESOURCES  Out of resource error.\r
+**/\r
+EFI_STATUS\r
+OpalHiiAddPackages(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Check whether enable feature or not.\r
+\r
+  @retval  Return the disk number.\r
+\r
+**/\r
+UINT8\r
+HiiGetNumConfigRequiredOpalDisksCB(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Returns the driver name.\r
+\r
+  @retval Returns the driver name.\r
+\r
+**/\r
+CHAR16*\r
+HiiGetDriverNameCB(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Returns the opaque pointer to a physical disk context.\r
+\r
+  @param  DiskIndex       Input the disk index.\r
+\r
+  @retval The device pointer.\r
+\r
+**/\r
+OPAL_DISK*\r
+HiiGetOpalDiskCB(\r
+  UINT8 DiskIndex\r
+  );\r
+\r
+/**\r
+  Returns the disk name.\r
+\r
+  @param  DiskIndex       Input the disk index.\r
+\r
+  @retval Returns the disk name.\r
+\r
+**/\r
+CHAR8*\r
+HiiDiskGetNameCB(\r
+  UINT8 DiskIndex\r
+  );\r
+\r
+/**\r
+  Set a string Value in a form.\r
+\r
+  @param      DestStringId   The stringid which need to update.\r
+  @param      SrcAsciiStr    The string nned to update.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+  @retval  Others            Other error occur.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiSetFormString(\r
+  EFI_STRING_ID       DestStringId,\r
+  CHAR8               *SrcAsciiStr\r
+  );\r
+\r
+/**\r
+  Install the HII related resources.\r
+\r
+  @retval  EFI_SUCCESS        Install all the resources success.\r
+  @retval  other              Error occur when install the resources.\r
+**/\r
+EFI_STATUS\r
+HiiInstall(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Uninstall the HII capability.\r
+\r
+  @retval  EFI_SUCCESS           Uninstall all the resources success.\r
+  @retval  others                Other errors occur when unistall the hii resource.\r
+**/\r
+EFI_STATUS\r
+HiiUninstall(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Initialize the Opal disk base on the hardware info get from device.\r
+\r
+  @param Dev                  The Opal device.\r
+\r
+  @retval EFI_SUCESS          Initialize the device success.\r
+  @retval EFI_DEVICE_ERROR    Get info from device failed.\r
+\r
+**/\r
+EFI_STATUS\r
+OpalDiskInitialize (\r
+  IN OPAL_DRIVER_DEVICE          *Dev\r
+  );\r
+\r
+#endif // _HII_H_\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiCallbacks.c b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiCallbacks.c
new file mode 100644 (file)
index 0000000..6f2eaeb
--- /dev/null
@@ -0,0 +1,221 @@
+/** @file\r
+  Callbacks required by the HII of the Opal UEFI Driver to help display\r
+  Opal device information and to send password to SMM handler.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "OpalHii.h"\r
+#include "OpalDriver.h"\r
+#include "OpalDriverPrivate.h"\r
+\r
+/**\r
+  Get Opal var name.\r
+  The return Value must be freed by caller if not NULL\r
+\r
+  @param      OpalDisk       The disk.\r
+  @param      Prefix         The prefix string.\r
+\r
+  @retval  The var name string.\r
+\r
+**/\r
+CHAR16*\r
+OpalDriverGetOpalVarName(\r
+  OPAL_DISK        *OpalDisk,\r
+  const CHAR16     *Prefix\r
+  )\r
+{\r
+  OPAL_DRIVER_DEVICE*          Dev;\r
+  UINTN                        PrefixLen;\r
+  UINTN                        NameLen;\r
+  UINTN                        VarNameLen;\r
+  CHAR16*                      VarName;\r
+\r
+  Dev = DRIVER_DEVICE_FROM_OPALDISK(OpalDisk);\r
+  if (Dev == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  PrefixLen = StrLen(Prefix);\r
+\r
+  NameLen = 0;\r
+  if (Dev->Name16 != NULL) {\r
+    NameLen = StrLen(Dev->Name16);\r
+  }\r
+\r
+  VarNameLen = PrefixLen + NameLen;\r
+\r
+  VarName = (CHAR16*)AllocateZeroPool((VarNameLen + 1) * sizeof(CHAR16));\r
+  if (VarName == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  CopyMem(VarName, Prefix, PrefixLen * sizeof(CHAR16));\r
+  if (Dev->Name16 != NULL) {\r
+    CopyMem(VarName + PrefixLen, Dev->Name16, NameLen * sizeof(CHAR16));\r
+  }\r
+  VarName[VarNameLen] = 0;\r
+\r
+  return VarName;\r
+}\r
+\r
+/**\r
+  Get the driver image handle.\r
+\r
+  @retval  the driver image handle.\r
+\r
+**/\r
+EFI_HANDLE\r
+HiiGetDriverImageHandleCB(\r
+  VOID\r
+  )\r
+{\r
+  return gImageHandle;\r
+}\r
+\r
+/**\r
+  Check whether enable feature or not.\r
+\r
+  @retval  Return the disk number.\r
+\r
+**/\r
+UINT8\r
+HiiGetNumConfigRequiredOpalDisksCB(\r
+  VOID\r
+  )\r
+{\r
+  UINT8                        NumDisks;\r
+  UINT8                        NumLockedOpalDisks;\r
+  OPAL_DISK                    *OpalDisk;\r
+  UINT8                        Index;\r
+\r
+  NumLockedOpalDisks = 0;\r
+\r
+  NumDisks = GetDeviceCount();\r
+\r
+  for (Index = 0; Index < NumDisks; Index++) {\r
+    OpalDisk = HiiGetOpalDiskCB(Index);\r
+\r
+    if (OpalDisk != NULL) {\r
+      if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {\r
+        DEBUG ((DEBUG_INFO, "Ignoring disk %u because feature is disabled or health has already been inspected\n", Index));\r
+      } else if (OpalDeviceLocked (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {\r
+        NumLockedOpalDisks++;\r
+      }\r
+    }\r
+  }\r
+\r
+  return NumLockedOpalDisks;\r
+}\r
+\r
+\r
+\r
+/**\r
+  Returns the opaque pointer to a physical disk context.\r
+\r
+  @param  DiskIndex       Input the disk index.\r
+\r
+  @retval The device pointer.\r
+\r
+**/\r
+VOID *\r
+HiiGetDiskContextCB(\r
+  UINT8 DiskIndex\r
+  )\r
+{\r
+  OPAL_DRIVER_DEVICE*                Dev;\r
+  UINT8                              CurrentDisk;\r
+\r
+  Dev = OpalDriverGetDeviceList();\r
+  CurrentDisk = 0;\r
+\r
+  if (DiskIndex >= GetDeviceCount()) {\r
+    return NULL;\r
+  }\r
+\r
+  while (Dev != NULL) {\r
+    if (CurrentDisk == DiskIndex) {\r
+      return Dev;\r
+    } else {\r
+      Dev = Dev->Next;\r
+      CurrentDisk++;\r
+    }\r
+  }\r
+\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Returns the opaque pointer to a physical disk context.\r
+\r
+  @param  DiskIndex       Input the disk index.\r
+\r
+  @retval The device pointer.\r
+\r
+**/\r
+OPAL_DISK*\r
+HiiGetOpalDiskCB(\r
+  UINT8 DiskIndex\r
+  )\r
+{\r
+  VOID                           *Ctx;\r
+  OPAL_DRIVER_DEVICE             *Tmp;\r
+\r
+  Ctx = HiiGetDiskContextCB (DiskIndex);\r
+\r
+  if (Ctx == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  Tmp = (OPAL_DRIVER_DEVICE*) Ctx;\r
+\r
+  return &Tmp->OpalDisk;\r
+}\r
+\r
+/**\r
+  Returns the disk name.\r
+\r
+  @param  DiskIndex       Input the disk index.\r
+\r
+  @retval Returns the disk name.\r
+\r
+**/\r
+CHAR8*\r
+HiiDiskGetNameCB(\r
+  UINT8 DiskIndex\r
+  )\r
+{\r
+  OPAL_DRIVER_DEVICE*                Ctx;\r
+\r
+  Ctx = (OPAL_DRIVER_DEVICE*) HiiGetDiskContextCB (DiskIndex);\r
+\r
+  if (Ctx != NULL) {\r
+    if (Ctx->NameZ == NULL) {\r
+      OpalDriverGetDriverDeviceName (Ctx);\r
+    }\r
+    return Ctx->NameZ;\r
+  }\r
+  return NULL;\r
+}\r
+\r
+/**\r
+  Returns the driver name.\r
+\r
+  @retval Returns the driver name.\r
+\r
+**/\r
+CHAR16*\r
+HiiGetDriverNameCB(\r
+  VOID\r
+  )\r
+{\r
+  return (CHAR16*)EFI_DRIVER_NAME_UNICODE;\r
+}\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormStrings.uni b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormStrings.uni
new file mode 100644 (file)
index 0000000..754dbf7
--- /dev/null
@@ -0,0 +1,91 @@
+// /** @file\r
+//\r
+//   String definitions for Setup formset.\r
+//\r
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+//\r
+// This program and the accompanying materials\r
+// are licensed and made available under the terms and conditions of the BSD License\r
+// which accompanies this distribution. The full text of the license may be found at\r
+// http://opensource.org/licenses/bsd-license.php\r
+//\r
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+//\r
+// **/\r
+\r
+/=#\r
+/////////////////////////////////   GENERIC DEFINITIONS   /////////////////////////////////\r
+#langdef en-US                                  "English"\r
+#string STR_NULL                                #language en-US " "\r
+\r
+/////////////////////////////////   FORM SET   /////////////////////////////////\r
+#string STR_FORM_SET_HELP                        #language en-US "Manage Opal disks"\r
+\r
+/////////////////////////////////   MULTIPLE FORMS   /////////////////////////////////\r
+#string STR_OPAL                                 #language en-US "Opal"\r
+#string STR_MAIN_OPAL_VERSION                    #language en-US "Version 00.0.0.0000"\r
+\r
+/////////////////////////////////   MAIN MENU FORM   /////////////////////////////////\r
+#string STR_MAIN_PHY_DISKS_LBL                   #language en-US "Physical Disks:"\r
+#string STR_MAIN_LOCKED_DISKS_LBL                #language en-US "Locked Disks:"\r
+\r
+#string STR_MAIN_GOTO_DISK_INFO_0                #language en-US " "\r
+#string STR_MAIN_GOTO_DISK_INFO_1                #language en-US " "\r
+#string STR_MAIN_GOTO_DISK_INFO_2                #language en-US " "\r
+#string STR_MAIN_GOTO_DISK_INFO_3                #language en-US " "\r
+#string STR_MAIN_GOTO_DISK_INFO_4                #language en-US " "\r
+#string STR_MAIN_GOTO_DISK_INFO_5                #language en-US " "\r
+\r
+#string STR_MAIN_GOTO_DISK_INFO_HELP             #language en-US "Select to see Opal disk actions"\r
+#string STR_MAIN_GOTO_DISK_HEALTH_HELP           #language en-US "Select disk to unlock"\r
+\r
+#string STR_MAIN_NO_DISKS_PRESENT_LBL            #language en-US "No disks connected to system"\r
+\r
+/////////////////////////////////   DISK INFO MENU FORM   /////////////////////////////////\r
+#string STR_DISK_INFO_SELECTED_DISK_NAME         #language en-US " "\r
+\r
+#string STR_DISK_INFO_LOCK                       #language en-US "Lock"\r
+#string STR_DISK_INFO_UNLOCK                     #language en-US "Unlock"\r
+#string STR_DISK_INFO_SET_ADMIN_PSWD             #language en-US "Update Drive Admin Password"\r
+#string STR_DISK_INFO_SET_USER_PSWD              #language en-US "Set Drive User Password"\r
+#string STR_DISK_INFO_SECURE_ERASE               #language en-US "Secure Erase User Data"\r
+#string STR_DISK_INFO_PSID_REVERT                #language en-US "PSID Revert to factory default"\r
+#string STR_DISK_INFO_REVERT                     #language en-US "Admin Revert to factory default and Disable"\r
+#string STR_DISK_INFO_DISABLE_USER               #language en-US "Disable User"\r
+#string STR_DISK_INFO_ENABLE_FEATURE             #language en-US "Enable Feature"\r
+#string STR_DISK_INFO_ENABLE_BLOCKSID            #language en-US "Enable BlockSID"\r
+#string STR_ENABLED                              #language en-US "Enabled"\r
+#string STR_DISABLED                             #language en-US "Disabled"\r
+\r
+#string STR_DISK_INFO_GOTO_LOCK_HELP             #language en-US "Lock the disk"\r
+#string STR_DISK_INFO_GOTO_UNLOCK_HELP           #language en-US "Unlock the disk"\r
+#string STR_DISK_INFO_GOTO_SET_ADMIN_PSWD_HELP   #language en-US "Set password for the administrator"\r
+#string STR_DISK_INFO_GOTO_SET_USER_PSWD_HELP    #language en-US "Set password for User 1"\r
+#string STR_DISK_INFO_GOTO_SECURE_ERASE_HELP     #language en-US "Securely erase the disk"\r
+#string STR_DISK_INFO_GOTO_PSID_REVERT_HELP      #language en-US "Revert the disk to factory defaults"\r
+#string STR_DISK_INFO_GOTO_DISABLE_USER_HELP     #language en-US "Disable User"\r
+#string STR_DISK_INFO_GOTO_ENABLE_FEATURE_HELP   #language en-US "Enable Feature"\r
+#string STR_DISK_INFO_GOTO_ENABLE_BLOCKSID_HELP  #language en-US "Enable to send BlockSID command"\r
+\r
+/////////////////////////////////   DISK ACTION MENU FORM   /////////////////////////////////\r
+#string STR_DISK_ACTION_LBL                     #language en-US " "\r
+\r
+#string STR_PASSWORD_PROMPT                     #language en-US "Enter Password"\r
+#string STR_PASSWORD_HELP                       #language en-US "Password must be between 6 and 20 characters"\r
+\r
+#string STR_REVERT_PROMPT                       #language en-US "Enter PSID"\r
+#string STR_REVERT_HELP                         #language en-US "PSID is a 32 character case sensitive value"\r
+#string STR_ACTION_STATUS                       #language en-US " "\r
+\r
+#string STR_PASSWORD_SUBMIT                     #language en-US "Submit Password Changes"\r
+#string STR_PASSWORD_SUBMIT_HELP                #language en-US "Submits Password Changes (new and update) after passwords have been entered"\r
+\r
+#string STR_GOTO_HOME                           #language en-US "Main Menu"\r
+#string STR_GOTO_HOME_HELP                      #language en-US "Return to the main menu"\r
+\r
+#string STR_KEEP_USER_DATA_PROMPT               #language en-US "Keep User Data"\r
+#string STR_KEEP_USER_DATA_HELP                 #language en-US "Checkmark to keep user data, otherwise data will be lost"\r
+\r
+#string STR_OK                                  #language en-US "OK"\r
+\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormValues.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiFormValues.h
new file mode 100644 (file)
index 0000000..50ad4ee
--- /dev/null
@@ -0,0 +1,120 @@
+/** @file\r
+  Defines Opal HII form ids, structures and values.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#ifndef _OPAL_HII_FORM_VALUES_H_\r
+#define _OPAL_HII_FORM_VALUES_H_\r
+\r
+// Maximum Opal password Length\r
+#define MAX_PASSWORD_CHARACTER_LENGTH                      0x14\r
+\r
+// PSID Length\r
+#define PSID_CHARACTER_LENGTH                              0x20\r
+\r
+// ID's for various forms that will be used by HII\r
+#define FORMID_VALUE_MAIN_MENU                             0x01\r
+#define FORMID_VALUE_DISK_INFO_FORM_MAIN                   0x02\r
+#define FORMID_VALUE_DISK_ACTION_FORM                      0x03\r
+\r
+// Structure defining the OPAL_HII_CONFIGURATION\r
+#pragma pack(1)\r
+typedef struct {\r
+    UINT8   NumDisks;\r
+    UINT8   SelectedDiskIndex;\r
+    UINT8   SelectedAction;\r
+    UINT16  SelectedDiskAvailableActions;\r
+    UINT16  SupportedDisks;\r
+    UINT8   KeepUserData;\r
+    UINT16  AvailableFields;\r
+    UINT16  Password[MAX_PASSWORD_CHARACTER_LENGTH];\r
+    UINT16  Psid[PSID_CHARACTER_LENGTH];\r
+    UINT8   EnableBlockSid;\r
+} OPAL_HII_CONFIGURATION;\r
+#pragma pack()\r
+\r
+/* Action Flags */\r
+#define HII_ACTION_NONE                                        0x0000\r
+#define HII_ACTION_LOCK                                        0x0001\r
+#define HII_ACTION_UNLOCK                                      0x0002\r
+#define HII_ACTION_SET_ADMIN_PWD                               0x0004\r
+#define HII_ACTION_SET_USER_PWD                                0x0008\r
+#define HII_ACTION_SECURE_ERASE                                0x0010\r
+#define HII_ACTION_PSID_REVERT                                 0x0020\r
+#define HII_ACTION_DISABLE_USER                                0x0040\r
+#define HII_ACTION_REVERT                                      0x0080\r
+#define HII_ACTION_DISABLE_FEATURE                             0x0100\r
+#define HII_ACTION_ENABLE_FEATURE                              0x0200\r
+#define HII_ACTION_ENABLE_BLOCKSID                             0x0400\r
+\r
+/* Flags for diskActionAvailableFields */\r
+#define HII_FIELD_PASSWORD                      0x0001\r
+#define HII_FIELD_PSID                          0x0002\r
+#define HII_FIELD_KEEP_USER_DATA                0x0004\r
+#define HII_FIELD_KEEP_USER_DATA_FORCED         0x0008\r
+\r
+/* Number of bits allocated for each part of a unique key for an HII_ITEM\r
+ * all bits together must be <= 16 (EFI_QUESTION_ID is UINT16)\r
+ * 1   1   1   1   1   1   1   1   1   1   1   1   1   1   1   1\r
+ * |   |-----------------------|   |---------------------------|\r
+ * FLG INDEX                       ID\r
+ */\r
+#define HII_KEY_ID_BITS                                     8\r
+#define HII_KEY_INDEX_BITS                                  7\r
+#define HII_KEY_FLAG_BITS                                   1\r
+\r
+#define HII_KEY_FLAG                                        0x8000 // bit 15 (zero based)\r
+\r
+/***********/\r
+/* Key IDs */\r
+/***********/\r
+\r
+#define HII_KEY_ID_GOTO_MAIN_MENU                       0\r
+#define HII_KEY_ID_GOTO_DISK_INFO                       1\r
+#define HII_KEY_ID_GOTO_LOCK                            2\r
+#define HII_KEY_ID_GOTO_UNLOCK                          3\r
+#define HII_KEY_ID_GOTO_SET_ADMIN_PWD                   4\r
+#define HII_KEY_ID_GOTO_SET_USER_PWD                    5\r
+#define HII_KEY_ID_GOTO_SECURE_ERASE                    6\r
+#define HII_KEY_ID_GOTO_PSID_REVERT                     7\r
+#define HII_KEY_ID_GOTO_REVERT                          8\r
+#define HII_KEY_ID_GOTO_DISABLE_USER                    9\r
+#define HII_KEY_ID_GOTO_ENABLE_FEATURE                  0xA //10\r
+#define HII_KEY_ID_GOTO_CONFIRM_TO_MAIN_MENU            0xB //11\r
+#define HII_KEY_ID_ENTER_PASSWORD                       0xC //12\r
+#define HII_KEY_ID_ENTER_PSID                           0xD //13\r
+#define HII_KEY_ID_VAR_SUPPORTED_DISKS                  0xE //14\r
+#define HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS  0xF //15\r
+\r
+#define HII_KEY_ID_BLOCKSID                             0x17 //23\r
+#define HII_KEY_ID_MAX                                  0x17 //23 // !!Update each time a new ID is added!!\r
+\r
+#define HII_KEY_WITH_INDEX(id, index) \\r
+    ( \\r
+        HII_KEY_FLAG | \\r
+        (id) | \\r
+        ((index) << HII_KEY_ID_BITS) \\r
+    )\r
+\r
+#define HII_KEY(id) HII_KEY_WITH_INDEX(id, 0)\r
+\r
+#define PACKAGE_LIST_GUID { 0xf0308176, 0x9058, 0x4153, { 0x93, 0x3d, 0xda, 0x2f, 0xdc, 0xc8, 0x3e, 0x44 } }\r
+\r
+/* {410483CF-F4F9-4ece-848A-1958FD31CEB7} */\r
+#define SETUP_FORMSET_GUID { 0x410483cf, 0xf4f9, 0x4ece, { 0x84, 0x8a, 0x19, 0x58, 0xfd, 0x31, 0xce, 0xb7 } }\r
+\r
+// {BBF1ACD2-28D8-44ea-A291-58A237FEDF1A}\r
+#define SETUP_VARIABLE_GUID { 0xbbf1acd2, 0x28d8, 0x44ea, { 0xa2, 0x91, 0x58, 0xa2, 0x37, 0xfe, 0xdf, 0x1a } }\r
+\r
+#endif //_HII_FORM_VALUES_H_\r
+\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiPrivate.h b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalHiiPrivate.h
new file mode 100644 (file)
index 0000000..366cd38
--- /dev/null
@@ -0,0 +1,266 @@
+/** @file\r
+  Private functions and sturctures used by the Opal UEFI Driver.\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _OPAL_HII_PRIVATE_H_\r
+#define _OPAL_HII_PRIVATE_H_\r
+\r
+\r
+\r
+#include <Library/OpalPasswordSupportLib.h>\r
+#include <Protocol/HiiConfigAccess.h>\r
+\r
+#include "OpalHii.h"\r
+#include "OpalHiiFormValues.h"\r
+\r
+\r
+#define  OPAL_PASSWORD_CONFIG_GUID \\r
+  { \\r
+    0x0d510a4f, 0xa81b, 0x473f, { 0x87, 0x07, 0xb7, 0xfd, 0xfb, 0xc0, 0x45, 0xba } \\r
+  }\r
+\r
+#pragma pack(1)\r
+\r
+typedef struct {\r
+  UINT16 Id: HII_KEY_ID_BITS;\r
+  UINT16 Index: HII_KEY_INDEX_BITS;\r
+  UINT16 Flag: HII_KEY_FLAG_BITS;\r
+} KEY_BITS;\r
+\r
+typedef union {\r
+    UINT16    Raw;\r
+    KEY_BITS  KeyBits;\r
+} HII_KEY;\r
+\r
+typedef struct {\r
+    VENDOR_DEVICE_PATH             VendorDevicePath;\r
+    EFI_DEVICE_PATH_PROTOCOL       End;\r
+} HII_VENDOR_DEVICE_PATH;\r
+\r
+/**\r
+* Opal PSID Authority utilized for PSID revert\r
+*\r
+* The type indicates the structure of the PSID authority\r
+*/\r
+typedef struct {\r
+    UINT8 Psid[32];\r
+} TCG_PSID;\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>\r
+                                 format.\r
+  @param  Progress               A pointer to a string filled in with the offset of\r
+                                 the most recent '&' before the first failing\r
+                                 name/value pair (or the beginning of the string if\r
+                                 the failure is in the first name/value pair) or\r
+                                 the terminating NULL if all was successful.\r
+\r
+  @retval EFI_SUCCESS            The Results is processed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RouteConfig(\r
+  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL    *This,\r
+  CONST EFI_STRING                        Configuration,\r
+  EFI_STRING                              *Progress\r
+  );\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Request                A null-terminated Unicode string in\r
+                                 <ConfigRequest> format.\r
+  @param  Progress               On return, points to a character in the Request\r
+                                 string. Points to the string's null terminator if\r
+                                 request was successful. Points to the most recent\r
+                                 '&' before the first failing name/value pair (or\r
+                                 the beginning of the string if the failure is in\r
+                                 the first name/value pair) if the request was not\r
+                                 successful.\r
+  @param  Results                A null-terminated Unicode string in\r
+                                 <ConfigAltResp> format which has all values filled\r
+                                 in for the names in the Request string. String to\r
+                                 be allocated by the called function.\r
+\r
+  @retval EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
+                                 driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ExtractConfig(\r
+  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL    *This,\r
+  CONST EFI_STRING                        Request,\r
+  EFI_STRING                              *Progress,\r
+  EFI_STRING                              *Results\r
+  );\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param  Action                 Specifies the type of action taken by the browser.\r
+  @param  QuestionId             A unique value which is sent to the original\r
+                                 exporting driver so that it can identify the type\r
+                                 of data to expect.\r
+  @param  Type                   The type of value for the question.\r
+  @param  Value                  A pointer to the data being sent to the original\r
+                                 exporting driver.\r
+  @param  ActionRequest          On return, points to the action requested by the\r
+                                 callback function.\r
+\r
+  @retval EFI_SUCCESS            The callback successfully handled the action.\r
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the\r
+                                 variable and its data.\r
+  @retval EFI_DEVICE_ERROR       The variable could not be saved.\r
+  @retval EFI_UNSUPPORTED        The specified Action is not supported by the\r
+                                 callback.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+DriverCallback(\r
+  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL*   This,\r
+  EFI_BROWSER_ACTION                      Action,\r
+  EFI_QUESTION_ID                         QuestionId,\r
+  UINT8                                   Type,\r
+  EFI_IFR_TYPE_VALUE*                     Value,\r
+  EFI_BROWSER_ACTION_REQUEST*             ActionRequest\r
+  );\r
+\r
+/**\r
+\r
+  Pass the current system state to the bios via the hii_G_Configuration.\r
+\r
+**/\r
+VOID\r
+OpalHiiSetBrowserData (\r
+  VOID\r
+  );\r
+\r
+/**\r
+\r
+  Populate the hii_g_Configuraton with the browser Data.\r
+\r
+**/\r
+VOID\r
+OpalHiiGetBrowserData (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Draws the disk info form.\r
+\r
+  @retval  EFI_SUCCESS       Draw the disk info success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiPopulateDiskInfoForm(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Update the global Disk index info.\r
+\r
+  @param   Index             The input disk index info.\r
+\r
+  @retval  EFI_SUCCESS       Update the disk index info success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiSelectDisk(\r
+  UINT8 Index\r
+  );\r
+\r
+/**\r
+  Use the input password to do the specified action.\r
+\r
+  @param      Str            The input password saved in.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+  @retval  Others            Other error occur.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiPasswordEntered(\r
+  EFI_STRING_ID            Str\r
+  );\r
+\r
+/**\r
+  Update block sid info.\r
+\r
+  @param      Enable         Enable/disable BlockSid.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+  @retval  Others            Other error occur.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiSetBlockSid (\r
+  BOOLEAN          Enable\r
+  );\r
+\r
+/**\r
+  Reverts the Opal disk to factory default.\r
+\r
+  @retval  EFI_SUCCESS       Do the required action success.\r
+\r
+**/\r
+EFI_STATUS\r
+HiiPsidRevert(\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get disk name string id.\r
+\r
+  @param   DiskIndex             The input disk index info.\r
+\r
+  @retval  The disk name string id.\r
+\r
+**/\r
+EFI_STRING_ID\r
+GetDiskNameStringId(\r
+  UINT8 DiskIndex\r
+  );\r
+\r
+/**\r
+  Update the device info.\r
+\r
+  @param OpalDisk                The Opal device.\r
+\r
+  @retval EFI_SUCESS             Initialize the device success.\r
+  @retval EFI_DEVICE_ERROR       Get info from device failed.\r
+  @retval EFI_INVALID_PARAMETER  Not get Msid info before get ownership info.\r
+\r
+**/\r
+EFI_STATUS\r
+OpalDiskUpdateStatus (\r
+  OPAL_DISK        *OpalDisk\r
+  );\r
+\r
+#pragma pack()\r
+\r
+#endif // _HII_P_H_\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordDxe.inf b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordDxe.inf
new file mode 100644 (file)
index 0000000..7da581b
--- /dev/null
@@ -0,0 +1,84 @@
+## @file\r
+#  This is a OpalPasswordDxe driver.\r
+#\r
+#  This module is used to Management the Opal feature\r
+#  for Opal supported devices.\r
+#\r
+#\r
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+[Defines]\r
+  INF_VERSION                    = 0x00010007\r
+  BASE_NAME                      = OpalPasswordDxe\r
+  FILE_GUID                      = E3E4048D-6C0C-43E4-AE1C-FFB579D8EF41\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = EfiDriverEntryPoint\r
+  UNLOAD_IMAGE                   = OpalEfiDriverUnload\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  OpalDriver.h\r
+  OpalHii.c\r
+  OpalHiiCallbacks.c\r
+  OpalDriver.c\r
+  OpalDriverPrivate.h\r
+  OpalHii.h\r
+  OpalHiiPrivate.h\r
+  OpalHiiFormValues.h\r
+  OpalPasswordForm.vfr\r
+  OpalHiiFormStrings.uni\r
+  ComponentName.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  SecurityPkg/SecurityPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  MemoryAllocationLib\r
+  UefiBootServicesTableLib\r
+  UefiDriverEntryPoint\r
+  UefiHiiServicesLib\r
+  UefiRuntimeServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  HiiLib\r
+  PrintLib\r
+  DevicePathLib\r
+  OpalPasswordSupportLib\r
+  UefiLib\r
+  TcgStorageOpalLib\r
+\r
+[Protocols]\r
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES\r
+  gEfiStorageSecurityCommandProtocolGuid        ## CONSUMES\r
+  gEfiComponentNameProtocolGuid                 ## PRODUCES\r
+  gEfiComponentName2ProtocolGuid                ## PRODUCES\r
+  gEfiBlockIoProtocolGuid                       ## CONSUMES\r
+  gEfiSmmCommunicationProtocolGuid              ## PRODUCES\r
+  gEfiPciIoProtocolGuid                         ## CONSUMES\r
+  gEfiDevicePathToTextProtocolGuid              ## CONSUMES\r
+\r
+[Guids]\r
+  gEfiEventExitBootServicesGuid                 ## CONSUMES ## Event\r
+  gOpalExtraInfoVariableGuid                    ## PRODUCES ## GUID\r
+\r
+[BuildOptions]\r
+  MSFT:*_*_*_CC_FLAGS = /Od /GL-\r
+\r
+[Depex]\r
+  gEfiSmmCommunicationProtocolGuid\r
diff --git a/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordForm.vfr b/SecurityPkg/Tcg/Opal/OpalPasswordDxe/OpalPasswordForm.vfr
new file mode 100644 (file)
index 0000000..9c35ec7
--- /dev/null
@@ -0,0 +1,327 @@
+/** @file\r
+\r
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include "OpalHiiFormValues.h"\r
+\r
+\r
+#define EFI_HII_PLATFORM_SETUP_FORMSET_GUID \\r
+  { 0x93039971, 0x8545, 0x4b04, { 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe } }\r
+\r
+formset\r
+  guid      = SETUP_FORMSET_GUID,\r
+  title     = STRING_TOKEN(STR_OPAL),\r
+  help      = STRING_TOKEN(STR_FORM_SET_HELP),\r
+  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,\r
+\r
+  // Define a Buffer Storage (EFI_IFR_VARSTORE) that will be filled\r
+  // out initially through extractConfig call\r
+  varstore OPAL_HII_CONFIGURATION,           // This is the Data structure type\r
+    name  = OpalHiiConfig,                   // Define referenced name in vfr\r
+    guid  = SETUP_VARIABLE_GUID;         // GUID of this Buffer storage\r
+\r
+form formid = FORMID_VALUE_MAIN_MENU,\r
+    title  = STRING_TOKEN(STR_OPAL);\r
+\r
+    //CONFIG_VARIABLE(HII_KEY(HII_KEY_ID_VAR_SUPPORTED_DISKS), SupportedDisks, 0x0, 0xFFFF);\r
+    suppressif TRUE;\r
+        numeric\r
+            name    = SupportedDisks,\r
+            varid   = OpalHiiConfig.SupportedDisks,\r
+            prompt  = STRING_TOKEN(STR_NULL),\r
+            help    = STRING_TOKEN(STR_NULL),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x800E,   //32782,\r
+            minimum = 0x0,\r
+            maximum = 0xFFFF,\r
+    endnumeric;\r
+    endif;\r
+\r
+    subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    text\r
+        help   = STRING_TOKEN(STR_NULL),\r
+        text   = STRING_TOKEN(STR_MAIN_PHY_DISKS_LBL);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    //DISK( 0 );\r
+    suppressif ( questionref(SupportedDisks) & ( 0x1 ) ) == 0;\r
+        goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
+            prompt  = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_0 ),\r
+            help    = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
+            flags   = INTERACTIVE, \\r
+            key     = 0x8001;   //32769\r
+    endif;\r
+\r
+    //DISK( 1 );\r
+    suppressif ( questionref(SupportedDisks) & ( 0x2 ) ) == 0;\r
+        goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
+            prompt  = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_1 ),\r
+            help    = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
+            flags   = INTERACTIVE, \\r
+            key     = 0x8101;   //33025\r
+    endif;\r
+\r
+    //DISK( 2 );\r
+    suppressif ( questionref(SupportedDisks) & ( 0x4 ) ) == 0;\r
+        goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
+            prompt  = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_2 ),\r
+            help    = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
+            flags   = INTERACTIVE, \\r
+            key     = 0x8201;   //33281\r
+    endif;\r
+\r
+    //DISK( 3 );\r
+    suppressif ( questionref(SupportedDisks) & ( 0x8 ) ) == 0;\r
+        goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
+            prompt  = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_3 ),\r
+            help    = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
+            flags   = INTERACTIVE, \\r
+            key     = 0x8301;  // 33537\r
+    endif;\r
+\r
+    //DISK( 4 );\r
+    suppressif ( questionref(SupportedDisks) & ( 0x10 ) ) == 0;\r
+        goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
+            prompt  = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_4 ),\r
+            help    = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
+            flags   = INTERACTIVE, \\r
+            key     = 0x8401;  // 33793\r
+    endif;\r
+\r
+    //DISK( 5 );\r
+    suppressif ( questionref(SupportedDisks) & ( 0x20 ) ) == 0;\r
+        goto FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
+            prompt  = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_5 ),\r
+            help    = STRING_TOKEN(STR_MAIN_GOTO_DISK_INFO_HELP),\r
+            flags   = INTERACTIVE, \\r
+            key     = 0x8501;   // 34049\r
+    endif;\r
+\r
+    //No disks on system\r
+    suppressif ideqval OpalHiiConfig.NumDisks > 0;\r
+        text\r
+            help    = STRING_TOKEN(STR_NULL),\r
+            text    = STRING_TOKEN(STR_MAIN_NO_DISKS_PRESENT_LBL);\r
+    endif;\r
+\r
+endform;  // MAIN MENU FORM\r
+\r
+//\r
+/////////////////   DISK INFO FORM   /////////////////\r
+//\r
+form formid = FORMID_VALUE_DISK_INFO_FORM_MAIN,\r
+    title  = STRING_TOKEN(STR_OPAL);\r
+\r
+    suppressif TRUE;\r
+        numeric\r
+            name    = SelectedDiskAvailableActions,\r
+            varid   = OpalHiiConfig.SelectedDiskAvailableActions,\r
+            prompt  = STRING_TOKEN(STR_NULL),\r
+            help    = STRING_TOKEN(STR_NULL),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x800F,     // 32783\r
+            minimum = 0x0,\r
+            maximum = 0xFFFF,\r
+    endnumeric;\r
+    endif;\r
+\r
+    subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    text\r
+        help   = STRING_TOKEN(STR_NULL),\r
+        text   = STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_LOCK ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_LOCK),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_LOCK_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8002;    // 32770\r
+    endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_UNLOCK ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_UNLOCK),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_UNLOCK_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8003; //32771;\r
+    endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SET_ADMIN_PWD ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_SET_ADMIN_PSWD),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_SET_ADMIN_PSWD_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8004; //32772;\r
+        endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SET_USER_PWD ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_SET_USER_PSWD),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_SET_USER_PSWD_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8005; //32773;\r
+    endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_SECURE_ERASE ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_SECURE_ERASE),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_SECURE_ERASE_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8006; //32774;\r
+    endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_REVERT ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_REVERT),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_PSID_REVERT_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8008; //32776;\r
+    endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_PSID_REVERT ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_PSID_REVERT),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_PSID_REVERT_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8007; //32775;\r
+    endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_DISABLE_USER ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_DISABLE_USER),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_DISABLE_USER_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8009; //32777;\r
+    endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_ENABLE_FEATURE ) == 0;\r
+        goto FORMID_VALUE_DISK_ACTION_FORM,\r
+            prompt  = STRING_TOKEN(STR_DISK_INFO_ENABLE_FEATURE),\r
+            help    = STRING_TOKEN(STR_DISK_INFO_GOTO_ENABLE_FEATURE_HELP),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x800A; //32778;\r
+    endif;\r
+\r
+    suppressif ( questionref(SelectedDiskAvailableActions) & HII_ACTION_ENABLE_BLOCKSID ) == 0;\r
+      oneof varid   = OpalHiiConfig.EnableBlockSid,\r
+        questionid  = 0x8017, // 32791,\r
+        prompt      = STRING_TOKEN(STR_DISK_INFO_ENABLE_BLOCKSID),\r
+        help        = STRING_TOKEN(STR_DISK_INFO_GOTO_ENABLE_BLOCKSID_HELP),\r
+        flags   = INTERACTIVE,\r
+        option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\r
+        option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\r
+      endoneof;\r
+    endif;\r
+\r
+endform;  // DISK INFO FORM\r
+\r
+//\r
+/////////////////   DISK ACTION FORM   /////////////////\r
+//\r
+form formid = FORMID_VALUE_DISK_ACTION_FORM,\r
+    title  = STRING_TOKEN(STR_OPAL);\r
+\r
+    suppressif TRUE;\r
+        numeric\r
+            name    = AvailableFields,\r
+            varid   = OpalHiiConfig.AvailableFields,\r
+            prompt  = STRING_TOKEN(STR_NULL),\r
+            help    = STRING_TOKEN(STR_NULL),\r
+            flags   = INTERACTIVE,\r
+            key     = 0x8012,  //32786,\r
+            minimum = 0x0,\r
+            maximum = 0xFFFF,\r
+    endnumeric;\r
+    endif;\r
+\r
+    subtitle text = STRING_TOKEN(STR_MAIN_OPAL_VERSION);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    text\r
+        help   = STRING_TOKEN(STR_NULL),\r
+        text   = STRING_TOKEN(STR_DISK_INFO_SELECTED_DISK_NAME);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    text\r
+        help   = STRING_TOKEN(STR_NULL),\r
+        text   = STRING_TOKEN(STR_DISK_ACTION_LBL);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    suppressif (questionref(AvailableFields) & HII_FIELD_KEEP_USER_DATA) == 0;\r
+        grayoutif (questionref(AvailableFields) & HII_FIELD_KEEP_USER_DATA_FORCED) != 0;\r
+            checkbox\r
+                name = MyCheckbox,\r
+                varid = OpalHiiConfig.KeepUserData,\r
+                prompt = STRING_TOKEN(STR_KEEP_USER_DATA_PROMPT),\r
+                help = STRING_TOKEN(STR_KEEP_USER_DATA_HELP),\r
+                key = 0x8011,    //32785,\r
+            endcheckbox;\r
+\r
+            //EMPTY_LINE;\r
+            text\r
+                help    = STRING_TOKEN(STR_NULL),\r
+                text    = STRING_TOKEN(STR_NULL);\r
+        endif;\r
+    endif;\r
+\r
+    suppressif (questionref(AvailableFields) & HII_FIELD_PASSWORD) == 0;\r
+        password\r
+            varid = OpalHiiConfig.Password,\r
+            prompt = STRING_TOKEN(STR_PASSWORD_PROMPT),\r
+            help = STRING_TOKEN(STR_PASSWORD_HELP),\r
+            flags = INTERACTIVE,\r
+            key = 0x800C,   //32780,\r
+            minsize = 6,\r
+            maxsize = 20,\r
+        endpassword;\r
+    endif;\r
+\r
+    suppressif (questionref(AvailableFields) & HII_FIELD_PSID) == 0;\r
+        string\r
+            varid = OpalHiiConfig.Psid,\r
+            prompt = STRING_TOKEN(STR_REVERT_PROMPT),\r
+            help = STRING_TOKEN(STR_REVERT_HELP),\r
+            flags = INTERACTIVE,\r
+            key = 0x800D,   //32781,\r
+            minsize = PSID_CHARACTER_LENGTH,\r
+            maxsize = PSID_CHARACTER_LENGTH,\r
+        endstring;\r
+    endif;\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    text\r
+        help   = STRING_TOKEN(STR_NULL),\r
+        text   = STRING_TOKEN(STR_ACTION_STATUS);\r
+\r
+    subtitle text = STRING_TOKEN(STR_NULL);\r
+\r
+    goto FORMID_VALUE_MAIN_MENU,\r
+        prompt  = STRING_TOKEN(STR_GOTO_HOME),\r
+        help    = STRING_TOKEN(STR_GOTO_HOME_HELP),\r
+        flags   = INTERACTIVE,\r
+        key     = 0x8000;   //32768;\r
+\r
+endform;  // DISK ACTION FORM\r
+\r
+endformset;\r