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