]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/PlatformDriverOverride/PlatOverMngr/PlatOverMngr.c
enhanced security check.
[mirror_edk2.git] / MdeModulePkg / Universal / PlatformDriverOverride / PlatOverMngr / PlatOverMngr.c
index 5f49a5b9260eae973c74e9627de959057e2f2cab..86c1891668c7af0854d731adfcccbe053c52cfff 100644 (file)
@@ -1,5 +1,17 @@
 /** @file\r
 \r
+  A UI application to offer a UI interface in device manager to let user configue\r
+  platform override protocol to override the default algorithm for matching\r
+  drivers to controllers.\r
+\r
+  The main flow:\r
+  1. The UI application dynamicly locate all controller device path.\r
+  2. The UI application dynamicly locate all drivers which support binding protocol.\r
+  3. The UI application export and dynamicly update two menu to let user select the\r
+     mapping between drivers to controllers.\r
+  4. The UI application save all the mapping info in NV variables which will be consumed\r
+     by platform override protocol driver to publish the platform override protocol.\r
+\r
 Copyright (c) 2007 - 2008, Intel Corporation\r
 All rights reserved. This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
@@ -9,38 +21,69 @@ http://opensource.org/licenses/bsd-license.php
 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
-Module Name:\r
-\r
-  PlatOverMngr.c\r
-\r
-Abstract:\r
-\r
-  A UI driver to offer a UI interface in device manager to let user configue\r
-  platform override protocol to override the default algorithm for matching\r
-  drivers to controllers.\r
-\r
-  The main flow:\r
-  1. The UI driver dynamicly locate all controller device path.\r
-  2. The UI driver dynamicly locate all drivers which support binding protocol.\r
-  3. The UI driver export and dynamicly update two  menu to let user select the\r
-     mapping between drivers to controllers.\r
-  4. The UI driver save all the mapping info in NV variables which will be consumed\r
-     by platform override protocol driver to publish the platform override protocol.\r
-\r
 **/\r
 \r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/HiiConfigRouting.h>\r
+#include <Protocol/HiiDatabase.h>\r
+#include <Protocol/FormBrowser2.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/PciIo.h>\r
+#include <Protocol/BusSpecificDriverOverride.h>\r
+#include <Protocol/ComponentName2.h>\r
+#include <Protocol/ComponentName.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Guid/GlobalVariable.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiApplicationEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/PlatDriOverLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/IfrSupportLib.h>\r
+#include <Library/ExtendedHiiLib.h>\r
+#include <Library/ExtendedIfrSupportLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/GenericBdsLib.h>\r
 #include "PlatOverMngr.h"\r
 \r
-EFI_GUID      mPlatformOverridesManagerGuid = PLAT_OVER_MNGR_GUID;\r
-\r
-LIST_ENTRY    mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);\r
-\r
-EFI_HANDLE    *mDevicePathHandleBuffer;\r
-EFI_HANDLE    *mDriverImageHandleBuffer;\r
-\r
-UINTN         mSelectedCtrIndex;\r
-EFI_STRING_ID mControllerToken[MAX_CHOICE_NUM];\r
-\r
+#define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')\r
+#define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)\r
+\r
+typedef struct {\r
+  UINTN                           Signature;\r
+  EFI_HANDLE                      DriverHandle;\r
+  EFI_HII_HANDLE                  RegisteredHandle;\r
+  PLAT_OVER_MNGR_DATA             FakeNvData;\r
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL  ConfigAccess;\r
+} EFI_CALLBACK_INFO;\r
+\r
+//\r
+// uni string and Vfr Binary data.\r
+//\r
+extern UINT8  VfrBin[];\r
+extern UINT8  PlatOverMngrStrings[];\r
+\r
+//\r
+// module global data\r
+//\r
+EFI_GUID                     mPlatformOverridesManagerGuid = PLAT_OVER_MNGR_GUID;\r
+LIST_ENTRY                   mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);\r
+\r
+EFI_HANDLE                   *mDevicePathHandleBuffer;\r
+EFI_HANDLE                   *mDriverImageHandleBuffer;\r
+\r
+INTN                         mSelectedCtrIndex;\r
+EFI_STRING_ID                mControllerToken[MAX_CHOICE_NUM];\r
 UINTN                        mDriverImageHandleCount;\r
 EFI_STRING_ID                mDriverImageToken[MAX_CHOICE_NUM];\r
 EFI_STRING_ID                mDriverImageFilePathToken[MAX_CHOICE_NUM];\r
