]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/Forms.c
Add support to map more Framework Opcode (such as OrderedList, OneOf, etc) to Uefi...
[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
45EFI_STATUS\r
46EFIAPI\r
47HiiGetForms (\r
48 IN EFI_HII_PROTOCOL *This,\r
49 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
50 IN EFI_FORM_ID FormId,\r
51 IN OUT UINTN *BufferLengthTemp,\r
52 OUT UINT8 *Buffer\r
53 )\r
54/*++\r
55\r
56Routine Description:\r
57\r
58 This function allows a program to extract a form or form package that has\r
59 previously been registered with the EFI HII database.\r
60\r
61Arguments:\r
62 This - A pointer to the EFI_HII_PROTOCOL instance.\r
63\r
64 Handle - Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE is defined in\r
65 EFI_HII_PROTOCOL.NewPack() in the Packages section.\r
66\r
67 FormId - The ID of the form to return. If the ID is zero, the entire form package is returned.\r
68 Type EFI_FORM_ID is defined in "Related Definitions" below.\r
69\r
70 BufferLength - On input, the length of the Buffer. On output, the length of the returned buffer, if\r
71 the length was sufficient and, if it was not, the length that is required to fit the\r
72 requested form(s).\r
73\r
74 Buffer - The buffer designed to receive the form(s).\r
75\r
76Returns:\r
77\r
78 EFI_SUCCESS - Buffer filled with the requested forms. BufferLength\r
79 was updated.\r
80\r
81 EFI_INVALID_PARAMETER - The handle is unknown.\r
82\r
83 EFI_NOT_FOUND - A form on the requested handle cannot be found with the\r
84 requested FormId.\r
85\r
86 EFI_BUFFER_TOO_SMALL - The buffer provided was not large enough to allow the form to be stored.\r
87\r
88--*/\r
89{\r
90 ASSERT (FALSE);\r
91 return EFI_UNSUPPORTED;\r
92}\r
93\r
59336178 94\r
4259256b 95EFI_STATUS\r
96EFIAPI\r
97HiiGetDefaultImage (\r
98 IN EFI_HII_PROTOCOL *This,\r
99 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
100 IN UINTN DefaultMask,\r
101 OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList\r
102 )\r
103/*++\r
104\r
105 Routine Description:\r
106\r
107 This function allows a program to extract the NV Image\r
108 that represents the default storage image\r
109\r
110 Arguments:\r
111 This - A pointer to the EFI_HII_PROTOCOL instance.\r
112 Handle - The HII handle from which will have default data retrieved.\r
113 UINTN - Mask used to retrieve the default image.\r
114 VariablePackList - Callee allocated, tightly-packed, link list data\r
115 structure that contain all default varaible packs\r
116 from the Hii Database.\r
117\r
118 Returns:\r
119 EFI_NOT_FOUND - If Hii database does not contain any default images.\r
120 EFI_INVALID_PARAMETER - Invalid input parameter.\r
121 EFI_SUCCESS - Operation successful.\r
122\r
123--*/\r
124{\r
59336178 125 LIST_ENTRY *UefiDefaults;\r
126 EFI_HII_HANDLE UefiHiiHandle;\r
127 EFI_STATUS Status;\r
128 EFI_HII_THUNK_PRIVATE_DATA *Private;\r
129\r
130 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
131\r
132 UefiHiiHandle = FrameworkHiiHandleToUefiHiiHandle (Private, Handle);\r
133 if (UefiHiiHandle == NULL) {\r
134 ASSERT (FALSE);\r
135 return EFI_INVALID_PARAMETER;\r
136 }\r
137\r
138 UefiDefaults = NULL;\r
139 Status = UefiIfrGetBufferTypeDefaults (UefiHiiHandle, &UefiDefaults);\r
140 if (EFI_ERROR (Status)) {\r
141 goto Done;\r
142 }\r
143\r
144 Status = UefiDefaultsToFrameworkDefaults (UefiDefaults, DefaultMask, VariablePackList);\r
145\r
146Done:\r
147 FreeDefaultList (UefiDefaults);\r
148 \r
149 return Status;\r
4259256b 150}\r
151\r
ebbd2793 152EFI_STATUS\r
153ThunkUpdateFormCallBack (\r
154 IN EFI_HANDLE CallbackHandle,\r
155 IN CONST HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry\r
156 )\r
157{\r
158 EFI_STATUS Status;\r
159 EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallbackProtocol;\r
160 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccessProtocol;\r
161 EFI_HANDLE UefiDriverHandle;\r
162 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigAccessProtocolInstance;\r
163 \r
164 Status = gBS->HandleProtocol (\r
165 CallbackHandle,\r
166 &gEfiFormCallbackProtocolGuid,\r
167 (VOID **) &FrameworkFormCallbackProtocol\r
168 );\r
169 if (EFI_ERROR (Status)) {\r
170 return EFI_INVALID_PARAMETER;\r
171 }\r
172 \r
59336178 173 Status = mHiiDatabase->GetPackageListHandle (\r
174 mHiiDatabase,\r
ebbd2793 175 HandleMapEntry->UefiHiiHandle,\r
176 &UefiDriverHandle\r
177 );\r
178 ASSERT_EFI_ERROR (Status);\r
179 Status = gBS->HandleProtocol (\r
180 UefiDriverHandle,\r
181 &gEfiHiiConfigAccessProtocolGuid,\r
182 (VOID **) &ConfigAccessProtocol\r
183 );\r
184 ASSERT_EFI_ERROR (Status);\r
185 \r
186 ConfigAccessProtocolInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (ConfigAccessProtocol);\r
187 \r
188 ConfigAccessProtocolInstance->FrameworkFormCallbackProtocol = FrameworkFormCallbackProtocol;\r
189\r
190 return EFI_SUCCESS;\r
191}\r
4259256b 192\r
59336178 193\r
194STATIC\r
195EFI_STATUS\r
196GetPackageDataFromPackageList (\r
197 IN EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,\r
198 IN UINT32 PackageIndex,\r
199 OUT UINT32 *BufferLen,\r
200 OUT EFI_HII_PACKAGE_HEADER **Buffer\r
201 )\r
202{\r
203 UINT32 Index;\r
204 EFI_HII_PACKAGE_HEADER *Package;\r
205 UINT32 Offset;\r
206 UINT32 PackageListLength;\r
207 EFI_HII_PACKAGE_HEADER PackageHeader = {0, 0};\r
208\r
209 ASSERT(HiiPackageList != NULL);\r
210\r
211 if ((BufferLen == NULL) || (Buffer == NULL)) {\r
212 return EFI_INVALID_PARAMETER;\r
213 }\r
214\r
215 Package = NULL;\r
216 Index = 0;\r
217 Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);\r
218 CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));\r
219 while (Offset < PackageListLength) {\r
220 Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);\r
221 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
222 if (Index == PackageIndex) {\r
223 break;\r
224 }\r
225 Offset += PackageHeader.Length;\r
226 Index++;\r
227 }\r
228 if (Offset >= PackageListLength) {\r
229 //\r
230 // no package found in this Package List\r
231 //\r
232 return EFI_NOT_FOUND;\r
233 }\r
234\r
235 *BufferLen = PackageHeader.Length;\r
236 *Buffer = Package;\r
237 return EFI_SUCCESS;\r
238}\r
239\r
240/**\r
241 Check if Label exist in the IFR form package.\r
242\r
243 @param \r
244\r
245**/\r
246EFI_STATUS\r
247LocateLabel (\r
248 IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
249 IN EFI_FORM_LABEL Label,\r
250 OUT EFI_GUID *FormsetGuid,\r
251 OUT EFI_FORM_ID *FormId\r
252 )\r
253{\r
254 UINTN Offset;\r
255 EFI_IFR_OP_HEADER *IfrOpHdr;\r
256 UINT8 ExtendOpCode;\r
257 UINT16 LabelNumber;\r
258 EFI_GUID InternalFormSetGuid;\r
259 EFI_FORM_ID InternalFormId;\r
260 BOOLEAN GetFormSet;\r
261 BOOLEAN GetForm;\r
262\r
263 IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));\r
264 Offset = sizeof (EFI_HII_PACKAGE_HEADER);\r
265\r
266 InternalFormId= 0;\r
267 ZeroMem (&InternalFormSetGuid, sizeof (EFI_GUID));\r
268 GetFormSet = FALSE;\r
269 GetForm = FALSE;\r
270\r
271 while (Offset < Package->Length) {\r
272 switch (IfrOpHdr->OpCode) {\r
273 case EFI_IFR_FORM_SET_OP :\r
274 CopyMem (&InternalFormSetGuid, &((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, sizeof (EFI_GUID));\r
275 GetFormSet = TRUE;\r
276 break;\r
277\r
278 case EFI_IFR_FORM_OP:\r
279 CopyMem (&InternalFormId, &((EFI_IFR_FORM *) IfrOpHdr)->FormId, sizeof (EFI_FORM_ID));\r
280 GetForm = TRUE;\r
281 break;\r
282\r
283 case EFI_IFR_GUID_OP :\r
284 ExtendOpCode = ((EFI_IFR_GUID_LABEL *) IfrOpHdr)->ExtendOpCode;\r
285 \r
286 if (ExtendOpCode != EFI_IFR_EXTEND_OP_LABEL) {\r
287 //\r
288 // Go to the next Op-Code\r
289 //\r
290 Offset += IfrOpHdr->Length;\r
291 IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
292 continue;\r
293 }\r
294 \r
295 CopyMem (&LabelNumber, &((EFI_IFR_GUID_LABEL *)IfrOpHdr)->Number, sizeof (UINT16));\r
296 if (LabelNumber == Label) {\r
297 ASSERT (GetForm && GetFormSet);\r
298 CopyGuid (FormsetGuid, &InternalFormSetGuid);\r
299 *FormId = InternalFormId;\r
300 return EFI_SUCCESS;\r
301 }\r
302 \r
303\r
304 break;\r
305 default :\r
306 break;\r
307 }\r
308\r
309 //\r
310 // Go to the next Op-Code\r
311 //\r
312 Offset += IfrOpHdr->Length;\r
313 IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);\r
314 }\r
315\r
316 return EFI_NOT_FOUND;\r
317}\r
318\r
319/**\r
320 Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.\r
321 \r
322 EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation\r
323 does not restrict labels with same label value to be duplicated in either FormSet \r
324 scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL\r
325 with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID \r
326 and Form ID is returned if such Label is found.\r
327\r
328 \r
329 @retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.\r
330 @retval EFI_NOT_FOUND The package list identified by UefiHiiHandle deos not contain FormSet or\r
331 There is no Form ID with value Label found in all Form Sets in the pacakge\r
332 list.\r
333 \r
334 @retval EFI_SUCCESS The first found Form ID is returned in FormId.\r
335**/\r
336EFI_STATUS\r
337ThunkLocateFormId (\r
338 IN EFI_HII_HANDLE Handle,\r
339 IN EFI_FORM_LABEL Label,\r
340 OUT EFI_GUID *FormsetGuid,\r
341 OUT EFI_FORM_ID *FormId\r
342 )\r
343{\r
344 EFI_STATUS Status;\r
345 EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;\r
346 UINT32 Index;\r
347 UINTN BufferSize;\r
348 EFI_HII_PACKAGE_HEADER PackageHeader;\r
349 EFI_HII_PACKAGE_HEADER *Package;\r
350 UINT32 PackageLength;\r
351\r
352 BufferSize = 0;\r
353 HiiPackageList = NULL;\r
354 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
355 if (Status == EFI_BUFFER_TOO_SMALL) {\r
356 HiiPackageList = AllocatePool (BufferSize);\r
357 ASSERT (HiiPackageList != NULL);\r
358\r
359 Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);\r
360 if (EFI_ERROR (Status)) {\r
361 goto Done;\r
362 }\r
363 }\r
364\r
365 for (Index = 0; ; Index++) {\r
366 Status = GetPackageDataFromPackageList (HiiPackageList, Index, &PackageLength, &Package);\r
367 if (!EFI_ERROR (Status)) {\r
368 CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));\r
369 if (PackageHeader.Type == EFI_HII_PACKAGE_FORM) {\r
370 Status = LocateLabel (Package, Label, FormsetGuid, FormId);\r
371 if (!EFI_ERROR(Status)) {\r
372 break;\r
373 }\r
374 }\r
375 } else {\r
376 break;\r
377 }\r
378 }\r
379\r
380 \r
381Done:\r
382 FreePool (HiiPackageList);\r
383 \r
384 return Status;\r
385}\r
4259256b 386EFI_STATUS\r
387EFIAPI\r
388HiiUpdateForm (\r
389 IN EFI_HII_PROTOCOL *This,\r
390 IN FRAMEWORK_EFI_HII_HANDLE Handle,\r
391 IN EFI_FORM_LABEL Label,\r
392 IN BOOLEAN AddData,\r
99a83b4c 393 IN FRAMEWORK_EFI_HII_UPDATE_DATA *Data\r
4259256b 394 )\r
395/*++\r
396\r
397Routine Description:\r
398 This function allows the caller to update a form that has\r
399 previously been registered with the EFI HII database.\r
400\r
401Arguments:\r
402 Handle - Hii Handle associated with the Formset to modify\r
403 Label - Update information starting immediately after this label in the IFR\r
404 AddData - If TRUE, add data. If FALSE, remove data\r
405 Data - If adding data, this is the pointer to the data to add\r
406\r
407Returns:\r
408 EFI_SUCCESS - Update success.\r
409 Other - Update fail.\r
410\r
411--*/\r
412{\r
ebbd2793 413 EFI_STATUS Status;\r
414 EFI_HII_THUNK_PRIVATE_DATA *Private;\r
415 HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *HandleMapEntry;\r
99a83b4c 416 EFI_HII_UPDATE_DATA *UefiHiiUpdateData;\r
417 EFI_HII_HANDLE UefiHiiHandle;\r
59336178 418 EFI_GUID FormsetGuid;\r
419 EFI_FORM_ID FormId;\r
99a83b4c 420\r
421 Status = EFI_SUCCESS;\r
ebbd2793 422\r
423 Private = EFI_HII_THUNK_PRIVATE_DATA_FROM_THIS(This);\r
424\r
425 HandleMapEntry = FrameworkHiiHandleToMapDatabaseEntry (Private, Handle);\r
426\r
427 if (HandleMapEntry == NULL) {\r
428 return EFI_NOT_FOUND;\r
429 }\r
430 \r
431 if (Data->FormSetUpdate) {\r
432 Status = ThunkUpdateFormCallBack ((EFI_HANDLE) (UINTN) Data->FormCallbackHandle, HandleMapEntry);\r
433 if (EFI_ERROR (Status)) {\r
434 return Status;\r
435 }\r
436 }\r
99a83b4c 437\r
438 if (Data->DataCount != 0) {\r
439 if (HandleMapEntry->IsPackageListWithOnlyStringPackages) {\r
440 UefiHiiHandle = TagGuidToUefiIfrHiiHandle (Private, &HandleMapEntry->TagGuid);\r
441\r
442 if (UefiHiiHandle == NULL) {\r
443 return EFI_INVALID_PARAMETER;\r
444 }\r
445 } else {\r
446 UefiHiiHandle = HandleMapEntry->UefiHiiHandle;\r
447 }\r
448\r
449 UefiHiiUpdateData = NULL;\r
450 \r
5391c4f1 451 Status = ThunkFrameworkUpdateDataToUefiUpdateData (Data, AddData, &UefiHiiUpdateData);\r
452 ASSERT_EFI_ERROR (Status);\r
99a83b4c 453\r
59336178 454 Status = ThunkLocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);\r
455 ASSERT_EFI_ERROR (Status);\r
456\r
457 Status = IfrLibUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, Label, AddData, UefiHiiUpdateData);\r
99a83b4c 458 ASSERT_EFI_ERROR (Status);\r
459 \r
460 if (UefiHiiUpdateData != NULL) {\r
461 SafeFreePool (UefiHiiUpdateData->Data);\r
462 SafeFreePool (UefiHiiUpdateData);\r
463 }\r
464 }\r
465\r
466 return Status;\r
4259256b 467}\r