]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/ConfigAccess.c
clean up for IPF ICC tool chain.
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / ConfigAccess.c
CommitLineData
ebbd2793 1/**@file\r
a9d85320 2 This file implements functions related to Config Access Protocols installed by\r
3 by HII Thunk Modules. These Config access Protocols are used to thunk UEFI Config \r
4 Access Callback to Framework HII Callback and EFI Variable Set/Get operations.\r
ebbd2793 5 \r
6Copyright (c) 2008, Intel Corporation\r
7All rights reserved. This program and the accompanying materials\r
8are licensed and made available under the terms and conditions of the BSD License\r
9which accompanies this distribution. The full text of the license may be found at\r
10http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include "HiiDatabase.h"\r
a9d85320 18#include "UefiIfrParser.h"\r
ebbd2793 19\r
a9d85320 20BOOLEAN mHiiPackageListUpdated = FALSE;\r
0368663f 21\r
22CONFIG_ACCESS_PRIVATE gConfigAccessPrivateTempate = {\r
23 CONFIG_ACCESS_PRIVATE_SIGNATURE,\r
ebbd2793 24 {\r
25 ThunkExtractConfig,\r
26 ThunkRouteConfig,\r
27 ThunkCallback\r
28 }, //ConfigAccessProtocol\r
0368663f 29 NULL, //FormCallbackProtocol\r
0368663f 30 NULL \r
ebbd2793 31};\r
32\r
1a6cdbd9 33/**\r
a9d85320 34 Get the first EFI_IFR_VARSTORE from the FormSet. \r
35 \r
36 @param FormSet The Form Set.\r
37 \r
38 @retval FORMSET_STORAGE * Return the first EFI_IFR_VARSTORE.\r
39 @retval NULL If the Form Set does not have EFI_IFR_VARSTORE.\r
40**/\r
41FORMSET_STORAGE *\r
42GetFirstStorageOfFormSet (\r
43 IN CONST FORM_BROWSER_FORMSET * FormSet\r
44 ) \r
45{\r
46 LIST_ENTRY *StorageList;\r
47 FORMSET_STORAGE *Storage;\r
48\r
49 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
50\r
51 if (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
52 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
53 return Storage;\r
54 }\r
55 \r
56 return NULL;\r
57}\r
58\r
59/**\r
60 Get the EFI_IFR_VARSTORE where the Question's value is stored.\r
1a6cdbd9 61 \r
a9d85320 62 @param FormSet The Form Set.\r
1a6cdbd9 63 \r
a9d85320 64 @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE where the Question's value is stored.\r
65 @retval NULL If the Form Set does not have EFI_IFR_VARSTORE.\r
1a6cdbd9 66**/\r
a9d85320 67FORMSET_STORAGE *\r
68GetStorageFromQuestionId (\r
69 IN CONST FORM_BROWSER_FORMSET * FormSet,\r
70 IN EFI_QUESTION_ID QuestionId\r
ebbd2793 71 )\r
72{\r
a9d85320 73 LIST_ENTRY *FormList;\r
74 LIST_ENTRY *StatementList;\r
75 FORM_BROWSER_FORM *Form;\r
76 FORM_BROWSER_STATEMENT *Statement;\r
77\r
78 FormList = GetFirstNode (&FormSet->FormListHead);\r
79\r
80 while (!IsNull (&FormSet->FormListHead, FormList)) {\r
81 Form = FORM_BROWSER_FORM_FROM_LINK (FormList);\r
82\r
83 StatementList = GetFirstNode (&Form->StatementListHead);\r
84\r
85 while (!IsNull (&Form->StatementListHead, StatementList)) {\r
86 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (StatementList);\r
87 if ((QuestionId == Statement->QuestionId) && (Statement->Storage != NULL)) {\r
88 //\r
89 // UEFI Question ID is unique in a FormSet.\r
90 //\r
91 ASSERT (Statement->Storage->Type == EFI_HII_VARSTORE_BUFFER);\r
92 return Statement->Storage;\r
93 }\r
94 StatementList = GetNextNode (&Form->StatementListHead, StatementList);\r
95 }\r
ebbd2793 96\r
a9d85320 97 FormList = GetNextNode (&FormSet->FormListHead, FormList);\r
98 }\r
99 \r
100 return NULL;\r
101}\r
ebbd2793 102\r
a9d85320 103/**\r
104 Get the EFI_IFR_VARSTORE based the ID.\r
105 \r
106 @param FormSet The Form Set.\r
107 \r
108 @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE with the ID.\r
109 @retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID.\r
110**/\r
111FORMSET_STORAGE *\r
112GetStorageFromVarStoreId (\r
113 IN CONST FORM_BROWSER_FORMSET * FormSet,\r
114 IN EFI_VARSTORE_ID VarStoreId\r
115 )\r
116{\r
117 LIST_ENTRY *StorageList;\r
118 FORMSET_STORAGE *Storage;\r
ebbd2793 119\r
a9d85320 120 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
ebbd2793 121\r
a9d85320 122 while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
123 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
ebbd2793 124\r
a9d85320 125 if (VarStoreId == Storage->VarStoreId) {\r
126 return Storage;\r
ebbd2793 127 }\r
ebbd2793 128\r
a9d85320 129 StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
130 }\r
131 \r
132 return NULL;\r
ebbd2793 133}\r
134\r
1a6cdbd9 135/**\r
a9d85320 136 Get the EFI_IFR_VARSTORE based the <ConfigHdr> string in a <ConfigRequest>\r
137 or a <ConfigResp> string.\r
138 \r
139 @param FormSet The Form Set.\r
140 @param ConfigString The Configuration String which is defined by UEFI HII.\r
1a6cdbd9 141 \r
a9d85320 142 @retval FORMSET_STORAGE * The EFI_IFR_VARSTORE where the Question's value is stored.\r
143 @retval NULL If the Form Set does not have EFI_IFR_VARSTORE with such ID.\r
1a6cdbd9 144**/\r
a9d85320 145FORMSET_STORAGE *\r
146GetStorageFromConfigString (\r
147 IN CONST FORM_BROWSER_FORMSET *FormSet,\r
148 IN CONST EFI_STRING ConfigString\r
ebbd2793 149 )\r
150{\r
a9d85320 151 LIST_ENTRY *StorageList;\r
152 FORMSET_STORAGE *Storage;\r
ebbd2793 153\r
a9d85320 154 StorageList = GetFirstNode (&FormSet->StorageListHead);\r
ebbd2793 155\r
a9d85320 156 while (!IsNull (&FormSet->StorageListHead, StorageList)) {\r
157 Storage = FORMSET_STORAGE_FROM_LINK (StorageList);\r
ebbd2793 158\r
a9d85320 159 if (IsConfigHdrMatch (ConfigString, &Storage->Guid, Storage->Name)) {\r
160 return Storage;\r
ebbd2793 161 }\r
a9d85320 162\r
163 StorageList = GetNextNode (&FormSet->StorageListHead, StorageList);\r
ebbd2793 164 }\r
1a6cdbd9 165\r
a9d85320 166 return NULL;\r
ebbd2793 167}\r
0368663f 168\r
1a6cdbd9 169/**\r
170 This function installs a EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered\r
171 by a module using Framework HII Protocol Interfaces.\r
172\r
a9d85320 173 UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so\r
174 that Setup Utility can load the Buffer Storage using this protocol.\r
1a6cdbd9 175 \r
a9d85320 176 @param Packages The Package List.\r
177 @param ThunkContext The Thunk Context.\r
1a6cdbd9 178 \r
a9d85320 179 @retval EFI_SUCCESS The Config Access Protocol is installed successfully.\r
180 @retval EFI_OUT_RESOURCE There is not enough memory.\r
1a6cdbd9 181 \r
182**/\r
ebbd2793 183EFI_STATUS\r
0368663f 184InstallDefaultConfigAccessProtocol (\r
185 IN CONST EFI_HII_PACKAGES *Packages,\r
186 IN OUT HII_THUNK_CONTEXT *ThunkContext\r
ebbd2793 187 )\r
188{\r
ebbd2793 189 EFI_STATUS Status;\r
0368663f 190 CONFIG_ACCESS_PRIVATE *ConfigAccessInstance;\r
ebbd2793 191\r
a9d85320 192 ASSERT (ThunkContext->IfrPackageCount != 0);\r
193\r
0368663f 194 Status = HiiLibCreateHiiDriverHandle (&ThunkContext->UefiHiiDriverHandle);\r
a9d85320 195 ASSERT_EFI_ERROR (Status);\r
196 \r
ebbd2793 197 ConfigAccessInstance = AllocateCopyPool (\r
0368663f 198 sizeof (CONFIG_ACCESS_PRIVATE), \r
199 &gConfigAccessPrivateTempate\r
ebbd2793 200 );\r
1a6cdbd9 201 ASSERT (ConfigAccessInstance != NULL);\r
0368663f 202 \r
ebbd2793 203 Status = gBS->InstallMultipleProtocolInterfaces (\r
0368663f 204 &ThunkContext->UefiHiiDriverHandle,\r
ebbd2793 205 &gEfiHiiConfigAccessProtocolGuid,\r
206 &ConfigAccessInstance->ConfigAccessProtocol,\r
207 NULL\r
208 );\r
209 ASSERT_EFI_ERROR (Status);\r
0368663f 210 \r
0368663f 211 ConfigAccessInstance->ThunkContext = ThunkContext;\r
ebbd2793 212 \r
213 return EFI_SUCCESS;\r
214}\r
215\r
a9d85320 216/**\r
217 This function un-installs the EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered\r
218 by a module using Framework HII Protocol Interfaces.\r
0368663f 219\r
a9d85320 220 ASSERT if no Config Access is found for such pakcage list or failed to uninstall the protocol.\r
0368663f 221\r
a9d85320 222 @param ThunkContext The Thunk Context.\r
223 \r
224**/\r
0368663f 225VOID\r
226UninstallDefaultConfigAccessProtocol (\r
227 IN HII_THUNK_CONTEXT *ThunkContext\r
ebbd2793 228 )\r
229{\r
0368663f 230 EFI_STATUS Status;\r
231 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
0368663f 232 \r
233 HiiLibDestroyHiiDriverHandle (ThunkContext->UefiHiiDriverHandle);\r
234\r
235 Status = gBS->HandleProtocol (\r
236 ThunkContext->UefiHiiDriverHandle,\r
237 &gEfiHiiConfigAccessProtocolGuid,\r
238 (VOID **) &ConfigAccess\r
239 );\r
0368663f 240 ASSERT_EFI_ERROR (Status);\r
241\r
242 Status = gBS->UninstallProtocolInterface (\r
243 ThunkContext->UefiHiiDriverHandle,\r
244 &gEfiHiiConfigAccessProtocolGuid,\r
245 ConfigAccess\r
246 );\r
247 ASSERT_EFI_ERROR (Status);\r
248\r
ebbd2793 249}\r
0368663f 250 \r
ebbd2793 251\r
1a6cdbd9 252/**\r
253 Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to EFI_FORM_CALLBACK_PROTOCOL.NvRead.\r
254 \r
0368663f 255 @param BufferStorage The key with all attributes needed to call EFI_FORM_CALLBACK_PROTOCOL.NvRead.\r
256 @param FwFormCallBack The EFI_FORM_CALLBACK_PROTOCOL registered by Framework HII module.\r
257 @param Data The data read.\r
258 @param DataSize The size of data.\r
1a6cdbd9 259 \r
0368663f 260 @retval EFI_STATUS The status returned by the EFI_FORM_CALLBACK_PROTOCOL.NvWrite.\r
1a6cdbd9 261 @retval EFI_INVALID_PARAMETER If the EFI_FORM_CALLBACK_PROTOCOL.NvRead return the size information of the data\r
0368663f 262 does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.\r
1a6cdbd9 263 **/\r
ebbd2793 264EFI_STATUS\r
0368663f 265CallFormCallBack (\r
a9d85320 266 IN FORMSET_STORAGE *BufferStorage,\r
0368663f 267 IN EFI_FORM_CALLBACK_PROTOCOL *FwFormCallBack,\r
ebbd2793 268 OUT VOID **Data,\r
269 OUT UINTN *DataSize\r
270 )\r
271{\r
272 EFI_STATUS Status;\r
273\r
274 *DataSize = 0;\r
275 *Data = NULL;\r
276 \r
0368663f 277 Status = FwFormCallBack->NvRead (\r
278 FwFormCallBack, \r
279 BufferStorage->Name,\r
280 &BufferStorage->Guid,\r
ebbd2793 281 NULL,\r
282 DataSize,\r
283 *Data\r
284 );\r
285 if (Status == EFI_BUFFER_TOO_SMALL) {\r
0368663f 286 if (BufferStorage->Size != *DataSize) {\r
ebbd2793 287 ASSERT (FALSE);\r
288 return EFI_INVALID_PARAMETER;\r
289 }\r
290\r
291 *Data = AllocateZeroPool (*DataSize);\r
292 if (Data == NULL) {\r
293 return EFI_OUT_OF_RESOURCES;\r
294 }\r
295\r
0368663f 296 FwFormCallBack->NvRead (\r
297 FwFormCallBack, \r
298 BufferStorage->Name,\r
299 &BufferStorage->Guid,\r
ebbd2793 300 NULL,\r
301 DataSize,\r
302 *Data\r
303 );\r
304 }\r
305\r
306 return Status;\r
307}\r
308\r
1a6cdbd9 309\r
310/**\r
311 Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to UEFI Variable Get Service.\r
312 \r
0368663f 313 @param BufferStorage The key with all attributes needed to call a UEFI Variable Get Service.\r
314 @param Data The data read.\r
315 @param DataSize The size of data.\r
1a6cdbd9 316\r
317 If the UEFI Variable Get Service return the size information of the data\r
0368663f 318 does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.\r
1a6cdbd9 319 then ASSERT.\r
320 \r
0368663f 321 @retval EFI_STATUS The status returned by the UEFI Variable Get Service.\r
1a6cdbd9 322 @retval EFI_INVALID_PARAMETER If the UEFI Variable Get Service return the size information of the data\r
0368663f 323 does not match what has been recorded early in he BUFFER_STORAGE_ENTRY.\r
1a6cdbd9 324 **/\r
325\r
ebbd2793 326EFI_STATUS\r
0368663f 327GetUefiVariable (\r
a9d85320 328 IN FORMSET_STORAGE *BufferStorage,\r
ebbd2793 329 OUT VOID **Data,\r
330 OUT UINTN *DataSize\r
331 )\r
332{\r
333 EFI_STATUS Status;\r
334\r
335 *DataSize = 0;\r
336 *Data = NULL;\r
337 Status = gRT->GetVariable (\r
0368663f 338 BufferStorage->Name,\r
339 &BufferStorage->Guid,\r
ebbd2793 340 NULL,\r
341 DataSize,\r
342 *Data\r
343 );\r
344 if (Status == EFI_BUFFER_TOO_SMALL) {\r
345\r
0368663f 346 if (BufferStorage->Size != *DataSize) {\r
ebbd2793 347 ASSERT (FALSE);\r
348 return EFI_INVALID_PARAMETER;\r
349 }\r
350\r
351 *Data = AllocateZeroPool (*DataSize);\r
352 if (Data == NULL) {\r
353 return EFI_OUT_OF_RESOURCES;\r
354 }\r
355\r
356 Status = gRT->GetVariable (\r
0368663f 357 BufferStorage->Name,\r
358 &BufferStorage->Guid,\r
ebbd2793 359 NULL,\r
360 DataSize,\r
361 *Data\r
362 );\r
363 }\r
364\r
365 return Status;\r
366}\r
367\r
1a6cdbd9 368/**\r
369\r
370 This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig\r
371 so that data can be read from the data storage such as UEFI Variable or module's\r
372 customized storage exposed by EFI_FRAMEWORK_CALLBACK.\r
373\r
0368663f 374 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL\r
1a6cdbd9 375 @param Request A null-terminated Unicode string in <ConfigRequest> format. Note that this\r
0368663f 376 includes the routing information as well as the configurable name / value pairs. It is\r
377 invalid for this string to be in <MultiConfigRequest> format.\r
1a6cdbd9 378\r
0368663f 379 @param Progress On return, points to a character in the Request string. Points to the string's null\r
380 terminator if request was successful. Points to the most recent '&' before the first\r
381 failing name / value pair (or the beginning of the string if the failure is in the first\r
382 name / value pair) if the request was not successful\r
1a6cdbd9 383 @param Results A null-terminated Unicode string in <ConfigAltResp> format which has all\r
0368663f 384 values filled in for the names in the Request string. String to be allocated by the called\r
385 function.\r
1a6cdbd9 386 \r
387 @retval EFI_INVALID_PARAMETER If there is no Buffer Storage for this Config Access instance.\r
0368663f 388 @retval EFI_SUCCESS The setting is retrived successfully.\r
389 @retval !EFI_SUCCESS The error returned by UEFI Get Variable or Framework Form Callback Nvread.\r
1a6cdbd9 390 **/\r
ebbd2793 391EFI_STATUS\r
392EFIAPI\r
393ThunkExtractConfig (\r
394 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
395 IN CONST EFI_STRING Request,\r
396 OUT EFI_STRING *Progress,\r
397 OUT EFI_STRING *Results\r
398 )\r
399{\r
400 EFI_STATUS Status;\r
0368663f 401 CONFIG_ACCESS_PRIVATE *ConfigAccess;\r
a9d85320 402 FORMSET_STORAGE *BufferStorage;\r
ebbd2793 403 VOID *Data;\r
404 UINTN DataSize;\r
405\r
406 Data = NULL;\r
0368663f 407 ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);\r
ebbd2793 408\r
a9d85320 409 BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Request);\r
ebbd2793 410\r
133a9dfb 411 if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
a9d85320 412 //\r
413 // NvMapOverride is not used. Get the Storage data from EFI Variable or Framework Form Callback.\r
414 //\r
133a9dfb 415 if (ConfigAccess->FormCallbackProtocol == NULL ||\r
416 ConfigAccess->FormCallbackProtocol->NvRead == NULL) {\r
417 Status = GetUefiVariable (\r
418 BufferStorage,\r
419 &Data,\r
420 &DataSize\r
421 );\r
422 } else {\r
423 Status = CallFormCallBack (\r
424 BufferStorage,\r
425 ConfigAccess->FormCallbackProtocol,\r
426 &Data,\r
427 &DataSize\r
428 );\r
429 }\r
ebbd2793 430 } else {\r
a9d85320 431 //\r
432 // Use the NvMapOverride.\r
433 //\r
133a9dfb 434 DataSize = BufferStorage->Size;\r
435 Data = AllocateCopyPool (DataSize, ConfigAccess->ThunkContext->NvMapOverride);\r
436 \r
437 if (Data != NULL) {\r
438 Status = EFI_SUCCESS;\r
439 } else {\r
440 Status = EFI_OUT_OF_RESOURCES;\r
441 }\r
ebbd2793 442 }\r
443 \r
444 if (!EFI_ERROR (Status)) {\r
59336178 445 Status = mHiiConfigRoutingProtocol->BlockToConfig (\r
446 mHiiConfigRoutingProtocol,\r
ebbd2793 447 Request,\r
448 Data,\r
449 DataSize,\r
450 Results,\r
451 Progress\r
452 );\r
453 }\r
454\r
7001eaf8 455 if (Data != NULL) {\r
456 FreePool (Data);\r
457 }\r
ebbd2793 458 return Status;\r
459}\r
460\r
1a6cdbd9 461/**\r
1a6cdbd9 462 This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig\r
463 so that data can be written to the data storage such as UEFI Variable or module's\r
464 customized storage exposed by EFI_FRAMEWORK_CALLBACK.\r
465 \r
0368663f 466 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL\r
467 @param Configuration A null-terminated Unicode string in <ConfigResp> format.\r
fd0d281b 468 @param Progress A pointer to a string filled in with the offset of the most recent '&' before the first\r
0368663f 469 failing name / value pair (or the beginning of the string if the failure is in the first\r
470 name / value pair) or the terminating NULL if all was successful.\r
1a6cdbd9 471 \r
472 @retval EFI_INVALID_PARAMETER If there is no Buffer Storage for this Config Access instance.\r
0368663f 473 @retval EFI_SUCCESS The setting is saved successfully.\r
474 @retval !EFI_SUCCESS The error returned by UEFI Set Variable or Framework Form Callback Nvwrite.\r
1a6cdbd9 475**/ \r
ebbd2793 476EFI_STATUS\r
477EFIAPI\r
478ThunkRouteConfig (\r
479 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
480 IN CONST EFI_STRING Configuration,\r
481 OUT EFI_STRING *Progress\r
482 )\r
483{\r
484 EFI_STATUS Status;\r
0368663f 485 CONFIG_ACCESS_PRIVATE *ConfigAccess;\r
a9d85320 486 FORMSET_STORAGE *BufferStorage;\r
98b16b9d 487 VOID *Data;\r
ebbd2793 488 UINTN DataSize;\r
0368663f 489 UINTN DataSize2;\r
ebbd2793 490 UINTN LastModifiedByteIndex;\r
0368663f 491 BOOLEAN ResetRequired;\r
492 BOOLEAN DataAllocated;\r
ebbd2793 493\r
494 Data = NULL;\r
0368663f 495 ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);\r
ebbd2793 496\r
a9d85320 497 BufferStorage = GetStorageFromConfigString (ConfigAccess->ThunkContext->FormSet, Configuration);\r
ebbd2793 498\r
0368663f 499 DataSize2 = BufferStorage->Size;\r
500 if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
133a9dfb 501 DataAllocated = TRUE;\r
0368663f 502 if (ConfigAccess->FormCallbackProtocol == NULL ||\r
503 ConfigAccess->FormCallbackProtocol->NvRead == NULL) {\r
504 Status = GetUefiVariable (\r
505 BufferStorage,\r
506 &Data,\r
507 &DataSize\r
508 );\r
0368663f 509 } else {\r
510 Status = CallFormCallBack (\r
511 BufferStorage,\r
512 ConfigAccess->FormCallbackProtocol,\r
513 &Data,\r
514 &DataSize\r
515 );\r
0368663f 516 }\r
517 } else {\r
133a9dfb 518 //\r
519 // ConfigToBlock will convert the Config String and update the NvMapOverride accordingly.\r
520 //\r
0368663f 521 Status = EFI_SUCCESS;\r
522 Data = ConfigAccess->ThunkContext->NvMapOverride;\r
523 DataSize = DataSize2;\r
524 DataAllocated = FALSE;\r
525 } \r
133a9dfb 526 if (EFI_ERROR (Status) || (DataSize2 != DataSize)) {\r
527 if (Data == NULL) {\r
528 Data = AllocateZeroPool (DataSize2);\r
529 }\r
ebbd2793 530 }\r
0368663f 531\r
59336178 532 Status = mHiiConfigRoutingProtocol->ConfigToBlock (\r
533 mHiiConfigRoutingProtocol,\r
ebbd2793 534 Configuration,\r
535 Data,\r
536 &LastModifiedByteIndex,\r
537 Progress\r
538 );\r
ebbd2793 539 if (EFI_ERROR (Status)) {\r
540 goto Done;\r
541 }\r
542\r
133a9dfb 543 if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
544 if (ConfigAccess->FormCallbackProtocol == NULL ||\r
545 ConfigAccess->FormCallbackProtocol->NvWrite == NULL) {\r
546 Status = gRT->SetVariable (\r
547 BufferStorage->Name,\r
548 &BufferStorage->Guid,\r
549 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
550 DataSize2,\r
551 Data\r
552 );\r
553 } else {\r
554 Status = ConfigAccess->FormCallbackProtocol->NvWrite (\r
555 ConfigAccess->FormCallbackProtocol, \r
556 BufferStorage->Name,\r
557 &BufferStorage->Guid,\r
558 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
559 DataSize2,\r
560 Data,\r
561 &ResetRequired\r
562 );\r
563 \r
564 }\r
ebbd2793 565 }\r
566\r
0368663f 567Done: \r
568 if (DataAllocated && (Data != NULL)) {\r
569 FreePool (Data);\r
570 }\r
571 \r
ebbd2793 572 return Status;\r
573}\r
574\r
a9d85320 575/**\r
576 Build the FRAMEWORK_EFI_IFR_DATA_ARRAY which will be used to pass to \r
577 EFI_FORM_CALLBACK_PROTOCOL.Callback. Check definition of FRAMEWORK_EFI_IFR_DATA_ARRAY\r
578 for details.\r
579\r
580 ASSERT if the Question Type is not EFI_IFR_TYPE_NUM_SIZE_* or EFI_IFR_TYPE_STRING.\r
581 \r
582 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL\r
583 @param QuestionId The Question ID.\r
584 @param Type The Question Type.\r
585 @param Value The Question Value.\r
586 @param NvMapAllocated On output indicates if a buffer is allocated for NvMap.\r
587 \r
588 @return A pointer to FRAMEWORK_EFI_IFR_DATA_ARRAY. The caller must free this buffer allocated.\r
589**/ \r
0368663f 590FRAMEWORK_EFI_IFR_DATA_ARRAY *\r
591CreateIfrDataArray (\r
592 IN CONFIG_ACCESS_PRIVATE *ConfigAccess,\r
593 IN EFI_QUESTION_ID QuestionId,\r
594 IN UINT8 Type,\r
595 IN EFI_IFR_TYPE_VALUE *Value,\r
596 OUT BOOLEAN *NvMapAllocated\r
597 )\r
598{\r
599 FRAMEWORK_EFI_IFR_DATA_ARRAY *IfrDataArray;\r
600 FRAMEWORK_EFI_IFR_DATA_ENTRY *IfrDataEntry;\r
601 UINTN BrowserDataSize;\r
a9d85320 602 FORMSET_STORAGE *BufferStorage;\r
133a9dfb 603 EFI_STATUS Status;\r
286f0de7 604 UINTN Size;\r
605 UINTN StringSize;\r
606 EFI_STRING String;\r
607\r
a9d85320 608 *NvMapAllocated = FALSE;\r
0368663f 609\r
a9d85320 610 String = NULL;\r
286f0de7 611\r
612 switch (Type) {\r
613 case EFI_IFR_TYPE_NUM_SIZE_8:\r
614 case EFI_IFR_TYPE_NUM_SIZE_16:\r
615 case EFI_IFR_TYPE_NUM_SIZE_32:\r
616 case EFI_IFR_TYPE_NUM_SIZE_64:\r
617 case EFI_IFR_TYPE_BOOLEAN:\r
618 Size = sizeof (*Value);\r
619 break;\r
620\r
621 case EFI_IFR_TYPE_STRING:\r
622 StringSize = 0;\r
623 Status = HiiLibGetString (ConfigAccess->ThunkContext->UefiHiiHandle, Value->string, String, &StringSize);\r
624 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
625\r
626 String = AllocateZeroPool (StringSize);\r
627 ASSERT (String != NULL);\r
628\r
629 Status = HiiLibGetString (ConfigAccess->ThunkContext->UefiHiiHandle, Value->string, String, &StringSize);\r
630 ASSERT_EFI_ERROR (Status);\r
631\r
632 Size = StringSize;\r
633 break;\r
634 \r
635 default:\r
636 ASSERT (FALSE);\r
637 Size = 0;\r
638 break;\r
639 }\r
640\r
641 IfrDataArray = AllocateZeroPool (sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY) + sizeof (FRAMEWORK_EFI_IFR_DATA_ENTRY) + Size);\r
0368663f 642 ASSERT (IfrDataArray != NULL);\r
643\r
a9d85320 644 BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);\r
0368663f 645\r
a9d85320 646 if (BufferStorage == NULL) {\r
647 //\r
648 // The QuestionId is not associated with a Buffer Storage.\r
649 // Try to get the first Buffer Storage then.\r
650 //\r
651 BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);\r
0368663f 652 }\r
133a9dfb 653 \r
a9d85320 654 if (BufferStorage != NULL) {\r
655 BrowserDataSize = BufferStorage->Size;\r
0368663f 656\r
a9d85320 657 if (ConfigAccess->ThunkContext->NvMapOverride == NULL) {\r
658 *NvMapAllocated = TRUE;\r
659 IfrDataArray->NvRamMap = AllocateZeroPool (BrowserDataSize);\r
660 } else {\r
661 *NvMapAllocated = FALSE;\r
662 IfrDataArray->NvRamMap = ConfigAccess->ThunkContext->NvMapOverride;\r
663 }\r
664 \r
665 Status = GetBrowserData (&BufferStorage->Guid, BufferStorage->Name, &BrowserDataSize, IfrDataArray->NvRamMap);\r
666 ASSERT_EFI_ERROR (Status);\r
0368663f 667\r
a9d85320 668 IfrDataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) (IfrDataArray + 1);\r
0368663f 669\r
a9d85320 670 switch (Type) {\r
671 case EFI_IFR_TYPE_NUM_SIZE_8:\r
672 case EFI_IFR_TYPE_NUM_SIZE_16:\r
673 case EFI_IFR_TYPE_NUM_SIZE_32:\r
674 case EFI_IFR_TYPE_NUM_SIZE_64:\r
675 case EFI_IFR_TYPE_BOOLEAN:\r
676 CopyMem (&IfrDataEntry->Data, &(Value->u8), sizeof (*Value));\r
677 break;\r
678\r
679 case EFI_IFR_TYPE_STRING:\r
680 ASSERT (String != NULL);\r
681 StrCpy ((CHAR16 *) &IfrDataEntry->Data, String);\r
682 FreePool (String);\r
683 break;\r
684 default:\r
685 ASSERT (FALSE);\r
686 break;\r
687 }\r
688\r
689 //\r
690 // Need to fiil in the information for the rest of field for FRAMEWORK_EFI_IFR_DATA_ENTRY.\r
691 // It seems that no implementation is found to use other fields. Leave them uninitialized for now.\r
692 //\r
693 //UINT8 OpCode; // Likely a string, numeric, or one-of\r
694 //UINT8 Length; // Length of the FRAMEWORK_EFI_IFR_DATA_ENTRY packet\r
695 //UINT16 Flags; // Flags settings to determine what behavior is desired from the browser after the callback\r
696 //VOID *Data; // The data in the form based on the op-code type - this is not a pointer to the data, the data follows immediately\r
697 // If the OpCode is a OneOf or Numeric type - Data is a UINT16 value\r
698 // If the OpCode is a String type - Data is a CHAR16[x] type\r
699 // If the OpCode is a Checkbox type - Data is a UINT8 value\r
700 // If the OpCode is a NV Access type - Data is a FRAMEWORK_EFI_IFR_NV_DATA structure\r
0368663f 701 }\r
702\r
703 return IfrDataArray;\r
704}\r
705\r
a9d85320 706/**\r
707 If a NvMapOverride is passed in to EFI_FORM_BROWSER_PROTOCOL.SendForm, the Form Browser\r
708 needs to be informed when data changed in NvMapOverride. This function will invoke\r
709 SetBrowserData () to set internal data of Form Browser.\r
710\r
711 @param ConfigAccess The Config Access Private Context.\r
712 @param QuestionId The Question Id that invokes the callback.\r
713 \r
714\r
715**/\r
133a9dfb 716VOID\r
717SyncBrowserDataForNvMapOverride (\r
a9d85320 718 IN CONST CONFIG_ACCESS_PRIVATE *ConfigAccess,\r
719 IN EFI_QUESTION_ID QuestionId\r
133a9dfb 720 )\r
721{\r
a9d85320 722 FORMSET_STORAGE *BufferStorage;\r
133a9dfb 723 EFI_STATUS Status;\r
724 UINTN BrowserDataSize;\r
725\r
726 if (ConfigAccess->ThunkContext->NvMapOverride != NULL) {\r
a9d85320 727\r
728 BufferStorage = GetStorageFromQuestionId (ConfigAccess->ThunkContext->FormSet, QuestionId);\r
729\r
730 if (BufferStorage == NULL) {\r
731 //\r
732 // QuestionId is a statement without Storage.\r
733 // 1) It is a Goto. \r
734 // \r
735 //\r
736 BufferStorage = GetFirstStorageOfFormSet (ConfigAccess->ThunkContext->FormSet);\r
737 }\r
738\r
739 //\r
740 // If NvMapOverride is not NULL, this Form must have at least one Buffer Type Variable Storage.\r
741 //\r
742 ASSERT (BufferStorage != NULL);\r
133a9dfb 743 \r
a9d85320 744 BrowserDataSize = BufferStorage->Size;\r
133a9dfb 745\r
a9d85320 746 Status = SetBrowserData (&BufferStorage->Guid, BufferStorage->Name, BrowserDataSize, ConfigAccess->ThunkContext->NvMapOverride, NULL);\r
133a9dfb 747 ASSERT_EFI_ERROR (Status);\r
748 }\r
749\r
750}\r
751\r
a9d85320 752/**\r
753 Free up resource allocated for a FRAMEWORK_EFI_IFR_DATA_ARRAY by CreateIfrDataArray ().\r
754\r
755 @param Array The FRAMEWORK_EFI_IFR_DATA_ARRAY allocated.\r
756 @param NvMapAllocated If the NvRamMap is allocated for FRAMEWORK_EFI_IFR_DATA_ARRAY.\r
757\r
758**/\r
0368663f 759VOID\r
760DestroyIfrDataArray (\r
761 IN FRAMEWORK_EFI_IFR_DATA_ARRAY *Array,\r
762 IN BOOLEAN NvMapAllocated\r
763 )\r
764{\r
d4775f2a 765 if (Array != NULL) {\r
766 if (NvMapAllocated) {\r
767 FreePool (Array->NvRamMap);\r
768 }\r
0368663f 769\r
d4775f2a 770 FreePool (Array);\r
771 }\r
0368663f 772}\r
773\r
a9d85320 774/**\r
775 Get the ONE_OF_OPTION_MAP_ENTRY for a QuestionId that invokes the \r
776 EFI_FORM_CALLBACK_PROTOCOL.Callback. The information is needed as\r
777 the callback mechanism for EFI_IFR_ONE_OF_OPTION is changed from \r
778 EFI_IFR_ONE_OF_OPTION in Framework IFR. Check EFI_IFR_GUID_OPTIONKEY\r
779 for detailed information.\r
780\r
781 @param ThunkContext The Thunk Context.\r
782 @param QuestionId The Question Id.\r
783 @param Type The Question Type.\r
784 @param Value The One Of Option's value.\r
785\r
786 @return The ONE_OF_OPTION_MAP_ENTRY found.\r
787 @retval NULL If no entry is found.\r
788**/\r
0368663f 789ONE_OF_OPTION_MAP_ENTRY *\r
790GetOneOfOptionMapEntry (\r
791 IN HII_THUNK_CONTEXT *ThunkContext,\r
792 IN EFI_QUESTION_ID QuestionId,\r
793 IN UINT8 Type,\r
794 IN EFI_IFR_TYPE_VALUE *Value\r
795 )\r
796{\r
797 LIST_ENTRY *Link;\r
798 LIST_ENTRY *Link2;\r
799 ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
800 ONE_OF_OPTION_MAP *OneOfOptionMap;\r
a9d85320 801 FORM_BROWSER_FORMSET *FormSet;\r
0368663f 802\r
a9d85320 803 FormSet = ThunkContext->FormSet;\r
0368663f 804\r
a9d85320 805 Link = GetFirstNode (&FormSet->OneOfOptionMapListHead);\r
806\r
807 while (!IsNull (&FormSet->OneOfOptionMapListHead, Link)) {\r
0368663f 808 OneOfOptionMap = ONE_OF_OPTION_MAP_FROM_LINK(Link);\r
809 if (OneOfOptionMap->QuestionId == QuestionId) {\r
810 ASSERT (OneOfOptionMap->ValueType == Type);\r
811\r
812 Link2 = GetFirstNode (&OneOfOptionMap->OneOfOptionMapEntryListHead);\r
813\r
814 while (!IsNull (&OneOfOptionMap->OneOfOptionMapEntryListHead, Link2)) {\r
815 OneOfOptionMapEntry = ONE_OF_OPTION_MAP_ENTRY_FROM_LINK (Link2);\r
816\r
817 if (CompareMem (Value, &OneOfOptionMapEntry->Value, sizeof (EFI_IFR_TYPE_VALUE)) == 0) {\r
818 return OneOfOptionMapEntry;\r
819 }\r
820\r
821 Link2 = GetNextNode (&OneOfOptionMap->OneOfOptionMapEntryListHead, Link2);\r
822 }\r
823 }\r
824\r
a9d85320 825 Link = GetNextNode (&FormSet->OneOfOptionMapListHead, Link);\r
0368663f 826 }\r
827\r
828\r
829 return NULL;\r
830}\r
831\r
832/**\r
833 Functions which are registered to receive notification of\r
834 database events have this prototype. The actual event is encoded\r
835 in NotifyType. The following table describes how PackageType,\r
836 PackageGuid, Handle, and Package are used for each of the\r
837 notification types.\r
838\r
a9d85320 839 If any Pakcage List in database is updated, mHiiPackageListUpdated\r
840 will be set. If mHiiPackageListUpdated is set, Framework ThunkCallback()\r
841 will force the UEFI Setup Browser to save the uncommitted data. This\r
842 is needed as Framework's Callback function may dynamically update\r
843 opcode in a Package List. UEFI Setup Browser will quit itself and reparse\r
844 the Package List's IFR and display it. UEFI Config Access's implementation\r
845 is required to save the modified (SetBrowserData or directly save the data\r
846 to NV storage). But Framework HII Modules is not aware of this rule. Therefore,\r
847 we will enforce the rule in ThunkCallback (). The side effect of force saving\r
848 of NV data is the NV flag in browser may not flag a update as data has already\r
849 been saved to NV storage.\r
850\r
0368663f 851 @param PackageType Package type of the notification.\r
852\r
853 @param PackageGuid If PackageType is\r
854 EFI_HII_PACKAGE_TYPE_GUID, then this is\r
855 the pointer to the GUID from the Guid\r
856 field of EFI_HII_PACKAGE_GUID_HEADER.\r
857 Otherwise, it must be NULL.\r
858\r
859 @param Package Points to the package referred to by the\r
860 notification Handle The handle of the package\r
861 list which contains the specified package.\r
862\r
863 @param Handle The HII handle.\r
864\r
865 @param NotifyType The type of change concerning the\r
866 database. See\r
867 EFI_HII_DATABASE_NOTIFY_TYPE.\r
868\r
869**/\r
870EFI_STATUS\r
871EFIAPI\r
872FormUpdateNotify (\r
873 IN UINT8 PackageType,\r
874 IN CONST EFI_GUID *PackageGuid,\r
875 IN CONST EFI_HII_PACKAGE_HEADER *Package,\r
876 IN EFI_HII_HANDLE Handle,\r
877 IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType\r
878 )\r
879{\r
880 mHiiPackageListUpdated = TRUE;\r
881\r
882 return EFI_SUCCESS;\r
883}\r
884\r
1a6cdbd9 885/**\r
886 Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.CallBack to EFI_FORM_CALLBACK_PROTOCOL.Callback. Therefor,\r
a9d85320 887 the framework HII module willl do no porting and work with a UEFI HII SetupBrowser.\r
1a6cdbd9 888 \r
0368663f 889 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
890 @param Action Specifies the type of action taken by the browser. See EFI_BROWSER_ACTION_x.\r
1a6cdbd9 891 @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the\r
0368663f 892 type of data to expect. The format of the data tends to vary based on the opcode that\r
893 generated the callback.\r
894 @param Type The type of value for the question. See EFI_IFR_TYPE_x in\r
895 EFI_IFR_ONE_OF_OPTION.\r
896 @param Value A pointer to the data being sent to the original exporting driver. The type is specified\r
897 by Type. Type EFI_IFR_TYPE_VALUE is defined in\r
898 EFI_IFR_ONE_OF_OPTION.\r
1a6cdbd9 899 @param ActionRequest On return, points to the action requested by the callback function. Type\r
0368663f 900 EFI_BROWSER_ACTION_REQUEST is specified in SendForm() in the Form\r
901 Browser Protocol.\r
1a6cdbd9 902 \r
0368663f 903 @retval EFI_UNSUPPORTED If the Framework HII module does not register Callback although it specify the opcode under\r
904 focuse to be INTERRACTIVE.\r
1a6cdbd9 905 @retval EFI_SUCCESS The callback complete successfully.\r
906 @retval !EFI_SUCCESS The error code returned by EFI_FORM_CALLBACK_PROTOCOL.Callback.\r
907 \r
908 **/\r
ebbd2793 909EFI_STATUS\r
910EFIAPI\r
911ThunkCallback (\r
912 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
913 IN EFI_BROWSER_ACTION Action,\r
914 IN EFI_QUESTION_ID QuestionId,\r
915 IN UINT8 Type,\r
916 IN EFI_IFR_TYPE_VALUE *Value,\r
917 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
918 )\r
919{\r
920 EFI_STATUS Status;\r
0368663f 921 CONFIG_ACCESS_PRIVATE *ConfigAccess;\r
922 EFI_FORM_CALLBACK_PROTOCOL *FormCallbackProtocol;\r
ebbd2793 923 EFI_HII_CALLBACK_PACKET *Packet;\r
0368663f 924 FRAMEWORK_EFI_IFR_DATA_ARRAY *Data;\r
ebbd2793 925 FRAMEWORK_EFI_IFR_DATA_ENTRY *DataEntry;\r
0368663f 926 UINT16 KeyValue;\r
927 ONE_OF_OPTION_MAP_ENTRY *OneOfOptionMapEntry;\r
928 EFI_HANDLE NotifyHandle;\r
929 EFI_INPUT_KEY Key; \r
930 BOOLEAN NvMapAllocated;\r
ebbd2793 931\r
932 ASSERT (This != NULL);\r
933 ASSERT (Value != NULL);\r
934 ASSERT (ActionRequest != NULL);\r
935\r
936 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
937\r
0368663f 938 ConfigAccess = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (This);\r
ebbd2793 939\r
0368663f 940 FormCallbackProtocol = ConfigAccess->FormCallbackProtocol;\r
941 if (FormCallbackProtocol == NULL) {\r
942 ASSERT (FALSE);\r
ebbd2793 943 return EFI_UNSUPPORTED;\r
944 }\r
ebbd2793 945\r
0368663f 946 //\r
947 // Check if the QuestionId match a OneOfOption.\r
948 //\r
949 OneOfOptionMapEntry = GetOneOfOptionMapEntry (ConfigAccess->ThunkContext, QuestionId, Type, Value);\r
950\r
951 if (OneOfOptionMapEntry == NULL) {\r
952 //\r
953 // This is not a One-Of-Option opcode. QuestionId is the KeyValue\r
954 //\r
955 KeyValue = QuestionId;\r
956 } else {\r
a9d85320 957 //\r
958 // Otherwise, use the original Key specified in One Of Option in the Framework VFR syntax.\r
959 //\r
0368663f 960 KeyValue = OneOfOptionMapEntry->FwKey;\r
961 }\r
962\r
963 //\r
964 // Build the FRAMEWORK_EFI_IFR_DATA_ARRAY\r
965 //\r
966 Data = CreateIfrDataArray (ConfigAccess, QuestionId, Type, Value, &NvMapAllocated);\r
967\r
968 Status = mHiiDatabase->RegisterPackageNotify (\r
969 mHiiDatabase,\r
4dd76ade 970 EFI_HII_PACKAGE_FORMS,\r
0368663f 971 NULL,\r
972 FormUpdateNotify,\r
973 EFI_HII_DATABASE_NOTIFY_REMOVE_PACK,\r
974 &NotifyHandle\r
975 );\r
976 //\r
a9d85320 977 //Call the Framework Callback function.\r
0368663f 978 //\r
979 Packet = NULL;\r
980 Status = FormCallbackProtocol->Callback (\r
981 FormCallbackProtocol,\r
982 KeyValue,\r
983 Data,\r
ebbd2793 984 &Packet\r
985 );\r
a9d85320 986 SyncBrowserDataForNvMapOverride (ConfigAccess, QuestionId);\r
ebbd2793 987\r
988 //\r
989 // Callback require browser to perform action\r
990 //\r
0368663f 991 if (EFI_ERROR (Status)) {\r
992 if (Packet != NULL) {\r
0368663f 993 do {\r
994 IfrLibCreatePopUp (1, &Key, Packet->String);\r
0368663f 995 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
ebbd2793 996 }\r
0368663f 997 //\r
998 // Error Code in Status is discarded.\r
999 //\r
1000 } else {\r
1001 if (Packet != NULL) {\r
1002 if (Packet->DataArray.EntryCount == 1 && Packet->DataArray.NvRamMap == NULL) {\r
1003 DataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY));\r
1004 if ((DataEntry->Flags & EXIT_REQUIRED) == EXIT_REQUIRED) {\r
1005 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
1006 }\r
1007\r
1008 if ((DataEntry->Flags & SAVE_REQUIRED) == SAVE_REQUIRED) {\r
1009 Status = ConfigAccess->ConfigAccessProtocol.RouteConfig (\r
1010 &ConfigAccess->ConfigAccessProtocol,\r
1011 NULL,\r
1012 NULL\r
1013 );\r
1014 }\r
1015 }\r
1016 FreePool (Packet);\r
1017 }\r
1018 }\r
1019\r
1020 //\r
1021 // Unregister notify for Form package update\r
1022 //\r
1023 Status = mHiiDatabase->UnregisterPackageNotify (\r
1024 mHiiDatabase,\r
1025 NotifyHandle\r
1026 );\r
1027 //\r
a3318eaf 1028 // UEFI SetupBrowser behaves differently with Framework SetupBrowser when call back function \r
0368663f 1029 // update any forms in HII database. UEFI SetupBrowser will re-parse the displaying form package and load\r
1030 // the values from variable storages. Framework SetupBrowser will only re-parse the displaying form packages.\r
1031 // To make sure customer's previous changes is saved and the changing question behaves as expected, we\r
1032 // issue a EFI_BROWSER_ACTION_REQUEST_SUBMIT to ask UEFI SetupBrowser to save the changes proceed to re-parse\r
1033 // the form and load all the variable storages.\r
1034 //\r
1035 if (*ActionRequest == EFI_BROWSER_ACTION_REQUEST_NONE && mHiiPackageListUpdated) {\r
a9d85320 1036 mHiiPackageListUpdated= FALSE;\r
0368663f 1037 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
fed39e58 1038 } else {\r
a9d85320 1039 if (ConfigAccess->ThunkContext->FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS ||\r
1040 ConfigAccess->ThunkContext->FormSet->SubClass == EFI_SINGLE_USE_SUBCLASS) {\r
fed39e58 1041 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
1042 }\r
ebbd2793 1043 }\r
0368663f 1044\r
d4775f2a 1045\r
a9d85320 1046 //\r
1047 // Clean up.\r
1048 //\r
0368663f 1049 DestroyIfrDataArray (Data, NvMapAllocated);\r
ebbd2793 1050 \r
1051 return Status;\r
1052}\r
1053\r