@@ -52,212 +95,58 @@ CHAR8                        mLanguage[RFC_3066_ENTRY_SIZE];
 UINT16                       mCurrentPage;\r
 \r
 /**\r
-  The driver Entry Point. The funciton will export a disk device class formset and\r
-  its callback function to hii database.\r
+  Do string convertion for the ComponentName supported language. It do\r
+  the convertion just for english language code from RFC 3066 to ISO 639-2.\r
+  Then it will check whether the converted language is in the supported language list.\r
+  If not supported, NULL is returned.\r
+  If Language is not english, NULL is returned.\r
 \r
-  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
-  @param  SystemTable    A pointer to the EFI System Table.\r
+  @param SupportedLanguages        Pointer to ComponentName supported language string list. ISO 639-2 language\r
+  @param Language                  The language string. RFC 3066 language\r
 \r
-  @retval EFI_SUCCESS    The entry point is executed successfully.\r
-  @retval other          Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-PlatOverMngrInit (\r
-  IN EFI_HANDLE                   ImageHandle,\r
-  IN EFI_SYSTEM_TABLE             *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  EFI_HII_DATABASE_PROTOCOL   *HiiDatabase;\r
-  EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
-  EFI_CALLBACK_INFO           *CallbackInfo;\r
-  EFI_HANDLE                  DriverHandle;\r
-  EFI_FORM_BROWSER2_PROTOCOL       *FormBrowser2;\r
-\r
-  //\r
-  // There should only be one HII protocol\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiHiiDatabaseProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &HiiDatabase\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status ;\r
-  }\r
-\r
-\r
-  //\r
-  // There should only be one Form Configuration protocol\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                 &gEfiFormBrowser2ProtocolGuid,\r
-                 NULL,\r
-                 (VOID **) &FormBrowser2\r
-                 );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;;\r
-  }\r
-\r
-\r
-  CallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));\r
-  if (CallbackInfo == NULL) {\r
-    return EFI_BAD_BUFFER_SIZE;\r
-  }\r
-\r
-  CallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;\r
-  CallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;\r
-  CallbackInfo->ConfigAccess.RouteConfig   = PlatOverMngrRouteConfig;\r
-  CallbackInfo->ConfigAccess.Callback      = PlatOverMngrCallback;\r
-\r
-  //\r
-  // Create driver handle used by HII database\r
-  //\r
-  Status = HiiLibCreateHiiDriverHandle (&DriverHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  CallbackInfo->DriverHandle = DriverHandle;\r
-\r
-  //\r
-  // Install Config Access protocol to driver handle\r
-  //\r
-  Status = gBS->InstallProtocolInterface (\r
-                  &DriverHandle,\r
-                  &gEfiHiiConfigAccessProtocolGuid,\r
-                  EFI_NATIVE_INTERFACE,\r
-                  &CallbackInfo->ConfigAccess\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Publish our HII data\r
-  //\r
-  PackageList = HiiLibPreparePackageList (\r
-                  2,\r
-                  &mPlatformOverridesManagerGuid,\r
-                  VfrBin,\r
-                  PlatOverMngrStrings\r
-                  );\r
-  ASSERT (PackageList != NULL);\r
-\r
-  Status = HiiDatabase->NewPackageList (\r
-                           HiiDatabase,\r
-                           PackageList,\r
-                           DriverHandle,\r
-                           &CallbackInfo->RegisteredHandle\r
-                           );\r
-  gBS->FreePool (PackageList);\r
-\r
-  //\r
-  // Locate ConfigRouting protocol\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiHiiConfigRoutingProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &CallbackInfo->HiiConfigRouting\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Clear all the globle variable\r
-  //\r
-  mDriverImageHandleCount = 0;\r
-  mCurrentPage = 0;\r
-  ZeroMem (mDriverImageToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
-  ZeroMem (mDriverImageFilePathToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
-  ZeroMem (mControllerToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
-  ZeroMem (mDriverImageProtocol, MAX_CHOICE_NUM * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));\r
-\r
-  //\r
-  // Show the page\r
-  //\r
-  Status = FormBrowser2->SendForm (\r
-                           FormBrowser2,\r
-                           &CallbackInfo->RegisteredHandle,\r
-                           1,\r
-                           NULL,\r
-                           0,\r
-                           NULL,\r
-                           NULL\r
-                           );\r
-\r
-  Status = HiiDatabase->RemovePackageList (HiiDatabase, CallbackInfo->RegisteredHandle);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Do some convertion for the ComponentName2 supported language. It do\r
-  the convertion just for english language code currently.\r
-\r
-  @param ComponentName    Pointer to the ComponentName2 protocl pointer.\r
-  @param Language         The language string.\r
-\r
-  @return   Return the duplication of Language if it is not english otherwise return\r
-            the supported english language code.\r
+  @return  English language string (ISO 639-2)\r
+  @return  NULL if the conertion is not successful.\r
 \r
 **/\r
 CHAR8 *\r
