]> git.proxmox.com Git - mirror_edk2.git/blob - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/ConfigAccess.c
a0cb4112b30723fab041eac3a34d8b5d15711604
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / ConfigAccess.c
1 /**@file
2 This file contains functions related to Config Access Protocols installed by
3 by HII Thunk Modules which is used to thunk UEFI Config Access Callback to
4 Framework HII Callback.
5
6 Copyright (c) 2008, Intel Corporation
7 All rights reserved. This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15 **/
16
17 #include "HiiDatabase.h"
18
19 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE ConfigAccessProtocolInstanceTempate = {
20 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_SIGNATURE,
21 {
22 ThunkExtractConfig,
23 ThunkRouteConfig,
24 ThunkCallback
25 }, //ConfigAccessProtocol
26 NULL, //FrameworkFormCallbackProtocol
27 {NULL, NULL} //ConfigAccessStorageListHead
28 };
29
30 /**
31 Find and return the pointer to Package Header of the Form package
32 in the Framework Package List. The Framework Package List is created
33 by a module calling the Framework HII interface.
34 The Framwork Package List contains package data
35 generated by Intel's UEFI VFR Compiler and String gather tool. The data format
36 of the package data is defined by TIANO_AUTOGEN_PACKAGES_HEADER.
37
38 If the package list contains other type of packages such as KEYBOARD_LAYOUT,
39 FONTS and IMAGES, the ASSERT. This is to make sure the caller is a
40 Framework Module which does not include packages introduced by UEFI Specification
41 or packages that is not supported by Thunk layer.
42
43 @param Packages The Framework Package List
44
45 @retval EFI_HII_PACKAGE_HEADER* Return the Package Header of
46 Form Package.
47 @retval NULL If no Form Package is found.
48 **/
49 EFI_HII_PACKAGE_HEADER *
50 GetIfrFormSet (
51 IN CONST EFI_HII_PACKAGES *Packages
52 )
53 {
54 TIANO_AUTOGEN_PACKAGES_HEADER **TianoAutogenPackageHdrArray;
55 EFI_HII_PACKAGE_HEADER *IfrPackage;
56 UINTN Index;
57
58 ASSERT (Packages != NULL);
59
60 IfrPackage = NULL;
61
62 TianoAutogenPackageHdrArray = (TIANO_AUTOGEN_PACKAGES_HEADER **) (((UINT8 *) &Packages->GuidId) + sizeof (Packages->GuidId));
63 for (Index = 0; Index < Packages->NumberOfPackages; Index++) {
64 //
65 // BugBug: The current UEFI HII build tool generate a binary in the format defined in:
66 // TIANO_AUTOGEN_PACKAGES_HEADER. We assume that all packages generated in
67 // this binary is with same package type. So the returned IfrPackNum and StringPackNum
68 // may not be the exact number of valid package number in the binary generated
69 // by HII Build tool.
70 //
71 switch (TianoAutogenPackageHdrArray[Index]->PackageHeader.Type) {
72 case EFI_HII_PACKAGE_FORM:
73 return &TianoAutogenPackageHdrArray[Index]->PackageHeader;
74 break;
75
76 case EFI_HII_PACKAGE_STRINGS:
77 case EFI_HII_PACKAGE_SIMPLE_FONTS:
78 break;
79
80 //
81 // The following fonts are invalid for a module that using Framework to UEFI thunk layer.
82 //
83 case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
84 case EFI_HII_PACKAGE_FONTS:
85 case EFI_HII_PACKAGE_IMAGES:
86 default:
87 ASSERT (FALSE);
88 break;
89 }
90 }
91
92 return (EFI_HII_PACKAGE_HEADER *) NULL;
93 }
94
95 /**
96 This function scan EFI_IFR_VARSTORE_OP in the Form Package.
97 It create entries for these VARSTORE found and append the entry
98 to a Link List.
99
100 If FormSetPackage is not EFI_HII_PACKAGE_FORM, then ASSERT.
101 If there is no linear buffer storage in this formset, then ASSERT.
102
103 @param FormSetPackage The Form Package header.
104 @param BufferStorageListHead The link list for the VARSTORE found in the form package.
105
106 @retval EFI_SUCCESS The function scan the form set and find one or more
107 VARSTOREs.
108 @retval EFI_OUT_OF_RESOURCES There is not enough memory to complete the function.
109 **/
110 EFI_STATUS
111 GetBufferStorage (
112 IN CONST EFI_HII_PACKAGE_HEADER *FormSetPackage,
113 OUT LIST_ENTRY *BufferStorageListHead
114 )
115 {
116 UINTN OpCodeOffset;
117 UINTN OpCodeLength;
118 UINT8 *OpCodeData;
119 UINT8 Operand;
120 EFI_IFR_VARSTORE *VarStoreOpCode;
121 HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;
122
123 ASSERT (FormSetPackage->Type == EFI_HII_PACKAGE_FORM);
124
125 OpCodeOffset = sizeof (EFI_HII_PACKAGE_HEADER);
126 while (OpCodeOffset < FormSetPackage->Length) {
127 OpCodeData = (UINT8 *) FormSetPackage + OpCodeOffset;
128
129 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;
130 OpCodeOffset += OpCodeLength;
131 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;
132
133 if (Operand == EFI_IFR_VARSTORE_OP) {
134 VarStoreOpCode = (EFI_IFR_VARSTORE *)OpCodeData;
135 BufferStorageKey = AllocateZeroPool (sizeof (*BufferStorageKey));
136 if (BufferStorageKey == NULL) {
137 return EFI_OUT_OF_RESOURCES;
138 }
139 CopyMem (&BufferStorageKey->Guid, &VarStoreOpCode->Guid, sizeof (EFI_GUID));
140
141 BufferStorageKey->Name = AllocateZeroPool (AsciiStrSize (VarStoreOpCode->Name) * 2);
142 AsciiStrToUnicodeStr (VarStoreOpCode->Name, BufferStorageKey->Name);
143
144 BufferStorageKey->VarStoreId = VarStoreOpCode->VarStoreId;
145
146 BufferStorageKey->Size = VarStoreOpCode->Size;
147 BufferStorageKey->Signature = HII_TRHUNK_BUFFER_STORAGE_KEY_SIGNATURE;
148
149 InsertTailList (BufferStorageListHead, &BufferStorageKey->List);
150 }
151 }
152
153 return EFI_SUCCESS;
154 }
155
156 /**
157 This function installs a EFI_CONFIG_ACCESS_PROTOCOL instance for a form package registered
158 by a module using Framework HII Protocol Interfaces.
159
160 UEFI HII require EFI_HII_CONFIG_ACCESS_PROTOCOL to be installed on a EFI_HANDLE, so
161 that Setup Utility can load the Buffer Storage using this protocol.
162
163 @param Packages The framework package list.
164 @param MapEntry The Thunk Layer Handle Mapping Database Entry.
165
166 @retval EFI_SUCCESS The Config Access Protocol is installed successfully.
167 @retval EFI_OUT_RESOURCE There is not enough memory.
168
169 **/
170 EFI_STATUS
171 InstallDefaultUefiConfigAccessProtocol (
172 IN CONST EFI_HII_PACKAGES *Packages,
173 IN OUT HII_TRHUNK_HANDLE_MAPPING_DATABASE_ENTRY *MapEntry
174 )
175 {
176 EFI_HII_PACKAGE_HEADER *FormSetPackage;
177 EFI_STATUS Status;
178 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigAccessInstance;
179
180 Status = HiiLibCreateHiiDriverHandle (&MapEntry->UefiHiiDriverHandle);
181 ConfigAccessInstance = AllocateCopyPool (
182 sizeof (HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE),
183 &ConfigAccessProtocolInstanceTempate
184 );
185 ASSERT (ConfigAccessInstance != NULL);
186 InitializeListHead (&ConfigAccessInstance->ConfigAccessBufferStorageListHead);
187
188 //
189 // We assume there is only one formset package in each Forms Package
190 //
191 FormSetPackage = GetIfrFormSet (Packages);
192 ASSERT (FormSetPackage != NULL);
193
194 Status = GetBufferStorage (FormSetPackage, &ConfigAccessInstance->ConfigAccessBufferStorageListHead);
195 if (EFI_ERROR (Status)) {
196 FreePool (ConfigAccessInstance);
197 ASSERT (FALSE);
198 return Status;
199 }
200
201 Status = gBS->InstallMultipleProtocolInterfaces (
202 &MapEntry->UefiHiiDriverHandle,
203 &gEfiHiiConfigAccessProtocolGuid,
204 &ConfigAccessInstance->ConfigAccessProtocol,
205 NULL
206 );
207 ASSERT_EFI_ERROR (Status);
208 if (EFI_ERROR (Status)) {
209 FreePool (ConfigAccessInstance);
210 return Status;
211 }
212
213 return EFI_SUCCESS;
214 }
215
216 /**
217
218 Wrap EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig to a call to EFI_FORM_CALLBACK_PROTOCOL.NvWrite.
219
220 @param BufferStorageKey The key with all attributes needed to call EFI_FORM_CALLBACK_PROTOCOL.NvWrite.
221 @param FrameworkFormCallBack The EFI_FORM_CALLBACK_PROTOCOL registered by Framework HII module.
222 @param Data The data to be saved.
223 @param DataSize The size of data.
224
225 @retval EFI_STATUS The status returned by the EFI_FORM_CALLBACK_PROTOCOL.NvWrite.
226 **/
227 EFI_STATUS
228 RouteConfigToFrameworkFormCallBack (
229 IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,
230 IN EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallBack,
231 IN VOID *Data,
232 IN UINTN DataSize
233 )
234 {
235 EFI_STATUS Status;
236 BOOLEAN ResetRequired;
237
238 Status = FrameworkFormCallBack->NvWrite (
239 FrameworkFormCallBack,
240 BufferStorageKey->Name,
241 &BufferStorageKey->Guid,
242 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
243 DataSize,
244 Data,
245 &ResetRequired
246 );
247 return Status;
248 }
249
250 /**
251 Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to EFI_FORM_CALLBACK_PROTOCOL.NvRead.
252
253 @param BufferStorageKey The key with all attributes needed to call EFI_FORM_CALLBACK_PROTOCOL.NvRead.
254 @param FrameworkFormCallBack The EFI_FORM_CALLBACK_PROTOCOL registered by Framework HII module.
255 @param Data The data read.
256 @param DataSize The size of data.
257
258 @retval EFI_STATUS The status returned by the EFI_FORM_CALLBACK_PROTOCOL.NvWrite.
259 @retval EFI_INVALID_PARAMETER If the EFI_FORM_CALLBACK_PROTOCOL.NvRead return the size information of the data
260 does not match what has been recorded early in he HII_TRHUNK_BUFFER_STORAGE_KEY.
261 **/
262 EFI_STATUS
263 ExtractConfigFromFrameworkFormCallBack (
264 IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,
265 IN EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallBack,
266 OUT VOID **Data,
267 OUT UINTN *DataSize
268 )
269 {
270 EFI_STATUS Status;
271
272 *DataSize = 0;
273 *Data = NULL;
274
275 Status = FrameworkFormCallBack->NvRead (
276 FrameworkFormCallBack,
277 BufferStorageKey->Name,
278 &BufferStorageKey->Guid,
279 NULL,
280 DataSize,
281 *Data
282 );
283 if (Status == EFI_BUFFER_TOO_SMALL) {
284 if (BufferStorageKey->Size != *DataSize) {
285 ASSERT (FALSE);
286 return EFI_INVALID_PARAMETER;
287 }
288
289 *Data = AllocateZeroPool (*DataSize);
290 if (Data == NULL) {
291 return EFI_OUT_OF_RESOURCES;
292 }
293
294 FrameworkFormCallBack->NvRead (
295 FrameworkFormCallBack,
296 BufferStorageKey->Name,
297 &BufferStorageKey->Guid,
298 NULL,
299 DataSize,
300 *Data
301 );
302 }
303
304 return Status;
305 }
306
307 /**
308 Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to UEFI Variable Set Service.
309
310 @param BufferStorageKey The key with all attributes needed to call a UEFI Variable Get Service.
311 @param Data The data read.
312 @param DataSize The size of data.
313
314 @retval EFI_STATUS The status returned by the UEFI Variable Set Service.
315
316 **/
317 EFI_STATUS
318 RouteConfigToUefiVariable (
319 IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,
320 IN VOID *Data,
321 IN UINTN DataSize
322 )
323 {
324 return gRT->SetVariable (
325 BufferStorageKey->Name,
326 &BufferStorageKey->Guid,
327 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
328 DataSize,
329 Data
330 );
331
332 }
333
334 /**
335 Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig to a call to UEFI Variable Get Service.
336
337 @param BufferStorageKey The key with all attributes needed to call a UEFI Variable Get Service.
338 @param Data The data read.
339 @param DataSize The size of data.
340
341 If the UEFI Variable Get Service return the size information of the data
342 does not match what has been recorded early in he HII_TRHUNK_BUFFER_STORAGE_KEY.
343 then ASSERT.
344
345 @retval EFI_STATUS The status returned by the UEFI Variable Get Service.
346 @retval EFI_INVALID_PARAMETER If the UEFI Variable Get Service return the size information of the data
347 does not match what has been recorded early in he HII_TRHUNK_BUFFER_STORAGE_KEY.
348 **/
349
350 EFI_STATUS
351 ExtractConfigFromUefiVariable (
352 IN HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey,
353 OUT VOID **Data,
354 OUT UINTN *DataSize
355 )
356 {
357 EFI_STATUS Status;
358
359 *DataSize = 0;
360 *Data = NULL;
361 Status = gRT->GetVariable (
362 BufferStorageKey->Name,
363 &BufferStorageKey->Guid,
364 NULL,
365 DataSize,
366 *Data
367 );
368 if (Status == EFI_BUFFER_TOO_SMALL) {
369
370 if (BufferStorageKey->Size != *DataSize) {
371 ASSERT (FALSE);
372 return EFI_INVALID_PARAMETER;
373 }
374
375 *Data = AllocateZeroPool (*DataSize);
376 if (Data == NULL) {
377 return EFI_OUT_OF_RESOURCES;
378 }
379
380 Status = gRT->GetVariable (
381 BufferStorageKey->Name,
382 &BufferStorageKey->Guid,
383 NULL,
384 DataSize,
385 *Data
386 );
387 }
388
389 return Status;
390 }
391
392 /**
393
394 This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.ExtractConfig
395 so that data can be read from the data storage such as UEFI Variable or module's
396 customized storage exposed by EFI_FRAMEWORK_CALLBACK.
397
398 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
399 @param Request A null-terminated Unicode string in <ConfigRequest> format. Note that this
400 includes the routing information as well as the configurable name / value pairs. It is
401 invalid for this string to be in <MultiConfigRequest> format.
402
403 @param Progress On return, points to a character in the Request string. Points to the string¡¯s null
404 terminator if request was successful. Points to the most recent ¡®&¡¯ before the first
405 failing name / value pair (or the beginning of the string if the failure is in the first
406 name / value pair) if the request was not successful
407 @param Results A null-terminated Unicode string in <ConfigAltResp> format which has all
408 values filled in for the names in the Request string. String to be allocated by the called
409 function.
410
411 @retval EFI_INVALID_PARAMETER If there is no Buffer Storage for this Config Access instance.
412 @retval EFI_SUCCESS The setting is retrived successfully.
413 @retval !EFI_SUCCESS The error returned by UEFI Get Variable or Framework Form Callback Nvread.
414 **/
415 EFI_STATUS
416 EFIAPI
417 ThunkExtractConfig (
418 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
419 IN CONST EFI_STRING Request,
420 OUT EFI_STRING *Progress,
421 OUT EFI_STRING *Results
422 )
423 {
424 EFI_STATUS Status;
425 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;
426 LIST_ENTRY *ListEntry;
427 HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;
428 VOID *Data;
429 UINTN DataSize;
430
431 Data = NULL;
432 ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);
433
434 //
435 // For now, only one var varstore is supported so that we don't need to parse the Configuration string.
436 //
437 ListEntry = GetFirstNode (&ConfigaAccessInstance->ConfigAccessBufferStorageListHead);
438 if (ListEntry == NULL) {
439 ASSERT (FALSE);
440 return EFI_INVALID_PARAMETER;
441 }
442
443 BufferStorageKey = HII_TRHUNK_BUFFER_STORAGE_KEY_FROM_LIST_ENTRY (ListEntry);
444
445 if (ConfigaAccessInstance->FrameworkFormCallbackProtocol == NULL ||
446 ConfigaAccessInstance->FrameworkFormCallbackProtocol->NvRead == NULL) {
447 Status = ExtractConfigFromUefiVariable (
448 BufferStorageKey,
449 &Data,
450 &DataSize
451 );
452 } else {
453 Status = ExtractConfigFromFrameworkFormCallBack (
454 BufferStorageKey,
455 ConfigaAccessInstance->FrameworkFormCallbackProtocol,
456 &Data,
457 &DataSize
458 );
459 }
460
461 if (!EFI_ERROR (Status)) {
462 Status = mHiiConfigRoutingProtocol->BlockToConfig (
463 mHiiConfigRoutingProtocol,
464 Request,
465 Data,
466 DataSize,
467 Results,
468 Progress
469 );
470 }
471
472 SafeFreePool (Data);
473 return Status;
474 }
475
476 /**
477
478 This function implement the EFI_HII_CONFIG_ACCESS_PROTOCOL.RouteConfig
479 so that data can be written to the data storage such as UEFI Variable or module's
480 customized storage exposed by EFI_FRAMEWORK_CALLBACK.
481
482 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL
483 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
484 @param a pointer to a string filled in with the offset of the most recent ¡®&¡¯ before the first
485 failing name / value pair (or the beginning of the string if the failure is in the first
486 name / value pair) or the terminating NULL if all was successful.
487
488 @retval EFI_INVALID_PARAMETER If there is no Buffer Storage for this Config Access instance.
489 @retval EFI_SUCCESS The setting is saved successfully.
490 @retval !EFI_SUCCESS The error returned by UEFI Set Variable or Framework Form Callback Nvwrite.
491 **/
492 EFI_STATUS
493 EFIAPI
494 ThunkRouteConfig (
495 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
496 IN CONST EFI_STRING Configuration,
497 OUT EFI_STRING *Progress
498 )
499 {
500 EFI_STATUS Status;
501 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;
502 LIST_ENTRY *ListEntry;
503 HII_TRHUNK_BUFFER_STORAGE_KEY *BufferStorageKey;
504 VOID *Data;
505 UINTN DataSize;
506 UINTN LastModifiedByteIndex;
507
508 Data = NULL;
509 ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);
510
511 //
512 // For now, only one var varstore is supported so that we don't need to parse the Configuration string.
513 //
514 ListEntry = GetFirstNode (&ConfigaAccessInstance->ConfigAccessBufferStorageListHead);
515 if (ListEntry == NULL) {
516 ASSERT (FALSE);
517 return EFI_INVALID_PARAMETER;
518 }
519
520 BufferStorageKey = HII_TRHUNK_BUFFER_STORAGE_KEY_FROM_LIST_ENTRY (ListEntry);
521
522 Data = AllocateZeroPool (BufferStorageKey->Size);
523 if (Data == NULL) {
524 return EFI_OUT_OF_RESOURCES;
525 }
526 Status = mHiiConfigRoutingProtocol->ConfigToBlock (
527 mHiiConfigRoutingProtocol,
528 Configuration,
529 Data,
530 &LastModifiedByteIndex,
531 Progress
532 );
533
534 if (EFI_ERROR (Status)) {
535 goto Done;
536 }
537
538 DataSize = BufferStorageKey->Size;
539 if (ConfigaAccessInstance->FrameworkFormCallbackProtocol == NULL ||
540 ConfigaAccessInstance->FrameworkFormCallbackProtocol->NvRead == NULL) {
541 Status = RouteConfigToUefiVariable (
542 BufferStorageKey,
543 Data,
544 DataSize
545 );
546 } else {
547 Status = RouteConfigToFrameworkFormCallBack (
548 BufferStorageKey,
549 ConfigaAccessInstance->FrameworkFormCallbackProtocol,
550 Data,
551 DataSize
552 );
553 }
554
555 Done:
556 SafeFreePool (Data);
557 return Status;
558 }
559
560 /**
561 Wrap the EFI_HII_CONFIG_ACCESS_PROTOCOL.CallBack to EFI_FORM_CALLBACK_PROTOCOL.Callback. Therefor,
562 the framework HII module willl do no porting (except some porting works needed for callback for EFI_ONE_OF_OPTION opcode)
563 and still work with a UEFI HII SetupBrowser.
564
565 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
566 @param Action Specifies the type of action taken by the browser. See EFI_BROWSER_ACTION_x.
567 @param QuestionId A unique value which is sent to the original exporting driver so that it can identify the
568 type of data to expect. The format of the data tends to vary based on the opcode that
569 generated the callback.
570 @param Type The type of value for the question. See EFI_IFR_TYPE_x in
571 EFI_IFR_ONE_OF_OPTION.
572 @param Value A pointer to the data being sent to the original exporting driver. The type is specified
573 by Type. Type EFI_IFR_TYPE_VALUE is defined in
574 EFI_IFR_ONE_OF_OPTION.
575 @param ActionRequest On return, points to the action requested by the callback function. Type
576 EFI_BROWSER_ACTION_REQUEST is specified in SendForm() in the Form
577 Browser Protocol.
578
579 @retval EFI_UNSUPPORTED If the Framework HII module does not register Callback although it specify the opcode under
580 focuse to be INTERRACTIVE.
581 @retval EFI_SUCCESS The callback complete successfully.
582 @retval !EFI_SUCCESS The error code returned by EFI_FORM_CALLBACK_PROTOCOL.Callback.
583
584 **/
585 EFI_STATUS
586 EFIAPI
587 ThunkCallback (
588 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
589 IN EFI_BROWSER_ACTION Action,
590 IN EFI_QUESTION_ID QuestionId,
591 IN UINT8 Type,
592 IN EFI_IFR_TYPE_VALUE *Value,
593 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
594 )
595 {
596 EFI_STATUS Status;
597 HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE *ConfigaAccessInstance;
598 EFI_FORM_CALLBACK_PROTOCOL *FrameworkFormCallbackProtocol;
599 EFI_HII_CALLBACK_PACKET *Packet;
600 FRAMEWORK_EFI_IFR_DATA_ARRAY Data;
601 FRAMEWORK_EFI_IFR_DATA_ENTRY *DataEntry;
602 EFI_FORM_CALLBACK Callback;
603
604 ASSERT (This != NULL);
605 ASSERT (Value != NULL);
606 ASSERT (ActionRequest != NULL);
607
608 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
609
610 ConfigaAccessInstance = HII_TRHUNK_CONFIG_ACCESS_PROTOCOL_INSTANCE_FROM_PROTOCOL (This);
611
612 FrameworkFormCallbackProtocol = ConfigaAccessInstance->FrameworkFormCallbackProtocol;
613 if (FrameworkFormCallbackProtocol == NULL) {
614 return EFI_UNSUPPORTED;
615 }
616 Callback = FrameworkFormCallbackProtocol->Callback;
617
618 Status = Callback (
619 FrameworkFormCallbackProtocol,
620 QuestionId,
621 &Data,
622 &Packet
623 );
624
625 //
626 // Callback require browser to perform action
627 //
628 if (Packet != NULL) {
629 if (Packet->DataArray.EntryCount == 1 && Packet->DataArray.NvRamMap == NULL) {
630 DataEntry = (FRAMEWORK_EFI_IFR_DATA_ENTRY *) ((UINT8 *) Packet + sizeof (FRAMEWORK_EFI_IFR_DATA_ARRAY));
631 switch (DataEntry->Flags) {
632 case EXIT_REQUIRED:
633 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
634 break;
635 case SAVE_REQUIRED:
636 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
637 break;
638 case RESET_REQUIRED:
639 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;
640 break;
641 default:
642 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
643 break;
644 }
645 }
646 }
647
648 return Status;
649 }
650