]> git.proxmox.com Git - mirror_edk2.git/blob - EdkNt32Pkg/Dxe/PlatformBds/Generic/BootMaint/FileExplorer.c
Bug fix for "Unplug U Disk during exploer using File Explorer cause tiano halt"
[mirror_edk2.git] / EdkNt32Pkg / Dxe / PlatformBds / Generic / BootMaint / FileExplorer.c
1 /*++
2
3 Copyright (c) 2006, 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 AgBStract:
17
18 File explorer related functions.
19
20 --*/
21
22 #include "Generic/Bds.h"
23 #include "BootMaint.h"
24 #include "BdsPlatform.h"
25
26 VOID
27 UpdateFileExplorePage (
28 IN BMM_CALLBACK_DATA *CallbackData,
29 BM_MENU_OPTION *MenuOption
30 )
31 /*++
32 Routine Description:
33 Update the File Explore page.
34
35 Arguments:
36 MenuOption - Pointer to menu options to display.
37
38 Returns:
39 None.
40
41 --*/
42 {
43 UINT8 *Location;
44 UINTN Index;
45 BM_MENU_ENTRY *NewMenuEntry;
46 BM_FILE_CONTEXT *NewFileContext;
47 FORM_ID FormId;
48
49 NewMenuEntry = NULL;
50 NewFileContext = NULL;
51 FormId = 0;
52
53 //
54 // Clean up file explore page.
55 //
56 RefreshUpdateData (FALSE, 0, FALSE, 0, 0xff);
57
58 //
59 // Remove all op-codes from dynamic page
60 //
61 CallbackData->Hii->UpdateForm (
62 CallbackData->Hii,
63 CallbackData->FeHiiHandle,
64 FORM_FILE_EXPLORER_ID,
65 FALSE,
66 UpdateData
67 );
68
69 RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 0);
70
71 Location = (UINT8 *) &UpdateData->Data;
72
73 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
74 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);
75 NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
76
77 if (NewFileContext->IsBootLegacy) {
78 continue;
79 }
80
81 if ((NewFileContext->IsDir) || (BOOT_FROM_FILE_STATE == CallbackData->FeCurrentState)) {
82 //
83 // Create Text opcode for directory, also create Text opcode for file in BOOT_FROM_FILE_STATE.
84 //
85 CreateTextOpCode (
86 NewMenuEntry->DisplayStringToken,
87 STR_NULL_STRING,
88 STR_NULL_STRING,
89 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
90 (UINT16) (FILE_OPTION_OFFSET + Index),
91 Location
92 );
93 } else {
94 //
95 // Create Goto opcode for file in ADD_BOOT_OPTION_STATE or ADD_DRIVER_OPTION_STATE.
96 //
97 if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {
98 FormId = FORM_BOOT_ADD_DESCRIPTION_ID;
99 } else if (ADD_DRIVER_OPTION_STATE == CallbackData->FeCurrentState) {
100 FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;
101 }
102
103 CreateGotoOpCode (
104 FormId,
105 NewMenuEntry->DisplayStringToken,
106 STRING_TOKEN (STR_NULL_STRING),
107 EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
108 (UINT16) (FILE_OPTION_OFFSET + Index),
109 Location
110 );
111 }
112
113 UpdateData->DataCount++;
114 Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
115 }
116
117 CallbackData->Hii->UpdateForm (
118 CallbackData->Hii,
119 CallbackData->FeHiiHandle,
120 FORM_FILE_EXPLORER_ID,
121 TRUE,
122 UpdateData
123 );
124 }
125
126 BOOLEAN
127 UpdateFileExplorer (
128 IN BMM_CALLBACK_DATA *CallbackData,
129 IN UINT16 KeyValue
130 )
131 /*++
132
133 Routine Description:
134 Update the file explower page with the refershed file system.
135
136 Arguments:
137 CallbackData - BMM context data
138 KeyValue - Key value to identify the type of data to expect.
139
140 Returns:
141 TRUE - Inform the caller to create a callback packet to exit file explorer.
142 FALSE - Indicate that there is no need to exit file explorer.
143
144 --*/
145 {
146 UINT16 FileOptionMask;
147 BM_MENU_ENTRY *NewMenuEntry;
148 BM_FILE_CONTEXT *NewFileContext;
149 FORM_ID FormId;
150 BOOLEAN ExitFileExplorer;
151 EFI_STATUS Status;
152
153 NewMenuEntry = NULL;
154 NewFileContext = NULL;
155 ExitFileExplorer = FALSE;
156
157 FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue);
158
159 if (UNKNOWN_CONTEXT == CallbackData->FeDisplayContext) {
160 //
161 // First in, display file system.
162 //
163 BOpt_FreeMenu (&FsOptionMenu);
164 BOpt_FindFileSystem (CallbackData);
165 CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu);
166
167 UpdateFileExplorePage (CallbackData, &FsOptionMenu);
168
169 CallbackData->FeDisplayContext = FILE_SYSTEM;
170 } else {
171 if (FILE_SYSTEM == CallbackData->FeDisplayContext) {
172 NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask);
173 } else if (DIRECTORY == CallbackData->FeDisplayContext) {
174 NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask);
175 }
176
177 CallbackData->FeDisplayContext = DIRECTORY;
178
179 NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;
180
181 if (NewFileContext->IsDir ) {
182 RemoveEntryList (&NewMenuEntry->Link);
183 BOpt_FreeMenu (&DirectoryMenu);
184 Status = BOpt_FindFiles (CallbackData, NewMenuEntry);
185 if (EFI_ERROR (Status)) {
186 ExitFileExplorer = TRUE;
187 goto exit;
188 }
189 CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu);
190 BOpt_DestroyMenuEntry (NewMenuEntry);
191
192 UpdateFileExplorePage (CallbackData, &DirectoryMenu);
193
194 } else {
195 switch (CallbackData->FeCurrentState) {
196 case BOOT_FROM_FILE_STATE:
197 //
198 // Here boot from file
199 //
200 BootThisFile (NewFileContext);
201 ExitFileExplorer = TRUE;
202 break;
203
204 case ADD_BOOT_OPTION_STATE:
205 case ADD_DRIVER_OPTION_STATE:
206 if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {
207 FormId = FORM_BOOT_ADD_DESCRIPTION_ID;
208 } else {
209 FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;
210 }
211
212 CallbackData->MenuEntry = NewMenuEntry;
213 CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;
214
215 //
216 // Clean up file explore page.
217 //
218 RefreshUpdateData (FALSE, 0, FALSE, 0, 1);
219
220 //
221 // Remove the Subtitle op-code.
222 //
223 CallbackData->Hii->UpdateForm (
224 CallbackData->Hii,
225 CallbackData->FeHiiHandle,
226 FormId,
227 FALSE,
228 UpdateData
229 );
230
231 //
232 // Create Subtitle op-code for the display string of the option.
233 //
234 RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 1);
235
236 CreateSubTitleOpCode (
237 NewMenuEntry->DisplayStringToken,
238 &UpdateData->Data
239 );
240
241 CallbackData->Hii->UpdateForm (
242 CallbackData->Hii,
243 CallbackData->FeHiiHandle,
244 FormId,
245 TRUE,
246 UpdateData
247 );
248 break;
249
250 default:
251 break;
252 }
253 }
254 }
255 exit:
256 return ExitFileExplorer;
257 }
258
259 EFI_STATUS
260 EFIAPI
261 FileExplorerCallback (
262 IN EFI_FORM_CALLBACK_PROTOCOL *This,
263 IN UINT16 KeyValue,
264 IN EFI_IFR_DATA_ARRAY *Data,
265 OUT EFI_HII_CALLBACK_PACKET **Packet
266 )
267 /*++
268 Routine Description:
269 Callback Function for file exploration and file interaction.
270
271 Arguments:
272 This - File explorer callback protocol pointer.
273 KeyValue - Key value to identify the type of data to expect.
274 Data - A pointer to the data being sent to the original exporting driver.
275 Packet - A pointer to a packet of information which a driver passes back to the browser.
276
277 Returns:
278 EFI_SUCCESS - Callback ended successfully.
279 Others - Contain some errors.
280
281 --*/
282 {
283 BMM_CALLBACK_DATA *Private;
284 FILE_EXPLORER_NV_DATA *NvRamMap;
285 EFI_STATUS Status;
286
287 Status = EFI_SUCCESS;
288 Private = FE_CALLBACK_DATA_FROM_THIS (This);
289 UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->FeCallbackHandle;
290 NvRamMap = (FILE_EXPLORER_NV_DATA *) Data->NvRamMap;
291
292 if (KEY_VALUE_SAVE_AND_EXIT == KeyValue) {
293 //
294 // Apply changes and exit formset.
295 //
296 if (ADD_BOOT_OPTION_STATE == Private->FeCurrentState) {
297 Status = Var_UpdateBootOption (Private, NvRamMap);
298 if (EFI_ERROR (Status)) {
299 return Status;
300 }
301
302 BOpt_GetBootOptions (Private);
303 CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);
304 } else if (ADD_DRIVER_OPTION_STATE == Private->FeCurrentState) {
305 Status = Var_UpdateDriverOption (
306 Private,
307 Private->FeHiiHandle,
308 NvRamMap->DescriptionData,
309 NvRamMap->OptionalData,
310 NvRamMap->ForceReconnect
311 );
312 if (EFI_ERROR (Status)) {
313 return Status;
314 }
315
316 BOpt_GetDriverOptions (Private);
317 CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);
318 }
319
320 CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED);
321 } else if (KEY_VALUE_NO_SAVE_AND_EXIT == KeyValue) {
322 //
323 // Discard changes and exit formset.
324 //
325 NvRamMap->OptionalData[0] = 0x0000;
326 NvRamMap->DescriptionData[0] = 0x0000;
327 CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED);
328 } else if (KeyValue < FILE_OPTION_OFFSET) {
329 //
330 // Exit File Explorer formset.
331 //
332 CreateCallbackPacket (Packet, EXIT_REQUIRED);
333 } else {
334 if (UpdateFileExplorer (Private, KeyValue)) {
335 CreateCallbackPacket (Packet, EXIT_REQUIRED);
336 }
337 }
338
339 return Status;
340 }