VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/RedfishPkg/Library/HiiUtilityLib/HiiUtilityLib.c@ 101291

Last change on this file since 101291 was 101291, checked in by vboxsync, 17 months ago

EFI/FirmwareNew: Make edk2-stable202308 build on all supported platforms (using gcc at least, msvc not tested yet), bugref:4643

  • Property svn:eol-style set to native
File size: 23.3 KB
Line 
1/** @file
2 Implementation of HII utility library.
3
4 Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
6 Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
7
8 SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12#include "HiiInternal.h"
13
14/**
15 Initialize the internal data structure of a FormSet.
16
17 @param Handle PackageList Handle
18 @param FormSetGuid On input, GUID or class GUID of a formset. If not
19 specified (NULL or zero GUID), take the first
20 FormSet with class GUID EFI_HII_PLATFORM_SETUP_FORMSET_GUID
21 found in package list.
22 On output, GUID of the formset found(if not NULL).
23 @param FormSet FormSet data structure.
24
25 @retval EFI_SUCCESS The function completed successfully.
26 @retval EFI_NOT_FOUND The specified FormSet could not be found.
27
28**/
29EFI_STATUS
30CreateFormSetFromHiiHandle (
31 IN EFI_HII_HANDLE Handle,
32 IN OUT EFI_GUID *FormSetGuid,
33 OUT HII_FORMSET *FormSet
34 )
35{
36 EFI_STATUS Status;
37 EFI_HANDLE DriverHandle;
38 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
39
40 if ((FormSetGuid == NULL) || (FormSet == NULL)) {
41 return EFI_INVALID_PARAMETER;
42 }
43
44 //
45 // Locate required Hii Database protocol
46 //
47 Status = gBS->LocateProtocol (
48 &gEfiHiiDatabaseProtocolGuid,
49 NULL,
50 (VOID **)&HiiDatabase
51 );
52 if (EFI_ERROR (Status)) {
53 return Status;
54 }
55
56 Status = GetIfrBinaryData (Handle, FormSetGuid, &FormSet->IfrBinaryLength, &FormSet->IfrBinaryData);
57 if (EFI_ERROR (Status)) {
58 return Status;
59 }
60
61 FormSet->Signature = HII_FORMSET_SIGNATURE;
62 FormSet->HiiHandle = Handle;
63 CopyMem (&FormSet->Guid, FormSetGuid, sizeof (EFI_GUID));
64 //
65 // Retrieve ConfigAccess Protocol associated with this HiiPackageList
66 //
67 Status = HiiDatabase->GetPackageListHandle (HiiDatabase, Handle, &DriverHandle);
68 if (EFI_ERROR (Status)) {
69 return Status;
70 }
71
72 FormSet->DriverHandle = DriverHandle;
73 Status = gBS->HandleProtocol (
74 DriverHandle,
75 &gEfiHiiConfigAccessProtocolGuid,
76 (VOID **)&FormSet->ConfigAccess
77 );
78 if (EFI_ERROR (Status)) {
79 //
80 // Configuration Driver don't attach ConfigAccess protocol to its HII package
81 // list, then there will be no configuration action required
82 //
83 FormSet->ConfigAccess = NULL;
84 }
85
86 Status = gBS->HandleProtocol (
87 DriverHandle,
88 &gEfiDevicePathProtocolGuid,
89 (VOID **)&FormSet->DevicePath
90 );
91 if (EFI_ERROR (Status)) {
92 //
93 // Configuration Driver don't attach ConfigAccess protocol to its HII package
94 // list, then there will be no configuration action required
95 //
96 FormSet->DevicePath = NULL;
97 }
98
99 //
100 // Parse the IFR binary OpCodes
101 //
102 Status = ParseOpCodes (FormSet);
103
104 return Status;
105}
106
107/**
108 Initialize a Formset and get current setting for Questions.
109
110 @param FormSet FormSet data structure.
111
112**/
113VOID
114InitializeFormSet (
115 IN OUT HII_FORMSET *FormSet
116 )
117{
118 LIST_ENTRY *Link;
119 HII_FORMSET_STORAGE *Storage;
120 LIST_ENTRY *FormLink;
121 HII_STATEMENT *Question;
122 HII_FORM *Form;
123
124 if (FormSet == NULL) {
125 return;
126 }
127
128 //
129 // Load Storage for all questions with storage
130 //
131 Link = GetFirstNode (&FormSet->StorageListHead);
132 while (!IsNull (&FormSet->StorageListHead, Link)) {
133 Storage = HII_STORAGE_FROM_LINK (Link);
134 LoadFormSetStorage (FormSet, Storage);
135 Link = GetNextNode (&FormSet->StorageListHead, Link);
136 }
137
138 //
139 // Get Current Value for all no storage questions
140 //
141 FormLink = GetFirstNode (&FormSet->FormListHead);
142 while (!IsNull (&FormSet->FormListHead, FormLink)) {
143 Form = HII_FORM_FROM_LINK (FormLink);
144 Link = GetFirstNode (&Form->StatementListHead);
145 while (!IsNull (&Form->StatementListHead, Link)) {
146 Question = HII_STATEMENT_FROM_LINK (Link);
147 if (Question->Storage == NULL) {
148 RetrieveQuestion (FormSet, Form, Question);
149 }
150
151 Link = GetNextNode (&Form->StatementListHead, Link);
152 }
153
154 FormLink = GetNextNode (&FormSet->FormListHead, FormLink);
155 }
156}
157
158/**
159 Free resources allocated for a FormSet.
160
161 @param[in,out] FormSet Pointer of the FormSet
162
163**/
164VOID
165DestroyFormSet (
166 IN OUT HII_FORMSET *FormSet
167 )
168{
169 LIST_ENTRY *Link;
170 HII_FORMSET_STORAGE *Storage;
171 HII_FORMSET_DEFAULTSTORE *DefaultStore;
172 HII_FORM *Form;
173
174 if (FormSet->IfrBinaryData == NULL) {
175 //
176 // Uninitialized FormSet
177 //
178 FreePool (FormSet);
179 return;
180 }
181
182 //
183 // Free IFR binary buffer
184 //
185 FreePool (FormSet->IfrBinaryData);
186
187 //
188 // Free FormSet Storage
189 //
190 if (FormSet->StorageListHead.ForwardLink != NULL) {
191 while (!IsListEmpty (&FormSet->StorageListHead)) {
192 Link = GetFirstNode (&FormSet->StorageListHead);
193 Storage = HII_STORAGE_FROM_LINK (Link);
194 RemoveEntryList (&Storage->Link);
195
196 if (Storage != NULL) {
197 FreePool (Storage);
198 }
199 }
200 }
201
202 //
203 // Free FormSet Default Store
204 //
205 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {
206 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {
207 Link = GetFirstNode (&FormSet->DefaultStoreListHead);
208 DefaultStore = HII_FORMSET_DEFAULTSTORE_FROM_LINK (Link);
209 RemoveEntryList (&DefaultStore->Link);
210
211 FreePool (DefaultStore);
212 }
213 }
214
215 //
216 // Free Forms
217 //
218 if (FormSet->FormListHead.ForwardLink != NULL) {
219 while (!IsListEmpty (&FormSet->FormListHead)) {
220 Link = GetFirstNode (&FormSet->FormListHead);
221 Form = HII_FORM_FROM_LINK (Link);
222 RemoveEntryList (&Form->Link);
223
224 DestroyForm (FormSet, Form);
225 }
226 }
227
228 FreePool (FormSet);
229}
230
231/**
232 Submit data for a form.
233
234 @param[in] FormSet FormSet which contains the Form.
235 @param[in] Form Form to submit.
236
237 @retval EFI_SUCCESS The function completed successfully.
238 @retval Others Other errors occur.
239
240**/
241EFI_STATUS
242SubmitForm (
243 IN HII_FORMSET *FormSet,
244 IN HII_FORM *Form
245 )
246{
247 EFI_STATUS Status;
248 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
249 LIST_ENTRY *Link;
250 EFI_STRING ConfigResp;
251 EFI_STRING Progress;
252 HII_FORMSET_STORAGE *Storage;
253 HII_FORM_CONFIG_REQUEST *ConfigInfo;
254
255 if ((FormSet == NULL) || (Form == NULL)) {
256 return EFI_INVALID_PARAMETER;
257 }
258
259 Status = NoSubmitCheck (FormSet, &Form, NULL);
260 if (EFI_ERROR (Status)) {
261 return Status;
262 }
263
264 Link = GetFirstNode (&Form->ConfigRequestHead);
265 while (!IsNull (&Form->ConfigRequestHead, Link)) {
266 ConfigInfo = HII_FORM_CONFIG_REQUEST_FROM_LINK (Link);
267 Link = GetNextNode (&Form->ConfigRequestHead, Link);
268
269 Storage = ConfigInfo->Storage;
270 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
271 continue;
272 }
273
274 //
275 // Skip if there is no RequestElement
276 //
277 if (ConfigInfo->ElementCount == 0) {
278 continue;
279 }
280
281 Status = StorageToConfigResp (ConfigInfo->Storage, &ConfigResp, ConfigInfo->ConfigRequest);
282 if (EFI_ERROR (Status)) {
283 return Status;
284 }
285
286 Status = gBS->LocateProtocol (
287 &gEfiHiiConfigRoutingProtocolGuid,
288 NULL,
289 (VOID **)&HiiConfigRouting
290 );
291 if (EFI_ERROR (Status)) {
292 return Status;
293 }
294
295 Status = HiiConfigRouting->RouteConfig (
296 HiiConfigRouting,
297 ConfigResp,
298 &Progress
299 );
300
301 if (EFI_ERROR (Status)) {
302 FreePool (ConfigResp);
303 continue;
304 }
305
306 FreePool (ConfigResp);
307 }
308
309 return Status;
310}
311
312/**
313 Save Question Value to the memory, but not to storage.
314
315 @param[in] FormSet FormSet data structure.
316 @param[in] Form Form data structure.
317 @param[in,out] Question Pointer to the Question.
318 @param[in] QuestionValue New Question Value to be set.
319
320 @retval EFI_SUCCESS The question value has been set successfully.
321 @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
322
323**/
324EFI_STATUS
325SetQuestionValue (
326 IN HII_FORMSET *FormSet,
327 IN HII_FORM *Form,
328 IN OUT HII_STATEMENT *Question,
329 IN HII_STATEMENT_VALUE *QuestionValue
330 )
331{
332 UINT8 *Src;
333 UINTN BufferLen;
334 UINTN StorageWidth;
335 HII_FORMSET_STORAGE *Storage;
336 CHAR16 *ValueStr;
337 BOOLEAN IsBufferStorage;
338 UINT8 *TemBuffer;
339 CHAR16 *TemName;
340 CHAR16 *TemString;
341 UINTN Index;
342 HII_NAME_VALUE_NODE *Node;
343 EFI_STATUS Status;
344
345 if ((FormSet == NULL) || (Form == NULL) || (Question == NULL) || (QuestionValue == NULL)) {
346 return EFI_INVALID_PARAMETER;
347 }
348
349 Status = EFI_SUCCESS;
350 Node = NULL;
351
352 //
353 // If Question value is provided by an Expression, then it is read only
354 //
355 if ((Question->ValueExpression != NULL) || (Question->Value.Type != QuestionValue->Type)) {
356 return EFI_INVALID_PARAMETER;
357 }
358
359 //
360 // Before set question value, evaluate its write expression.
361 //
362 if ((Question->WriteExpression != NULL) && (Form->FormType == STANDARD_MAP_FORM_TYPE)) {
363 Status = EvaluateHiiExpression (FormSet, Form, Question->WriteExpression);
364 if (EFI_ERROR (Status)) {
365 return Status;
366 }
367 }
368
369 Storage = Question->Storage;
370 if (Storage != NULL) {
371 StorageWidth = Question->StorageWidth;
372 if (Question->Value.Type == EFI_IFR_TYPE_BUFFER) {
373 Question->Value.BufferLen = QuestionValue->BufferLen;
374 Question->Value.Buffer = AllocateCopyPool (QuestionValue->BufferLen, QuestionValue->Buffer);
375 if (Question->Value.Buffer == NULL) {
376 return EFI_OUT_OF_RESOURCES;
377 }
378
379 Question->Value.BufferValueType = QuestionValue->BufferValueType;
380 Src = Question->Value.Buffer;
381 } else if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
382 Question->Value.Value.string = QuestionValue->Value.string;
383 TemString = HiiGetString (FormSet->HiiHandle, QuestionValue->Value.string, NULL);
384 if (TemString == NULL) {
385 return EFI_ABORTED;
386 }
387
388 Question->Value.BufferLen = Question->StorageWidth;
389 Question->Value.Buffer = AllocateZeroPool (Question->StorageWidth);
390 if (Question->Value.Buffer == NULL) {
391 return EFI_OUT_OF_RESOURCES;
392 }
393
394 CopyMem (Question->Value.Buffer, TemString, StrSize (TemString));
395 Src = Question->Value.Buffer;
396 } else {
397 CopyMem (&Question->Value.Value, &QuestionValue->Value, sizeof (EFI_IFR_TYPE_VALUE));
398 Src = (UINT8 *)&Question->Value.Value;
399 }
400
401 if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
402 IsBufferStorage = TRUE;
403 } else {
404 IsBufferStorage = FALSE;
405 }
406
407 if (IsBufferStorage) {
408 //
409 // If the Question refer to bit filed, copy the value in related bit filed to storage edit buffer.
410 //
411 if (Question->QuestionReferToBitField) {
412 SetBitsQuestionValue (Question, Storage->Buffer + Question->VarStoreInfo.VarOffset, (UINT32)(*Src));
413 } else {
414 CopyMem (Storage->Buffer + Question->VarStoreInfo.VarOffset, Src, StorageWidth);
415 }
416 } else {
417 if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
418 //
419 // Allocate enough string buffer.
420 //
421 ValueStr = NULL;
422 BufferLen = ((StrLen ((CHAR16 *)Src) * 4) + 1) * sizeof (CHAR16);
423 ValueStr = AllocatePool (BufferLen);
424 if (ValueStr == NULL) {
425 if (Question->Value.Buffer != NULL) {
426 FreePool (Question->Value.Buffer);
427 }
428
429 return EFI_OUT_OF_RESOURCES;
430 }
431
432 //
433 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
434 //
435 TemName = (CHAR16 *)Src;
436 TemString = ValueStr;
437 for ( ; *TemName != L'\0'; TemName++) {
438 UnicodeValueToStringS (
439 TemString,
440 BufferLen - ((UINTN)TemString - (UINTN)ValueStr),
441 PREFIX_ZERO | RADIX_HEX,
442 *TemName,
443 4
444 );
445 TemString += StrnLenS (TemString, (BufferLen - ((UINTN)TemString - (UINTN)ValueStr)) / sizeof (CHAR16));
446 }
447 } else {
448 BufferLen = StorageWidth * 2 + 1;
449 ValueStr = AllocateZeroPool (BufferLen * sizeof (CHAR16));
450 if (ValueStr == NULL) {
451 if (Question->Value.Buffer != NULL) {
452 FreePool (Question->Value.Buffer);
453 }
454
455 return EFI_OUT_OF_RESOURCES;
456 }
457
458 //
459 // Convert Buffer to Hex String
460 //
461 TemBuffer = Src + StorageWidth - 1;
462 TemString = ValueStr;
463 for (Index = 0; Index < StorageWidth; Index++, TemBuffer--) {
464 UnicodeValueToStringS (
465 TemString,
466 BufferLen * sizeof (CHAR16) - ((UINTN)TemString - (UINTN)ValueStr),
467 PREFIX_ZERO | RADIX_HEX,
468 *TemBuffer,
469 2
470 );
471 TemString += StrnLenS (TemString, BufferLen - ((UINTN)TemString - (UINTN)ValueStr) / sizeof (CHAR16));
472 }
473 }
474
475 Status = SetValueByName (Storage, Question->VariableName, ValueStr, &Node);
476 FreePool (ValueStr);
477 if (EFI_ERROR (Status)) {
478 if (Question->Value.Buffer != NULL) {
479 FreePool (Question->Value.Buffer);
480 }
481
482 return Status;
483 }
484 }
485 } else {
486 if (Question->Value.Type == EFI_IFR_TYPE_BUFFER) {
487 Question->Value.BufferLen = QuestionValue->BufferLen;
488 Question->Value.Buffer = AllocateCopyPool (QuestionValue->BufferLen, QuestionValue->Buffer);
489 if (Question->Value.Buffer == NULL) {
490 return EFI_OUT_OF_RESOURCES;
491 }
492
493 Question->Value.BufferValueType = QuestionValue->BufferValueType;
494 } else if (Question->Value.Type == EFI_IFR_TYPE_STRING) {
495 Question->Value.Value.string = QuestionValue->Value.string;
496 TemString = HiiGetString (FormSet->HiiHandle, QuestionValue->Value.string, NULL);
497 if (TemString == NULL) {
498 return EFI_ABORTED;
499 }
500
501 Question->Value.BufferLen = (UINT16)StrSize (TemString);
502 Question->Value.Buffer = AllocateZeroPool (QuestionValue->BufferLen);
503 if (Question->Value.Buffer == NULL) {
504 FreePool (TemString);
505 return EFI_OUT_OF_RESOURCES;
506 }
507
508 CopyMem (Question->Value.Buffer, TemString, StrSize (TemString));
509 FreePool (TemString);
510 } else {
511 CopyMem (&Question->Value.Value, &QuestionValue->Value, sizeof (EFI_IFR_TYPE_VALUE));
512 }
513 }
514
515 return Status;
516}
517
518/**
519 Get Question's current Value from storage.
520
521 @param[in] FormSet FormSet data structure.
522 @param[in] Form Form data structure.
523 @param[in,out] Question Question to be initialized.
524
525 @return the current Question Value in storage if success.
526 @return NULL if Question is not found or any error occurs.
527
528**/
529HII_STATEMENT_VALUE *
530RetrieveQuestion (
531 IN HII_FORMSET *FormSet,
532 IN HII_FORM *Form,
533 IN OUT HII_STATEMENT *Question
534 )
535{
536 EFI_STATUS Status;
537 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
538 EFI_BROWSER_ACTION_REQUEST ActionRequest;
539 HII_FORMSET_STORAGE *Storage;
540 HII_STATEMENT_VALUE *QuestionValue;
541 EFI_IFR_TYPE_VALUE *TypeValue;
542 EFI_TIME EfiTime;
543 BOOLEAN Enabled;
544 BOOLEAN Pending;
545 UINT8 *Dst;
546 UINTN StorageWidth;
547 CHAR16 *ConfigRequest;
548 CHAR16 *Progress;
549 CHAR16 *Result;
550 CHAR16 *ValueStr;
551 UINTN Length;
552 BOOLEAN IsBufferStorage;
553 CHAR16 *NewHiiString;
554
555 if ((FormSet == NULL) || (Form == NULL) || (Question == NULL)) {
556 return NULL;
557 }
558
559 Status = EFI_SUCCESS;
560 ValueStr = NULL;
561 Result = NULL;
562
563 QuestionValue = AllocateZeroPool (sizeof (HII_STATEMENT_VALUE));
564 if (QuestionValue == NULL) {
565 return NULL;
566 }
567
568 QuestionValue->Type = Question->Value.Type;
569 QuestionValue->BufferLen = Question->Value.BufferLen;
570 if (QuestionValue->BufferLen != 0) {
571 QuestionValue->Buffer = AllocateZeroPool (QuestionValue->BufferLen);
572 if (QuestionValue->Buffer == NULL) {
573 FreePool (QuestionValue);
574 return NULL;
575 }
576 }
577
578 //
579 // Question value is provided by RTC
580 //
581 Storage = Question->Storage;
582 StorageWidth = Question->StorageWidth;
583
584 if (Storage == NULL) {
585 //
586 // It's a Question without storage, or RTC date/time
587 //
588 if ((Question->Operand == EFI_IFR_DATE_OP) || (Question->Operand == EFI_IFR_TIME_OP)) {
589 //
590 // Date and time define the same Flags bit
591 //
592 switch (Question->ExtraData.Flags & EFI_QF_DATE_STORAGE) {
593 case QF_DATE_STORAGE_TIME:
594
595 Status = gRT->GetTime (&EfiTime, NULL);
596 break;
597
598 case QF_DATE_STORAGE_WAKEUP:
599
600 Status = gRT->GetWakeupTime (&Enabled, &Pending, &EfiTime);
601 break;
602
603 case QF_DATE_STORAGE_NORMAL:
604 default:
605
606 goto ON_ERROR;
607 }
608
609 if (EFI_ERROR (Status)) {
610 if (Question->Operand == EFI_IFR_DATE_OP) {
611 QuestionValue->Value.date.Year = 0xff;
612 QuestionValue->Value.date.Month = 0xff;
613 QuestionValue->Value.date.Day = 0xff;
614 } else {
615 QuestionValue->Value.time.Hour = 0xff;
616 QuestionValue->Value.time.Minute = 0xff;
617 QuestionValue->Value.time.Second = 0xff;
618 }
619
620 return QuestionValue;
621 }
622
623 if (Question->Operand == EFI_IFR_DATE_OP) {
624 QuestionValue->Value.date.Year = EfiTime.Year;
625 QuestionValue->Value.date.Month = EfiTime.Month;
626 QuestionValue->Value.date.Day = EfiTime.Day;
627 } else {
628 QuestionValue->Value.time.Hour = EfiTime.Hour;
629 QuestionValue->Value.time.Minute = EfiTime.Minute;
630 QuestionValue->Value.time.Second = EfiTime.Second;
631 }
632 } else {
633 if (((Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK) != EFI_IFR_FLAG_CALLBACK) ||
634 (FormSet->ConfigAccess == NULL))
635 {
636 goto ON_ERROR;
637 }
638
639 if (QuestionValue->Type == EFI_IFR_TYPE_BUFFER) {
640 //
641 // For OrderedList, passing in the value buffer to Callback()
642 //
643 TypeValue = (EFI_IFR_TYPE_VALUE *)QuestionValue->Buffer;
644 } else {
645 TypeValue = &QuestionValue->Value;
646 }
647
648 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
649 Status = FormSet->ConfigAccess->Callback (
650 FormSet->ConfigAccess,
651 EFI_BROWSER_ACTION_RETRIEVE,
652 Question->QuestionId,
653 QuestionValue->Type,
654 TypeValue,
655 &ActionRequest
656 );
657
658 if (!EFI_ERROR (Status) && (QuestionValue->Type == EFI_IFR_TYPE_STRING)) {
659 if (TypeValue->string == 0) {
660 goto ON_ERROR;
661 }
662
663 NewHiiString = GetTokenString (TypeValue->string, FormSet->HiiHandle);
664 if (NewHiiString == NULL) {
665 goto ON_ERROR;
666 }
667
668 QuestionValue->Buffer = AllocatePool (StrSize (NewHiiString));
669 if (QuestionValue->Buffer == NULL) {
670 FreePool (NewHiiString);
671 goto ON_ERROR;
672 }
673
674 CopyMem (QuestionValue->Buffer, NewHiiString, StrSize (NewHiiString));
675 QuestionValue->BufferLen = (UINT16)StrSize (NewHiiString);
676
677 FreePool (NewHiiString);
678 }
679 }
680
681 return QuestionValue;
682 }
683
684 //
685 // Question value is provided by EFI variable
686 //
687 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
688 if ((QuestionValue->Type != EFI_IFR_TYPE_BUFFER) && (QuestionValue->Type != EFI_IFR_TYPE_STRING)) {
689 Dst = QuestionValue->Buffer;
690 StorageWidth = QuestionValue->BufferLen;
691 } else {
692 Dst = (UINT8 *)&QuestionValue->Value;
693 StorageWidth = sizeof (EFI_IFR_TYPE_VALUE);
694 }
695
696 Status = gRT->GetVariable (
697 Question->VariableName,
698 &Storage->Guid,
699 NULL,
700 &StorageWidth,
701 Dst
702 );
703
704 return QuestionValue;
705 }
706
707 Status = gBS->LocateProtocol (
708 &gEfiHiiConfigRoutingProtocolGuid,
709 NULL,
710 (VOID **)&HiiConfigRouting
711 );
712 if (EFI_ERROR (Status)) {
713 goto ON_ERROR;
714 }
715
716 if (QuestionValue->BufferLen != 0) {
717 Dst = QuestionValue->Buffer;
718 } else {
719 Dst = (UINT8 *)&QuestionValue->Value;
720 }
721
722 if ((Storage->Type == EFI_HII_VARSTORE_BUFFER) || (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER)) {
723 IsBufferStorage = TRUE;
724 } else {
725 IsBufferStorage = FALSE;
726 }
727
728 Storage = GetFstStgFromVarId (FormSet, Question->VarStoreId);
729 if (Storage == NULL) {
730 goto ON_ERROR;
731 }
732
733 //
734 // <ConfigRequest> ::= <ConfigHdr> + <BlockName> || <ConfigHdr> + "&" + <VariableName>
735 //
736 if (IsBufferStorage) {
737 Length = StrLen (Storage->ConfigHdr);
738 Length += StrLen (Question->BlockName);
739 } else {
740 Length = StrLen (Storage->ConfigHdr);
741 Length += StrLen (Question->VariableName) + 1;
742 }
743
744 ConfigRequest = AllocatePool ((Length + 1) * sizeof (CHAR16));
745 if (ConfigRequest == NULL) {
746 goto ON_ERROR;
747 }
748
749 StrCpyS (ConfigRequest, Length + 1, Storage->ConfigHdr);
750 if (IsBufferStorage) {
751 StrCatS (ConfigRequest, Length + 1, Question->BlockName);
752 } else {
753 StrCatS (ConfigRequest, Length + 1, L"&");
754 StrCatS (ConfigRequest, Length + 1, Question->VariableName);
755 }
756
757 //
758 // Request current settings from Configuration Driver
759 //
760 Status = HiiConfigRouting->ExtractConfig (
761 HiiConfigRouting,
762 ConfigRequest,
763 &Progress,
764 &Result
765 );
766 FreePool (ConfigRequest);
767 if (EFI_ERROR (Status)) {
768 goto ON_ERROR;
769 }
770
771 if (IsBufferStorage) {
772 ValueStr = StrStr (Result, L"&VALUE");
773 if (ValueStr == NULL) {
774 FreePool (Result);
775 goto ON_ERROR;
776 }
777
778 ValueStr = ValueStr + 6;
779 } else {
780 ValueStr = Result + Length;
781 }
782
783 if (*ValueStr != '=') {
784 FreePool (Result);
785 goto ON_ERROR;
786 }
787
788 ValueStr++;
789 Status = BufferToQuestionValue (Question, ValueStr, QuestionValue);
790 if (EFI_ERROR (Status)) {
791 FreePool (Result);
792 goto ON_ERROR;
793 }
794
795 if (Result != NULL) {
796 FreePool (Result);
797 }
798
799 return QuestionValue;
800
801ON_ERROR:
802
803 if (QuestionValue->Buffer != NULL) {
804 FreePool (QuestionValue->Buffer);
805 }
806
807 FreePool (QuestionValue);
808
809 return NULL;
810}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette