]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c
Update HiiLib to copy all IfrOpcode, not Opcode by Opcode.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / FileExplorer.c
1 /** @file
2 File explorer related functions.
3
4 Copyright (c) 2004 - 2008, Intel Corporation. <BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "BootMaint.h"
16
17 /**
18 Update the File Explore page.
19
20 @param CallbackData The BMM context data.
21 @param MenuOption Pointer to menu options to display.
22
23 **/
24 VOID
25 UpdateFileExplorePage (
26 IN BMM_CALLBACK_DATA *CallbackData,
27 BM_MENU_OPTION *MenuOption
28 )
29 {
30 UINTN Index;
31 BM_MENU_ENTRY *NewMenuEntry;
32 BM_FILE_CONTEXT *NewFileContext;
33 EFI_FORM_ID FormId;
34
35 NewMenuEntry = NULL;
36 NewFileContext = NULL;
37 FormId = 0;
38
39 RefreshUpdateData ();
40
41 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
42 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);
43 NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
44
45 if (NewFileContext->IsBootLegacy) {
46 continue;
47 }
48
49 if ((NewFileContext->IsDir) || (BOOT_FROM_FILE_STATE == CallbackData->FeCurrentState)) {
50 //
51 // Create Text opcode for directory, also create Text opcode for file in BOOT_FROM_FILE_STATE.
52 //
53 CreateActionOpCode (
54 (UINT16) (FILE_OPTION_OFFSET + Index),
55 NewMenuEntry->DisplayStringToken,
56 STRING_TOKEN (STR_NULL_STRING),
57 EFI_IFR_FLAG_CALLBACK,
58 0,
59 &gUpdateData
60 );
61 } else {
62 //
63 // Create Goto opcode for file in ADD_BOOT_OPTION_STATE or ADD_DRIVER_OPTION_STATE.
64 //
65 if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {
66 FormId = FORM_BOOT_ADD_DESCRIPTION_ID;
67 } else if (ADD_DRIVER_OPTION_STATE == CallbackData->FeCurrentState) {
68 FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;
69 }
70
71 CreateGotoOpCode (
72 FormId,
73 NewMenuEntry->DisplayStringToken,
74 STRING_TOKEN (STR_NULL_STRING),
75 EFI_IFR_FLAG_CALLBACK,
76 (UINT16) (FILE_OPTION_OFFSET + Index),
77 &gUpdateData
78 );
79 }
80 }
81
82 IfrLibUpdateForm (
83 CallbackData->FeHiiHandle,
84 &mFileExplorerGuid,
85 FORM_FILE_EXPLORER_ID,
86 FORM_FILE_EXPLORER_ID,
87 FALSE,
88 &gUpdateData
89 );
90 }
91
92 /**
93 Update the file explower page with the refershed file system.
94
95
96 @param CallbackData BMM context data
97 @param KeyValue Key value to identify the type of data to expect.
98
99 @retval TRUE Inform the caller to create a callback packet to exit file explorer.
100 @retval FALSE Indicate that there is no need to exit file explorer.
101
102 **/
103 BOOLEAN
104 UpdateFileExplorer (
105 IN BMM_CALLBACK_DATA *CallbackData,
106 IN UINT16 KeyValue
107 )
108 {
109 UINT16 FileOptionMask;
110 BM_MENU_ENTRY *NewMenuEntry;
111 BM_FILE_CONTEXT *NewFileContext;
112 EFI_FORM_ID FormId;
113 BOOLEAN ExitFileExplorer;
114 EFI_STATUS Status;
115
116 NewMenuEntry = NULL;
117 NewFileContext = NULL;
118 ExitFileExplorer = FALSE;
119
120 FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue);
121
122 if (UNKNOWN_CONTEXT == CallbackData->FeDisplayContext) {
123 //
124 // First in, display file system.
125 //
126 BOpt_FreeMenu (&FsOptionMenu);
127 BOpt_FindFileSystem (CallbackData);
128 CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu);
129
130 UpdateFileExplorePage (CallbackData, &FsOptionMenu);
131
132 CallbackData->FeDisplayContext = FILE_SYSTEM;
133 } else {
134 if (FILE_SYSTEM == CallbackData->FeDisplayContext) {
135 NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask);
136 } else if (DIRECTORY == CallbackData->FeDisplayContext) {
137 NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask);
138 }
139
140 CallbackData->FeDisplayContext = DIRECTORY;
141
142 NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
143
144 if (NewFileContext->IsDir ) {
145 RemoveEntryList (&NewMenuEntry->Link);
146 BOpt_FreeMenu (&DirectoryMenu);
147 Status = BOpt_FindFiles (CallbackData, NewMenuEntry);
148 if (EFI_ERROR (Status)) {
149 ExitFileExplorer = TRUE;
150 goto exit;
151 }
152 CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu);
153 BOpt_DestroyMenuEntry (NewMenuEntry);
154
155 UpdateFileExplorePage (CallbackData, &DirectoryMenu);
156
157 } else {
158 switch (CallbackData->FeCurrentState) {
159 case BOOT_FROM_FILE_STATE:
160 //
161 // Here boot from file
162 //
163 BootThisFile (NewFileContext);
164 ExitFileExplorer = TRUE;
165 break;
166
167 case ADD_BOOT_OPTION_STATE:
168 case ADD_DRIVER_OPTION_STATE:
169 if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {
170 FormId = FORM_BOOT_ADD_DESCRIPTION_ID;
171 } else {
172 FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;
173 }
174
175 CallbackData->MenuEntry = NewMenuEntry;
176 CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;
177
178 //
179 // Create Subtitle op-code for the display string of the option.
180 //
181 RefreshUpdateData ();
182
183 CreateSubTitleOpCode (
184 NewMenuEntry->DisplayStringToken,
185 0,
186 0,
187 0,
188 &gUpdateData
189 );
190
191 IfrLibUpdateForm (
192 CallbackData->FeHiiHandle,
193 &mFileExplorerGuid,
194 FormId,
195 FormId,
196 FALSE,
197 &gUpdateData
198 );
199 break;
200
201 default:
202 break;
203 }
204 }
205 }
206 exit:
207 return ExitFileExplorer;
208 }
209
210 /**
211 This function processes the results of changes in configuration.
212 When user select a interactive opcode, this callback will be triggered.
213 Based on the Question(QuestionId) that triggers the callback, the corresponding
214 actions is performed. It handles:
215
216 1) the addition of boot option.
217 2) the addition of driver option.
218 3) exit from file browser
219 4) update of file content if a dir is selected.
220 5) boot the file if a file is selected in "boot from file"
221
222
223 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
224 @param Action Specifies the type of action taken by the browser.
225 @param QuestionId A unique value which is sent to the original exporting driver
226 so that it can identify the type of data to expect.
227 @param Type The type of value for the question.
228 @param Value A pointer to the data being sent to the original exporting driver.
229 @param ActionRequest On return, points to the action requested by the callback function.
230
231 @retval EFI_SUCCESS The callback successfully handled the action.
232 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
233 @retval EFI_DEVICE_ERROR The variable could not be saved.
234 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
235 @retval EFI_INVALID_PARAMETER If paramter Value or ActionRequest is NULL.
236 **/
237 EFI_STATUS
238 EFIAPI
239 FileExplorerCallback (
240 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
241 IN EFI_BROWSER_ACTION Action,
242 IN EFI_QUESTION_ID QuestionId,
243 IN UINT8 Type,
244 IN EFI_IFR_TYPE_VALUE *Value,
245 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
246 )
247 {
248 BMM_CALLBACK_DATA *Private;
249 FILE_EXPLORER_NV_DATA *NvRamMap;
250 EFI_STATUS Status;
251 UINTN BufferSize;
252
253 if ((Value == NULL) || (ActionRequest == NULL)) {
254 return EFI_INVALID_PARAMETER;
255 }
256
257 Status = EFI_SUCCESS;
258 Private = FE_CALLBACK_DATA_FROM_THIS (This);
259 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
260
261 //
262 // Retrieve uncommitted data from Form Browser
263 //
264 NvRamMap = &Private->FeFakeNvData;
265 BufferSize = sizeof (FILE_EXPLORER_NV_DATA);
266 Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) NvRamMap);
267 if (EFI_ERROR (Status)) {
268 return Status;
269 }
270
271 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
272 //
273 // Apply changes and exit formset
274 //
275 if (ADD_BOOT_OPTION_STATE == Private->FeCurrentState) {
276 Status = Var_UpdateBootOption (Private, NvRamMap);
277 if (EFI_ERROR (Status)) {
278 return Status;
279 }
280
281 BOpt_GetBootOptions (Private);
282 CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);
283 } else if (ADD_DRIVER_OPTION_STATE == Private->FeCurrentState) {
284 Status = Var_UpdateDriverOption (
285 Private,
286 Private->FeHiiHandle,
287 NvRamMap->DescriptionData,
288 NvRamMap->OptionalData,
289 NvRamMap->ForceReconnect
290 );
291 if (EFI_ERROR (Status)) {
292 return Status;
293 }
294
295 BOpt_GetDriverOptions (Private);
296 CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);
297 }
298
299 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
300 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
301 //
302 // Discard changes and exit formset
303 //
304 NvRamMap->OptionalData[0] = 0x0000;
305 NvRamMap->DescriptionData[0] = 0x0000;
306 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
307 } else if (QuestionId < FILE_OPTION_OFFSET) {
308 //
309 // Exit File Explorer formset
310 //
311 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
312 } else {
313 if (UpdateFileExplorer (Private, QuestionId)) {
314 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
315 }
316 }
317
318 return Status;
319 }