-ConvertComponentName2SupportLanguage (\r
-  IN EFI_COMPONENT_NAME2_PROTOCOL    *ComponentName,\r
+ConvertComponentNameSupportLanguage (\r
+  IN CHAR8                           *SupportedLanguages,\r
   IN CHAR8                           *Language\r
   )\r
 {\r
-  CHAR8                              *SupportedLanguages;\r
-  CHAR8                              *LangCode;\r
-  UINTN                              Index;\r
-\r
-  LangCode           = NULL;\r
-  SupportedLanguages = NULL;\r
+  CHAR8    *LangCode;\r
+  LangCode = NULL;\r
 \r
   //\r
-  // treat all the english language code (en-xx or eng) equally\r
+  // Check the input language is English\r
   //\r
-  if ((AsciiStrnCmp (Language, "en-", 3) == 0) || (AsciiStrCmp (Language, "eng") == 0)) {\r
-    SupportedLanguages = AsciiStrStr (ComponentName->SupportedLanguages, "en");\r
-    if (SupportedLanguages == NULL) {\r
-      SupportedLanguages = AsciiStrStr (ComponentName->SupportedLanguages, "eng");\r
-    }\r
-  }\r
-\r
-  //\r
-  // duplicate the Language if it is not english\r
-  //\r
-  if (SupportedLanguages == NULL) {\r
-    SupportedLanguages = Language;\r
+  if (AsciiStrnCmp (Language, "en-", 3) != 0) {\r
+    return NULL;\r
   }\r
-\r
+  \r
   //\r
-  // duplicate the returned language code.\r
+  // Check SupportedLanguages format\r
   //\r
-  if (AsciiStrStr (SupportedLanguages, "-") != NULL) {\r
-    LangCode = AllocateZeroPool(32);\r
-    for(Index = 0; (Index < 31) && (SupportedLanguages[Index] != '\0') && (SupportedLanguages[Index] != ';'); Index++) {\r
-      LangCode[Index] = SupportedLanguages[Index];\r
-    }\r
-    LangCode[Index] = '\0';\r
-  } else {\r
+  if (AsciiStrStr (SupportedLanguages, "en-") != NULL) {\r
+    //\r
+    // Create RFC 3066 language\r
+    //\r
+    LangCode = AllocateZeroPool(AsciiStrSize (Language));\r
+    AsciiStrCpy (LangCode, Language);\r
+  } else if (AsciiStrStr (SupportedLanguages, "en") != NULL) {\r
+    //\r
+    // Create ISO 639-2 Language\r
+    //\r
     LangCode = AllocateZeroPool(4);\r
-    for(Index = 0; (Index < 3) && (SupportedLanguages[Index] != '\0'); Index++) {\r
-      LangCode[Index] = SupportedLanguages[Index];\r
-    }\r
-    LangCode[Index] = '\0';\r
+    AsciiStrCpy (LangCode, "eng");    \r
   }\r
+  \r
   return LangCode;\r
 }\r
 \r
 /**\r
-  Get the ComponentName or ComponentName2 protocol according to the driver binding handle\r
+  Get the driver name by ComponentName or ComponentName2 protocol \r
+  according to the driver binding handle\r
 \r
   @param DriverBindingHandle  The Handle of DriverBinding.\r
 \r
@@ -301,23 +190,26 @@ GetComponentName (
   DriverName = NULL;\r
   if (ComponentName != NULL) {\r
     if (ComponentName->GetDriverName != NULL) {\r
-      Status = ComponentName->GetDriverName (\r
-                                ComponentName,\r
-                                mLanguage,\r
-                                &DriverName\r
-                                );\r
+      SupportedLanguage = ConvertComponentNameSupportLanguage (ComponentName->SupportedLanguages, mLanguage);\r
+      if (SupportedLanguage != NULL) {\r
+        Status = ComponentName->GetDriverName (\r
+                                  ComponentName,\r
+                                  SupportedLanguage,\r
+                                  &DriverName\r
+                                  );\r
+        FreePool (SupportedLanguage);\r
+      }\r
     }\r
   } else if (ComponentName2 != NULL) {\r
     if (ComponentName2->GetDriverName != NULL) {\r
-      SupportedLanguage = ConvertComponentName2SupportLanguage (ComponentName2, mLanguage);\r
       Status = ComponentName2->GetDriverName (\r
                                  ComponentName2,\r
-                                 SupportedLanguage,\r
+                                 mLanguage,\r
                                  &DriverName\r
                                  );\r
-        gBS->FreePool (SupportedLanguage);\r
     }\r
   }\r
+\r
   if (EFI_ERROR (Status)) {\r
     return NULL;\r
   }\r
@@ -326,12 +218,13 @@ GetComponentName (
 }\r
 \r
 /**\r
-  Get the image name\r
+  Get the image name from EFI UI section.\r
+  Get FV protocol by its loaded image protoocl to abastract EFI UI section.\r
 \r
-  @param Image            Image to search.\r
+  @param Image            Pointer to the loaded image protocol\r
 \r
-  @retval !NULL           Pointer into the image name if the image name is found,\r
-  @retval NULL            Pointer to NULL if the image name is not found.\r
+  @retval !NULL           Pointer to the image name if the image name is found,\r
+  @retval NULL            NULL if the image name is not found.\r
 \r
 **/\r
 CHAR16 *\r
@@ -356,13 +249,8 @@ GetImageName (
   if (Image->FilePath == NULL) {\r
     return NULL;\r
   }\r
-\r
   DevPathNode  = Image->FilePath;\r
 \r
-  if (DevPathNode == NULL) {\r
-    return NULL;\r
-  }\r
-\r
   while (!IsDevicePathEnd (DevPathNode)) {\r
     //\r
     // Make sure device path node is aligned when accessing it's FV Name Guid field.\r
@@ -380,6 +268,9 @@ GetImageName (
                     &gEfiFirmwareVolume2ProtocolGuid,\r
                     (VOID **) &Fv2\r
                     );\r
+      //\r
+      // Locate Image EFI UI section to get the image name.\r
+      //\r
       if (!EFI_ERROR (Status)) {\r
         Status = Fv2->ReadSection (\r
                         Fv2,\r
@@ -411,7 +302,9 @@ GetImageName (
 \r
 /**\r
   Prepare the first page to let user select the device controller which need to\r
-  add mapping drivers.\r
+  add mapping drivers if user select 'Refresh' in first page.\r
+  During first page, user will see all currnet controller device path in system,\r
+  select any device path will go to second page to select its overrides drivers.\r
 \r
   @param  Private        Pointer to EFI_CALLBACK_INFO.\r
   @param  KeyValue       The callback key value of device controller item in first page.\r
@@ -439,14 +332,15 @@ UpdateDeviceSelectPage (
   EFI_PCI_IO_PROTOCOL                       *PciIo;\r
   EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
   UINTN                                     Len;\r
-\r
-  mCurrentPage = FORM_ID_DEVICE;\r
+  \r
   //\r
-  // Following code will be run if user select 'Refresh' in first page\r
-  // During first page, user will see all currnet controller device path in system,\r
-  // select any device path will go to second page to select its overrides drivers\r
+  // set current page form ID.\r
+  //\r
+  mCurrentPage = FORM_ID_DEVICE;  \r
+  \r
+  //\r
+  // Get Platform supported Language (RFC_3066 format)\r
   //\r
-\r
   LangSize = RFC_3066_ENTRY_SIZE;\r
   Status = gRT->GetVariable (\r
               L"PlatformLang",\r
@@ -484,21 +378,22 @@ UpdateDeviceSelectPage (
 \r
   //\r
   // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,\r
-  // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are  same after the replacement\r
+  // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement\r
   //\r
   NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH);\r
   HiiLibGetStringFromHandle (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH), &NewString);\r
   ASSERT (NewString != NULL);\r
   Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, NewString);\r
   ASSERT_EFI_ERROR (Status);\r
-  gBS->FreePool (NewString);\r
+  FreePool (NewString);\r
 \r
   NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH_HELP);\r
   HiiLibGetStringFromHandle (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH_HELP), &NewString);\r
   ASSERT (NewString != NULL);\r
   Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, NewString);\r
   ASSERT_EFI_ERROR (Status);\r
-  gBS->FreePool (NewString);\r
+  FreePool (NewString);\r
+\r
   //\r
   // created needed controller device item in first page\r
   //\r
@@ -573,6 +468,7 @@ UpdateDeviceSelectPage (
     //\r
     Len = StrSize (ControllerName);\r
     NewString = AllocateZeroPool (Len + StrSize (L"--"));\r
+    ASSERT (NewString != NULL);\r
     if (EFI_ERROR (CheckMapping (ControllerDevicePath,NULL, &mMappingDataBase, NULL, NULL))) {\r
       StrCat (NewString, L"--");\r
     } else {\r
@@ -587,7 +483,7 @@ UpdateDeviceSelectPage (
       Status = HiiLibSetString (Private->RegisteredHandle, NewStringToken, NewString);\r
     }\r
     ASSERT_EFI_ERROR (Status);\r
-    gBS->FreePool (NewString);\r
+    FreePool (NewString);\r
     //\r
     // Save the device path string toke for next access use\r
     //\r
@@ -615,16 +511,85 @@ UpdateDeviceSelectPage (
     &UpdateData\r
     );\r
 \r
-  gBS->FreePool (UpdateData.Data);\r
+  FreePool (UpdateData.Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Get the first Driver Binding handle which has the specific image handle.\r
+\r
+  @param  ImageHandle          The Image handle\r
+\r
+  @return                      Handle to Driver binding\r
+  @retval NULL                 The paramter is not valid or the driver binding handle is not found.\r
+\r
+**/\r
+EFI_HANDLE\r
+GetDriverBindingHandleFromImageHandle (\r
+  IN  EFI_HANDLE   ImageHandle\r
+  )\r
+{\r
+  EFI_STATUS                        Status;\r
+  UINTN                             Index;\r
+  UINTN                             DriverBindingHandleCount;\r
+  EFI_HANDLE                        *DriverBindingHandleBuffer;\r
+  EFI_DRIVER_BINDING_PROTOCOL       *DriverBindingInterface;\r
+  EFI_HANDLE                        DriverBindingHandle;\r
+\r
+  DriverBindingHandle = NULL;\r
+\r
+  if (ImageHandle == NULL) {\r
+    return NULL;\r
+  }\r
+  //\r
+  // Get all drivers which support driver binding protocol\r
+  //\r
+  DriverBindingHandleCount  = 0;\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiDriverBindingProtocolGuid,\r
+                  NULL,\r
+                  &DriverBindingHandleCount,\r
+                  &DriverBindingHandleBuffer\r
+                  );\r
+  if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {\r
+    return NULL;\r
+  }\r
+  \r
+  //\r
+  // Get the first Driver Binding handle which has the specific image handle.\r
+  //\r
+  for (Index = 0; Index < DriverBindingHandleCount; Index++) {\r
+    DriverBindingInterface = NULL;\r
+    Status = gBS->OpenProtocol (\r
+                    DriverBindingHandleBuffer[Index],\r
+                    &gEfiDriverBindingProtocolGuid,\r
+                    (VOID **) &DriverBindingInterface,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    if (DriverBindingInterface->ImageHandle == ImageHandle) {\r
+      DriverBindingHandle = DriverBindingHandleBuffer[Index];\r
+      break;\r
+    }\r
+  }\r
+\r
+  FreePool (DriverBindingHandleBuffer);\r
+  return DriverBindingHandle;\r
+}\r
+\r
 /**\r
   Prepare to let user select the drivers which need mapping with the device controller\r
   selected in first page.\r
 \r
   @param  Private        Pointer to EFI_CALLBACK_INFO.\r
   @param  KeyValue       The callback key value of device controller item in first page.\r
+                         KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.\r
   @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.\r
 \r
   @retval EFI_SUCCESS    Always returned.\r
@@ -640,20 +605,17 @@ UpdateBindingDriverSelectPage (
   EFI_HII_UPDATE_DATA                       UpdateData;\r
   EFI_STATUS                                Status;\r
   UINTN                                     Index;\r
-\r
   CHAR16                                    *NewString;\r
   EFI_STRING_ID                             NewStringToken;\r
   EFI_STRING_ID                             NewStringHelpToken;\r
   UINTN                                     DriverImageHandleCount;\r
-\r
-  EFI_DRIVER_BINDING_PROTOCOL               *DriverBindingInterface;\r
   EFI_LOADED_IMAGE_PROTOCOL                 *LoadedImage;\r
   CHAR16                                    *DriverName;\r
   BOOLEAN                                   FreeDriverName;\r
-\r
   EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;\r
   EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;\r
   EFI_HANDLE                                DriverBindingHandle;\r
+\r
   //\r
   // If user select a controller item in the first page  the following code will be run.\r
   // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown\r
@@ -667,8 +629,9 @@ UpdateBindingDriverSelectPage (
   //\r
   // Switch the item callback key value to its NO. in mDevicePathHandleBuffer\r
   //\r
-  mSelectedCtrIndex = KeyValue - 0x100;\r
-  ASSERT (mSelectedCtrIndex < MAX_CHOICE_NUM);\r
+  mSelectedCtrIndex = KeyValue - KEY_VALUE_DEVICE_OFFSET;\r
+  ASSERT (mSelectedCtrIndex > 0 && mSelectedCtrIndex < MAX_CHOICE_NUM);\r
+\r
   mLastSavedDriverImageNum = 0;\r
   //\r
   // Clear all the content in dynamic page\r
@@ -731,13 +694,8 @@ UpdateBindingDriverSelectPage (
     //\r
     // Find its related driver binding protocol\r
     //\r
-    DriverBindingInterface = NULL;\r
-    DriverBindingHandle = NULL;\r
-    DriverBindingInterface = GetBindingProtocolFromImageHandle (\r
-                                mDriverImageHandleBuffer[Index],\r
-                                &DriverBindingHandle\r
-                                );\r
-    if (DriverBindingInterface == NULL) {\r
+    DriverBindingHandle = GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer[Index]);\r
+    if (DriverBindingHandle == NULL) {\r
       FakeNvData->DriSelection[Index] = 0x00;\r
       continue;\r
     }\r
@@ -807,6 +765,7 @@ UpdateBindingDriverSelectPage (
     // First create the driver image name\r
     //\r
     NewString = AllocateZeroPool (StrSize (DriverName));\r
+    ASSERT (NewString != NULL); \r
     if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], LoadedImageDevicePath, &mMappingDataBase, NULL, NULL))) {\r
       FakeNvData->DriSelection[Index] = 0x00;\r
     } else {\r
@@ -822,9 +781,9 @@ UpdateBindingDriverSelectPage (
     }\r
     mDriverImageToken[Index] = NewStringToken;\r
     ASSERT_EFI_ERROR (Status);\r
-    gBS->FreePool (NewString);\r
+    FreePool (NewString);\r
     if (FreeDriverName) {\r
-      gBS->FreePool (DriverName);\r
+      FreePool (DriverName);\r
     }\r
 \r
     //\r
@@ -833,6 +792,7 @@ UpdateBindingDriverSelectPage (
     DriverName = DevicePathToStr (LoadedImageDevicePath);\r
 \r
     NewString = AllocateZeroPool (StrSize (DriverName));\r
+    ASSERT (NewString != NULL); \r
     StrCat (NewString, DriverName);\r
     NewStringHelpToken = mDriverImageFilePathToken[Index];\r
     if (NewStringHelpToken == 0) {\r
@@ -842,8 +802,8 @@ UpdateBindingDriverSelectPage (
     }\r
     mDriverImageFilePathToken[Index] = NewStringHelpToken;\r
     ASSERT_EFI_ERROR (Status);\r
-    gBS->FreePool (NewString);\r
-    gBS->FreePool (DriverName);\r
+    FreePool (NewString);\r
+    FreePool (DriverName);\r
 \r
     CreateCheckBoxOpCode (\r
       (UINT16) (DRIVER_SELECTION_QUESTION_ID + Index),\r
@@ -869,7 +829,7 @@ UpdateBindingDriverSelectPage (
     &UpdateData\r
     );\r
 \r
-  gBS->FreePool (UpdateData.Data);\r
+  FreePool (UpdateData.Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -893,9 +853,7 @@ UpdatePrioritySelectPage (
 {\r
   EFI_HII_UPDATE_DATA                       UpdateData;\r
   UINTN                                     Index;\r
-\r
   EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;\r
-\r
   IFR_OPTION                                *IfrOptionList;\r
   UINTN                                     SelectedDriverImageNum;\r
   UINT32                                    DriverImageNO;\r
@@ -939,9 +897,9 @@ UpdatePrioritySelectPage (
   if (SelectedDriverImageNum == 0) {\r
     return EFI_SUCCESS;\r
   }\r
-\r
-  IfrOptionList = AllocateZeroPool (0x200);\r
-  ASSERT_EFI_ERROR (IfrOptionList != NULL);\r
+  \r
+  IfrOptionList = AllocateZeroPool (sizeof (IFR_OPTION) * mSelectedDriverImageNum);\r
+  ASSERT (IfrOptionList != NULL);\r
   //\r
   // Create order list for those selected drivers\r
   //\r
@@ -970,6 +928,7 @@ UpdatePrioritySelectPage (
       // Check the driver DriverImage's order number in mapping database\r
       //\r
       DriverImageNO = 0;\r
+      ASSERT (mSelectedCtrIndex < MAX_CHOICE_NUM);\r
       CheckMapping (\r
               mControllerDevicePathProtocol[mSelectedCtrIndex],\r
               LoadedImageDevicePath,\r
@@ -990,7 +949,7 @@ UpdatePrioritySelectPage (
   //\r
   // NvRamMap Must be clear firstly\r
   //\r
-  ZeroMem (FakeNvData->DriOrder, 100);\r
+  ZeroMem (FakeNvData->DriOrder, sizeof (FakeNvData->DriOrder));\r
 \r
   //\r
   // Order the selected drivers according to the info already in mapping database\r
@@ -1010,7 +969,7 @@ UpdatePrioritySelectPage (
     // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer\r
     //\r
     FakeNvData->DriOrder[Index] =IfrOptionList[MinNO].Value.u8;\r
-    TempNO[MinNO] = 101;\r
+    TempNO[MinNO] = MAX_CHOICE_NUM + 1;\r
   }\r
 \r
   CreateOrderedListOpCode (\r
@@ -1022,7 +981,7 @@ UpdatePrioritySelectPage (
     EFI_IFR_FLAG_RESET_REQUIRED,\r
     0,\r
     EFI_IFR_NUMERIC_SIZE_1,\r
-    100,\r
+    (UINT8) MAX_CHOICE_NUM,\r
     IfrOptionList,\r
     SelectedDriverImageNum,\r
     &UpdateData\r
@@ -1040,8 +999,8 @@ UpdatePrioritySelectPage (
     &UpdateData\r
     );\r
 \r
-  gBS->FreePool (IfrOptionList);\r
-  gBS->FreePool (UpdateData.Data);\r
+  FreePool (IfrOptionList);\r
+  FreePool (UpdateData.Data);\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -1070,6 +1029,7 @@ CommintChanges (
   //  Following code will be run if user select 'commint changes' in third page\r
   //  user enter 'Commit Changes' to save the mapping database\r
   //\r
+  ASSERT (mSelectedCtrIndex < MAX_CHOICE_NUM);\r
   DeleteDriverImage (mControllerDevicePathProtocol[mSelectedCtrIndex], NULL, &mMappingDataBase);\r
   for (SelectedDriverImageNum = 0; SelectedDriverImageNum < mSelectedDriverImageNum; SelectedDriverImageNum++) {\r
     //\r
@@ -1124,7 +1084,7 @@ CommintChanges (
 EFI_STATUS\r
 EFIAPI\r
 PlatOverMngrExtractConfig (\r
- IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
 IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
   IN  CONST EFI_STRING                       Request,\r
   OUT EFI_STRING                             *Progress,\r
   OUT EFI_STRING                             *Results\r
@@ -1273,9 +1233,9 @@ PlatOverMngrCallback (
     ASSERT_EFI_ERROR (Status);\r
   }\r
 \r
-  if (((KEY_VALUE_DEVICE_OFFSET <= KeyValue) && (KeyValue < KEY_VALUE_DEVICE_MAX)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {\r
+  if (((KeyValue >= KEY_VALUE_DEVICE_OFFSET) && (KeyValue < KEY_VALUE_DEVICE_MAX)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {\r
     if (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS) {\r
-      KeyValue = (EFI_QUESTION_ID) (mSelectedCtrIndex + 0x100);\r
+      KeyValue = (EFI_QUESTION_ID) (mSelectedCtrIndex + KEY_VALUE_DEVICE_OFFSET);\r
     }\r
     UpdateBindingDriverSelectPage (Private, KeyValue, FakeNvData);\r
     //\r
@@ -1323,41 +1283,161 @@ PlatOverMngrCallback (
 }\r
 \r
 /**\r
-  Get the description string by device path.\r
+  The driver Entry Point. The funciton will export a disk device class formset and\r
+  its callback function to hii database.\r
 \r
-  @param  DevPath     The input device path.\r
+  @param  ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param  SystemTable    A pointer to the EFI System Table.\r
 \r
-  @retval !NULL       The description string retured.\r
-  @retval  NULL       The description string cannot be found.\r
+  @retval EFI_SUCCESS    The entry point is executed successfully.\r
+  @retval other          Some error occurs when executing this entry point.\r
 \r
 **/\r
-CHAR16 *\r
-DevicePathToStr (\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath\r
+EFI_STATUS\r
+EFIAPI\r
+PlatOverMngrInit (\r
+  IN EFI_HANDLE                   ImageHandle,\r
+  IN EFI_SYSTEM_TABLE             *SystemTable\r
   )\r
 {\r
-  EFI_STATUS                       Status;\r
-  CHAR16                           *ToText;\r
-  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
+  EFI_STATUS                  Status;\r
+  EFI_HII_DATABASE_PROTOCOL   *HiiDatabase;\r
+  EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
+  EFI_CALLBACK_INFO           *CallbackInfo;\r
+  EFI_HANDLE                  DriverHandle;\r
+  EFI_FORM_BROWSER2_PROTOCOL       *FormBrowser2;\r
+  \r
+  //\r
+  // There should only be one HII protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiHiiDatabaseProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &HiiDatabase\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
-  if (DevPath == NULL) {\r
-    return NULL;\r
+  //\r
+  // There should only be one Form Configuration protocol\r
+  //\r
+  Status = gBS->LocateProtocol (\r
+                 &gEfiFormBrowser2ProtocolGuid,\r
+                 NULL,\r
+                 (VOID **) &FormBrowser2\r
+                 );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  CallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));\r
+  if (CallbackInfo == NULL) {\r
+    return EFI_BAD_BUFFER_SIZE;\r
+  }\r
+\r
+  CallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;\r
+  CallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;\r
+  CallbackInfo->ConfigAccess.RouteConfig   = PlatOverMngrRouteConfig;\r
+  CallbackInfo->ConfigAccess.Callback      = PlatOverMngrCallback;\r
+\r
+  //\r
+  // Create driver handle used by HII database\r
+  //\r
+  Status = HiiLibCreateHiiDriverHandle (&DriverHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
   }\r
+  CallbackInfo->DriverHandle = DriverHandle;\r
 \r
+  //\r
+  // Install Config Access protocol to driver handle\r
+  //\r
+  Status = gBS->InstallProtocolInterface (\r
+                  &DriverHandle,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &CallbackInfo->ConfigAccess\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // Publish our HII data\r
+  //\r
+  PackageList = HiiLibPreparePackageList (\r
+                  2,\r
+                  &mPlatformOverridesManagerGuid,\r
+                  VfrBin,\r
+                  PlatOverMngrStrings\r
+                  );\r
+  ASSERT (PackageList != NULL);\r
+\r
+  Status = HiiDatabase->NewPackageList (\r
+                           HiiDatabase,\r
+                           PackageList,\r
+                           DriverHandle,\r
+                           &CallbackInfo->RegisteredHandle\r
+                           );\r
+  FreePool (PackageList);\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // Locate ConfigRouting protocol\r
+  //\r
   Status = gBS->LocateProtocol (\r
-                  &gEfiDevicePathToTextProtocolGuid,\r
+                  &gEfiHiiConfigRoutingProtocolGuid,\r
                   NULL,\r
-                  (VOID **) &DevPathToText\r
+                  (VOID **) &CallbackInfo->HiiConfigRouting\r
                   );\r
-  if (!EFI_ERROR (Status)) {\r
-    ToText = DevPathToText->ConvertDevicePathToText (\r
-                              DevPath,\r
-                              FALSE,\r
-                              TRUE\r
-                              );\r
-    ASSERT (ToText != NULL);\r
-    return ToText;\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
+  }\r
+\r
+  //\r
+  // Clear all the globle variable\r
+  //\r
+  mDriverImageHandleCount = 0;\r
+  mCurrentPage = 0;\r
+  ZeroMem (mDriverImageToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+  ZeroMem (mDriverImageFilePathToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+  ZeroMem (mControllerToken, MAX_CHOICE_NUM * sizeof (EFI_STRING_ID));\r
+  ZeroMem (mDriverImageProtocol, MAX_CHOICE_NUM * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));\r
+\r
+  //\r
+  // Show the page\r
+  //\r
+  Status = FormBrowser2->SendForm (\r
+                           FormBrowser2,\r
+                           &CallbackInfo->RegisteredHandle,\r
+                           1,\r
+                           NULL,\r
+                           0,\r
+                           NULL,\r
+                           NULL\r
+                           );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
   }\r
 \r
-  return NULL;\r
+  Status = HiiDatabase->RemovePackageList (HiiDatabase, CallbackInfo->RegisteredHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Finish;\r
+  }\r
+  \r
+  return EFI_SUCCESS;\r
+\r
+Finish:\r
+  if (CallbackInfo->DriverHandle != NULL) {\r
+    HiiLibDestroyHiiDriverHandle (CallbackInfo->DriverHandle);\r
+  }\r
+  if (CallbackInfo != NULL) {\r
+    FreePool (CallbackInfo);\r
+  }\r
+\r
+  return Status;\r
 }\r