]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c
03dd09bc2cf1794697bdb191e991e81b684c3215
[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 EDES_TODO: Add parameter description
22 @param MenuOption Pointer to menu options to display.
23
24 EDES_TODO: Incomplete Descriptions None.
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
216
217 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
218 @param Action Specifies the type of action taken by the browser.
219 @param QuestionId A unique value which is sent to the original exporting driver
220 so that it can identify the type of data to expect.
221 @param Type The type of value for the question.
222 @param Value A pointer to the data being sent to the original exporting driver.
223 @param ActionRequest On return, points to the action requested by the callback function.
224
225 @retval EFI_SUCCESS The callback successfully handled the action.
226 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
227 @retval EFI_DEVICE_ERROR The variable could not be saved.
228 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
229
230 **/
231 EFI_STATUS
232 EFIAPI
233 FileExplorerCallback (
234 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
235 IN EFI_BROWSER_ACTION Action,
236 IN EFI_QUESTION_ID QuestionId,
237 IN UINT8 Type,
238 IN EFI_IFR_TYPE_VALUE *Value,
239 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
240 )
241 {
242 BMM_CALLBACK_DATA *Private;
243 FILE_EXPLORER_NV_DATA *NvRamMap;
244 EFI_STATUS Status;
245 UINTN BufferSize;
246
247 if ((Value == NULL) || (ActionRequest == NULL)) {
248 return EFI_INVALID_PARAMETER;
249 }
250
251 Status = EFI_SUCCESS;
252 Private = FE_CALLBACK_DATA_FROM_THIS (This);
253 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
254
255 //
256 // Retrive uncommitted data from Form Browser
257 //
258 NvRamMap = &Private->FeFakeNvData;
259 BufferSize = sizeof (FILE_EXPLORER_NV_DATA);
260 Status = GetBrowserData (NULL, NULL, &BufferSize, (UINT8 *) NvRamMap);
261 if (EFI_ERROR (Status)) {
262 return Status;
263 }
264
265 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
266 //
267 // Apply changes and exit formset
268 //
269 if (ADD_BOOT_OPTION_STATE == Private->FeCurrentState) {
270 Status = Var_UpdateBootOption (Private, NvRamMap);
271 if (EFI_ERROR (Status)) {
272 return Status;
273 }
274
275 BOpt_GetBootOptions (Private);
276 CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);
277 } else if (ADD_DRIVER_OPTION_STATE == Private->FeCurrentState) {
278 Status = Var_UpdateDriverOption (
279 Private,
280 Private->FeHiiHandle,
281 NvRamMap->DescriptionData,
282 NvRamMap->OptionalData,
283 NvRamMap->ForceReconnect
284 );
285 if (EFI_ERROR (Status)) {
286 return Status;
287 }
288
289 BOpt_GetDriverOptions (Private);
290 CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);
291 }
292
293 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
294 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
295 //
296 // Discard changes and exit formset
297 //
298 NvRamMap->OptionalData[0] = 0x0000;
299 NvRamMap->DescriptionData[0] = 0x0000;
300 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
301 } else if (QuestionId < FILE_OPTION_OFFSET) {
302 //
303 // Exit File Explorer formset
304 //
305 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
306 } else {
307 if (UpdateFileExplorer (Private, QuestionId)) {
308 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
309 }
310 }
311
312 return Status;
313 }