Home | History | Annotate | Download | only in PlatformDriOverrideDxe
      1 /** @file
      2   This file also installs UEFI PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
      3 
      4   The main code offers a UI interface in device manager to let user configure
      5   platform override protocol to override the default algorithm for matching
      6   drivers to controllers.
      7 
      8   The main flow:
      9   1. It dynamicly locate all controller device path.
     10   2. It dynamicly locate all drivers which support binding protocol.
     11   3. It export and dynamicly update two menu to let user select the
     12      mapping between drivers to controllers.
     13   4. It save all the mapping info in NV variables which will be consumed
     14      by platform override protocol driver to publish the platform override protocol.
     15 
     16 Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
     17 This program and the accompanying materials
     18 are licensed and made available under the terms and conditions of the BSD License
     19 which accompanies this distribution.  The full text of the license may be found at
     20 http://opensource.org/licenses/bsd-license.php
     21 
     22 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     23 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     24 
     25 **/
     26 
     27 #include "InternalPlatDriOverrideDxe.h"
     28 #include "PlatOverMngr.h"
     29 
     30 #define EFI_CALLBACK_INFO_SIGNATURE SIGNATURE_32 ('C', 'l', 'b', 'k')
     31 #define EFI_CALLBACK_INFO_FROM_THIS(a)  CR (a, EFI_CALLBACK_INFO, ConfigAccess, EFI_CALLBACK_INFO_SIGNATURE)
     32 
     33 typedef struct {
     34   UINTN                           Signature;
     35   EFI_HANDLE                      DriverHandle;
     36   EFI_HII_HANDLE                  RegisteredHandle;
     37   PLAT_OVER_MNGR_DATA             FakeNvData;
     38   EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
     39   EFI_HII_CONFIG_ACCESS_PROTOCOL  ConfigAccess;
     40   EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL PlatformDriverOverride;
     41 } EFI_CALLBACK_INFO;
     42 
     43 #pragma pack(1)
     44 
     45 ///
     46 /// HII specific Vendor Device Path definition.
     47 ///
     48 typedef struct {
     49   VENDOR_DEVICE_PATH             VendorDevicePath;
     50   EFI_DEVICE_PATH_PROTOCOL       End;
     51 } HII_VENDOR_DEVICE_PATH;
     52 
     53 #pragma pack()
     54 
     55 //
     56 // uni string and Vfr Binary data.
     57 //
     58 extern UINT8  VfrBin[];
     59 extern UINT8  PlatDriOverrideDxeStrings[];
     60 
     61 //
     62 // module global data
     63 //
     64 CHAR16                       mVariableName[] = L"Data";
     65 LIST_ENTRY                   mMappingDataBase = INITIALIZE_LIST_HEAD_VARIABLE (mMappingDataBase);
     66 BOOLEAN                      mEnvironmentVariableRead = FALSE;
     67 EFI_HANDLE                   mCallerImageHandle = NULL;
     68 
     69 EFI_HANDLE                   *mDevicePathHandleBuffer;
     70 EFI_HANDLE                   *mDriverImageHandleBuffer;
     71 
     72 INTN                         mSelectedCtrIndex;
     73 EFI_STRING_ID                *mControllerToken;
     74 UINTN                        mDriverImageHandleCount;
     75 EFI_STRING_ID                *mDriverImageToken;
     76 EFI_DEVICE_PATH_PROTOCOL     **mControllerDevicePathProtocol;
     77 UINTN                        mSelectedDriverImageNum;
     78 UINTN                        mLastSavedDriverImageNum;
     79 UINT16                       mCurrentPage;
     80 EFI_CALLBACK_INFO           *mCallbackInfo;
     81 BOOLEAN                     *mDriSelection;
     82 UINTN                        mMaxDeviceCount;
     83 
     84 HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath = {
     85   {
     86     {
     87       HARDWARE_DEVICE_PATH,
     88       HW_VENDOR_DP,
     89       {
     90         (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
     91         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
     92       }
     93     },
     94     PLAT_OVER_MNGR_GUID
     95   },
     96   {
     97     END_DEVICE_PATH_TYPE,
     98     END_ENTIRE_DEVICE_PATH_SUBTYPE,
     99     {
    100       (UINT8) (END_DEVICE_PATH_LENGTH),
    101       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
    102     }
    103   }
    104 };
    105 
    106 /**
    107   Converting a given device to an unicode string.
    108 
    109   @param    DevPath     Given device path instance
    110 
    111   @return   Converted string from given device path.
    112   @retval   L"?" Converting failed.
    113 **/
    114 CHAR16 *
    115 DevicePathToStr (
    116   IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
    117   )
    118 {
    119   CHAR16                          *Text;
    120   Text = ConvertDevicePathToText (
    121            DevPath,
    122            FALSE,
    123            TRUE
    124            );
    125   if (Text == NULL) {
    126     Text = AllocateCopyPool (sizeof (L"?"), L"?");
    127     ASSERT (Text != NULL);
    128   }
    129 
    130   return Text;
    131 }
    132 
    133 /**
    134   Worker function to get the driver name by ComponentName or ComponentName2 protocol
    135   according to the driver binding handle.
    136 
    137   @param  DriverBindingHandle  The Handle of DriverBinding.
    138   @param  ProtocolGuid         The pointer to Component Name (2) protocol GUID.
    139   @param  VariableName         The name of the RFC 4646 or ISO 639-2 language variable.
    140 
    141   @retval !NULL               Pointer into the image name if the image name is found,
    142   @retval NULL                Pointer to NULL if the image name is not found.
    143 
    144 **/
    145 CHAR16 *
    146 GetComponentNameWorker (
    147   IN EFI_HANDLE                      DriverBindingHandle,
    148   IN EFI_GUID                        *ProtocolGuid,
    149   IN CONST CHAR16                    *VariableName
    150   )
    151 {
    152   EFI_STATUS                         Status;
    153   EFI_COMPONENT_NAME_PROTOCOL        *ComponentName;
    154   CHAR16                             *DriverName;
    155   CHAR8                              *Language;
    156   CHAR8                              *BestLanguage;
    157 
    158   Status = gBS->OpenProtocol (
    159                   DriverBindingHandle,
    160                   ProtocolGuid,
    161                   (VOID *) &ComponentName,
    162                   NULL,
    163                   NULL,
    164                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    165                   );
    166   if (EFI_ERROR (Status)) {
    167     return NULL;
    168   }
    169 
    170   //
    171   // Find the best matching language.
    172   //
    173   GetEfiGlobalVariable2 (VariableName, (VOID**)&Language, NULL);
    174   BestLanguage = GetBestLanguage (
    175                    ComponentName->SupportedLanguages,
    176                    (BOOLEAN) (ProtocolGuid == &gEfiComponentNameProtocolGuid),
    177                    Language,
    178                    NULL
    179                    );
    180 
    181   DriverName = NULL;
    182   if (BestLanguage != NULL) {
    183     ComponentName->GetDriverName (
    184                      ComponentName,
    185                      BestLanguage,
    186                      &DriverName
    187                      );
    188     FreePool (BestLanguage);
    189   }
    190 
    191   if (Language != NULL) {
    192     FreePool (Language);
    193   }
    194 
    195   return DriverName;
    196 }
    197 
    198 
    199 /**
    200   Get the driver name by ComponentName or ComponentName2 protocol
    201   according to the driver binding handle
    202 
    203   @param DriverBindingHandle  The Handle of DriverBinding.
    204 
    205   @retval !NULL               Pointer into the image name if the image name is found,
    206   @retval NULL                Pointer to NULL if the image name is not found.
    207 
    208 **/
    209 CHAR16 *
    210 GetComponentName (
    211   IN EFI_HANDLE                      DriverBindingHandle
    212   )
    213 {
    214   CHAR16                    *DriverName;
    215 
    216   //
    217   // Try RFC 4646 Component Name 2 protocol first.
    218   //
    219   DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentName2ProtocolGuid, L"PlatformLang");
    220   if (DriverName == NULL) {
    221     //
    222     // If we can not get driver name from Component Name 2 protocol, we can try ISO 639-2 Component Name protocol.
    223     //
    224     DriverName = GetComponentNameWorker (DriverBindingHandle, &gEfiComponentNameProtocolGuid, L"Lang");
    225   }
    226 
    227   return DriverName;
    228 }
    229 
    230 /**
    231   Get the image name from EFI UI section.
    232   Get FV protocol by its loaded image protocol to abstract EFI UI section.
    233 
    234   @param Image            Pointer to the loaded image protocol
    235 
    236   @retval !NULL           Pointer to the image name if the image name is found,
    237   @retval NULL            NULL if the image name is not found.
    238 
    239 **/
    240 CHAR16 *
    241 GetImageName (
    242   IN EFI_LOADED_IMAGE_PROTOCOL *Image
    243   )
    244 {
    245   EFI_STATUS                        Status;
    246   EFI_DEVICE_PATH_PROTOCOL          *DevPathNode;
    247   EFI_DEVICE_PATH_PROTOCOL          *AlignedDevPathNode;
    248   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
    249   VOID                              *Buffer;
    250   UINTN                             BufferSize;
    251   UINT32                            AuthenticationStatus;
    252   EFI_GUID                          *NameGuid;
    253   EFI_FIRMWARE_VOLUME2_PROTOCOL     *Fv2;
    254 
    255   Fv2         = NULL;
    256   Buffer      = NULL;
    257   BufferSize  = 0;
    258 
    259   if (Image->FilePath == NULL) {
    260     return NULL;
    261   }
    262   DevPathNode  = Image->FilePath;
    263 
    264   while (!IsDevicePathEnd (DevPathNode)) {
    265     //
    266     // Make sure device path node is aligned when accessing it's FV Name Guid field.
    267     //
    268     AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength(DevPathNode), DevPathNode);
    269 
    270     //
    271     // Find the Fv File path
    272     //
    273     NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)AlignedDevPathNode);
    274     if (NameGuid != NULL) {
    275       FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) AlignedDevPathNode;
    276       Status = gBS->HandleProtocol (
    277                     Image->DeviceHandle,
    278                     &gEfiFirmwareVolume2ProtocolGuid,
    279                     (VOID **) &Fv2
    280                     );
    281       //
    282       // Locate Image EFI UI section to get the image name.
    283       //
    284       if (!EFI_ERROR (Status)) {
    285         Status = Fv2->ReadSection (
    286                         Fv2,
    287                         &FvFilePath->FvFileName,
    288                         EFI_SECTION_USER_INTERFACE,
    289                         0,
    290                         &Buffer,
    291                         &BufferSize,
    292                         &AuthenticationStatus
    293                         );
    294         if (!EFI_ERROR (Status)) {
    295           FreePool (AlignedDevPathNode);
    296           break;
    297         }
    298         Buffer = NULL;
    299       }
    300     }
    301 
    302     FreePool (AlignedDevPathNode);
    303 
    304     //
    305     // Next device path node
    306     //
    307     DevPathNode = NextDevicePathNode (DevPathNode);
    308   }
    309 
    310   return Buffer;
    311 }
    312 
    313 /**
    314   Prepare the first page to let user select the device controller which need to
    315   add mapping drivers if user select 'Refresh' in first page.
    316   During first page, user will see all currnet controller device path in system,
    317   select any device path will go to second page to select its overrides drivers.
    318 
    319   @param  Private        Pointer to EFI_CALLBACK_INFO.
    320   @param  KeyValue       The callback key value of device controller item in first page.
    321   @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.
    322 
    323   @retval EFI_SUCCESS    Always returned.
    324 
    325 **/
    326 EFI_STATUS
    327 UpdateDeviceSelectPage (
    328   IN EFI_CALLBACK_INFO                *Private,
    329   IN UINT16                           KeyValue,
    330   IN PLAT_OVER_MNGR_DATA              *FakeNvData
    331   )
    332 {
    333   EFI_STATUS                                Status;
    334   UINTN                                     Index;
    335   UINTN                                     DevicePathHandleCount;
    336   UINTN                                     NewStrSize;
    337   CHAR16                                    *NewString;
    338   EFI_STRING_ID                             NewStringToken;
    339   CHAR16                                    *ControllerName;
    340   EFI_DEVICE_PATH_PROTOCOL                  *ControllerDevicePath;
    341   EFI_PCI_IO_PROTOCOL                       *PciIo;
    342   EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
    343   UINTN                                     Len;
    344   VOID                                      *StartOpCodeHandle;
    345   VOID                                      *EndOpCodeHandle;
    346   EFI_IFR_GUID_LABEL                        *StartLabel;
    347   EFI_IFR_GUID_LABEL                        *EndLabel;
    348 
    349   //
    350   // Set current page form ID.
    351   //
    352   mCurrentPage = FORM_ID_DEVICE;
    353 
    354   //
    355   // Initial the mapping database in memory
    356   //
    357   FreeMappingDatabase (&mMappingDataBase);
    358   InitOverridesMapping (&mMappingDataBase);
    359 
    360   //
    361   // Init OpCode Handle
    362   //
    363   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    364   ASSERT (StartOpCodeHandle != NULL);
    365 
    366   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    367   ASSERT (EndOpCodeHandle != NULL);
    368 
    369   //
    370   // Create Hii Extend Label OpCode as the start opcode
    371   //
    372   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
    373   StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    374   StartLabel->Number = FORM_ID_DEVICE;
    375 
    376   //
    377   // Create Hii Extend Label OpCode as the end opcode
    378   //
    379   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
    380   EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    381   EndLabel->Number       = LABEL_END;
    382 
    383   //
    384   // Clear first page form
    385   //
    386   HiiUpdateForm (
    387     Private->RegisteredHandle,
    388     &gPlatformOverridesManagerGuid,
    389     FORM_ID_DEVICE,
    390     StartOpCodeHandle, // Label FORM_ID_DEVICE
    391     EndOpCodeHandle    // LABEL_END
    392     );
    393 
    394   //
    395   // When user enter the page at first time, the 'first refresh' string is given to notify user to refresh all the drivers,
    396   // then the 'first refresh' string will be replaced by the 'refresh' string, and the two strings content are same after the replacement
    397   //
    398   NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH);
    399   NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH), NULL);
    400   ASSERT (NewString != NULL);
    401   if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {
    402     ASSERT (FALSE);
    403   }
    404   FreePool (NewString);
    405 
    406   NewStringToken = STRING_TOKEN (STR_FIRST_REFRESH_HELP);
    407   NewString = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_REFRESH_HELP), NULL);
    408   ASSERT (NewString != NULL);
    409   if (HiiSetString (Private->RegisteredHandle, NewStringToken, NewString, NULL) == 0) {
    410     ASSERT (FALSE);
    411   }
    412   FreePool (NewString);
    413 
    414   //
    415   // created needed controller device item in first page
    416   //
    417   DevicePathHandleCount  = 0;
    418   Status = gBS->LocateHandleBuffer (
    419                   ByProtocol,
    420                   &gEfiDevicePathProtocolGuid,
    421                   NULL,
    422                   &DevicePathHandleCount,
    423                   &mDevicePathHandleBuffer
    424                   );
    425   if (EFI_ERROR (Status) || (DevicePathHandleCount == 0)) {
    426     return EFI_SUCCESS;
    427   }
    428 
    429   mMaxDeviceCount = DevicePathHandleCount;
    430   mControllerDevicePathProtocol = AllocateZeroPool (DevicePathHandleCount * sizeof (EFI_DEVICE_PATH_PROTOCOL *));
    431   ASSERT (mControllerDevicePathProtocol != NULL);
    432   mControllerToken = AllocateZeroPool (DevicePathHandleCount * sizeof (EFI_STRING_ID));
    433   ASSERT (mControllerToken != NULL);
    434 
    435   for (Index = 0; Index < DevicePathHandleCount; Index++) {
    436     if (FakeNvData->PciDeviceFilter == 0x01) {
    437       //
    438       // Only care PCI device which contain efi driver in its option rom.
    439       //
    440 
    441       //
    442       // Check whether it is a pci device
    443       //
    444       ControllerDevicePath = NULL;
    445       Status = gBS->OpenProtocol (
    446                       mDevicePathHandleBuffer[Index],
    447                       &gEfiPciIoProtocolGuid,
    448                       (VOID **) &PciIo,
    449                       NULL,
    450                       NULL,
    451                       EFI_OPEN_PROTOCOL_GET_PROTOCOL
    452                       );
    453       if (EFI_ERROR (Status)) {
    454         continue;
    455       }
    456       //
    457       // Check whether it contain efi driver in its option rom
    458       //
    459       Status = gBS->HandleProtocol(
    460                        mDevicePathHandleBuffer[Index],
    461                        &gEfiBusSpecificDriverOverrideProtocolGuid,
    462                        (VOID **) &BusSpecificDriverOverride
    463                        );
    464       if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {
    465         continue;
    466       }
    467     }
    468 
    469     ControllerDevicePath = NULL;
    470     Status = gBS->OpenProtocol (
    471                     mDevicePathHandleBuffer[Index],
    472                     &gEfiDevicePathProtocolGuid,
    473                     (VOID **) &ControllerDevicePath,
    474                     NULL,
    475                     NULL,
    476                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    477                     );
    478     ASSERT_EFI_ERROR (Status);
    479     //
    480     // Save the device path protocol interface
    481     //
    482     mControllerDevicePathProtocol[Index] = ControllerDevicePath;
    483 
    484     //
    485     // Get the driver name
    486     //
    487     ControllerName = DevicePathToStr (ControllerDevicePath);
    488 
    489     //
    490     // Export the driver name string and create item in set options page
    491     //
    492     Len = StrSize (ControllerName);
    493     NewStrSize = Len + StrSize (L"--");
    494     NewString = AllocateZeroPool (NewStrSize);
    495     ASSERT (NewString != NULL);
    496     if (EFI_ERROR (CheckMapping (ControllerDevicePath,NULL, &mMappingDataBase, NULL, NULL))) {
    497       StrCatS (NewString, NewStrSize/sizeof(CHAR16), L"--");
    498     } else {
    499       StrCatS (NewString, NewStrSize/sizeof(CHAR16), L"**");
    500     }
    501     StrCatS (NewString, NewStrSize/sizeof(CHAR16), ControllerName);
    502 
    503     NewStringToken = HiiSetString (Private->RegisteredHandle, mControllerToken[Index], NewString, NULL);
    504     ASSERT (NewStringToken != 0);
    505     FreePool (NewString);
    506     //
    507     // Save the device path string toke for next access use
    508     //
    509     mControllerToken[Index] = NewStringToken;
    510 
    511     HiiCreateGotoOpCode (
    512       StartOpCodeHandle,
    513       FORM_ID_DRIVER,
    514       NewStringToken,
    515       STRING_TOKEN (STR_GOTO_HELP_DRIVER),
    516       EFI_IFR_FLAG_CALLBACK,
    517       (UINT16) (Index + KEY_VALUE_DEVICE_OFFSET)
    518       );
    519   }
    520 
    521   //
    522   // Update first page form
    523   //
    524   HiiUpdateForm (
    525     Private->RegisteredHandle,
    526     &gPlatformOverridesManagerGuid,
    527     FORM_ID_DEVICE,
    528     StartOpCodeHandle, // Label FORM_ID_DEVICE
    529     EndOpCodeHandle    // LABEL_END
    530     );
    531 
    532   HiiFreeOpCodeHandle (StartOpCodeHandle);
    533   HiiFreeOpCodeHandle (EndOpCodeHandle);
    534 
    535   return EFI_SUCCESS;
    536 }
    537 
    538 /**
    539   Get the first Driver Binding handle which has the specific image handle.
    540 
    541   @param  ImageHandle          The Image handle
    542 
    543   @return                      Handle to Driver binding
    544   @retval NULL                 The parameter is not valid or the driver binding handle is not found.
    545 
    546 **/
    547 EFI_HANDLE
    548 GetDriverBindingHandleFromImageHandle (
    549   IN  EFI_HANDLE   ImageHandle
    550   )
    551 {
    552   EFI_STATUS                        Status;
    553   UINTN                             Index;
    554   UINTN                             DriverBindingHandleCount;
    555   EFI_HANDLE                        *DriverBindingHandleBuffer;
    556   EFI_DRIVER_BINDING_PROTOCOL       *DriverBindingInterface;
    557   EFI_HANDLE                        DriverBindingHandle;
    558 
    559   DriverBindingHandle = NULL;
    560 
    561   if (ImageHandle == NULL) {
    562     return NULL;
    563   }
    564   //
    565   // Get all drivers which support driver binding protocol
    566   //
    567   DriverBindingHandleCount  = 0;
    568   Status = gBS->LocateHandleBuffer (
    569                   ByProtocol,
    570                   &gEfiDriverBindingProtocolGuid,
    571                   NULL,
    572                   &DriverBindingHandleCount,
    573                   &DriverBindingHandleBuffer
    574                   );
    575   if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
    576     return NULL;
    577   }
    578 
    579   //
    580   // Get the first Driver Binding handle which has the specific image handle.
    581   //
    582   for (Index = 0; Index < DriverBindingHandleCount; Index++) {
    583     DriverBindingInterface = NULL;
    584     Status = gBS->OpenProtocol (
    585                     DriverBindingHandleBuffer[Index],
    586                     &gEfiDriverBindingProtocolGuid,
    587                     (VOID **) &DriverBindingInterface,
    588                     NULL,
    589                     NULL,
    590                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    591                     );
    592     if (EFI_ERROR (Status)) {
    593       continue;
    594     }
    595 
    596     if (DriverBindingInterface->ImageHandle == ImageHandle) {
    597       DriverBindingHandle = DriverBindingHandleBuffer[Index];
    598       break;
    599     }
    600   }
    601 
    602   FreePool (DriverBindingHandleBuffer);
    603   return DriverBindingHandle;
    604 }
    605 
    606 /**
    607   Prepare to let user select the drivers which need mapping with the device controller
    608   selected in first page.
    609 
    610   @param  Private        Pointer to EFI_CALLBACK_INFO.
    611   @param  KeyValue       The callback key value of device controller item in first page.
    612                          KeyValue is larger than or equal to KEY_VALUE_DEVICE_OFFSET.
    613   @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.
    614 
    615   @retval EFI_SUCCESS    Always returned.
    616 
    617 **/
    618 EFI_STATUS
    619 UpdateBindingDriverSelectPage (
    620   IN EFI_CALLBACK_INFO                *Private,
    621   IN UINT16                           KeyValue,
    622   IN PLAT_OVER_MNGR_DATA              *FakeNvData
    623   )
    624 {
    625   EFI_STATUS                                Status;
    626   UINTN                                     Index;
    627   UINTN                                     NewStrSize;
    628   CHAR16                                    *NewString;
    629   EFI_STRING_ID                             NewStringToken;
    630   EFI_STRING_ID                             NewStringHelpToken;
    631   UINTN                                     DriverImageHandleCount;
    632   EFI_LOADED_IMAGE_PROTOCOL                 *LoadedImage;
    633   CHAR16                                    *DriverName;
    634   BOOLEAN                                   FreeDriverName;
    635   EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;
    636   EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
    637   EFI_HANDLE                                DriverBindingHandle;
    638   VOID                                      *StartOpCodeHandle;
    639   VOID                                      *EndOpCodeHandle;
    640   EFI_IFR_GUID_LABEL                        *StartLabel;
    641   EFI_IFR_GUID_LABEL                        *EndLabel;
    642   EFI_LOADED_IMAGE_PROTOCOL                 **DriverImageProtocol;
    643   EFI_STRING_ID                             *DriverImageFilePathToken;
    644   UINT8                                     CheckFlags;
    645 
    646   //
    647   // If user select a controller item in the first page  the following code will be run.
    648   // During second page, user will see all currnet driver bind protocol driver, the driver name and its device path will be shown
    649   //
    650   //First acquire the list of Loaded Image Protocols, and then when  want the name of the driver, look up all the Driver Binding Protocols
    651   // and find the first one whose ImageHandle field matches the image handle of the Loaded Image Protocol.
    652   // then use the Component Name Protocol on the same handle as the first matching Driver Binding Protocol to look up the name of the driver.
    653   //
    654 
    655   mCurrentPage = FORM_ID_DRIVER;
    656   //
    657   // Switch the item callback key value to its NO. in mDevicePathHandleBuffer
    658   //
    659   mSelectedCtrIndex = KeyValue - KEY_VALUE_DEVICE_OFFSET;
    660   ASSERT (mSelectedCtrIndex >= 0 && mSelectedCtrIndex < MAX_CHOICE_NUM);
    661 
    662   mLastSavedDriverImageNum = 0;
    663 
    664   //
    665   // Init OpCode Handle
    666   //
    667   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    668   ASSERT (StartOpCodeHandle != NULL);
    669 
    670   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    671   ASSERT (EndOpCodeHandle != NULL);
    672 
    673   //
    674   // Create Hii Extend Label OpCode as the start opcode
    675   //
    676   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
    677   StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    678   StartLabel->Number       = FORM_ID_DRIVER;
    679 
    680   //
    681   // Create Hii Extend Label OpCode as the end opcode
    682   //
    683   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
    684   EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    685   EndLabel->Number       = LABEL_END;
    686 
    687   //
    688   // Clear second page form
    689   //
    690   HiiUpdateForm (
    691     Private->RegisteredHandle,
    692     &gPlatformOverridesManagerGuid,
    693     FORM_ID_DRIVER,
    694     StartOpCodeHandle,
    695     EndOpCodeHandle
    696     );
    697 
    698   //
    699   // Show all driver which support loaded image protocol in second page
    700   //
    701   DriverImageHandleCount  = 0;
    702   Status = gBS->LocateHandleBuffer (
    703                   ByProtocol,
    704                   &gEfiLoadedImageProtocolGuid,
    705                   NULL,
    706                   &DriverImageHandleCount,
    707                   &mDriverImageHandleBuffer
    708                   );
    709   if (EFI_ERROR (Status) || (DriverImageHandleCount == 0)) {
    710     return EFI_NOT_FOUND;
    711   }
    712 
    713   mDriverImageToken = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_STRING_ID));
    714   ASSERT (mDriverImageToken != NULL);
    715   mDriSelection = AllocateZeroPool (DriverImageHandleCount * sizeof (BOOLEAN));
    716   ASSERT (mDriSelection != NULL);
    717 
    718   DriverImageProtocol = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_LOADED_IMAGE_PROTOCOL *));
    719   ASSERT (DriverImageProtocol != NULL);
    720   DriverImageFilePathToken = AllocateZeroPool (DriverImageHandleCount * sizeof (EFI_STRING_ID));
    721   ASSERT (DriverImageFilePathToken != NULL);
    722 
    723   mDriverImageHandleCount = DriverImageHandleCount;
    724   for (Index = 0; Index < DriverImageHandleCount; Index++) {
    725     //
    726     // Step1: Get the driver image total file path for help string and the driver name.
    727     //
    728 
    729     //
    730     // Find driver's Loaded Image protocol
    731     //
    732     LoadedImage =NULL;
    733 
    734     Status = gBS->OpenProtocol (
    735                     mDriverImageHandleBuffer[Index],
    736                     &gEfiLoadedImageProtocolGuid,
    737                     (VOID **) &LoadedImage,
    738                     NULL,
    739                     NULL,
    740                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    741                     );
    742     if (EFI_ERROR (Status)) {
    743       mDriSelection[Index] = FALSE;
    744       continue;
    745     }
    746     DriverImageProtocol[Index] = LoadedImage;
    747     //
    748     // Find its related driver binding protocol
    749     //
    750     DriverBindingHandle = GetDriverBindingHandleFromImageHandle (mDriverImageHandleBuffer[Index]);
    751     if (DriverBindingHandle == NULL) {
    752       mDriSelection[Index] = FALSE;
    753       continue;
    754     }
    755 
    756     //
    757     // Get the EFI Loaded Image Device Path Protocol
    758     //
    759     LoadedImageDevicePath = NULL;
    760     Status = gBS->HandleProtocol (
    761                         mDriverImageHandleBuffer[Index],
    762                         &gEfiLoadedImageDevicePathProtocolGuid,
    763                         (VOID **) &LoadedImageDevicePath
    764                         );
    765     if (LoadedImageDevicePath == NULL) {
    766       mDriSelection[Index] = FALSE;
    767       continue;
    768     }
    769 
    770     if (FakeNvData->PciDeviceFilter == 0x01) {
    771       //
    772       // only care the driver which is in a Pci device option rom,
    773       // and the driver's LoadedImage->DeviceHandle must point to a pci device which has efi option rom
    774       //
    775       if (!EFI_ERROR (Status)) {
    776         Status = gBS->HandleProtocol(
    777                          LoadedImage->DeviceHandle,
    778                          &gEfiBusSpecificDriverOverrideProtocolGuid,
    779                          (VOID **) &BusSpecificDriverOverride
    780                          );
    781         if (EFI_ERROR (Status) || BusSpecificDriverOverride == NULL) {
    782           mDriSelection[Index] = FALSE;
    783           continue;
    784         }
    785       } else {
    786         mDriSelection[Index] = FALSE;
    787         continue;
    788       }
    789     }
    790 
    791     //
    792     // For driver name, try to get its component name, if fail, get its image name,
    793     // if also fail, give a default name.
    794     //
    795     FreeDriverName = FALSE;
    796     DriverName = GetComponentName (DriverBindingHandle);
    797     if (DriverName == NULL) {
    798       //
    799       // get its image name
    800       //
    801       DriverName = GetImageName (LoadedImage);
    802     }
    803     if (DriverName == NULL) {
    804       //
    805       // give a default name
    806       //
    807       DriverName = HiiGetString (Private->RegisteredHandle, STRING_TOKEN (STR_DRIVER_DEFAULT_NAME), NULL);
    808       ASSERT (DriverName != NULL);
    809       FreeDriverName = TRUE;  // the DriverName string need to free pool
    810     }
    811 
    812 
    813     //
    814     // Step2 Export the driver name string and create check box item in second page
    815     //
    816 
    817     //
    818     // First create the driver image name
    819     //
    820     NewStrSize = StrSize (DriverName);
    821     NewString = AllocateZeroPool (NewStrSize);
    822     ASSERT (NewString != NULL);
    823     if (EFI_ERROR (CheckMapping (mControllerDevicePathProtocol[mSelectedCtrIndex], LoadedImageDevicePath, &mMappingDataBase, NULL, NULL))) {
    824       mDriSelection[Index] = FALSE;
    825     } else {
    826       mDriSelection[Index] = TRUE;
    827       mLastSavedDriverImageNum++;
    828     }
    829     StrCatS (NewString, NewStrSize/sizeof(CHAR16), DriverName);
    830     NewStringToken = HiiSetString (Private->RegisteredHandle, mDriverImageToken[Index], NewString, NULL);
    831     ASSERT (NewStringToken != 0);
    832     mDriverImageToken[Index] = NewStringToken;
    833     FreePool (NewString);
    834     if (FreeDriverName) {
    835       FreePool (DriverName);
    836     }
    837 
    838     //
    839     // Second create the driver image device path as item help string
    840     //
    841     DriverName = DevicePathToStr (LoadedImageDevicePath);
    842 
    843     NewStrSize = StrSize (DriverName);
    844     NewString = AllocateZeroPool (NewStrSize);
    845     ASSERT (NewString != NULL);
    846     StrCatS (NewString, NewStrSize/sizeof(CHAR16), DriverName);
    847     NewStringHelpToken = HiiSetString (Private->RegisteredHandle, DriverImageFilePathToken[Index], NewString, NULL);
    848     ASSERT (NewStringHelpToken != 0);
    849     DriverImageFilePathToken[Index] = NewStringHelpToken;
    850     FreePool (NewString);
    851     FreePool (DriverName);
    852 
    853     CheckFlags        = 0;
    854     if (mDriSelection[Index]) {
    855       CheckFlags |= EFI_IFR_CHECKBOX_DEFAULT;
    856     }
    857 
    858     HiiCreateCheckBoxOpCode (
    859       StartOpCodeHandle,
    860       (UINT16) (KEY_VALUE_DRIVER_OFFSET + Index),
    861       0,
    862       0,
    863       NewStringToken,
    864       NewStringHelpToken,
    865       EFI_IFR_FLAG_CALLBACK,
    866       CheckFlags,
    867       NULL
    868       );
    869   }
    870 
    871   //
    872   // Update second page form
    873   //
    874   HiiUpdateForm (
    875     Private->RegisteredHandle,
    876     &gPlatformOverridesManagerGuid,
    877     FORM_ID_DRIVER,
    878     StartOpCodeHandle, // Label FORM_ID_DRIVER
    879     EndOpCodeHandle    // LABEL_END
    880     );
    881 
    882   HiiFreeOpCodeHandle (StartOpCodeHandle);
    883   HiiFreeOpCodeHandle (EndOpCodeHandle);
    884 
    885   if (DriverImageProtocol != NULL) {
    886     FreePool (DriverImageProtocol);
    887   }
    888 
    889   if (DriverImageFilePathToken != NULL) {
    890     FreePool (DriverImageFilePathToken);
    891   }
    892 
    893   return EFI_SUCCESS;
    894 }
    895 
    896 /**
    897   Prepare to let user select the priority order of the drivers which are
    898   selected in second page.
    899 
    900   @param  Private        Pointer to EFI_CALLBACK_INFO.
    901   @param  KeyValue       The callback key value of device controller item in first page.
    902   @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.
    903 
    904   @retval EFI_SUCCESS    Always returned.
    905 
    906 **/
    907 EFI_STATUS
    908 UpdatePrioritySelectPage (
    909   IN EFI_CALLBACK_INFO                *Private,
    910   IN UINT16                           KeyValue,
    911   IN PLAT_OVER_MNGR_DATA              *FakeNvData
    912   )
    913 {
    914   UINTN                                     Index;
    915   EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;
    916   UINTN                                     SelectedDriverImageNum;
    917   UINT32                                    DriverImageNO;
    918   UINTN                                     MinNO;
    919   UINTN                                     Index1;
    920   UINTN                                     TempNO[100];
    921   UINTN                                     OrderNO[100];
    922   VOID                                      *StartOpCodeHandle;
    923   VOID                                      *EndOpCodeHandle;
    924   VOID                                      *OptionsOpCodeHandle;
    925   EFI_IFR_GUID_LABEL                        *StartLabel;
    926   EFI_IFR_GUID_LABEL                        *EndLabel;
    927 
    928   //
    929   // Following code will be run if user select 'order ... priority' item in second page
    930   // Prepare third page.  In third page, user will order the  drivers priority which are selected in second page
    931   //
    932   mCurrentPage = FORM_ID_ORDER;
    933 
    934   //
    935   // Init OpCode Handle
    936   //
    937   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    938   ASSERT (StartOpCodeHandle != NULL);
    939 
    940   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    941   ASSERT (EndOpCodeHandle != NULL);
    942 
    943   //
    944   // Create Hii Extend Label OpCode as the start opcode
    945   //
    946   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
    947   StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    948   StartLabel->Number       = FORM_ID_ORDER;
    949 
    950   //
    951   // Create Hii Extend Label OpCode as the end opcode
    952   //
    953   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
    954   EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    955   EndLabel->Number       = LABEL_END;
    956 
    957   //
    958   // Clear third page form
    959   //
    960   HiiUpdateForm (
    961     Private->RegisteredHandle,
    962     &gPlatformOverridesManagerGuid,
    963     FORM_ID_ORDER,
    964     StartOpCodeHandle,
    965     EndOpCodeHandle
    966     );
    967 
    968   //
    969   // Check how many drivers have been selected
    970   //
    971   SelectedDriverImageNum = 0;
    972   for (Index = 0; Index < mDriverImageHandleCount; Index++) {
    973     if (mDriSelection[Index]) {
    974       SelectedDriverImageNum ++;
    975     }
    976   }
    977 
    978   mSelectedDriverImageNum = SelectedDriverImageNum;
    979   if (SelectedDriverImageNum == 0) {
    980     return EFI_SUCCESS;
    981   }
    982 
    983   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
    984   ASSERT (OptionsOpCodeHandle != NULL);
    985 
    986   //
    987   // Create order list for those selected drivers
    988   //
    989   SelectedDriverImageNum = 0;
    990   for (Index = 0; Index < mDriverImageHandleCount; Index++) {
    991     if (mDriSelection[Index]) {
    992       //
    993       // Use the NO. in driver binding buffer as value, will use it later
    994       //
    995       HiiCreateOneOfOptionOpCode (
    996         OptionsOpCodeHandle,
    997         mDriverImageToken[Index],
    998         0,
    999         EFI_IFR_NUMERIC_SIZE_1,
   1000         Index + 1
   1001         );
   1002 
   1003       //
   1004       // Get the EFI Loaded Image Device Path Protocol
   1005       //
   1006       LoadedImageDevicePath = NULL;
   1007       gBS->HandleProtocol (
   1008                  mDriverImageHandleBuffer[Index],
   1009                  &gEfiLoadedImageDevicePathProtocolGuid,
   1010                  (VOID **) &LoadedImageDevicePath
   1011                  );
   1012       ASSERT (LoadedImageDevicePath != NULL);
   1013 
   1014       //
   1015       // Check the driver DriverImage's order number in mapping database
   1016       //
   1017       DriverImageNO = 0;
   1018       CheckMapping (
   1019               mControllerDevicePathProtocol[mSelectedCtrIndex],
   1020               LoadedImageDevicePath,
   1021               &mMappingDataBase,
   1022               NULL,
   1023               &DriverImageNO
   1024               );
   1025       if (DriverImageNO == 0) {
   1026         DriverImageNO = (UINT32) mLastSavedDriverImageNum + 1;
   1027         mLastSavedDriverImageNum++;
   1028       }
   1029       TempNO[SelectedDriverImageNum] = DriverImageNO;
   1030       OrderNO[SelectedDriverImageNum] = Index + 1;
   1031       SelectedDriverImageNum ++;
   1032     }
   1033   }
   1034 
   1035   ASSERT (SelectedDriverImageNum == mSelectedDriverImageNum);
   1036   //
   1037   // NvRamMap Must be clear firstly
   1038   //
   1039   ZeroMem (FakeNvData->DriOrder, sizeof (FakeNvData->DriOrder));
   1040 
   1041   //
   1042   // Order the selected drivers according to the info already in mapping database
   1043   // the less order number in mapping database the less order number in NvRamMap
   1044   //
   1045   for (Index=0; Index < SelectedDriverImageNum; Index++) {
   1046     //
   1047     // Find the minimal order number in TempNO array,  its index in TempNO is same as IfrOptionList array
   1048     //
   1049     MinNO = 0;
   1050     for (Index1=0; Index1 < SelectedDriverImageNum; Index1++) {
   1051       if (TempNO[Index1] < TempNO[MinNO]) {
   1052         MinNO = Index1;
   1053       }
   1054     }
   1055     //
   1056     // the IfrOptionList[MinNO].Value = the driver NO. in driver binding buffer
   1057     //
   1058     FakeNvData->DriOrder[Index] = (UINT8) OrderNO[MinNO];
   1059     TempNO[MinNO] = MAX_CHOICE_NUM + 1;
   1060   }
   1061 
   1062   //
   1063   // Create Order List OpCode
   1064   //
   1065   HiiCreateOrderedListOpCode (
   1066     StartOpCodeHandle,
   1067     (UINT16) DRIVER_ORDER_QUESTION_ID,
   1068     VARSTORE_ID_PLAT_OVER_MNGR,
   1069     (UINT16) DRIVER_ORDER_VAR_OFFSET,
   1070     mControllerToken[mSelectedCtrIndex],
   1071     mControllerToken[mSelectedCtrIndex],
   1072     EFI_IFR_FLAG_RESET_REQUIRED,
   1073     0,
   1074     EFI_IFR_NUMERIC_SIZE_1,
   1075     (UINT8) MAX_CHOICE_NUM,
   1076     OptionsOpCodeHandle,
   1077     NULL
   1078     );
   1079 
   1080   //
   1081   // Update third page form
   1082   //
   1083   HiiUpdateForm (
   1084     Private->RegisteredHandle,
   1085     &gPlatformOverridesManagerGuid,
   1086     FORM_ID_ORDER,
   1087     StartOpCodeHandle, // Label FORM_ID_ORDER
   1088     EndOpCodeHandle    // LABEL_END
   1089     );
   1090 
   1091   HiiFreeOpCodeHandle (StartOpCodeHandle);
   1092   HiiFreeOpCodeHandle (EndOpCodeHandle);
   1093   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
   1094 
   1095   return EFI_SUCCESS;
   1096 }
   1097 
   1098 /**
   1099   Save the save the mapping database to NV variable.
   1100 
   1101   @param  Private        Pointer to EFI_CALLBACK_INFO.
   1102   @param  KeyValue       The callback key value of device controller item in first page.
   1103   @param  FakeNvData     Pointer to PLAT_OVER_MNGR_DATA.
   1104 
   1105   @retval EFI_SUCCESS    Always returned.
   1106 
   1107 **/
   1108 EFI_STATUS
   1109 CommitChanges (
   1110   IN EFI_CALLBACK_INFO                *Private,
   1111   IN UINT16                           KeyValue,
   1112   IN PLAT_OVER_MNGR_DATA              *FakeNvData
   1113   )
   1114 {
   1115   EFI_STATUS                                Status;
   1116   UINTN                                     Index;
   1117   UINTN                                     SelectedDriverImageNum;
   1118   EFI_DEVICE_PATH_PROTOCOL                  *LoadedImageDevicePath;
   1119   //
   1120   //  Following code will be run if user select 'commint changes' in third page
   1121   //  user enter 'Commit Changes' to save the mapping database
   1122   //
   1123   DeleteDriverImage (mControllerDevicePathProtocol[mSelectedCtrIndex], NULL, &mMappingDataBase);
   1124   for (SelectedDriverImageNum = 0; SelectedDriverImageNum < mSelectedDriverImageNum; SelectedDriverImageNum++) {
   1125     //
   1126     // DriOrder[SelectedDriverImageNum] = the driver NO. in driver binding buffer
   1127     //
   1128     Index = FakeNvData->DriOrder[SelectedDriverImageNum] - 1;
   1129 
   1130     //
   1131     // Get the EFI Loaded Image Device Path Protocol
   1132     //
   1133     LoadedImageDevicePath = NULL;
   1134     Status = gBS->HandleProtocol (
   1135                         mDriverImageHandleBuffer[Index],
   1136                         &gEfiLoadedImageDevicePathProtocolGuid,
   1137                         (VOID **) &LoadedImageDevicePath
   1138                         );
   1139     ASSERT (LoadedImageDevicePath != NULL);
   1140 
   1141     InsertDriverImage (
   1142             mControllerDevicePathProtocol[mSelectedCtrIndex],
   1143             LoadedImageDevicePath,
   1144             &mMappingDataBase,
   1145             (UINT32)SelectedDriverImageNum + 1
   1146             );
   1147   }
   1148   Status = SaveOverridesMapping (&mMappingDataBase);
   1149 
   1150   return Status;
   1151 }
   1152 
   1153 /**
   1154   This function allows a caller to extract the current configuration for one
   1155   or more named elements from the target driver.
   1156 
   1157   @param  This         Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
   1158   @param  Request      A null-terminated Unicode string in <ConfigRequest> format.
   1159   @param  Progress     On return, points to a character in the Request string.
   1160                        Points to the string's null terminator if request was successful.
   1161                        Points to the most recent '&' before the first failing name/value
   1162                        pair (or the beginning of the string if the failure is in the
   1163                        first name/value pair) if the request was not successful.
   1164   @param  Results      A null-terminated Unicode string in <ConfigAltResp> format which
   1165                        has all values filled in for the names in the Request string.
   1166                        String to be allocated by the called function.
   1167 
   1168   @retval EFI_SUCCESS            The Results is filled with the requested values.
   1169   @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
   1170   @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
   1171   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
   1172 
   1173 **/
   1174 EFI_STATUS
   1175 EFIAPI
   1176 PlatOverMngrExtractConfig (
   1177   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
   1178   IN  CONST EFI_STRING                       Request,
   1179   OUT EFI_STRING                             *Progress,
   1180   OUT EFI_STRING                             *Results
   1181   )
   1182 {
   1183   EFI_STATUS                       Status;
   1184   EFI_CALLBACK_INFO                *Private;
   1185   EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;
   1186   EFI_STRING                       ConfigRequestHdr;
   1187   EFI_STRING                       ConfigRequest;
   1188   BOOLEAN                          AllocatedRequest;
   1189   UINTN                            Size;
   1190   UINTN                            BufferSize;
   1191 
   1192   if (Progress == NULL || Results == NULL) {
   1193     return EFI_INVALID_PARAMETER;
   1194   }
   1195 
   1196   *Progress = Request;
   1197   if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gPlatformOverridesManagerGuid, mVariableName)) {
   1198     return EFI_NOT_FOUND;
   1199   }
   1200 
   1201   ConfigRequestHdr = NULL;
   1202   ConfigRequest    = NULL;
   1203   Size             = 0;
   1204   AllocatedRequest = FALSE;
   1205 
   1206   Private          = EFI_CALLBACK_INFO_FROM_THIS (This);
   1207   HiiConfigRouting = Private->HiiConfigRouting;
   1208   ConfigRequest = Request;
   1209   if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
   1210     //
   1211     // Request has no request element, construct full request string.
   1212     // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
   1213     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
   1214     //
   1215     ConfigRequestHdr = HiiConstructConfigHdr (&gPlatformOverridesManagerGuid, mVariableName, Private->DriverHandle);
   1216     Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
   1217     ConfigRequest = AllocateZeroPool (Size);
   1218     ASSERT (ConfigRequest != NULL);
   1219     AllocatedRequest = TRUE;
   1220     BufferSize = sizeof (PLAT_OVER_MNGR_DATA);
   1221     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
   1222     FreePool (ConfigRequestHdr);
   1223   }
   1224 
   1225   //
   1226   // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
   1227   //
   1228   Status = HiiConfigRouting->BlockToConfig (
   1229                                 HiiConfigRouting,
   1230                                 ConfigRequest,
   1231                                 (UINT8 *) &Private->FakeNvData,
   1232                                 sizeof (PLAT_OVER_MNGR_DATA),
   1233                                 Results,
   1234                                 Progress
   1235                                 );
   1236 
   1237   //
   1238   // Free the allocated config request string.
   1239   //
   1240   if (AllocatedRequest) {
   1241     FreePool (ConfigRequest);
   1242     ConfigRequest = NULL;
   1243   }
   1244   //
   1245   // Set Progress string to the original request string.
   1246   //
   1247   if (Request == NULL) {
   1248     *Progress = NULL;
   1249   } else if (StrStr (Request, L"OFFSET") == NULL) {
   1250     *Progress = Request + StrLen (Request);
   1251   }
   1252 
   1253   return Status;
   1254 }
   1255 
   1256 /**
   1257   This function processes the results of changes in configuration.
   1258 
   1259   @param  This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
   1260   @param  Configuration   A null-terminated Unicode string in <ConfigRequest> format.
   1261   @param  Progress        A pointer to a string filled in with the offset of the most
   1262                           recent '&' before the first failing name/value pair (or the
   1263                           beginning of the string if the failure is in the first
   1264                           name/value pair) or the terminating NULL if all was successful.
   1265 
   1266   @retval EFI_SUCCESS            The Results is processed successfully.
   1267   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
   1268   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
   1269 
   1270 **/
   1271 EFI_STATUS
   1272 EFIAPI
   1273 PlatOverMngrRouteConfig (
   1274   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
   1275   IN  CONST EFI_STRING                       Configuration,
   1276   OUT EFI_STRING                             *Progress
   1277   )
   1278 {
   1279   EFI_CALLBACK_INFO                         *Private;
   1280   UINT16                                    KeyValue;
   1281   PLAT_OVER_MNGR_DATA                       *FakeNvData;
   1282   EFI_STATUS                                Status;
   1283 
   1284   if (Configuration == NULL || Progress == NULL) {
   1285     return EFI_INVALID_PARAMETER;
   1286   }
   1287   *Progress = Configuration;
   1288 
   1289   if (!HiiIsConfigHdrMatch (Configuration, &gPlatformOverridesManagerGuid, mVariableName)) {
   1290     return EFI_NOT_FOUND;
   1291   }
   1292 
   1293   *Progress = Configuration + StrLen (Configuration);
   1294   Private    = EFI_CALLBACK_INFO_FROM_THIS (This);
   1295   FakeNvData = &Private->FakeNvData;
   1296   if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData)) {
   1297     //
   1298     // FakeNvData can't be got from SetupBrowser, which doesn't need to be set.
   1299     //
   1300     return EFI_SUCCESS;
   1301   }
   1302 
   1303   Status = EFI_SUCCESS;
   1304 
   1305   if (mCurrentPage == FORM_ID_ORDER) {
   1306     KeyValue = KEY_VALUE_ORDER_SAVE_AND_EXIT;
   1307     Status = CommitChanges (Private, KeyValue, FakeNvData);
   1308   }
   1309 
   1310   return Status;
   1311 }
   1312 
   1313 /**
   1314   This is the function that is called to provide results data to the driver.  This data
   1315   consists of a unique key which is used to identify what data is either being passed back
   1316   or being asked for.
   1317 
   1318   @param  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
   1319   @param  Action         A null-terminated Unicode string in <ConfigRequest> format.
   1320   @param  KeyValue       A unique Goto OpCode callback value which record user's selection.
   1321                          0x100 <= KeyValue <0x500 : user select a controller item in the first page;
   1322                          KeyValue == 0x1234       : user select 'Refresh' in first page, or user select 'Go to Previous Menu' in second page
   1323                          KeyValue == 0x1235       : user select 'Pci device filter' in first page
   1324                          KeyValue == 0x1500       : user select 'order ... priority' item in second page
   1325                          KeyValue == 0x1800       : user select 'commint changes' in third page
   1326                          KeyValue == 0x2000       : user select 'Go to Previous Menu' in third page
   1327   @param  Type           The type of value for the question.
   1328   @param  Value          A pointer to the data being sent to the original exporting driver.
   1329   @param  ActionRequest  On return, points to the action requested by the callback function.
   1330 
   1331   @retval EFI_SUCCESS    Always returned.
   1332 
   1333 **/
   1334 EFI_STATUS
   1335 EFIAPI
   1336 PlatOverMngrCallback (
   1337   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
   1338   IN  EFI_BROWSER_ACTION                     Action,
   1339   IN  EFI_QUESTION_ID                        KeyValue,
   1340   IN  UINT8                                  Type,
   1341   IN  EFI_IFR_TYPE_VALUE                     *Value,
   1342   OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
   1343   )
   1344 {
   1345   EFI_CALLBACK_INFO                         *Private;
   1346   EFI_STATUS                                Status;
   1347   EFI_STRING_ID                             NewStringToken;
   1348   EFI_INPUT_KEY                             Key;
   1349   PLAT_OVER_MNGR_DATA                       *FakeNvData;
   1350 
   1351   if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
   1352     //
   1353     // All other action return unsupported.
   1354     //
   1355     return EFI_UNSUPPORTED;
   1356   }
   1357 
   1358   Private = EFI_CALLBACK_INFO_FROM_THIS (This);
   1359   FakeNvData = &Private->FakeNvData;
   1360   if (!HiiGetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData)) {
   1361     return EFI_NOT_FOUND;
   1362   }
   1363 
   1364   if (Action == EFI_BROWSER_ACTION_CHANGING) {
   1365     if (Value == NULL) {
   1366       return EFI_INVALID_PARAMETER;
   1367     }
   1368 
   1369     if (KeyValue == KEY_VALUE_DRIVER_GOTO_PREVIOUS) {
   1370       UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
   1371       //
   1372       // Update page title string
   1373       //
   1374       NewStringToken = STRING_TOKEN (STR_TITLE);
   1375       if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {
   1376         ASSERT (FALSE);
   1377       }
   1378     }
   1379 
   1380     if (((KeyValue >= KEY_VALUE_DEVICE_OFFSET) && (KeyValue < KEY_VALUE_DEVICE_OFFSET + mMaxDeviceCount)) || (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS)) {
   1381       if (KeyValue == KEY_VALUE_ORDER_GOTO_PREVIOUS) {
   1382         KeyValue = (EFI_QUESTION_ID) (mSelectedCtrIndex + KEY_VALUE_DEVICE_OFFSET);
   1383       }
   1384       UpdateBindingDriverSelectPage (Private, KeyValue, FakeNvData);
   1385       //
   1386       // Update page title string
   1387       //
   1388       NewStringToken = STRING_TOKEN (STR_TITLE);
   1389       if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Second, Select drivers for the previous selected controller", NULL) == 0) {
   1390         ASSERT (FALSE);
   1391       }
   1392     }
   1393 
   1394     if (KeyValue == KEY_VALUE_DRIVER_GOTO_ORDER) {
   1395       UpdatePrioritySelectPage (Private, KeyValue, FakeNvData);
   1396       //
   1397       // Update page title string
   1398       //
   1399       NewStringToken = STRING_TOKEN (STR_TITLE);
   1400       if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"Finally, Set the priority order for the drivers and save them", NULL) == 0) {
   1401         ASSERT (FALSE);
   1402       }
   1403     }
   1404 
   1405     if (KeyValue == KEY_VALUE_DEVICE_CLEAR) {
   1406       //
   1407       // Deletes all environment variable(s) that contain the override mappings info
   1408       //
   1409       FreeMappingDatabase (&mMappingDataBase);
   1410       Status = SaveOverridesMapping (&mMappingDataBase);
   1411       UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
   1412     }
   1413   } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
   1414     if ((KeyValue >= KEY_VALUE_DRIVER_OFFSET) && (KeyValue < KEY_VALUE_DRIVER_OFFSET + mDriverImageHandleCount)) {
   1415       mDriSelection[KeyValue - KEY_VALUE_DRIVER_OFFSET] = Value->b;
   1416     } else {
   1417       switch (KeyValue) {
   1418       case KEY_VALUE_DEVICE_REFRESH:
   1419       case KEY_VALUE_DEVICE_FILTER:
   1420         UpdateDeviceSelectPage (Private, KeyValue, FakeNvData);
   1421         //
   1422         // Update page title string
   1423         //
   1424         NewStringToken = STRING_TOKEN (STR_TITLE);
   1425         if (HiiSetString (Private->RegisteredHandle, NewStringToken, L"First, Select the controller by device path", NULL) == 0) {
   1426           ASSERT (FALSE);
   1427         }
   1428       break;
   1429 
   1430       case KEY_VALUE_ORDER_SAVE_AND_EXIT:
   1431         Status = CommitChanges (Private, KeyValue, FakeNvData);
   1432         *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
   1433         if (EFI_ERROR (Status)) {
   1434           CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Single Override Info too large, Saving Error!", NULL);
   1435           return EFI_DEVICE_ERROR;
   1436         }
   1437       break;
   1438 
   1439       default:
   1440       break;
   1441       }
   1442     }
   1443   }
   1444 
   1445   //
   1446   // Pass changed uncommitted data back to Form Browser
   1447   //
   1448   HiiSetBrowserData (&gPlatformOverridesManagerGuid, mVariableName, sizeof (PLAT_OVER_MNGR_DATA), (UINT8 *) FakeNvData, NULL);
   1449 
   1450   return EFI_SUCCESS;
   1451 }
   1452 
   1453 /**
   1454   Retrieves the image handle of the platform override driver for a controller in the system.
   1455 
   1456   @param  This                   A pointer to the
   1457                                  EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL instance.
   1458   @param  ControllerHandle       The device handle of the controller to check if a
   1459                                  driver override exists.
   1460   @param  DriverImageHandle      On input, a pointer to the previous driver image
   1461                                  handle returned by GetDriver().  On output, a
   1462                                  pointer to the next driver image handle. Passing
   1463                                  in a NULL,  will return the first driver image
   1464                                  handle for ControllerHandle.
   1465 
   1466   @retval EFI_SUCCESS            The driver override for ControllerHandle was
   1467                                  returned in DriverImageHandle.
   1468   @retval EFI_NOT_FOUND          A driver override for ControllerHandle was not
   1469                                  found.
   1470   @retval EFI_INVALID_PARAMETER  The handle specified by ControllerHandle is NULL.
   1471                                  DriverImageHandle is not a handle that was returned
   1472                                  on a previous  call to GetDriver().
   1473 
   1474 **/
   1475 EFI_STATUS
   1476 EFIAPI
   1477 GetDriver (
   1478   IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL              *This,
   1479   IN     EFI_HANDLE                                     ControllerHandle,
   1480   IN OUT EFI_HANDLE                                     *DriverImageHandle
   1481   )
   1482 {
   1483   EFI_STATUS  Status;
   1484 
   1485   //
   1486   // Check that ControllerHandle is a valid handle
   1487   //
   1488   if (ControllerHandle == NULL) {
   1489     return EFI_INVALID_PARAMETER;
   1490   }
   1491 
   1492   //
   1493   // Read the environment variable(s) that contain the override mappings from Controller Device Path to
   1494   // a set of Driver Device Paths, and  initialize in memory database of the overrides that map Controller
   1495   // Device Paths to an ordered set of Driver Device Paths and Driver Handles. This action is only performed
   1496   // once and finished in first call.
   1497   //
   1498   if (!mEnvironmentVariableRead) {
   1499     mEnvironmentVariableRead = TRUE;
   1500 
   1501     Status = InitOverridesMapping (&mMappingDataBase);
   1502     if (EFI_ERROR (Status)){
   1503       DEBUG ((DEBUG_ERROR, "The status to Get Platform Driver Override Variable is %r\n", Status));
   1504       InitializeListHead (&mMappingDataBase);
   1505       return EFI_NOT_FOUND;
   1506     }
   1507   }
   1508 
   1509   //
   1510   // if the environment variable does not exist, just return not found
   1511   //
   1512   if (IsListEmpty (&mMappingDataBase)) {
   1513     return EFI_NOT_FOUND;
   1514   }
   1515 
   1516   return GetDriverFromMapping (
   1517             ControllerHandle,
   1518             DriverImageHandle,
   1519             &mMappingDataBase,
   1520             mCallerImageHandle
   1521             );
   1522 }
   1523 
   1524 /**
   1525   Retrieves the device path of the platform override driver for a controller in the system.
   1526   This driver doesn't support this API.
   1527 
   1528   @param  This                  A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
   1529                                 PROTOCOL instance.
   1530   @param  ControllerHandle      The device handle of the controller to check if a driver override
   1531                                 exists.
   1532   @param  DriverImagePath       On input, a pointer to the previous driver device path returned by
   1533                                 GetDriverPath(). On output, a pointer to the next driver
   1534                                 device path. Passing in a pointer to NULL, will return the first
   1535                                 driver device path for ControllerHandle.
   1536 
   1537   @retval EFI_UNSUPPORTED
   1538 **/
   1539 EFI_STATUS
   1540 EFIAPI
   1541 GetDriverPath (
   1542   IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL              *This,
   1543   IN     EFI_HANDLE                                     ControllerHandle,
   1544   IN OUT EFI_DEVICE_PATH_PROTOCOL                       **DriverImagePath
   1545   )
   1546 {
   1547   return EFI_UNSUPPORTED;
   1548 }
   1549 
   1550 
   1551 /**
   1552   Used to associate a driver image handle with a device path that was returned on a prior call to the
   1553   GetDriverPath() service. This driver image handle will then be available through the
   1554   GetDriver() service. This driver doesn't support this API.
   1555 
   1556   @param  This                  A pointer to the EFI_PLATFORM_DRIVER_OVERRIDE_
   1557                                 PROTOCOL instance.
   1558   @param  ControllerHandle      The device handle of the controller.
   1559   @param  DriverImagePath       A pointer to the driver device path that was returned in a prior
   1560                                 call to GetDriverPath().
   1561   @param  DriverImageHandle     The driver image handle that was returned by LoadImage()
   1562                                 when the driver specified by DriverImagePath was loaded
   1563                                 into memory.
   1564 
   1565   @retval EFI_UNSUPPORTED
   1566 **/
   1567 EFI_STATUS
   1568 EFIAPI
   1569 DriverLoaded (
   1570   IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL          *This,
   1571   IN EFI_HANDLE                                     ControllerHandle,
   1572   IN EFI_DEVICE_PATH_PROTOCOL                       *DriverImagePath,
   1573   IN EFI_HANDLE                                     DriverImageHandle
   1574   )
   1575 {
   1576   return EFI_UNSUPPORTED;
   1577 }
   1578 
   1579 /**
   1580   The driver Entry Point. The function will export a disk device class formset and
   1581   its callback function to hii database.
   1582 
   1583   @param  ImageHandle    The firmware allocated handle for the EFI image.
   1584   @param  SystemTable    A pointer to the EFI System Table.
   1585 
   1586   @retval EFI_SUCCESS    The entry point is executed successfully.
   1587   @retval other          Some error occurs when executing this entry point.
   1588 
   1589 **/
   1590 EFI_STATUS
   1591 EFIAPI
   1592 PlatDriOverrideDxeInit (
   1593   IN EFI_HANDLE                   ImageHandle,
   1594   IN EFI_SYSTEM_TABLE             *SystemTable
   1595   )
   1596 {
   1597   EFI_STATUS                  Status;
   1598   EFI_FORM_BROWSER2_PROTOCOL  *FormBrowser2;
   1599   VOID                        *Instance;
   1600 
   1601   //
   1602   // There should only be one Form Configuration protocol
   1603   //
   1604   Status = gBS->LocateProtocol (
   1605                  &gEfiFormBrowser2ProtocolGuid,
   1606                  NULL,
   1607                  (VOID **) &FormBrowser2
   1608                  );
   1609   if (EFI_ERROR (Status)) {
   1610     return Status;
   1611   }
   1612 
   1613   //
   1614   // According to UEFI spec, there can be at most a single instance
   1615   // in the system of the EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL.
   1616   // So here we check the existence.
   1617   //
   1618   Status = gBS->LocateProtocol (
   1619                   &gEfiPlatformDriverOverrideProtocolGuid,
   1620                   NULL,
   1621                   &Instance
   1622                   );
   1623   //
   1624   // If there was no error, assume there is an installation and return error
   1625   //
   1626   if (!EFI_ERROR (Status)) {
   1627     return EFI_ALREADY_STARTED;
   1628   }
   1629 
   1630   mCallerImageHandle = ImageHandle;
   1631   mCallbackInfo = AllocateZeroPool (sizeof (EFI_CALLBACK_INFO));
   1632   if (mCallbackInfo == NULL) {
   1633     return EFI_BAD_BUFFER_SIZE;
   1634   }
   1635 
   1636   mCallbackInfo->Signature = EFI_CALLBACK_INFO_SIGNATURE;
   1637   mCallbackInfo->ConfigAccess.ExtractConfig = PlatOverMngrExtractConfig;
   1638   mCallbackInfo->ConfigAccess.RouteConfig   = PlatOverMngrRouteConfig;
   1639   mCallbackInfo->ConfigAccess.Callback      = PlatOverMngrCallback;
   1640   mCallbackInfo->PlatformDriverOverride.GetDriver      = GetDriver;
   1641   mCallbackInfo->PlatformDriverOverride.GetDriverPath  = GetDriverPath;
   1642   mCallbackInfo->PlatformDriverOverride.DriverLoaded   = DriverLoaded;
   1643 
   1644   //
   1645   // Locate ConfigRouting protocol
   1646   //
   1647   Status = gBS->LocateProtocol (
   1648                   &gEfiHiiConfigRoutingProtocolGuid,
   1649                   NULL,
   1650                   (VOID **) &mCallbackInfo->HiiConfigRouting
   1651                   );
   1652   if (EFI_ERROR (Status)) {
   1653     goto Finish;
   1654   }
   1655 
   1656   //
   1657   // Install Device Path Protocol and Config Access protocol to driver handle
   1658   // Install Platform Driver Override Protocol to driver handle
   1659   //
   1660   Status = gBS->InstallMultipleProtocolInterfaces (
   1661                   &mCallbackInfo->DriverHandle,
   1662                   &gEfiDevicePathProtocolGuid,
   1663                   &mHiiVendorDevicePath,
   1664                   &gEfiHiiConfigAccessProtocolGuid,
   1665                   &mCallbackInfo->ConfigAccess,
   1666                   &gEfiPlatformDriverOverrideProtocolGuid,
   1667                   &mCallbackInfo->PlatformDriverOverride,
   1668                   NULL
   1669                   );
   1670   if (EFI_ERROR (Status)) {
   1671     goto Finish;
   1672   }
   1673 
   1674   //
   1675   // Publish our HII data
   1676   //
   1677   mCallbackInfo->RegisteredHandle = HiiAddPackages (
   1678                                      &gPlatformOverridesManagerGuid,
   1679                                      mCallbackInfo->DriverHandle,
   1680                                      VfrBin,
   1681                                      PlatDriOverrideDxeStrings,
   1682                                      NULL
   1683                                      );
   1684   if (mCallbackInfo->RegisteredHandle == NULL) {
   1685     Status = EFI_OUT_OF_RESOURCES;
   1686     goto Finish;
   1687   }
   1688 
   1689   //
   1690   // Clear all the globle variable
   1691   //
   1692   mDriverImageHandleCount = 0;
   1693   mCurrentPage = 0;
   1694 
   1695   return EFI_SUCCESS;
   1696 
   1697 Finish:
   1698   PlatDriOverrideDxeUnload (ImageHandle);
   1699 
   1700   return Status;
   1701 }
   1702 
   1703 /**
   1704   Unload its installed protocol.
   1705 
   1706   @param[in]  ImageHandle       Handle that identifies the image to be unloaded.
   1707 
   1708   @retval EFI_SUCCESS           The image has been unloaded.
   1709 **/
   1710 EFI_STATUS
   1711 EFIAPI
   1712 PlatDriOverrideDxeUnload (
   1713   IN EFI_HANDLE  ImageHandle
   1714   )
   1715 {
   1716   ASSERT (mCallbackInfo != NULL);
   1717 
   1718   if (mCallbackInfo->DriverHandle != NULL) {
   1719     gBS->UninstallMultipleProtocolInterfaces (
   1720            mCallbackInfo->DriverHandle,
   1721            &gEfiDevicePathProtocolGuid,
   1722            &mHiiVendorDevicePath,
   1723            &gEfiHiiConfigAccessProtocolGuid,
   1724            &mCallbackInfo->ConfigAccess,
   1725            &gEfiPlatformDriverOverrideProtocolGuid,
   1726            &mCallbackInfo->PlatformDriverOverride,
   1727            NULL
   1728            );
   1729   }
   1730 
   1731   if (mCallbackInfo->RegisteredHandle != NULL) {
   1732     HiiRemovePackages (mCallbackInfo->RegisteredHandle);
   1733   }
   1734 
   1735   FreePool (mCallbackInfo);
   1736 
   1737   if (mControllerToken != NULL) {
   1738     FreePool (mControllerToken);
   1739   }
   1740 
   1741   if (mControllerDevicePathProtocol != NULL) {
   1742     FreePool (mControllerDevicePathProtocol);
   1743   }
   1744 
   1745   if (mDriverImageToken != NULL) {
   1746     FreePool (mDriverImageToken);
   1747   }
   1748 
   1749   return EFI_SUCCESS;
   1750 }
   1751