Home | History | Annotate | Download | only in RamDiskDxe
      1 /** @file
      2   HII Config Access protocol implementation of RamDiskDxe driver.
      3 
      4   Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
      5   (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
      6   This program and the accompanying materials
      7   are licensed and made available under the terms and conditions of the BSD License
      8   which accompanies this distribution.  The full text of the license may be found at
      9   http://opensource.org/licenses/bsd-license.php
     10 
     11   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     12   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     13 
     14 **/
     15 
     16 #include "RamDiskImpl.h"
     17 
     18 CHAR16  mRamDiskStorageName[] = L"RAM_DISK_CONFIGURATION";
     19 
     20 RAM_DISK_CONFIG_PRIVATE_DATA mRamDiskConfigPrivateDataTemplate = {
     21   RAM_DISK_CONFIG_PRIVATE_DATA_SIGNATURE,
     22   {
     23     EFI_PAGE_SIZE,
     24     RAM_DISK_BOOT_SERVICE_DATA_MEMORY
     25   },
     26   {
     27     RamDiskExtractConfig,
     28     RamDiskRouteConfig,
     29     RamDiskCallback
     30   }
     31 };
     32 
     33 HII_VENDOR_DEVICE_PATH       mRamDiskHiiVendorDevicePath = {
     34   {
     35     {
     36       HARDWARE_DEVICE_PATH,
     37       HW_VENDOR_DP,
     38       {
     39         (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
     40         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
     41       }
     42     },
     43     RAM_DISK_FORM_SET_GUID
     44   },
     45   {
     46     END_DEVICE_PATH_TYPE,
     47     END_ENTIRE_DEVICE_PATH_SUBTYPE,
     48     {
     49       (UINT8) (END_DEVICE_PATH_LENGTH),
     50       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
     51     }
     52   }
     53 };
     54 
     55 
     56 /**
     57   This function publish the RAM disk configuration Form.
     58 
     59   @param[in, out]  ConfigPrivateData
     60                              Points to RAM disk configuration private data.
     61 
     62   @retval EFI_SUCCESS             HII Form is installed successfully.
     63   @retval EFI_OUT_OF_RESOURCES    Not enough resource for HII Form installation.
     64   @retval Others                  Other errors as indicated.
     65 
     66 **/
     67 EFI_STATUS
     68 InstallRamDiskConfigForm (
     69   IN OUT RAM_DISK_CONFIG_PRIVATE_DATA       *ConfigPrivateData
     70   )
     71 {
     72   EFI_STATUS                      Status;
     73   EFI_HII_HANDLE                  HiiHandle;
     74   EFI_HANDLE                      DriverHandle;
     75   EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
     76 
     77   DriverHandle = NULL;
     78   ConfigAccess = &ConfigPrivateData->ConfigAccess;
     79   Status = gBS->InstallMultipleProtocolInterfaces (
     80                   &DriverHandle,
     81                   &gEfiDevicePathProtocolGuid,
     82                   &mRamDiskHiiVendorDevicePath,
     83                   &gEfiHiiConfigAccessProtocolGuid,
     84                   ConfigAccess,
     85                   NULL
     86                   );
     87   if (EFI_ERROR (Status)) {
     88     return Status;
     89   }
     90 
     91   ConfigPrivateData->DriverHandle = DriverHandle;
     92 
     93   //
     94   // Publish the HII package list
     95   //
     96   HiiHandle = HiiAddPackages (
     97                 &gRamDiskFormSetGuid,
     98                 DriverHandle,
     99                 RamDiskDxeStrings,
    100                 RamDiskHiiBin,
    101                 NULL
    102                 );
    103   if (HiiHandle == NULL) {
    104     gBS->UninstallMultipleProtocolInterfaces (
    105            DriverHandle,
    106            &gEfiDevicePathProtocolGuid,
    107            &mRamDiskHiiVendorDevicePath,
    108            &gEfiHiiConfigAccessProtocolGuid,
    109            ConfigAccess,
    110            NULL
    111            );
    112     return EFI_OUT_OF_RESOURCES;
    113   }
    114 
    115   ConfigPrivateData->HiiHandle = HiiHandle;
    116 
    117   return EFI_SUCCESS;
    118 }
    119 
    120 
    121 /**
    122   This function removes RAM disk configuration Form.
    123 
    124   @param[in, out]  ConfigPrivateData
    125                              Points to RAM disk configuration private data.
    126 
    127 **/
    128 VOID
    129 UninstallRamDiskConfigForm (
    130   IN OUT RAM_DISK_CONFIG_PRIVATE_DATA       *ConfigPrivateData
    131   )
    132 {
    133   //
    134   // Uninstall HII package list
    135   //
    136   if (ConfigPrivateData->HiiHandle != NULL) {
    137     HiiRemovePackages (ConfigPrivateData->HiiHandle);
    138     ConfigPrivateData->HiiHandle = NULL;
    139   }
    140 
    141   //
    142   // Uninstall HII Config Access Protocol
    143   //
    144   if (ConfigPrivateData->DriverHandle != NULL) {
    145     gBS->UninstallMultipleProtocolInterfaces (
    146            ConfigPrivateData->DriverHandle,
    147            &gEfiDevicePathProtocolGuid,
    148            &mRamDiskHiiVendorDevicePath,
    149            &gEfiHiiConfigAccessProtocolGuid,
    150            &ConfigPrivateData->ConfigAccess,
    151            NULL
    152            );
    153     ConfigPrivateData->DriverHandle = NULL;
    154   }
    155 
    156   FreePool (ConfigPrivateData);
    157 }
    158 
    159 
    160 /**
    161   Unregister all registered RAM disks.
    162 
    163 **/
    164 VOID
    165 UnregisterAllRamDisks (
    166   VOID
    167   )
    168 {
    169   LIST_ENTRY                      *Entry;
    170   LIST_ENTRY                      *NextEntry;
    171   RAM_DISK_PRIVATE_DATA           *PrivateData;
    172 
    173   if (!IsListEmpty(&RegisteredRamDisks)) {
    174     EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {
    175       PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
    176 
    177       gBS->UninstallMultipleProtocolInterfaces (
    178              PrivateData->Handle,
    179              &gEfiBlockIoProtocolGuid,
    180              &PrivateData->BlockIo,
    181              &gEfiBlockIo2ProtocolGuid,
    182              &PrivateData->BlockIo2,
    183              &gEfiDevicePathProtocolGuid,
    184              (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath,
    185              NULL
    186              );
    187 
    188       RemoveEntryList (&PrivateData->ThisInstance);
    189 
    190       if (RamDiskCreateHii == PrivateData->CreateMethod) {
    191         //
    192         // If a RAM disk is created within HII, then the RamDiskDxe driver
    193         // driver is responsible for freeing the allocated memory for the
    194         // RAM disk.
    195         //
    196         FreePool ((VOID *)(UINTN) PrivateData->StartingAddr);
    197       }
    198 
    199       FreePool (PrivateData->DevicePath);
    200       FreePool (PrivateData);
    201     }
    202   }
    203 }
    204 
    205 
    206 /**
    207   This function allows a caller to extract the current configuration for one
    208   or more named elements from the target driver.
    209 
    210   @param[in]  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    211   @param[in]  Request        A null-terminated Unicode string in
    212                              <ConfigRequest> format.
    213   @param[out] Progress       On return, points to a character in the Request
    214                              string. Points to the string's null terminator if
    215                              request was successful. Points to the most recent
    216                              '&' before the first failing name/value pair (or
    217                              the beginning of the string if the failure is in
    218                              the first name/value pair) if the request was not
    219                              successful.
    220   @param[out] Results        A null-terminated Unicode string in
    221                              <ConfigAltResp> format which has all values filled
    222                              in for the names in the Request string. String to
    223                              be allocated by the called function.
    224 
    225   @retval EFI_SUCCESS             The Results is filled with the requested
    226                                   values.
    227   @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the results.
    228   @retval EFI_INVALID_PARAMETER   Request is illegal syntax, or unknown name.
    229   @retval EFI_NOT_FOUND           Routing data doesn't match any storage in
    230                                   this driver.
    231 
    232 **/
    233 EFI_STATUS
    234 EFIAPI
    235 RamDiskExtractConfig (
    236   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
    237   IN CONST EFI_STRING                       Request,
    238        OUT EFI_STRING                       *Progress,
    239        OUT EFI_STRING                       *Results
    240   )
    241 {
    242   if (Progress == NULL || Results == NULL) {
    243     return EFI_INVALID_PARAMETER;
    244   }
    245   *Progress = Request;
    246   return EFI_NOT_FOUND;
    247 }
    248 
    249 
    250 /**
    251   This function processes the results of changes in configuration.
    252 
    253   @param[in]  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    254   @param[in]  Configuration  A null-terminated Unicode string in <ConfigResp>
    255                              format.
    256   @param[out] Progress       A pointer to a string filled in with the offset of
    257                              the most recent '&' before the first failing
    258                              name/value pair (or the beginning of the string if
    259                              the failure is in the first name/value pair) or
    260                              the terminating NULL if all was successful.
    261 
    262   @retval EFI_SUCCESS             The Results is processed successfully.
    263   @retval EFI_INVALID_PARAMETER   Configuration is NULL.
    264   @retval EFI_NOT_FOUND           Routing data doesn't match any storage in
    265                                   this driver.
    266 
    267 **/
    268 EFI_STATUS
    269 EFIAPI
    270 RamDiskRouteConfig (
    271   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
    272   IN CONST EFI_STRING                       Configuration,
    273        OUT EFI_STRING                       *Progress
    274   )
    275 {
    276   if (Configuration == NULL || Progress == NULL) {
    277     return EFI_INVALID_PARAMETER;
    278   }
    279 
    280   return EFI_NOT_FOUND;
    281 }
    282 
    283 
    284 /**
    285   Allocate memory and register the RAM disk created within RamDiskDxe
    286   driver HII.
    287 
    288   @param[in] Size            If creating raw, size of the RAM disk to create.
    289                              If creating from file, zero.
    290   @param[in] FileHandle      If creating raw, NULL. If creating from file, the
    291                              file handle.
    292   @param[in] MemoryType      Type of memory to be used to create RAM Disk.
    293 
    294   @retval EFI_SUCCESS             RAM disk is created and registered.
    295   @retval EFI_OUT_OF_RESOURCES    Not enough storage is available to match the
    296                                   size required.
    297 
    298 **/
    299 EFI_STATUS
    300 HiiCreateRamDisk (
    301   IN UINT64                                 Size,
    302   IN EFI_FILE_HANDLE                        FileHandle,
    303   IN UINT8                                  MemoryType
    304   )
    305 {
    306   EFI_STATUS                      Status;
    307   UINTN                           BufferSize;
    308   UINT64                          *StartingAddr;
    309   EFI_INPUT_KEY                   Key;
    310   EFI_DEVICE_PATH_PROTOCOL        *DevicePath;
    311   RAM_DISK_PRIVATE_DATA           *PrivateData;
    312   EFI_FILE_INFO                   *FileInformation;
    313 
    314   FileInformation = NULL;
    315   StartingAddr    = NULL;
    316 
    317   if (FileHandle != NULL) {
    318     //
    319     // Create from file.
    320     //
    321     FileInformation = FileInfo (FileHandle);
    322     if (NULL == FileInformation) {
    323       do {
    324         CreatePopUp (
    325           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    326           &Key,
    327           L"",
    328           L"Not enough memory to get the file information!",
    329           L"Press ENTER to continue ...",
    330           L"",
    331           NULL
    332           );
    333       } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
    334 
    335       return EFI_OUT_OF_RESOURCES;
    336     }
    337 
    338     //
    339     // Update the size of RAM disk according to the file size.
    340     //
    341     Size = FileInformation->FileSize;
    342   }
    343 
    344   if (Size > (UINTN) -1) {
    345     do {
    346       CreatePopUp (
    347         EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    348         &Key,
    349         L"",
    350         L"The given RAM disk size is too large!",
    351         L"Press ENTER to continue ...",
    352         L"",
    353         NULL
    354         );
    355     } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
    356 
    357     return EFI_OUT_OF_RESOURCES;
    358   }
    359 
    360   if (MemoryType == RAM_DISK_BOOT_SERVICE_DATA_MEMORY) {
    361     Status = gBS->AllocatePool (
    362                     EfiBootServicesData,
    363                     (UINTN)Size,
    364                     (VOID**)&StartingAddr
    365                     );
    366   } else if (MemoryType == RAM_DISK_RESERVED_MEMORY) {
    367     Status = gBS->AllocatePool (
    368                     EfiReservedMemoryType,
    369                     (UINTN)Size,
    370                     (VOID**)&StartingAddr
    371                     );
    372   } else {
    373     Status = EFI_INVALID_PARAMETER;
    374   }
    375 
    376   if ((StartingAddr == NULL) || EFI_ERROR(Status)) {
    377     do {
    378       CreatePopUp (
    379         EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    380         &Key,
    381         L"",
    382         L"Not enough memory to create the RAM disk!",
    383         L"Press ENTER to continue ...",
    384         L"",
    385         NULL
    386         );
    387     } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
    388 
    389     return EFI_OUT_OF_RESOURCES;
    390   }
    391 
    392   if (FileHandle != NULL) {
    393     //
    394     // Copy the file content to the RAM disk.
    395     //
    396     BufferSize = (UINTN) Size;
    397     FileHandle->Read (
    398                   FileHandle,
    399                   &BufferSize,
    400                   (VOID *)(UINTN) StartingAddr
    401                   );
    402     if (BufferSize != FileInformation->FileSize) {
    403       do {
    404         CreatePopUp (
    405           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    406           &Key,
    407           L"",
    408           L"File content read error!",
    409           L"Press ENTER to continue ...",
    410           L"",
    411           NULL
    412           );
    413       } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
    414 
    415       return EFI_DEVICE_ERROR;
    416     }
    417   }
    418 
    419   //
    420   // Register the newly created RAM disk.
    421   //
    422   Status = RamDiskRegister (
    423              ((UINT64)(UINTN) StartingAddr),
    424              Size,
    425              &gEfiVirtualDiskGuid,
    426              NULL,
    427              &DevicePath
    428              );
    429   if (EFI_ERROR (Status)) {
    430     do {
    431       CreatePopUp (
    432         EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
    433         &Key,
    434         L"",
    435         L"Fail to register the newly created RAM disk!",
    436         L"Press ENTER to continue ...",
    437         L"",
    438         NULL
    439         );
    440     } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
    441 
    442     return Status;
    443   }
    444 
    445   //
    446   // If RAM disk is created within HII, memory should be freed when the
    447   // RAM disk is unregisterd.
    448   //
    449   PrivateData = RAM_DISK_PRIVATE_FROM_THIS (RegisteredRamDisks.BackLink);
    450   PrivateData->CreateMethod = RamDiskCreateHii;
    451 
    452   return EFI_SUCCESS;
    453 }
    454 
    455 
    456 /**
    457   This function updates the registered RAM disks list on the main form.
    458 
    459   @param[in, out] ConfigPrivate
    460                              Private data for configurating hii data for RAM
    461                              disks.
    462 
    463 **/
    464 VOID
    465 UpdateMainForm (
    466   IN OUT RAM_DISK_CONFIG_PRIVATE_DATA       *ConfigPrivate
    467   )
    468 {
    469   VOID                      *StartOpCodeHandle;
    470   VOID                      *EndOpCodeHandle;
    471   EFI_IFR_GUID_LABEL        *StartLabel;
    472   EFI_IFR_GUID_LABEL        *EndLabel;
    473   LIST_ENTRY                *Entry;
    474   UINTN                     Index;
    475   RAM_DISK_PRIVATE_DATA     *PrivateData;
    476   CHAR16                    *String;
    477   CHAR16                    RamDiskStr[128];
    478   EFI_STRING_ID             StringId;
    479 
    480   //
    481   // Init OpCode Handle
    482   //
    483   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
    484   ASSERT (StartOpCodeHandle != NULL);
    485 
    486   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
    487   ASSERT (EndOpCodeHandle != NULL);
    488 
    489   //
    490   // Create Hii Extend Label OpCode as the start opcode
    491   //
    492   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    493                                         StartOpCodeHandle,
    494                                         &gEfiIfrTianoGuid,
    495                                         NULL,
    496                                         sizeof (EFI_IFR_GUID_LABEL)
    497                                         );
    498   StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    499   StartLabel->Number       = MAIN_LABEL_LIST_START;
    500 
    501   //
    502   // Create Hii Extend Label OpCode as the end opcode
    503   //
    504   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
    505                                       EndOpCodeHandle,
    506                                       &gEfiIfrTianoGuid,
    507                                       NULL,
    508                                       sizeof (EFI_IFR_GUID_LABEL)
    509                                       );
    510   EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
    511   EndLabel->Number       = MAIN_LABEL_LIST_END;
    512 
    513   Index = 0;
    514   EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {
    515     PrivateData                  = RAM_DISK_PRIVATE_FROM_THIS (Entry);
    516     PrivateData->CheckBoxId      = (EFI_QUESTION_ID)
    517                                    (MAIN_CHECKBOX_QUESTION_ID_START + Index);
    518     //
    519     // CheckBox is unchecked by default.
    520     //
    521     PrivateData->CheckBoxChecked = FALSE;
    522     String                       = RamDiskStr;
    523 
    524     UnicodeSPrint (
    525       String,
    526       sizeof (RamDiskStr),
    527       L"  RAM Disk %d: [0x%lx, 0x%lx]\n",
    528       Index,
    529       PrivateData->StartingAddr,
    530       PrivateData->StartingAddr + PrivateData->Size - 1
    531       );
    532 
    533     StringId = HiiSetString (ConfigPrivate->HiiHandle, 0, RamDiskStr, NULL);
    534     ASSERT (StringId != 0);
    535 
    536     HiiCreateCheckBoxOpCode (
    537       StartOpCodeHandle,
    538       PrivateData->CheckBoxId,
    539       0,
    540       0,
    541       StringId,
    542       STRING_TOKEN (STR_RAM_DISK_LIST_HELP),
    543       EFI_IFR_FLAG_CALLBACK,
    544       0,
    545       NULL
    546       );
    547 
    548     Index++;
    549   }
    550 
    551   HiiUpdateForm (
    552     ConfigPrivate->HiiHandle,
    553     &gRamDiskFormSetGuid,
    554     MAIN_FORM_ID,
    555     StartOpCodeHandle,
    556     EndOpCodeHandle
    557     );
    558 
    559   HiiFreeOpCodeHandle (StartOpCodeHandle);
    560   HiiFreeOpCodeHandle (EndOpCodeHandle);
    561 }
    562 
    563 
    564 /**
    565   This function processes the results of changes in configuration.
    566 
    567   @param[in]  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
    568   @param[in]  Action         Specifies the type of action taken by the browser.
    569   @param[in]  QuestionId     A unique value which is sent to the original
    570                              exporting driver so that it can identify the type
    571                              of data to expect.
    572   @param[in]  Type           The type of value for the question.
    573   @param[in]  Value          A pointer to the data being sent to the original
    574                              exporting driver.
    575   @param[out] ActionRequest  On return, points to the action requested by the
    576                              callback function.
    577 
    578   @retval EFI_SUCCESS             The callback successfully handled the action.
    579   @retval EFI_OUT_OF_RESOURCES    Not enough storage is available to hold the
    580                                   variable and its data.
    581   @retval EFI_DEVICE_ERROR        The variable could not be saved.
    582   @retval EFI_UNSUPPORTED         The specified Action is not supported by the
    583                                   callback.
    584 
    585 **/
    586 EFI_STATUS
    587 EFIAPI
    588 RamDiskCallback (
    589   IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
    590   IN     EFI_BROWSER_ACTION                 Action,
    591   IN     EFI_QUESTION_ID                    QuestionId,
    592   IN     UINT8                              Type,
    593   IN     EFI_IFR_TYPE_VALUE                 *Value,
    594      OUT EFI_BROWSER_ACTION_REQUEST         *ActionRequest
    595   )
    596 {
    597   EFI_STATUS                      Status;
    598   RAM_DISK_PRIVATE_DATA           *PrivateData;
    599   RAM_DISK_CONFIG_PRIVATE_DATA    *ConfigPrivate;
    600   EFI_DEVICE_PATH_PROTOCOL        *FileDevPath;
    601   EFI_FILE_HANDLE                 FileHandle;
    602   LIST_ENTRY                      *Entry;
    603   LIST_ENTRY                      *NextEntry;
    604 
    605   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
    606     return EFI_INVALID_PARAMETER;
    607   }
    608 
    609   ConfigPrivate = RAM_DISK_CONFIG_PRIVATE_FROM_THIS (This);
    610 
    611   if (Action == EFI_BROWSER_ACTION_RETRIEVE) {
    612     Status = EFI_UNSUPPORTED;
    613     if (QuestionId == CREATE_RAW_SIZE_QUESTION_ID) {
    614       Value->u64 = EFI_PAGE_SIZE;
    615       ConfigPrivate->ConfigStore.Size = EFI_PAGE_SIZE;
    616       Status = EFI_SUCCESS;
    617     } else if (QuestionId == CREATE_RAW_MEMORY_TYPE_QUESTION_ID) {
    618       Value->u8 = RAM_DISK_BOOT_SERVICE_DATA_MEMORY;
    619       ConfigPrivate->ConfigStore.MemType = RAM_DISK_BOOT_SERVICE_DATA_MEMORY;
    620       Status = EFI_SUCCESS;
    621     }
    622     return Status;
    623   }
    624 
    625   if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
    626       (Action != EFI_BROWSER_ACTION_CHANGING) &&
    627       (Action != EFI_BROWSER_ACTION_FORM_OPEN)) {
    628     return EFI_UNSUPPORTED;
    629   }
    630 
    631   //
    632   // Update the RAM disk list show at the main form first.
    633   //
    634   if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
    635     Status = EFI_UNSUPPORTED;
    636     if (QuestionId == MAIN_GOTO_FILE_EXPLORER_ID) {
    637       UpdateMainForm (ConfigPrivate);
    638       Status = EFI_SUCCESS;
    639     }
    640     return Status;
    641   }
    642 
    643   Status = EFI_SUCCESS;
    644 
    645   if (Action == EFI_BROWSER_ACTION_CHANGING) {
    646     switch (QuestionId) {
    647     case MAIN_GOTO_FILE_EXPLORER_ID:
    648       Status = ChooseFile (NULL, NULL, NULL, &FileDevPath);
    649       if (EFI_ERROR (Status)) {
    650         break;
    651       }
    652 
    653       if (FileDevPath != NULL) {
    654         //
    655         // Open the file.
    656         //
    657         Status = OpenFileByDevicePath (
    658                    &FileDevPath,
    659                    &FileHandle,
    660                    EFI_FILE_MODE_READ,
    661                    0
    662                    );
    663         if (EFI_ERROR (Status)) {
    664           break;
    665         }
    666 
    667         //
    668         // Create from file, RAM disk size is zero. It will be updated
    669         // according to the file size.
    670         //
    671         Status = HiiCreateRamDisk (
    672                    0,
    673                    FileHandle,
    674                    ConfigPrivate->ConfigStore.MemType
    675                    );
    676         if (EFI_ERROR (Status)) {
    677           break;
    678         }
    679 
    680         //
    681         // Refresh the registered RAM disks list.
    682         //
    683         UpdateMainForm (ConfigPrivate);
    684       }
    685       break;
    686 
    687     default:
    688       break;
    689     }
    690   } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    691     switch (QuestionId) {
    692     case MAIN_REMOVE_RD_QUESTION_ID:
    693       //
    694       // Remove the selected RAM disks
    695       //
    696       EFI_LIST_FOR_EACH_SAFE (Entry, NextEntry, &RegisteredRamDisks) {
    697         PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
    698         if (PrivateData->CheckBoxChecked) {
    699           RamDiskUnregister (
    700             (EFI_DEVICE_PATH_PROTOCOL *) PrivateData->DevicePath
    701             );
    702         }
    703       }
    704 
    705       UpdateMainForm (ConfigPrivate);
    706 
    707       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
    708       break;
    709 
    710     case CREATE_RAW_SIZE_QUESTION_ID:
    711       ConfigPrivate->ConfigStore.Size = Value->u64;
    712       break;
    713 
    714     case CREATE_RAW_MEMORY_TYPE_QUESTION_ID:
    715       ConfigPrivate->ConfigStore.MemType = Value->u8;
    716       break;
    717 
    718     case CREATE_RAW_SUBMIT_QUESTION_ID:
    719       //
    720       // Create raw, FileHandle is NULL.
    721       //
    722       Status = HiiCreateRamDisk (
    723                  ConfigPrivate->ConfigStore.Size,
    724                  NULL,
    725                  ConfigPrivate->ConfigStore.MemType
    726                  );
    727       if (EFI_ERROR (Status)) {
    728         break;
    729       }
    730 
    731       //
    732       // Refresh the registered RAM disks list.
    733       //
    734       UpdateMainForm (ConfigPrivate);
    735 
    736       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
    737       break;
    738 
    739     case CREATE_RAW_DISCARD_QUESTION_ID:
    740       *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
    741       break;
    742 
    743     default:
    744       //
    745       // QuestionIds for checkboxes
    746       //
    747       if ((QuestionId >= MAIN_CHECKBOX_QUESTION_ID_START) &&
    748           (QuestionId < CREATE_RAW_RAM_DISK_FORM_ID)) {
    749         EFI_LIST_FOR_EACH (Entry, &RegisteredRamDisks) {
    750           PrivateData = RAM_DISK_PRIVATE_FROM_THIS (Entry);
    751           if (PrivateData->CheckBoxId == QuestionId) {
    752             PrivateData->CheckBoxChecked = (BOOLEAN) (Value->u8 != 0);
    753           }
    754         }
    755       }
    756       break;
    757     }
    758   }
    759 
    760   return EFI_SUCCESS;
    761 }
    762