]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c
Add in supports for platform Setup module which is programmed using Framework HII...
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / Forms.c
CommitLineData
4259256b 1/**@file\r
2 This file contains the form processing code to the HII database.\r
3\r
4Copyright (c) 2006 - 2008 Intel Corporation. <BR>\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15\r
16#include "HiiDatabase.h"\r
59336178 17#include "UefiIfrDefault.h"\r
5391c4f1 18#include "OpcodeCreation.h"\r
4259256b 19\r
20EFI_STATUS\r
21EFIAPI\r
22HiiExportDatabase (\r
23 IN EFI_HII_PROTOCOL *This,\r
24 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
25 IN OUT UINTN *BufferSize,\r
26 OUT VOID *Buffer\r
27 )\r
28/*++\r
29\r
30Routine Description:\r
31\r
32 This function allows a program to extract a form or form package that has\r
33 previously been registered with the EFI HII database.\r
34\r
35Arguments:\r
36\r
37Returns:\r
38\r
39--*/\r
40{\r
41 ASSERT (FALSE);\r
42 return EFI_UNSUPPORTED;\r
43}\r
44\r
ea58467b 45#pragma pack(push, 1)\r
46typedef struct {\r
47 EFI_HII_PACK_HEADER PackageHeader;\r
48 FRAMEWORK_EFI_IFR_FORM_SET FormSet;\r
49 FRAMEWORK_EFI_IFR_END_FORM_SET EndFormSet;\r
50} FRAMEWORK_HII_FORMSET_TEMPLATE;\r
51#pragma pack(pop)\r
52\r
53FRAMEWORK_HII_FORMSET_TEMPLATE FormSetTemplate = {\r
54 {\r
55 sizeof (FRAMEWORK_HII_FORMSET_TEMPLATE),\r
56 EFI_HII_IFR\r
57 },\r
58 {\r
59 {\r
60 FRAMEWORK_EFI_IFR_FORM_SET_OP,\r
61 sizeof (FRAMEWORK_EFI_IFR_FORM_SET)\r
62 },\r
63 //Guid\r
64 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
65 0,\r
66 0,\r
67 0,\r
68 0,\r
69 0,\r
70 0\r
71 },\r
72 {\r
73 FRAMEWORK_EFI_IFR_END_FORM_SET_OP,\r
74 sizeof (FRAMEWORK_EFI_IFR_END_FORM_SET)\r
75 }\r
76};\r
77\r
4259256b 78EFI_STATUS\r
79EFIAPI\r
80HiiGetForms (\r
81 IN EFI_HII_PROTOCOL *This,\r
82 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
83 IN EFI_FORM_ID FormId,\r
84 IN OUT UINTN *BufferLengthTemp,\r
85 OUT UINT8 *Buffer\r
86 )\r
87/*++\r
88\r
89Routine Description:\r
90\r
91 This function allows a program to extract a form or form package that has\r
92 previously been registered with the EFI HII database.\r
93\r
94Arguments:\r
95 This - A pointer to the EFI_HII_PROTOCOL instance.\r
96\r
97 Handle - Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE is defined in\r
98 EFI_HII_PROTOCOL.NewPack() in the Packages section.\r
99\r
100 FormId - The ID of the form to return. If the ID is zero, the entire form package is returned.\r
101 Type EFI_FORM_ID is defined in "Related Definitions" below.\r
102\r
103 BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if\r
104 the length was sufficient and, if it was not, the length that is required to fit the\r
105 requested form(s).\r
106\r
107 Buffer - The buffer designed to receive the form(s).\r
108\r
109Returns:\r
110\r
111 EFI_SUCCESS - Buffer filled with the requested forms. BufferLength\r
112 was updated.\r
113\r
114 EFI_INVALID_PARAMETER - The handle is unknown.\r
115\r
116 EFI_NOT_FOUND - A form on the requested handle cannot be found with the\r
117 requested FormId.\r
118\r
119 EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored.\r
120\r
121--*/\r
122{\r
ea58467b 123 EFI_HII_THUNK_PRIVATE_DATA *Private;\r
124 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *MapEntry;\r
125 FRAMEWORK_HII_FORMSET_TEMPLATE *OutputFormSet;\r
126\r
127 if (*BufferLengthTemp < sizeof(FRAMEWORK_HII_FORMSET_TEMPLATE)) {\r
128 *BufferLengthTemp = sizeof(FRAMEWORK_HII_FORMSET_TEMPLATE);\r
129 return EFI_BUFFER_TOO_SMALL;\r
130 }\r
131 \r
132 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
133\r
134 MapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
135\r
136 if (MapEntry == NULL) {\r
137 return EFI_NOT_FOUND;\r
138 }\r
139\r
140 OutputFormSet = (FRAMEWORK_HII_FORMSET_TEMPLATE *) Buffer;\r
141 \r
142 CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FRAMEWORK_HII_FORMSET_TEMPLATE));\r
143 CopyMem (&OutputFormSet->FormSet.Guid, &MapEntry->TagGuid, sizeof (EFI_GUID)); \r
144 \r
145 return EFI_SUCCESS;\r
4259256b 146}\r
147\r
59336178 148\r
4259256b 149EFI_STATUS\r
150EFIAPI\r
151HiiGetDefaultImage (\r
152 IN EFI_HII_PROTOCOL *This,\r
153 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
154 IN UINTN DefaultMask,\r
155 OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
156 )\r
157/*++\r
158\r
159 Routine Description:\r
160\r
161 This function allows a program to extract the NV Image\r
162 that represents the default storage image\r
163\r
164 Arguments:\r
165 This - A pointer to the EFI_HII_PROTOCOL instance.\r
166 Handle - The HII handle from which will have default data retrieved.\r
167 UINTN - Mask used to retrieve the default image.\r
168 VariablePackList - Callee allocated, tightly-packed, link list data\r
169 structure that contain all default varaible packs\r
170 from the Hii Database.\r
171\r
172 Returns:\r
173 EFI_NOT_FOUND - If Hii database does not contain any default images.\r
174 EFI_INVALID_PARAMETER - Invalid input parameter.\r
175 EFI_SUCCESS - Operation successful.\r
176\r
177--*/\r
178{\r
59336178 179 LIST_ENTRY *UefiDefaults;\r
180 EFI_HII_HANDLE UefiHiiHandle;\r
181 EFI_STATUS Status;\r
182 EFI_HII_THUNK_PRIVATE_DATA *Private;\r
183\r
184 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
185\r
186 UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);\r
187 if (UefiHiiHandle == NULL) {\r
188 ASSERT (FALSE);\r
189 return EFI_INVALID_PARAMETER;\r
190 }\r
191\r
192 UefiDefaults = NULL;\r
193 Status = UefiIfrGetBufferTypeDefaults (UefiHiiHandle, &UefiDefaults);\r
194 if (EFI_ERROR (Status)) {\r
195 goto Done;\r
196 }\r
197\r
198 Status = UefiDefaultsToFrameworkDefaults (UefiDefaults, DefaultMask, VariablePackList);\r
199\r
200Done:\r
201 FreeDefaultList (UefiDefaults);\r
202 \r
203 return Status;\r
4259256b 204}\r
205\r
ebbd2793 206EFI_STATUS\r
207ThunkUpdateFormCallBack (\r
208 IN EFI_HANDLE CallbackHandle,\r
209 IN CONST HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry\r
210 )\r
211{\r
212 EFI_STATUS Status;\r
213 EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallbackProtocol;\r
214 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccessProtocol;\r
215 EFI_HANDLE UefiDriverHandle;\r
216 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigAccessProtocolInstance;\r
217 \r
218 Status = gBS->HandleProtocol (\r
219 CallbackHandle,\r
220 &gEfiFormCallbackProtocolGuid,\r
221 (VOID **) &FrameworkFormCallbackProtocol\r
222 );\r
223 if (EFI_ERROR (Status)) {\r
224 return EFI_INVALID_PARAMETER;\r
225 }\r
226 \r
59336178 227 Status = mHiiDatabase->GetPackageListHandle (\r
228 mHiiDatabase,\r
ebbd2793 229 HandleMapEntry->UefiHiiHandle,\r
230 &UefiDriverHandle\r
231 );\r
232 ASSERT_EFI_ERROR (Status);\r
233 Status = gBS->HandleProtocol (\r
234 UefiDriverHandle,\r
235 &gEfiHiiConfigAccessProtocolGuid,\r
236 (VOID **) &ConfigAccessProtocol\r
237 );\r
238 ASSERT_EFI_ERROR (Status);\r
239 \r
240 ConfigAccessProtocolInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (ConfigAccessProtocol);\r
241 \r
242 ConfigAccessProtocolInstance->FrameworkFormCallbackProtocol = FrameworkFormCallbackProtocol;\r
243\r
244 return EFI_SUCCESS;\r
245}\r
4259256b 246\r
59336178 247\r
248STATIC\r
249EFI_STATUS\r
250GetPackageDataFromPackageList (\r
251 IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,\r
252 IN UINT32 PackageIndex,\r
253 OUT UINT32 *BufferLen,\r
254 OUT EFI_HII_PACKAGE_HEADER **Buffer\r
255 )\r
256{\r
257 UINT32 Index;\r
258 EFI_HII_PACKAGE_HEADER *Package;\r
259 UINT32 Offset;\r
260 UINT32 PackageListLength;\r
261 EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0};\r
262\r
263 ASSERT(HiiPackageList != NULL);\r
264\r
265 if ((BufferLen == NULL) || (Buffer == NULL)) {\r
266 return EFI_INVALID_PARAMETER;\r
267 }\r
268\r
269 Package = NULL;\r
270 Index = 0;\r
271 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
272 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
273 while (Offset < PackageListLength) {\r
274 Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);\r
275 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
276 if (Index == PackageIndex) {\r
277 break;\r
278 }\r
279 Offset += PackageHeader.Length;\r
280 Index++;\r
281 }\r
282 if (Offset >= PackageListLength) {\r
283 //\r
284 // no package found in this Package List\r
285 //\r
286 return EFI_NOT_FOUND;\r
287 }\r
288\r
289 *BufferLen = PackageHeader.Length;\r
290 *Buffer = Package;\r
291 return EFI_SUCCESS;\r
292}\r
293\r
294/**\r
295 Check if Label exist in the IFR form package.\r
296\r
297 @param \r
298\r
299**/\r
300EFI_STATUS\r
301LocateLabel (\r
302 IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
303 IN EFI_FORM_LABEL Label,\r
304 OUT EFI_GUID *FormsetGuid,\r
305 OUT EFI_FORM_ID *FormId\r
306 )\r
307{\r
308 UINTN Offset;\r
309 EFI_IFR_OP_HEADER *IfrOpHdr;\r
310 UINT8 ExtendOpCode;\r
311 UINT16 LabelNumber;\r
312 EFI_GUID InternalFormSetGuid;\r
313 EFI_FORM_ID InternalFormId;\r
314 BOOLEAN GetFormSet;\r
315 BOOLEAN GetForm;\r
316\r
317 IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));\r
318 Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
319\r
320 InternalFormId= 0;\r
321 ZeroMem (&InternalFormSetGuid, sizeof (EFI_GUID));\r
322 GetFormSet = FALSE;\r
323 GetForm = FALSE;\r
324\r
325 while (Offset < Package->Length) {\r
326 switch (IfrOpHdr->OpCode) {\r
327 case EFI_IFR_FORM_SET_OP :\r
328 CopyMem (&InternalFormSetGuid, &((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, sizeof (EFI_GUID));\r
329 GetFormSet = TRUE;\r
330 break;\r
331\r
332 case EFI_IFR_FORM_OP:\r
333 CopyMem (&InternalFormId, &((EFI_IFR_FORM *) IfrOpHdr)->FormId, sizeof (EFI_FORM_ID));\r
334 GetForm = TRUE;\r
335 break;\r
336\r
337 case EFI_IFR_GUID_OP :\r
338 ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;\r
339 \r
340 if (ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) {\r
341 //\r
342 // Go to the next Op-Code\r
343 //\r
344 Offset += IfrOpHdr->Length;\r
345 IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
346 continue;\r
347 }\r
348 \r
349 CopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16));\r
350 if (LabelNumber == Label) {\r
351 ASSERT (GetForm && GetFormSet);\r
352 CopyGuid (FormsetGuid, &InternalFormSetGuid);\r
353 *FormId = InternalFormId;\r
354 return EFI_SUCCESS;\r
355 }\r
356 \r
357\r
358 break;\r
359 default :\r
360 break;\r
361 }\r
362\r
363 //\r
364 // Go to the next Op-Code\r
365 //\r
366 Offset += IfrOpHdr->Length;\r
367 IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
368 }\r
369\r
370 return EFI_NOT_FOUND;\r
371}\r
372\r
373/**\r
374 Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.\r
375 \r
376 EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation\r
377 does not restrict labels with same label value to be duplicated in either FormSet \r
378 scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL\r
379 with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID \r
380 and Form ID is returned if such Label is found.\r
381\r
382 \r
383 @retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.\r
384 @retval EFI_NOT_FOUND The package list identified by UefiHiiHandle deos not contain FormSet or\r
385 There is no Form ID with value Label found in all Form Sets in the pacakge\r
386 list.\r
387 \r
388 @retval EFI_SUCCESS The first found Form ID is returned in FormId.\r
389**/\r
390EFI_STATUS\r
391ThunkLocateFormId (\r
392 IN EFI_HII_HANDLE Handle,\r
393 IN EFI_FORM_LABEL Label,\r
394 OUT EFI_GUID *FormsetGuid,\r
395 OUT EFI_FORM_ID *FormId\r
396 )\r
397{\r
398 EFI_STATUS Status;\r
399 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
400 UINT32 Index;\r
401 UINTN BufferSize;\r
402 EFI_HII_PACKAGE_HEADER PackageHeader;\r
403 EFI_HII_PACKAGE_HEADER *Package;\r
404 UINT32 PackageLength;\r
405\r
406 BufferSize = 0;\r
407 HiiPackageList = NULL;\r
408 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
409 if (Status == EFI_BUFFER_TOO_SMALL) {\r
410 HiiPackageList = AllocatePool (BufferSize);\r
411 ASSERT (HiiPackageList != NULL);\r
412\r
413 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
414 if (EFI_ERROR (Status)) {\r
415 goto Done;\r
416 }\r
417 }\r
418\r
419 for (Index = 0; ; Index++) {\r
420 Status = GetPackageDataFromPackageList (HiiPackageList, Index, &PackageLength, &Package);\r
421 if (!EFI_ERROR (Status)) {\r
422 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
423 if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
424 Status = LocateLabel (Package, Label, FormsetGuid, FormId);\r
425 if (!EFI_ERROR(Status)) {\r
426 break;\r
427 }\r
428 }\r
429 } else {\r
430 break;\r
431 }\r
432 }\r
433\r
434 \r
435Done:\r
436 FreePool (HiiPackageList);\r
437 \r
438 return Status;\r
439}\r
4259256b 440EFI_STATUS\r
441EFIAPI\r
442HiiUpdateForm (\r
443 IN EFI_HII_PROTOCOL *This,\r
444 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
445 IN EFI_FORM_LABEL Label,\r
446 IN BOOLEAN AddData,\r
99a83b4c 447 IN FRAMEWORK_EFI_HII_UPDATE_DATA *Data\r
4259256b 448 )\r
449/*++\r
450\r
451Routine Description:\r
452 This function allows the caller to update a form that has\r
453 previously been registered with the EFI HII database.\r
454\r
455Arguments:\r
456 Handle - Hii Handle associated with the Formset to modify\r
457 Label - Update information starting immediately after this label in the IFR\r
458 AddData - If TRUE, add data. If FALSE, remove data\r
459 Data - If adding data, this is the pointer to the data to add\r
460\r
461Returns:\r
462 EFI_SUCCESS - Update success.\r
463 Other - Update fail.\r
464\r
465--*/\r
466{\r
ebbd2793 467 EFI_STATUS Status;\r
468 EFI_HII_THUNK_PRIVATE_DATA *Private;\r
469 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
99a83b4c 470 EFI_HII_UPDATE_DATA *UefiHiiUpdateData;\r
471 EFI_HII_HANDLE UefiHiiHandle;\r
59336178 472 EFI_GUID FormsetGuid;\r
473 EFI_FORM_ID FormId;\r
99a83b4c 474\r
475 Status = EFI_SUCCESS;\r
ebbd2793 476\r
477 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
478\r
479 HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
480\r
481 if (HandleMapEntry == NULL) {\r
482 return EFI_NOT_FOUND;\r
483 }\r
484 \r
485 if (Data->FormSetUpdate) {\r
486 Status = ThunkUpdateFormCallBack ((EFI_HANDLE) (UINTN) Data->FormCallbackHandle, HandleMapEntry);\r
487 if (EFI_ERROR (Status)) {\r
488 return Status;\r
489 }\r
490 }\r
99a83b4c 491\r
f274810c 492 if (HandleMapEntry->IsPackageListWithOnlyStringPackages) {\r
493 UefiHiiHandle = TagGuidToUefiIfrHiiHandle (Private, &HandleMapEntry->TagGuid);\r
494 \r
495 if (UefiHiiHandle == NULL) {\r
496 return EFI_INVALID_PARAMETER;\r
497 }\r
498 } else {\r
499 UefiHiiHandle = HandleMapEntry->UefiHiiHandle;\r
500 }\r
99a83b4c 501\r
f274810c 502 UefiHiiUpdateData = NULL;\r
503\r
504 if (AddData) {\r
505 if (Data->DataCount != 0) {\r
506 \r
507 Status = ThunkFrameworkUpdateDataToUefiUpdateData (Data, AddData, &UefiHiiUpdateData);\r
508 ASSERT_EFI_ERROR (Status);\r
509\r
510 Status = ThunkLocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);\r
511 ASSERT_EFI_ERROR (Status);\r
512\r
513 Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, AddData, UefiHiiUpdateData);\r
514 ASSERT_EFI_ERROR (Status);\r
515 \r
22f5582e 516 } \r
f274810c 517 } else {\r
59336178 518 Status = ThunkLocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);\r
519 ASSERT_EFI_ERROR (Status);\r
520\r
f274810c 521 //\r
522 // Delete Opcode starting from Labe in FormId found\r
523 //\r
22f5582e 524 UefiHiiUpdateData = AllocateZeroPool (sizeof (*UefiHiiUpdateData));\r
525 \r
526 Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, FALSE, UefiHiiUpdateData);\r
f274810c 527 ASSERT_EFI_ERROR (Status);\r
528 }\r
529\r
530 if (UefiHiiUpdateData != NULL) {\r
531 SafeFreePool (UefiHiiUpdateData->Data);\r
532 SafeFreePool (UefiHiiUpdateData);\r
99a83b4c 533 }\r
534\r
535 return Status;\r
4259256b 536}\r