/** This function processes the results of changes in configuration. When user select a interactive opcode, this callback will be triggered. Based on the Question(QuestionId) that triggers the callback, the corresponding actions is performed. It handles: 1) the addition of boot option. 2) the addition of driver option. 3) exit from file browser 4) update of file content if a dir is selected. 5) boot the file if a file is selected in "boot from file" @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Action Specifies the type of action taken by the browser. @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. @param Type The type of value for the question. @param Value A pointer to the data being sent to the original exporting driver. @param ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback. @retval EFI_INVALID_PARAMETER If paramter Value or ActionRequest is NULL. **/ EFI_STATUS EFIAPI FileExplorerCallback ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { BMM_CALLBACK_DATA *Private; FILE_EXPLORER_NV_DATA *NvRamMap; EFI_STATUS Status; if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) { // // Do nothing for other UEFI Action. Only do call back when data is changed. // return EFI_UNSUPPORTED; } Status = EFI_SUCCESS; Private = FE_CALLBACK_DATA_FROM_THIS (This); *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; // // Retrieve uncommitted data from Form Browser // NvRamMap = &Private->FeFakeNvData; HiiGetBrowserData (&mFileExplorerGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap); if (Action == EFI_BROWSER_ACTION_CHANGED) { if ((Value == NULL) || (ActionRequest == NULL)) { return EFI_INVALID_PARAMETER; } if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) { // // Apply changes and exit formset // if (FileExplorerStateAddBootOption == Private->FeCurrentState) { Status = Var_UpdateBootOption (Private, NvRamMap); if (EFI_ERROR (Status)) { return Status; } BOpt_GetBootOptions (Private); CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu); } else if (FileExplorerStateAddDriverOptionState == Private->FeCurrentState) { Status = Var_UpdateDriverOption ( Private, Private->FeHiiHandle, NvRamMap->DescriptionData, NvRamMap->OptionalData, NvRamMap->ForceReconnect ); if (EFI_ERROR (Status)) { return Status; } BOpt_GetDriverOptions (Private); CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu); } *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) { // // Discard changes and exit formset // NvRamMap->OptionalData[0] = 0x0000; NvRamMap->DescriptionData[0] = 0x0000; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } else if (QuestionId < FILE_OPTION_OFFSET) { // // Exit File Explorer formset // *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } } else if (Action == EFI_BROWSER_ACTION_CHANGING) { if (Value == NULL) { return EFI_INVALID_PARAMETER; } if (QuestionId >= FILE_OPTION_OFFSET) { UpdateFileExplorer (Private, QuestionId); } } return Status; }
/** This function applies changes in a driver's configuration. Input is a Configuration, which has the routing data for this driver followed by name / value configuration pairs. The driver must apply those pairs to its configurable storage. If the driver's configuration is stored in a linear block of data and the driver's name / value pairs are in <BlockConfig> format, it may use the ConfigToBlock helper function (above) to simplify the job. Currently not implemented. @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param[in] Configuration A null-terminated Unicode string in <ConfigString> format. @param[out] Progress A pointer to a string filled in with the offset of the most recent '&' before the first failing name / value pair (or the beginn ing of the string if the failure is in the first name / value pair) or the terminating NULL if all was successful. @retval EFI_SUCCESS The results have been distributed or are awaiting distribution. @retval EFI_OUT_OF_RESOURCES Not enough memory to store the parts of the results that must be stored awaiting possible future protocols. @retval EFI_INVALID_PARAMETERS Passing in a NULL for the Results parameter would result in this type of error. @retval EFI_NOT_FOUND Target for the specified routing data was not found. **/ EFI_STATUS EFIAPI FileExplorerRouteConfig ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN CONST EFI_STRING Configuration, OUT EFI_STRING *Progress ) { EFI_STATUS Status; UINTN BufferSize; EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting; FILE_EXPLORER_NV_DATA *FeData; BMM_CALLBACK_DATA *Private; if (Progress == NULL) { return EFI_INVALID_PARAMETER; } *Progress = Configuration; if (Configuration == NULL) { return EFI_INVALID_PARAMETER; } // // Check routing data in <ConfigHdr>. // Note: there is no name for Name/Value storage, only GUID will be checked // if (!HiiIsConfigHdrMatch (Configuration, &gFileExploreFormSetGuid, mFileExplorerStorageName)) { return EFI_NOT_FOUND; } Status = gBS->LocateProtocol ( &gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID**) &ConfigRouting ); if (EFI_ERROR (Status)) { return Status; } Private = FE_CALLBACK_DATA_FROM_THIS (This); // // Get Buffer Storage data from EFI variable // BufferSize = sizeof (FILE_EXPLORER_NV_DATA ); FeData = &Private->FeFakeNvData; // // Convert <ConfigResp> to buffer data by helper function ConfigToBlock() // Status = ConfigRouting->ConfigToBlock ( ConfigRouting, Configuration, (UINT8 *) FeData, &BufferSize, Progress ); ASSERT_EFI_ERROR (Status); if (FeData->BootDescriptionData[0] != 0x00 || FeData->BootOptionalData[0] != 0x00) { Status = Var_UpdateBootOption (Private, FeData); if (EFI_ERROR (Status)) { return Status; } BOpt_GetBootOptions (Private); CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu); } if (FeData->DriverDescriptionData[0] != 0x00 || FeData->DriverOptionalData[0] != 0x00) { Status = Var_UpdateDriverOption ( Private, Private->FeHiiHandle, FeData->DriverDescriptionData, FeData->DriverOptionalData, FeData->ForceReconnect ); if (EFI_ERROR (Status)) { return Status; } BOpt_GetDriverOptions (Private); CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu); } return EFI_SUCCESS; }
/** This function processes the results of changes in configuration. When user select a interactive opcode, this callback will be triggered. Based on the Question(QuestionId) that triggers the callback, the corresponding actions is performed. It handles: 1) the addition of boot option. 2) the addition of driver option. 3) exit from file browser 4) update of file content if a dir is selected. 5) boot the file if a file is selected in "boot from file" @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param Action Specifies the type of action taken by the browser. @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. @param Type The type of value for the question. @param Value A pointer to the data being sent to the original exporting driver. @param ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback. @retval EFI_INVALID_PARAMETER If paramter Value or ActionRequest is NULL. **/ EFI_STATUS EFIAPI FileExplorerCallback ( IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, IN EFI_BROWSER_ACTION Action, IN EFI_QUESTION_ID QuestionId, IN UINT8 Type, IN EFI_IFR_TYPE_VALUE *Value, OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest ) { BMM_CALLBACK_DATA *Private; FILE_EXPLORER_NV_DATA *NvRamMap; EFI_STATUS Status; if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) { // // All other action return unsupported. // return EFI_UNSUPPORTED; } Status = EFI_SUCCESS; Private = FE_CALLBACK_DATA_FROM_THIS (This); // // Retrieve uncommitted data from Form Browser // NvRamMap = &Private->FeFakeNvData; HiiGetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap); if (Action == EFI_BROWSER_ACTION_CHANGED) { if ((Value == NULL) || (ActionRequest == NULL)) { return EFI_INVALID_PARAMETER; } if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) { NvRamMap->BootOptionChanged = FALSE; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) { NvRamMap->DriverOptionChanged = FALSE; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT; } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) { // // Discard changes and exit formset // NvRamMap->DriverOptionalData[0] = 0x0000; NvRamMap->DriverDescriptionData[0] = 0x0000; NvRamMap->DriverOptionChanged = FALSE; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) { // // Discard changes and exit formset // NvRamMap->BootOptionalData[0] = 0x0000; NvRamMap->BootDescriptionData[0] = 0x0000; NvRamMap->BootOptionChanged = FALSE; *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) { NvRamMap->BootOptionChanged = TRUE; } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) { NvRamMap->DriverOptionChanged = TRUE; } else if (QuestionId < FILE_OPTION_OFFSET) { // // Exit File Explorer formset // *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } else if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < FILE_OPTION_GOTO_OFFSET) { // // Update forms may return TRUE or FALSE, need to check here. // if (UpdateFileExplorer (Private, QuestionId)) { *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; } } } else if (Action == EFI_BROWSER_ACTION_CHANGING) { if (Value == NULL) { return EFI_INVALID_PARAMETER; } if (QuestionId >= FILE_OPTION_GOTO_OFFSET) { // // function will always return FALSE, no need to check here. // UpdateFileExplorer (Private, QuestionId); } } // // Pass changed uncommitted data back to Form Browser // HiiSetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap, NULL); return Status; }
EFI_STATUS EFIAPI FileExplorerCallback ( IN EFI_FORM_CALLBACK_PROTOCOL *This, IN UINT16 KeyValue, IN EFI_IFR_DATA_ARRAY *Data, OUT EFI_HII_CALLBACK_PACKET **Packet ) /*++ Routine Description: Callback Function for file exploration and file interaction. Arguments: This - File explorer callback protocol pointer. KeyValue - Key value to identify the type of data to expect. Data - A pointer to the data being sent to the original exporting driver. Packet - A pointer to a packet of information which a driver passes back to the browser. Returns: EFI_SUCCESS - Callback ended successfully. Others - Contain some errors. --*/ { BMM_CALLBACK_DATA *Private; FILE_EXPLORER_NV_DATA *NvRamMap; EFI_STATUS Status; Status = EFI_SUCCESS; Private = FE_CALLBACK_DATA_FROM_THIS (This); UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->FeCallbackHandle; NvRamMap = (FILE_EXPLORER_NV_DATA *) Data->NvRamMap; if (KEY_VALUE_SAVE_AND_EXIT == KeyValue) { // // Apply changes and exit formset. // if (ADD_BOOT_OPTION_STATE == Private->FeCurrentState) { Status = Var_UpdateBootOption (Private, NvRamMap); if (EFI_ERROR (Status)) { return Status; } BOpt_GetBootOptions (Private); CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu); } else if (ADD_DRIVER_OPTION_STATE == Private->FeCurrentState) { Status = Var_UpdateDriverOption ( Private, Private->FeHiiHandle, NvRamMap->DescriptionData, NvRamMap->OptionalData, NvRamMap->ForceReconnect ); if (EFI_ERROR (Status)) { return Status; } BOpt_GetDriverOptions (Private); CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu); } CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED); } else if (KEY_VALUE_NO_SAVE_AND_EXIT == KeyValue) { // // Discard changes and exit formset. // NvRamMap->OptionalData[0] = 0x0000; NvRamMap->DescriptionData[0] = 0x0000; CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED); } else if (KeyValue < FILE_OPTION_OFFSET) { // // Exit File Explorer formset. // CreateCallbackPacket (Packet, EXIT_REQUIRED); } else { if (UpdateFileExplorer (Private, KeyValue)) { CreateCallbackPacket (Packet, EXIT_REQUIRED); } } return Status; }