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