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