]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/SetupBrowserDxe/Expression.c
Update Base type SecPeiDxeTimerLibUefiCpu to support all module type.
[mirror_edk2.git] / MdeModulePkg / Universal / SetupBrowserDxe / Expression.c
CommitLineData
7936fb6a 1/** @file\r
2Utility functions for expression evaluation.\r
3\r
b18e7050 4Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
7936fb6a 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
7936fb6a 15#include "Setup.h"\r
16\r
17//\r
18// Global stack used to evaluate boolean expresions\r
19//\r
20EFI_HII_VALUE *mOpCodeScopeStack = NULL;\r
21EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;\r
22EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;\r
23\r
24EFI_HII_VALUE *mExpressionEvaluationStack = NULL;\r
25EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;\r
26EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;\r
2573712e
LG
27UINTN mExpressionEvaluationStackOffset = 0;\r
28\r
29EFI_HII_VALUE *mCurrentExpressionStack = NULL;\r
30EFI_HII_VALUE *mCurrentExpressionEnd = NULL;\r
31EFI_HII_VALUE *mCurrentExpressionPointer = NULL;\r
32\r
33EFI_HII_VALUE *mMapExpressionListStack = NULL;\r
34EFI_HII_VALUE *mMapExpressionListEnd = NULL;\r
35EFI_HII_VALUE *mMapExpressionListPointer = NULL;\r
7936fb6a 36\r
37//\r
38// Unicode collation protocol interface\r
39//\r
40EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;\r
cbf73e50 41EFI_USER_MANAGER_PROTOCOL *mUserManager = NULL;\r
7936fb6a 42\r
43/**\r
44 Grow size of the stack.\r
45\r
46 This is an internal function.\r
47\r
48 @param Stack On input: old stack; On output: new stack\r
49 @param StackPtr On input: old stack pointer; On output: new stack\r
50 pointer\r
51 @param StackEnd On input: old stack end; On output: new stack end\r
52\r
53 @retval EFI_SUCCESS Grow stack success.\r
54 @retval EFI_OUT_OF_RESOURCES No enough memory for stack space.\r
55\r
56**/\r
57EFI_STATUS\r
58GrowStack (\r
59 IN OUT EFI_HII_VALUE **Stack,\r
60 IN OUT EFI_HII_VALUE **StackPtr,\r
61 IN OUT EFI_HII_VALUE **StackEnd\r
62 )\r
63{\r
64 UINTN Size;\r
65 EFI_HII_VALUE *NewStack;\r
66\r
67 Size = EXPRESSION_STACK_SIZE_INCREMENT;\r
68 if (*StackPtr != NULL) {\r
69 Size = Size + (*StackEnd - *Stack);\r
70 }\r
71\r
72 NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));\r
73 if (NewStack == NULL) {\r
74 return EFI_OUT_OF_RESOURCES;\r
75 }\r
76\r
77 if (*StackPtr != NULL) {\r
78 //\r
79 // Copy from Old Stack to the New Stack\r
80 //\r
81 CopyMem (\r
82 NewStack,\r
83 *Stack,\r
84 (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)\r
85 );\r
86\r
87 //\r
88 // Free The Old Stack\r
89 //\r
f4113e1f 90 FreePool (*Stack);\r
7936fb6a 91 }\r
92\r
93 //\r
94 // Make the Stack pointer point to the old data in the new stack\r
95 //\r
96 *StackPtr = NewStack + (*StackPtr - *Stack);\r
97 *Stack = NewStack;\r
98 *StackEnd = NewStack + Size;\r
99\r
100 return EFI_SUCCESS;\r
101}\r
102\r
103\r
104/**\r
105 Push an element onto the Boolean Stack.\r
106\r
107 @param Stack On input: old stack; On output: new stack\r
108 @param StackPtr On input: old stack pointer; On output: new stack\r
109 pointer\r
110 @param StackEnd On input: old stack end; On output: new stack end\r
111 @param Data Data to push.\r
112\r
113 @retval EFI_SUCCESS Push stack success.\r
114\r
115**/\r
116EFI_STATUS\r
117PushStack (\r
118 IN OUT EFI_HII_VALUE **Stack,\r
119 IN OUT EFI_HII_VALUE **StackPtr,\r
120 IN OUT EFI_HII_VALUE **StackEnd,\r
121 IN EFI_HII_VALUE *Data\r
122 )\r
123{\r
124 EFI_STATUS Status;\r
125\r
126 //\r
127 // Check for a stack overflow condition\r
128 //\r
129 if (*StackPtr >= *StackEnd) {\r
130 //\r
131 // Grow the stack\r
132 //\r
133 Status = GrowStack (Stack, StackPtr, StackEnd);\r
134 if (EFI_ERROR (Status)) {\r
135 return Status;\r
136 }\r
137 }\r
138\r
139 //\r
140 // Push the item onto the stack\r
141 //\r
142 CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));\r
143 *StackPtr = *StackPtr + 1;\r
144\r
145 return EFI_SUCCESS;\r
146}\r
147\r
148\r
149/**\r
150 Pop an element from the stack.\r
151\r
2573712e
LG
152 @param Stack On input: old stack\r
153 @param StackPtr On input: old stack pointer; On output: new stack pointer\r
7936fb6a 154 @param Data Data to pop.\r
155\r
156 @retval EFI_SUCCESS The value was popped onto the stack.\r
157 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
158\r
159**/\r
160EFI_STATUS\r
161PopStack (\r
2573712e 162 IN EFI_HII_VALUE *Stack,\r
7936fb6a 163 IN OUT EFI_HII_VALUE **StackPtr,\r
7936fb6a 164 OUT EFI_HII_VALUE *Data\r
165 )\r
166{\r
167 //\r
168 // Check for a stack underflow condition\r
169 //\r
2573712e 170 if (*StackPtr == Stack) {\r
7936fb6a 171 return EFI_ACCESS_DENIED;\r
172 }\r
173\r
174 //\r
175 // Pop the item off the stack\r
176 //\r
177 *StackPtr = *StackPtr - 1;\r
178 CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));\r
179 return EFI_SUCCESS;\r
180}\r
181\r
182\r
2573712e
LG
183/**\r
184 Reset stack pointer to begin of the stack.\r
185\r
186**/\r
187VOID\r
188ResetCurrentExpressionStack (\r
189 VOID\r
190 )\r
191{\r
192 mCurrentExpressionPointer = mCurrentExpressionStack;\r
193}\r
194\r
195\r
196/**\r
197 Push current expression onto the Stack\r
198\r
199 @param Pointer Pointer to current expression.\r
200\r
201 @retval EFI_SUCCESS The value was pushed onto the stack.\r
202 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
203\r
204**/\r
205EFI_STATUS\r
206PushCurrentExpression (\r
207 IN VOID *Pointer\r
208 )\r
209{\r
210 EFI_HII_VALUE Data;\r
211\r
212 Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
213 Data.Value.u64 = (UINT64) (UINTN) Pointer;\r
214\r
215 return PushStack (\r
216 &mCurrentExpressionStack,\r
217 &mCurrentExpressionPointer,\r
218 &mCurrentExpressionEnd,\r
219 &Data\r
220 );\r
221}\r
222\r
223\r
224/**\r
225 Pop current expression from the Stack\r
226\r
227 @param Pointer Pointer to current expression to be pop.\r
228\r
229 @retval EFI_SUCCESS The value was pushed onto the stack.\r
230 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
231\r
232**/\r
233EFI_STATUS\r
234PopCurrentExpression (\r
235 OUT VOID **Pointer\r
236 )\r
237{\r
238 EFI_STATUS Status;\r
239 EFI_HII_VALUE Data;\r
240\r
241 Status = PopStack (\r
242 mCurrentExpressionStack,\r
243 &mCurrentExpressionPointer,\r
244 &Data\r
245 );\r
246\r
247 *Pointer = (VOID *) (UINTN) Data.Value.u64;\r
248\r
249 return Status;\r
250}\r
251\r
252/**\r
253 Reset stack pointer to begin of the stack.\r
254\r
255**/\r
256VOID\r
257ResetMapExpressionListStack (\r
258 VOID\r
259 )\r
260{\r
261 mMapExpressionListPointer = mMapExpressionListStack;\r
262}\r
263\r
264\r
265/**\r
266 Push the list of map expression onto the Stack\r
267\r
268 @param Pointer Pointer to the list of map expression to be pushed.\r
269\r
270 @retval EFI_SUCCESS The value was pushed onto the stack.\r
271 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
272\r
273**/\r
274EFI_STATUS\r
275PushMapExpressionList (\r
276 IN VOID *Pointer\r
277 )\r
278{\r
279 EFI_HII_VALUE Data;\r
280\r
281 Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
282 Data.Value.u64 = (UINT64) (UINTN) Pointer;\r
283\r
284 return PushStack (\r
285 &mMapExpressionListStack,\r
286 &mMapExpressionListPointer,\r
287 &mMapExpressionListEnd,\r
288 &Data\r
289 );\r
290}\r
291\r
292\r
293/**\r
294 Pop the list of map expression from the Stack\r
295\r
296 @param Pointer Pointer to the list of map expression to be pop.\r
297\r
298 @retval EFI_SUCCESS The value was pushed onto the stack.\r
299 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.\r
300\r
301**/\r
302EFI_STATUS\r
303PopMapExpressionList (\r
304 OUT VOID **Pointer\r
305 )\r
306{\r
307 EFI_STATUS Status;\r
308 EFI_HII_VALUE Data;\r
309\r
310 Status = PopStack (\r
311 mMapExpressionListStack,\r
312 &mMapExpressionListPointer,\r
313 &Data\r
314 );\r
315\r
316 *Pointer = (VOID *) (UINTN) Data.Value.u64;\r
317\r
318 return Status;\r
319}\r
320\r
7936fb6a 321/**\r
322 Reset stack pointer to begin of the stack.\r
323\r
324**/\r
325VOID\r
326ResetScopeStack (\r
327 VOID\r
328 )\r
329{\r
330 mOpCodeScopeStackPointer = mOpCodeScopeStack;\r
331}\r
332\r
333\r
334/**\r
335 Push an Operand onto the Stack\r
336\r
337 @param Operand Operand to push.\r
338\r
339 @retval EFI_SUCCESS The value was pushed onto the stack.\r
340 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
341 stack.\r
342\r
343**/\r
344EFI_STATUS\r
345PushScope (\r
346 IN UINT8 Operand\r
347 )\r
348{\r
349 EFI_HII_VALUE Data;\r
350\r
351 Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
352 Data.Value.u8 = Operand;\r
353\r
354 return PushStack (\r
355 &mOpCodeScopeStack,\r
356 &mOpCodeScopeStackPointer,\r
357 &mOpCodeScopeStackEnd,\r
358 &Data\r
359 );\r
360}\r
361\r
362\r
363/**\r
364 Pop an Operand from the Stack\r
365\r
366 @param Operand Operand to pop.\r
367\r
368 @retval EFI_SUCCESS The value was pushed onto the stack.\r
369 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
370 stack.\r
371\r
372**/\r
373EFI_STATUS\r
374PopScope (\r
375 OUT UINT8 *Operand\r
376 )\r
377{\r
378 EFI_STATUS Status;\r
379 EFI_HII_VALUE Data;\r
380\r
381 Status = PopStack (\r
2573712e 382 mOpCodeScopeStack,\r
7936fb6a 383 &mOpCodeScopeStackPointer,\r
7936fb6a 384 &Data\r
385 );\r
386\r
387 *Operand = Data.Value.u8;\r
388\r
389 return Status;\r
390}\r
391\r
392\r
7936fb6a 393/**\r
394 Push an Expression value onto the Stack\r
395\r
396 @param Value Expression value to push.\r
397\r
398 @retval EFI_SUCCESS The value was pushed onto the stack.\r
399 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
400 stack.\r
401\r
402**/\r
403EFI_STATUS\r
404PushExpression (\r
405 IN EFI_HII_VALUE *Value\r
406 )\r
407{\r
408 return PushStack (\r
409 &mExpressionEvaluationStack,\r
410 &mExpressionEvaluationStackPointer,\r
411 &mExpressionEvaluationStackEnd,\r
412 Value\r
413 );\r
414}\r
415\r
416\r
417/**\r
418 Pop an Expression value from the stack.\r
419\r
420 @param Value Expression value to pop.\r
421\r
422 @retval EFI_SUCCESS The value was popped onto the stack.\r
423 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
424\r
425**/\r
426EFI_STATUS\r
427PopExpression (\r
428 OUT EFI_HII_VALUE *Value\r
429 )\r
430{\r
431 return PopStack (\r
2573712e 432 mExpressionEvaluationStack + mExpressionEvaluationStackOffset,\r
7936fb6a 433 &mExpressionEvaluationStackPointer,\r
7936fb6a 434 Value\r
435 );\r
436}\r
437\r
2573712e
LG
438/**\r
439 Get current stack offset from stack start.\r
440\r
441 @return Stack offset to stack start.\r
442**/\r
443UINTN\r
444SaveExpressionEvaluationStackOffset (\r
445 )\r
446{\r
447 UINTN TempStackOffset;\r
448 TempStackOffset = mExpressionEvaluationStackOffset;\r
449 mExpressionEvaluationStackOffset = mExpressionEvaluationStackPointer - mExpressionEvaluationStack;\r
450 return TempStackOffset;\r
451}\r
452\r
453/**\r
454 Restore stack offset based on input stack offset\r
455\r
456 @param StackOffset Offset to stack start.\r
457\r
458**/\r
459VOID\r
460RestoreExpressionEvaluationStackOffset (\r
461 UINTN StackOffset\r
462 )\r
463{\r
464 mExpressionEvaluationStackOffset = StackOffset;\r
465}\r
7936fb6a 466\r
467/**\r
468 Get Form given its FormId.\r
469\r
470 @param FormSet The formset which contains this form.\r
471 @param FormId Id of this form.\r
472\r
473 @retval Pointer The form.\r
474 @retval NULL Specified Form is not found in the formset.\r
475\r
476**/\r
477FORM_BROWSER_FORM *\r
478IdToForm (\r
479 IN FORM_BROWSER_FORMSET *FormSet,\r
480 IN UINT16 FormId\r
481)\r
482{\r
483 LIST_ENTRY *Link;\r
484 FORM_BROWSER_FORM *Form;\r
485\r
486 Link = GetFirstNode (&FormSet->FormListHead);\r
487 while (!IsNull (&FormSet->FormListHead, Link)) {\r
488 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
489\r
490 if (Form->FormId == FormId) {\r
491 return Form;\r
492 }\r
493\r
494 Link = GetNextNode (&FormSet->FormListHead, Link);\r
495 }\r
496\r
497 return NULL;\r
498}\r
499\r
500\r
501/**\r
502 Search a Question in Form scope using its QuestionId.\r
503\r
504 @param Form The form which contains this Question.\r
505 @param QuestionId Id of this Question.\r
506\r
507 @retval Pointer The Question.\r
508 @retval NULL Specified Question not found in the form.\r
509\r
510**/\r
511FORM_BROWSER_STATEMENT *\r
512IdToQuestion2 (\r
513 IN FORM_BROWSER_FORM *Form,\r
514 IN UINT16 QuestionId\r
515 )\r
516{\r
517 LIST_ENTRY *Link;\r
518 FORM_BROWSER_STATEMENT *Question;\r
519\r
520 if (QuestionId == 0) {\r
521 //\r
522 // The value of zero is reserved\r
523 //\r
524 return NULL;\r
525 }\r
526\r
527 Link = GetFirstNode (&Form->StatementListHead);\r
528 while (!IsNull (&Form->StatementListHead, Link)) {\r
529 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
530\r
531 if (Question->QuestionId == QuestionId) {\r
532 return Question;\r
533 }\r
534\r
535 Link = GetNextNode (&Form->StatementListHead, Link);\r
536 }\r
537\r
538 return NULL;\r
539}\r
540\r
541\r
542/**\r
543 Search a Question in Formset scope using its QuestionId.\r
544\r
545 @param FormSet The formset which contains this form.\r
546 @param Form The form which contains this Question.\r
547 @param QuestionId Id of this Question.\r
548\r
549 @retval Pointer The Question.\r
550 @retval NULL Specified Question not found in the form.\r
551\r
552**/\r
553FORM_BROWSER_STATEMENT *\r
554IdToQuestion (\r
555 IN FORM_BROWSER_FORMSET *FormSet,\r
556 IN FORM_BROWSER_FORM *Form,\r
557 IN UINT16 QuestionId\r
558 )\r
559{\r
560 LIST_ENTRY *Link;\r
561 FORM_BROWSER_STATEMENT *Question;\r
562\r
563 //\r
564 // Search in the form scope first\r
565 //\r
566 Question = IdToQuestion2 (Form, QuestionId);\r
567 if (Question != NULL) {\r
568 return Question;\r
569 }\r
570\r
571 //\r
572 // Search in the formset scope\r
573 //\r
574 Link = GetFirstNode (&FormSet->FormListHead);\r
575 while (!IsNull (&FormSet->FormListHead, Link)) {\r
576 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
577\r
578 Question = IdToQuestion2 (Form, QuestionId);\r
579 if (Question != NULL) {\r
8d00a0f1 580 //\r
581 // EFI variable storage may be updated by Callback() asynchronous,\r
582 // to keep synchronous, always reload the Question Value.\r
583 //\r
584 if (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
585 GetQuestionValue (FormSet, Form, Question, FALSE);\r
586 }\r
587\r
7936fb6a 588 return Question;\r
589 }\r
590\r
591 Link = GetNextNode (&FormSet->FormListHead, Link);\r
592 }\r
593\r
594 return NULL;\r
595}\r
596\r
597\r
598/**\r
599 Get Expression given its RuleId.\r
600\r
601 @param Form The form which contains this Expression.\r
602 @param RuleId Id of this Expression.\r
603\r
604 @retval Pointer The Expression.\r
605 @retval NULL Specified Expression not found in the form.\r
606\r
607**/\r
608FORM_EXPRESSION *\r
609RuleIdToExpression (\r
610 IN FORM_BROWSER_FORM *Form,\r
611 IN UINT8 RuleId\r
612 )\r
613{\r
614 LIST_ENTRY *Link;\r
615 FORM_EXPRESSION *Expression;\r
616\r
617 Link = GetFirstNode (&Form->ExpressionListHead);\r
618 while (!IsNull (&Form->ExpressionListHead, Link)) {\r
619 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
620\r
621 if (Expression->Type == EFI_HII_EXPRESSION_RULE && Expression->RuleId == RuleId) {\r
622 return Expression;\r
623 }\r
624\r
625 Link = GetNextNode (&Form->ExpressionListHead, Link);\r
626 }\r
627\r
628 return NULL;\r
629}\r
630\r
631\r
632/**\r
633 Locate the Unicode Collation Protocol interface for later use.\r
634\r
635 @retval EFI_SUCCESS Protocol interface initialize success.\r
636 @retval Other Protocol interface initialize failed.\r
637\r
638**/\r
639EFI_STATUS\r
640InitializeUnicodeCollationProtocol (\r
641 VOID\r
642 )\r
643{\r
644 EFI_STATUS Status;\r
645\r
646 if (mUnicodeCollation != NULL) {\r
647 return EFI_SUCCESS;\r
648 }\r
649\r
650 //\r
651 // BUGBUG: Proper impelmentation is to locate all Unicode Collation Protocol\r
652 // instances first and then select one which support English language.\r
653 // Current implementation just pick the first instance.\r
654 //\r
655 Status = gBS->LocateProtocol (\r
656 &gEfiUnicodeCollation2ProtocolGuid,\r
657 NULL,\r
658 (VOID **) &mUnicodeCollation\r
659 );\r
660 return Status;\r
661}\r
662\r
663/**\r
664 Convert the input Unicode character to upper.\r
665\r
666 @param String Th Unicode character to be converted.\r
667\r
668**/\r
669VOID\r
670IfrStrToUpper (\r
8b0fc5c1 671 IN CHAR16 *String\r
7936fb6a 672 )\r
673{\r
674 while (*String != 0) {\r
675 if ((*String >= 'a') && (*String <= 'z')) {\r
676 *String = (UINT16) ((*String) & ((UINT16) ~0x20));\r
677 }\r
678 String++;\r
679 }\r
680}\r
681\r
682\r
683/**\r
684 Evaluate opcode EFI_IFR_TO_STRING.\r
685\r
686 @param FormSet Formset which contains this opcode.\r
687 @param Format String format in EFI_IFR_TO_STRING.\r
688 @param Result Evaluation result for this opcode.\r
689\r
690 @retval EFI_SUCCESS Opcode evaluation success.\r
691 @retval Other Opcode evaluation failed.\r
692\r
693**/\r
694EFI_STATUS\r
695IfrToString (\r
696 IN FORM_BROWSER_FORMSET *FormSet,\r
697 IN UINT8 Format,\r
698 OUT EFI_HII_VALUE *Result\r
699 )\r
700{\r
701 EFI_STATUS Status;\r
702 EFI_HII_VALUE Value;\r
703 CHAR16 *String;\r
704 CHAR16 *PrintFormat;\r
705 CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];\r
706 UINTN BufferSize;\r
707\r
708 Status = PopExpression (&Value);\r
709 if (EFI_ERROR (Status)) {\r
710 return Status;\r
711 }\r
712\r
713 switch (Value.Type) {\r
714 case EFI_IFR_TYPE_NUM_SIZE_8:\r
715 case EFI_IFR_TYPE_NUM_SIZE_16:\r
716 case EFI_IFR_TYPE_NUM_SIZE_32:\r
717 case EFI_IFR_TYPE_NUM_SIZE_64:\r
718 BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16);\r
719 switch (Format) {\r
720 case EFI_IFR_STRING_UNSIGNED_DEC:\r
721 case EFI_IFR_STRING_SIGNED_DEC:\r
722 PrintFormat = L"%ld";\r
723 break;\r
724\r
725 case EFI_IFR_STRING_LOWERCASE_HEX:\r
726 PrintFormat = L"%lx";\r
727 break;\r
728\r
729 case EFI_IFR_STRING_UPPERCASE_HEX:\r
730 PrintFormat = L"%lX";\r
731 break;\r
732\r
733 default:\r
734 return EFI_UNSUPPORTED;\r
735 }\r
736 UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);\r
737 String = Buffer;\r
738 break;\r
739\r
740 case EFI_IFR_TYPE_STRING:\r
741 CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
742 return EFI_SUCCESS;\r
743\r
744 case EFI_IFR_TYPE_BOOLEAN:\r
745 String = (Value.Value.b) ? L"True" : L"False";\r
746 break;\r
747\r
748 default:\r
749 return EFI_UNSUPPORTED;\r
750 }\r
751\r
752 Result->Type = EFI_IFR_TYPE_STRING;\r
753 Result->Value.string = NewString (String, FormSet->HiiHandle);\r
754 return EFI_SUCCESS;\r
755}\r
756\r
757\r
758/**\r
759 Evaluate opcode EFI_IFR_TO_UINT.\r
760\r
761 @param FormSet Formset which contains this opcode.\r
762 @param Result Evaluation result for this opcode.\r
763\r
764 @retval EFI_SUCCESS Opcode evaluation success.\r
765 @retval Other Opcode evaluation failed.\r
766\r
767**/\r
768EFI_STATUS\r
769IfrToUint (\r
770 IN FORM_BROWSER_FORMSET *FormSet,\r
771 OUT EFI_HII_VALUE *Result\r
772 )\r
773{\r
774 EFI_STATUS Status;\r
775 EFI_HII_VALUE Value;\r
776 CHAR16 *String;\r
777 CHAR16 *StringPtr;\r
7936fb6a 778\r
779 Status = PopExpression (&Value);\r
780 if (EFI_ERROR (Status)) {\r
781 return Status;\r
782 }\r
783\r
784 if (Value.Type >= EFI_IFR_TYPE_OTHER) {\r
785 return EFI_UNSUPPORTED;\r
786 }\r
787\r
788 Status = EFI_SUCCESS;\r
789 if (Value.Type == EFI_IFR_TYPE_STRING) {\r
790 String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
791 if (String == NULL) {\r
792 return EFI_NOT_FOUND;\r
793 }\r
8b0fc5c1 794\r
7936fb6a 795 IfrStrToUpper (String);\r
796 StringPtr = StrStr (String, L"0X");\r
797 if (StringPtr != NULL) {\r
798 //\r
799 // Hex string\r
800 //\r
ac7e320c 801 Result->Value.u64 = StrHexToUint64 (String);\r
7936fb6a 802 } else {\r
803 //\r
ac7e320c 804 // decimal string\r
7936fb6a 805 //\r
ac7e320c 806 Result->Value.u64 = StrDecimalToUint64 (String);\r
7936fb6a 807 }\r
f4113e1f 808 FreePool (String);\r
7936fb6a 809 } else {\r
810 CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));\r
811 }\r
812\r
813 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
814 return Status;\r
815}\r
816\r
817\r
818/**\r
819 Evaluate opcode EFI_IFR_CATENATE.\r
820\r
821 @param FormSet Formset which contains this opcode.\r
822 @param Result Evaluation result for this opcode.\r
823\r
824 @retval EFI_SUCCESS Opcode evaluation success.\r
825 @retval Other Opcode evaluation failed.\r
826\r
827**/\r
828EFI_STATUS\r
829IfrCatenate (\r
830 IN FORM_BROWSER_FORMSET *FormSet,\r
831 OUT EFI_HII_VALUE *Result\r
832 )\r
833{\r
834 EFI_STATUS Status;\r
835 EFI_HII_VALUE Value;\r
836 CHAR16 *String[2];\r
837 UINTN Index;\r
838 CHAR16 *StringPtr;\r
839 UINTN Size;\r
840\r
841 //\r
842 // String[0] - The second string\r
843 // String[1] - The first string\r
844 //\r
845 String[0] = NULL;\r
846 String[1] = NULL;\r
847 StringPtr = NULL;\r
848 Status = EFI_SUCCESS;\r
849\r
850 for (Index = 0; Index < 2; Index++) {\r
851 Status = PopExpression (&Value);\r
852 if (EFI_ERROR (Status)) {\r
853 goto Done;\r
854 }\r
855\r
856 if (Value.Type != EFI_IFR_TYPE_STRING) {\r
857 Status = EFI_UNSUPPORTED;\r
858 goto Done;\r
859 }\r
860\r
861 String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
d0720b57 862 if (String[Index] == NULL) {\r
7936fb6a 863 Status = EFI_NOT_FOUND;\r
864 goto Done;\r
865 }\r
866 }\r
867\r
868 Size = StrSize (String[0]);\r
869 StringPtr= AllocatePool (StrSize (String[1]) + Size);\r
870 ASSERT (StringPtr != NULL);\r
871 StrCpy (StringPtr, String[1]);\r
872 StrCat (StringPtr, String[0]);\r
873\r
874 Result->Type = EFI_IFR_TYPE_STRING;\r
875 Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);\r
876\r
877Done:\r
676df92c 878 if (String[0] != NULL) {\r
879 FreePool (String[0]);\r
880 }\r
881 if (String[1] != NULL) {\r
882 FreePool (String[1]);\r
8b0fc5c1 883 }\r
676df92c 884 if (StringPtr != NULL) {\r
885 FreePool (StringPtr);\r
886 }\r
7936fb6a 887\r
888 return Status;\r
889}\r
890\r
891\r
892/**\r
893 Evaluate opcode EFI_IFR_MATCH.\r
894\r
895 @param FormSet Formset which contains this opcode.\r
896 @param Result Evaluation result for this opcode.\r
897\r
898 @retval EFI_SUCCESS Opcode evaluation success.\r
899 @retval Other Opcode evaluation failed.\r
900\r
901**/\r
902EFI_STATUS\r
903IfrMatch (\r
904 IN FORM_BROWSER_FORMSET *FormSet,\r
905 OUT EFI_HII_VALUE *Result\r
906 )\r
907{\r
908 EFI_STATUS Status;\r
909 EFI_HII_VALUE Value;\r
910 CHAR16 *String[2];\r
911 UINTN Index;\r
912\r
913 //\r
914 // String[0] - The string to search\r
915 // String[1] - pattern\r
916 //\r
917 String[0] = NULL;\r
918 String[1] = NULL;\r
919 Status = EFI_SUCCESS;\r
920 for (Index = 0; Index < 2; Index++) {\r
921 Status = PopExpression (&Value);\r
922 if (EFI_ERROR (Status)) {\r
923 goto Done;\r
924 }\r
925\r
926 if (Value.Type != EFI_IFR_TYPE_STRING) {\r
927 Status = EFI_UNSUPPORTED;\r
928 goto Done;\r
929 }\r
930\r
931 String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
bc166db3 932 if (String [Index] == NULL) {\r
7936fb6a 933 Status = EFI_NOT_FOUND;\r
934 goto Done;\r
935 }\r
936 }\r
937\r
938 Result->Type = EFI_IFR_TYPE_BOOLEAN;\r
939 Result->Value.b = mUnicodeCollation->MetaiMatch (mUnicodeCollation, String[0], String[1]);\r
940\r
941Done:\r
676df92c 942 if (String[0] != NULL) {\r
943 FreePool (String[0]);\r
944 }\r
945 if (String[1] != NULL) {\r
946 FreePool (String[1]);\r
8b0fc5c1 947 }\r
7936fb6a 948\r
949 return Status;\r
950}\r
951\r
952\r
953/**\r
954 Evaluate opcode EFI_IFR_FIND.\r
955\r
956 @param FormSet Formset which contains this opcode.\r
957 @param Format Case sensitive or insensitive.\r
958 @param Result Evaluation result for this opcode.\r
959\r
960 @retval EFI_SUCCESS Opcode evaluation success.\r
961 @retval Other Opcode evaluation failed.\r
962\r
963**/\r
964EFI_STATUS\r
965IfrFind (\r
966 IN FORM_BROWSER_FORMSET *FormSet,\r
967 IN UINT8 Format,\r
968 OUT EFI_HII_VALUE *Result\r
969 )\r
970{\r
971 EFI_STATUS Status;\r
972 EFI_HII_VALUE Value;\r
973 CHAR16 *String[2];\r
974 UINTN Base;\r
975 CHAR16 *StringPtr;\r
976 UINTN Index;\r
977\r
978 if (Format > EFI_IFR_FF_CASE_INSENSITIVE) {\r
979 return EFI_UNSUPPORTED;\r
980 }\r
981\r
982 Status = PopExpression (&Value);\r
983 if (EFI_ERROR (Status)) {\r
984 return Status;\r
985 }\r
986 if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
987 return EFI_UNSUPPORTED;\r
988 }\r
989 Base = (UINTN) Value.Value.u64;\r
990\r
991 //\r
992 // String[0] - sub-string\r
993 // String[1] - The string to search\r
994 //\r
995 String[0] = NULL;\r
996 String[1] = NULL;\r
997 for (Index = 0; Index < 2; Index++) {\r
998 Status = PopExpression (&Value);\r
999 if (EFI_ERROR (Status)) {\r
1000 goto Done;\r
1001 }\r
1002\r
1003 if (Value.Type != EFI_IFR_TYPE_STRING) {\r
1004 Status = EFI_UNSUPPORTED;\r
1005 goto Done;\r
1006 }\r
1007\r
1008 String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
d0720b57 1009 if (String[Index] == NULL) {\r
7936fb6a 1010 Status = EFI_NOT_FOUND;\r
1011 goto Done;\r
1012 }\r
1013\r
1014 if (Format == EFI_IFR_FF_CASE_INSENSITIVE) {\r
1015 //\r
1016 // Case insensitive, convert both string to upper case\r
1017 //\r
1018 IfrStrToUpper (String[Index]);\r
1019 }\r
1020 }\r
1021\r
1022 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1023 if (Base >= StrLen (String[1])) {\r
1024 Result->Value.u64 = 0xFFFFFFFFFFFFFFFFULL;\r
1025 } else {\r
1026 StringPtr = StrStr (String[1] + Base, String[0]);\r
1027 Result->Value.u64 = (StringPtr == NULL) ? 0xFFFFFFFFFFFFFFFFULL : (StringPtr - String[1]);\r
1028 }\r
1029\r
1030Done:\r
676df92c 1031 if (String[0] != NULL) {\r
1032 FreePool (String[0]);\r
1033 }\r
1034 if (String[1] != NULL) {\r
1035 FreePool (String[1]);\r
8b0fc5c1 1036 }\r
7936fb6a 1037\r
1038 return Status;\r
1039}\r
1040\r
1041\r
1042/**\r
1043 Evaluate opcode EFI_IFR_MID.\r
1044\r
1045 @param FormSet Formset which contains this opcode.\r
1046 @param Result Evaluation result for this opcode.\r
1047\r
1048 @retval EFI_SUCCESS Opcode evaluation success.\r
1049 @retval Other Opcode evaluation failed.\r
1050\r
1051**/\r
1052EFI_STATUS\r
1053IfrMid (\r
1054 IN FORM_BROWSER_FORMSET *FormSet,\r
1055 OUT EFI_HII_VALUE *Result\r
1056 )\r
1057{\r
1058 EFI_STATUS Status;\r
1059 EFI_HII_VALUE Value;\r
1060 CHAR16 *String;\r
1061 UINTN Base;\r
1062 UINTN Length;\r
1063 CHAR16 *SubString;\r
1064\r
1065 Status = PopExpression (&Value);\r
1066 if (EFI_ERROR (Status)) {\r
1067 return Status;\r
1068 }\r
1069 if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
1070 return EFI_UNSUPPORTED;\r
1071 }\r
1072 Length = (UINTN) Value.Value.u64;\r
1073\r
1074 Status = PopExpression (&Value);\r
1075 if (EFI_ERROR (Status)) {\r
1076 return Status;\r
1077 }\r
1078 if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
1079 return EFI_UNSUPPORTED;\r
1080 }\r
1081 Base = (UINTN) Value.Value.u64;\r
1082\r
1083 Status = PopExpression (&Value);\r
1084 if (EFI_ERROR (Status)) {\r
1085 return Status;\r
1086 }\r
1087 if (Value.Type != EFI_IFR_TYPE_STRING) {\r
1088 return EFI_UNSUPPORTED;\r
1089 }\r
1090 String = GetToken (Value.Value.string, FormSet->HiiHandle);\r
1091 if (String == NULL) {\r
1092 return EFI_NOT_FOUND;\r
1093 }\r
1094\r
1095 if (Length == 0 || Base >= StrLen (String)) {\r
1096 SubString = gEmptyString;\r
1097 } else {\r
1098 SubString = String + Base;\r
1099 if ((Base + Length) < StrLen (String)) {\r
1100 SubString[Length] = L'\0';\r
1101 }\r
1102 }\r
1103\r
1104 Result->Type = EFI_IFR_TYPE_STRING;\r
1105 Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
1106\r
f4113e1f 1107 FreePool (String);\r
7936fb6a 1108\r
1109 return Status;\r
1110}\r
1111\r
1112\r
1113/**\r
1114 Evaluate opcode EFI_IFR_TOKEN.\r
1115\r
1116 @param FormSet Formset which contains this opcode.\r
1117 @param Result Evaluation result for this opcode.\r
1118\r
1119 @retval EFI_SUCCESS Opcode evaluation success.\r
1120 @retval Other Opcode evaluation failed.\r
1121\r
1122**/\r
1123EFI_STATUS\r
1124IfrToken (\r
1125 IN FORM_BROWSER_FORMSET *FormSet,\r
1126 OUT EFI_HII_VALUE *Result\r
1127 )\r
1128{\r
1129 EFI_STATUS Status;\r
1130 EFI_HII_VALUE Value;\r
1131 CHAR16 *String[2];\r
1132 UINTN Count;\r
1133 CHAR16 *Delimiter;\r
1134 CHAR16 *SubString;\r
1135 CHAR16 *StringPtr;\r
1136 UINTN Index;\r
1137\r
1138 Status = PopExpression (&Value);\r
1139 if (EFI_ERROR (Status)) {\r
1140 return Status;\r
1141 }\r
1142 if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
1143 return EFI_UNSUPPORTED;\r
1144 }\r
1145 Count = (UINTN) Value.Value.u64;\r
1146\r
1147 //\r
1148 // String[0] - Delimiter\r
1149 // String[1] - The string to search\r
1150 //\r
1151 String[0] = NULL;\r
1152 String[1] = NULL;\r
1153 for (Index = 0; Index < 2; Index++) {\r
1154 Status = PopExpression (&Value);\r
1155 if (EFI_ERROR (Status)) {\r
1156 goto Done;\r
1157 }\r
1158\r
1159 if (Value.Type != EFI_IFR_TYPE_STRING) {\r
1160 Status = EFI_UNSUPPORTED;\r
1161 goto Done;\r
1162 }\r
1163\r
1164 String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
d0720b57 1165 if (String[Index] == NULL) {\r
7936fb6a 1166 Status = EFI_NOT_FOUND;\r
1167 goto Done;\r
1168 }\r
1169 }\r
1170\r
1171 Delimiter = String[0];\r
1172 SubString = String[1];\r
1173 while (Count > 0) {\r
1174 SubString = StrStr (SubString, Delimiter);\r
1175 if (SubString != NULL) {\r
1176 //\r
1177 // Skip over the delimiter\r
1178 //\r
1179 SubString = SubString + StrLen (Delimiter);\r
1180 } else {\r
1181 break;\r
1182 }\r
1183 Count--;\r
1184 }\r
1185\r
1186 if (SubString == NULL) {\r
1187 //\r
1188 // nth delimited sub-string not found, push an empty string\r
1189 //\r
1190 SubString = gEmptyString;\r
1191 } else {\r
1192 //\r
1193 // Put a NULL terminator for nth delimited sub-string\r
1194 //\r
1195 StringPtr = StrStr (SubString, Delimiter);\r
1196 if (StringPtr != NULL) {\r
1197 *StringPtr = L'\0';\r
1198 }\r
1199 }\r
1200\r
1201 Result->Type = EFI_IFR_TYPE_STRING;\r
1202 Result->Value.string = NewString (SubString, FormSet->HiiHandle);\r
1203\r
1204Done:\r
676df92c 1205 if (String[0] != NULL) {\r
1206 FreePool (String[0]);\r
1207 }\r
1208 if (String[1] != NULL) {\r
1209 FreePool (String[1]);\r
8b0fc5c1 1210 }\r
7936fb6a 1211\r
1212 return Status;\r
1213}\r
1214\r
1215\r
1216/**\r
1217 Evaluate opcode EFI_IFR_SPAN.\r
1218\r
1219 @param FormSet Formset which contains this opcode.\r
1220 @param Flags FIRST_MATCHING or FIRST_NON_MATCHING.\r
1221 @param Result Evaluation result for this opcode.\r
1222\r
1223 @retval EFI_SUCCESS Opcode evaluation success.\r
1224 @retval Other Opcode evaluation failed.\r
1225\r
1226**/\r
1227EFI_STATUS\r
1228IfrSpan (\r
1229 IN FORM_BROWSER_FORMSET *FormSet,\r
1230 IN UINT8 Flags,\r
1231 OUT EFI_HII_VALUE *Result\r
1232 )\r
1233{\r
1234 EFI_STATUS Status;\r
1235 EFI_HII_VALUE Value;\r
1236 CHAR16 *String[2];\r
1237 CHAR16 *Charset;\r
1238 UINTN Base;\r
1239 UINTN Index;\r
1240 CHAR16 *StringPtr;\r
1241 BOOLEAN Found;\r
1242\r
1243 Status = PopExpression (&Value);\r
1244 if (EFI_ERROR (Status)) {\r
1245 return Status;\r
1246 }\r
1247 if (Value.Type > EFI_IFR_TYPE_NUM_SIZE_64) {\r
1248 return EFI_UNSUPPORTED;\r
1249 }\r
1250 Base = (UINTN) Value.Value.u64;\r
1251\r
1252 //\r
1253 // String[0] - Charset\r
1254 // String[1] - The string to search\r
1255 //\r
1256 String[0] = NULL;\r
1257 String[1] = NULL;\r
1258 for (Index = 0; Index < 2; Index++) {\r
1259 Status = PopExpression (&Value);\r
1260 if (EFI_ERROR (Status)) {\r
1261 goto Done;\r
1262 }\r
1263\r
1264 if (Value.Type != EFI_IFR_TYPE_STRING) {\r
1265 Status = EFI_UNSUPPORTED;\r
1266 goto Done;\r
1267 }\r
1268\r
1269 String[Index] = GetToken (Value.Value.string, FormSet->HiiHandle);\r
bc166db3 1270 if (String [Index] == NULL) {\r
7936fb6a 1271 Status = EFI_NOT_FOUND;\r
1272 goto Done;\r
1273 }\r
1274 }\r
1275\r
1276 if (Base >= StrLen (String[1])) {\r
1277 Status = EFI_UNSUPPORTED;\r
1278 goto Done;\r
1279 }\r
1280\r
1281 Found = FALSE;\r
1282 StringPtr = String[1] + Base;\r
1283 Charset = String[0];\r
1284 while (*StringPtr != 0 && !Found) {\r
1285 Index = 0;\r
1286 while (Charset[Index] != 0) {\r
1287 if (*StringPtr >= Charset[Index] && *StringPtr <= Charset[Index + 1]) {\r
1288 if (Flags == EFI_IFR_FLAGS_FIRST_MATCHING) {\r
1289 Found = TRUE;\r
1290 break;\r
1291 }\r
1292 } else {\r
1293 if (Flags == EFI_IFR_FLAGS_FIRST_NON_MATCHING) {\r
1294 Found = TRUE;\r
1295 break;\r
1296 }\r
1297 }\r
1298 //\r
1299 // Skip characters pair representing low-end of a range and high-end of a range\r
1300 //\r
1301 Index += 2;\r
1302 }\r
1303\r
1304 if (!Found) {\r
1305 StringPtr++;\r
1306 }\r
1307 }\r
1308\r
1309 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1310 Result->Value.u64 = StringPtr - String[1];\r
1311\r
1312Done:\r
676df92c 1313 if (String[0] != NULL) {\r
1314 FreePool (String[0]);\r
1315 }\r
1316 if (String[1] != NULL) {\r
1317 FreePool (String[1]);\r
8b0fc5c1 1318 }\r
7936fb6a 1319\r
1320 return Status;\r
1321}\r
1322\r
1323\r
1324/**\r
1325 Zero extend integer/boolean/date/time to UINT64 for comparing.\r
1326\r
1327 @param Value HII Value to be converted.\r
1328\r
1329**/\r
1330VOID\r
1331ExtendValueToU64 (\r
1332 IN EFI_HII_VALUE *Value\r
1333 )\r
1334{\r
1335 UINT64 Temp;\r
1336\r
1337 Temp = 0;\r
1338 switch (Value->Type) {\r
1339 case EFI_IFR_TYPE_NUM_SIZE_8:\r
1340 Temp = Value->Value.u8;\r
1341 break;\r
1342\r
1343 case EFI_IFR_TYPE_NUM_SIZE_16:\r
1344 Temp = Value->Value.u16;\r
1345 break;\r
1346\r
1347 case EFI_IFR_TYPE_NUM_SIZE_32:\r
1348 Temp = Value->Value.u32;\r
1349 break;\r
1350\r
1351 case EFI_IFR_TYPE_BOOLEAN:\r
1352 Temp = Value->Value.b;\r
1353 break;\r
1354\r
1355 case EFI_IFR_TYPE_TIME:\r
1356 Temp = Value->Value.u32 & 0xffffff;\r
1357 break;\r
1358\r
1359 case EFI_IFR_TYPE_DATE:\r
1360 Temp = Value->Value.u32;\r
1361 break;\r
1362\r
1363 default:\r
1364 return;\r
1365 }\r
1366\r
1367 Value->Value.u64 = Temp;\r
1368}\r
1369\r
1370\r
1371/**\r
1372 Compare two Hii value.\r
1373\r
1374 @param Value1 Expression value to compare on left-hand.\r
1375 @param Value2 Expression value to compare on right-hand.\r
1376 @param HiiHandle Only required for string compare.\r
1377\r
2573712e
LG
1378 @retval EFI_INVALID_PARAMETER Could not perform compare on two values.\r
1379 @retval 0 Two operators equal.\r
7936fb6a 1380 @return Positive value if Value1 is greater than Value2.\r
1381 @retval Negative value if Value1 is less than Value2.\r
1382\r
1383**/\r
1384INTN\r
1385CompareHiiValue (\r
1386 IN EFI_HII_VALUE *Value1,\r
1387 IN EFI_HII_VALUE *Value2,\r
1388 IN EFI_HII_HANDLE HiiHandle OPTIONAL\r
1389 )\r
1390{\r
1391 INTN Result;\r
1392 INT64 Temp64;\r
1393 CHAR16 *Str1;\r
1394 CHAR16 *Str2;\r
1395\r
1396 if (Value1->Type >= EFI_IFR_TYPE_OTHER || Value2->Type >= EFI_IFR_TYPE_OTHER ) {\r
1397 return EFI_INVALID_PARAMETER;\r
1398 }\r
1399\r
1400 if (Value1->Type == EFI_IFR_TYPE_STRING || Value2->Type == EFI_IFR_TYPE_STRING ) {\r
1401 if (Value1->Type != Value2->Type) {\r
1402 //\r
1403 // Both Operator should be type of String\r
1404 //\r
1405 return EFI_INVALID_PARAMETER;\r
1406 }\r
1407\r
1408 if (Value1->Value.string == 0 || Value2->Value.string == 0) {\r
1409 //\r
1410 // StringId 0 is reserved\r
1411 //\r
1412 return EFI_INVALID_PARAMETER;\r
1413 }\r
1414\r
1415 if (Value1->Value.string == Value2->Value.string) {\r
1416 return 0;\r
1417 }\r
1418\r
1419 Str1 = GetToken (Value1->Value.string, HiiHandle);\r
1420 if (Str1 == NULL) {\r
1421 //\r
1422 // String not found\r
1423 //\r
1424 return EFI_INVALID_PARAMETER;\r
1425 }\r
1426\r
1427 Str2 = GetToken (Value2->Value.string, HiiHandle);\r
1428 if (Str2 == NULL) {\r
f4113e1f 1429 FreePool (Str1);\r
7936fb6a 1430 return EFI_INVALID_PARAMETER;\r
1431 }\r
1432\r
1433 Result = StrCmp (Str1, Str2);\r
1434\r
f4113e1f 1435 FreePool (Str1);\r
1436 FreePool (Str2);\r
7936fb6a 1437\r
1438 return Result;\r
1439 }\r
1440\r
1441 //\r
1442 // Take remain types(integer, boolean, date/time) as integer\r
1443 //\r
1444 Temp64 = (INT64) (Value1->Value.u64 - Value2->Value.u64);\r
1445 if (Temp64 > 0) {\r
1446 Result = 1;\r
1447 } else if (Temp64 < 0) {\r
1448 Result = -1;\r
1449 } else {\r
1450 Result = 0;\r
1451 }\r
1452\r
1453 return Result;\r
1454}\r
1455\r
cbf73e50 1456/**\r
1457 Check if current user has the privilege specified by the permissions GUID.\r
1458\r
1459 @param[in] Guid A GUID specifying setup access permissions.\r
1460\r
1461 @retval TRUE Current user has the privilege.\r
1462 @retval FALSE Current user does not have the privilege.\r
1463**/\r
1464BOOLEAN\r
1465CheckUserPrivilege (\r
1466 IN EFI_GUID *Guid\r
1467 )\r
1468{\r
1469 EFI_STATUS Status;\r
1470 EFI_USER_PROFILE_HANDLE UserProfileHandle;\r
1471 EFI_USER_INFO_HANDLE UserInfoHandle;\r
1472 EFI_USER_INFO *UserInfo;\r
1473 EFI_GUID *UserPermissionsGuid;\r
1474 UINTN UserInfoSize;\r
1475 UINTN AccessControlDataSize;\r
1476 EFI_USER_INFO_ACCESS_CONTROL *AccessControl;\r
1477 UINTN RemainSize;\r
1478\r
1479 if (mUserManager == NULL) {\r
1480 Status = gBS->LocateProtocol (\r
1481 &gEfiUserManagerProtocolGuid,\r
1482 NULL,\r
1483 (VOID **) &mUserManager\r
1484 );\r
1485 if (EFI_ERROR (Status)) {\r
1486 ///\r
1487 /// If the system does not support user management, then it is assumed that\r
1488 /// all users have admin privilege and evaluation of each EFI_IFR_SECURITY\r
1489 /// op-code is always TRUE.\r
1490 ///\r
1491 return TRUE;\r
1492 }\r
1493 }\r
1494\r
1495 Status = mUserManager->Current (mUserManager, &UserProfileHandle);\r
1496 ASSERT_EFI_ERROR (Status);\r
1497\r
1498 ///\r
1499 /// Enumerate all user information of the current user profile\r
1500 /// to look for any EFI_USER_INFO_ACCESS_SETUP record.\r
1501 ///\r
1502 \r
1503 for (UserInfoHandle = NULL;;) {\r
1504 Status = mUserManager->GetNextInfo (mUserManager, UserProfileHandle, &UserInfoHandle);\r
1505 if (EFI_ERROR (Status)) {\r
1506 break;\r
1507 }\r
1508\r
1509 UserInfoSize = 0;\r
1510 Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, NULL, &UserInfoSize);\r
1511 if (Status != EFI_BUFFER_TOO_SMALL) {\r
1512 continue;\r
1513 }\r
1514\r
1515 UserInfo = (EFI_USER_INFO *) AllocatePool (UserInfoSize);\r
1516 if (UserInfo == NULL) {\r
1517 break;\r
1518 }\r
1519\r
1520 Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, UserInfo, &UserInfoSize);\r
1521 if (EFI_ERROR (Status) ||\r
1522 UserInfo->InfoType != EFI_USER_INFO_ACCESS_POLICY_RECORD ||\r
1523 UserInfo->InfoSize <= sizeof (EFI_USER_INFO)) {\r
1524 FreePool (UserInfo);\r
1525 continue;\r
1526 }\r
1527\r
1528 RemainSize = UserInfo->InfoSize - sizeof (EFI_USER_INFO);\r
1529 AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)(UserInfo + 1);\r
1530 while (RemainSize >= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
3dd405be 1531 if (RemainSize < AccessControl->Size || AccessControl->Size < sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {\r
cbf73e50 1532 break;\r
1533 }\r
1534 if (AccessControl->Type == EFI_USER_INFO_ACCESS_SETUP) {\r
1535 ///\r
1536 /// Check if current user has the privilege specified by the permissions GUID.\r
1537 ///\r
1538\r
1539 UserPermissionsGuid = (EFI_GUID *)(AccessControl + 1);\r
1540 AccessControlDataSize = AccessControl->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);\r
1541 while (AccessControlDataSize >= sizeof (EFI_GUID)) {\r
1542 if (CompareGuid (Guid, UserPermissionsGuid)) {\r
1543 FreePool (UserInfo);\r
1544 return TRUE;\r
1545 }\r
1546 UserPermissionsGuid++;\r
1547 AccessControlDataSize -= sizeof (EFI_GUID);\r
1548 }\r
1549 }\r
1550 RemainSize -= AccessControl->Size;\r
1551 AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)((UINT8 *)AccessControl + AccessControl->Size);\r
1552 }\r
1553\r
1554 FreePool (UserInfo);\r
1555 }\r
1556 return FALSE;\r
1557}\r
7936fb6a 1558\r
1559/**\r
bc166db3 1560 Evaluate the result of a HII expression.\r
1561\r
1562 If Expression is NULL, then ASSERT.\r
7936fb6a 1563\r
1564 @param FormSet FormSet associated with this expression.\r
1565 @param Form Form associated with this expression.\r
1566 @param Expression Expression to be evaluated.\r
1567\r
1568 @retval EFI_SUCCESS The expression evaluated successfuly\r
1569 @retval EFI_NOT_FOUND The Question which referenced by a QuestionId\r
1570 could not be found.\r
1571 @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the\r
1572 stack.\r
1573 @retval EFI_ACCESS_DENIED The pop operation underflowed the stack\r
1574 @retval EFI_INVALID_PARAMETER Syntax error with the Expression\r
1575\r
1576**/\r
1577EFI_STATUS\r
1578EvaluateExpression (\r
1579 IN FORM_BROWSER_FORMSET *FormSet,\r
1580 IN FORM_BROWSER_FORM *Form,\r
1581 IN OUT FORM_EXPRESSION *Expression\r
1582 )\r
1583{\r
1584 EFI_STATUS Status;\r
1585 LIST_ENTRY *Link;\r
1586 EXPRESSION_OPCODE *OpCode;\r
1587 FORM_BROWSER_STATEMENT *Question;\r
1588 FORM_BROWSER_STATEMENT *Question2;\r
1589 UINT16 Index;\r
1590 EFI_HII_VALUE Data1;\r
1591 EFI_HII_VALUE Data2;\r
1592 EFI_HII_VALUE Data3;\r
1593 FORM_EXPRESSION *RuleExpression;\r
1594 EFI_HII_VALUE *Value;\r
1595 INTN Result;\r
1596 CHAR16 *StrPtr;\r
2573712e 1597 CHAR16 *NameValue;\r
7936fb6a 1598 UINT32 TempValue;\r
2573712e
LG
1599 LIST_ENTRY *SubExpressionLink;\r
1600 FORM_EXPRESSION *SubExpression;\r
1601 UINTN StackOffset;\r
1602 UINTN TempLength;\r
1603 CHAR16 TempStr[5];\r
1604 UINT8 DigitUint8;\r
1605 UINT8 *TempBuffer;\r
1606 EFI_TIME EfiTime;\r
7936fb6a 1607\r
1608 //\r
2573712e 1609 // Save current stack offset.\r
7936fb6a 1610 //\r
2573712e 1611 StackOffset = SaveExpressionEvaluationStackOffset ();\r
7936fb6a 1612\r
bc166db3 1613 ASSERT (Expression != NULL);\r
7936fb6a 1614 Expression->Result.Type = EFI_IFR_TYPE_OTHER;\r
1615\r
1616 Link = GetFirstNode (&Expression->OpCodeListHead);\r
1617 while (!IsNull (&Expression->OpCodeListHead, Link)) {\r
1618 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
1619\r
1620 Link = GetNextNode (&Expression->OpCodeListHead, Link);\r
1621\r
1622 ZeroMem (&Data1, sizeof (EFI_HII_VALUE));\r
1623 ZeroMem (&Data2, sizeof (EFI_HII_VALUE));\r
1624 ZeroMem (&Data3, sizeof (EFI_HII_VALUE));\r
1625\r
1626 Value = &Data3;\r
1627 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
1628 Status = EFI_SUCCESS;\r
1629\r
1630 switch (OpCode->Operand) {\r
1631 //\r
1632 // Built-in functions\r
1633 //\r
1634 case EFI_IFR_EQ_ID_VAL_OP:\r
1635 Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
1636 if (Question == NULL) {\r
2573712e
LG
1637 Status = EFI_NOT_FOUND;\r
1638 goto Done;\r
7936fb6a 1639 }\r
1640\r
1641 Result = CompareHiiValue (&Question->HiiValue, &OpCode->Value, NULL);\r
1642 if (Result == EFI_INVALID_PARAMETER) {\r
2573712e
LG
1643 Status = EFI_INVALID_PARAMETER;\r
1644 goto Done;\r
7936fb6a 1645 }\r
1646 Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
1647 break;\r
1648\r
1649 case EFI_IFR_EQ_ID_ID_OP:\r
1650 Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
1651 if (Question == NULL) {\r
2573712e
LG
1652 Status = EFI_NOT_FOUND;\r
1653 goto Done;\r
7936fb6a 1654 }\r
1655\r
1656 Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);\r
1657 if (Question2 == NULL) {\r
2573712e
LG
1658 Status = EFI_NOT_FOUND;\r
1659 goto Done;\r
7936fb6a 1660 }\r
1661\r
1662 Result = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, FormSet->HiiHandle);\r
1663 if (Result == EFI_INVALID_PARAMETER) {\r
2573712e
LG
1664 Status = EFI_INVALID_PARAMETER;\r
1665 goto Done;\r
7936fb6a 1666 }\r
1667 Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
1668 break;\r
1669\r
1670 case EFI_IFR_EQ_ID_LIST_OP:\r
1671 Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
1672 if (Question == NULL) {\r
2573712e
LG
1673 Status = EFI_NOT_FOUND;\r
1674 goto Done;\r
7936fb6a 1675 }\r
1676\r
1677 Value->Value.b = FALSE;\r
1678 for (Index =0; Index < OpCode->ListLength; Index++) {\r
1679 if (Question->HiiValue.Value.u16 == OpCode->ValueList[Index]) {\r
1680 Value->Value.b = TRUE;\r
1681 break;\r
1682 }\r
1683 }\r
1684 break;\r
1685\r
1686 case EFI_IFR_DUP_OP:\r
1687 Status = PopExpression (Value);\r
1688 if (EFI_ERROR (Status)) {\r
2573712e 1689 goto Done;\r
7936fb6a 1690 }\r
1691\r
1692 Status = PushExpression (Value);\r
1693 break;\r
1694\r
1695 case EFI_IFR_QUESTION_REF1_OP:\r
1696 case EFI_IFR_THIS_OP:\r
1697 Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);\r
1698 if (Question == NULL) {\r
2573712e
LG
1699 Status = EFI_NOT_FOUND;\r
1700 goto Done;\r
7936fb6a 1701 }\r
1702\r
1703 Value = &Question->HiiValue;\r
1704 break;\r
1705\r
cbf73e50 1706 case EFI_IFR_SECURITY_OP:\r
1707 Value->Value.b = CheckUserPrivilege (&OpCode->Guid);\r
1708 break;\r
1709\r
2573712e
LG
1710 case EFI_IFR_GET_OP:\r
1711 //\r
1712 // Get Value from VarStore buffer, EFI VarStore, Name/Value VarStore.\r
1713 //\r
1714 Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
1715 Value->Value.u8 = 0;\r
1716 if (OpCode->VarStorage != NULL) {\r
1717 switch (OpCode->VarStorage->Type) {\r
1718 case EFI_HII_VARSTORE_BUFFER:\r
cce6230f 1719 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
2573712e
LG
1720 //\r
1721 // Get value from Edit Buffer\r
1722 //\r
1723 Value->Type = OpCode->ValueType;\r
1724 CopyMem (&Value->Value, OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, OpCode->ValueWidth);\r
1725 break;\r
1726 case EFI_HII_VARSTORE_NAME_VALUE:\r
1727 if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {\r
1728 //\r
1729 // Get value from string except for STRING value.\r
1730 //\r
1731 Status = GetValueByName (OpCode->VarStorage, OpCode->ValueName, &StrPtr);\r
1732 if (!EFI_ERROR (Status)) {\r
771ececd 1733 ASSERT (StrPtr != NULL);\r
2573712e
LG
1734 TempLength = StrLen (StrPtr);\r
1735 if (OpCode->ValueWidth >= ((TempLength + 1) / 2)) {\r
1736 Value->Type = OpCode->ValueType;\r
1737 TempBuffer = (UINT8 *) &Value->Value;\r
1738 ZeroMem (TempStr, sizeof (TempStr));\r
1739 for (Index = 0; Index < TempLength; Index ++) {\r
1740 TempStr[0] = StrPtr[TempLength - Index - 1];\r
1741 DigitUint8 = (UINT8) StrHexToUint64 (TempStr);\r
1742 if ((Index & 1) == 0) {\r
1743 TempBuffer [Index/2] = DigitUint8;\r
1744 } else {\r
771ececd 1745 TempBuffer [Index/2] = (UINT8) ((DigitUint8 << 4) + TempBuffer [Index/2]);\r
2573712e
LG
1746 }\r
1747 }\r
1748 } \r
1749 }\r
1750 }\r
1751 break;\r
1752 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
1753 //\r
1754 // Get value from variable.\r
1755 //\r
1756 TempLength = OpCode->ValueWidth;\r
1757 Value->Type = OpCode->ValueType;\r
1758 Status = gRT->GetVariable (\r
1759 OpCode->ValueName,\r
1760 &OpCode->VarStorage->Guid,\r
1761 NULL,\r
1762 &TempLength,\r
1763 &Value->Value\r
1764 );\r
1765 if (EFI_ERROR (Status)) {\r
1766 Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
1767 Value->Value.u8 = 0;\r
1768 }\r
cce6230f 1769 break;\r
2573712e
LG
1770 default:\r
1771 //\r
1772 // Not recognize storage.\r
1773 //\r
1774 Status = EFI_UNSUPPORTED;\r
1775 goto Done;\r
1776 }\r
1777 } else {\r
1778 //\r
1779 // For Time/Date Data\r
1780 //\r
1781 if (OpCode->ValueType != EFI_IFR_TYPE_DATE && OpCode->ValueType != EFI_IFR_TYPE_TIME) {\r
1782 //\r
1783 // Only support Data/Time data when storage doesn't exist.\r
1784 //\r
1785 Status = EFI_UNSUPPORTED;\r
1786 goto Done;\r
1787 }\r
1788 Status = gRT->GetTime (&EfiTime, NULL);\r
1789 if (!EFI_ERROR (Status)) {\r
1790 if (OpCode->ValueType == EFI_IFR_TYPE_DATE) {\r
1791 switch (OpCode->VarStoreInfo.VarOffset) {\r
1792 case 0x00:\r
1793 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1794 Value->Value.u16 = EfiTime.Year;\r
1795 break;\r
1796 case 0x02:\r
1797 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1798 Value->Value.u8 = EfiTime.Month;\r
1799 break;\r
1800 case 0x03:\r
1801 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1802 Value->Value.u8 = EfiTime.Day;\r
1803 break;\r
1804 default:\r
1805 //\r
1806 // Invalid Date field.\r
1807 //\r
1808 Status = EFI_INVALID_PARAMETER;\r
1809 goto Done;\r
1810 }\r
1811 } else {\r
1812 switch (OpCode->VarStoreInfo.VarOffset) {\r
1813 case 0x00:\r
1814 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1815 Value->Value.u8 = EfiTime.Hour;\r
1816 break;\r
1817 case 0x01:\r
1818 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1819 Value->Value.u8 = EfiTime.Minute;\r
1820 break;\r
1821 case 0x02:\r
1822 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1823 Value->Value.u8 = EfiTime.Second;\r
1824 break;\r
1825 default:\r
1826 //\r
1827 // Invalid Time field.\r
1828 //\r
1829 Status = EFI_INVALID_PARAMETER;\r
1830 goto Done;\r
1831 }\r
1832 }\r
1833 }\r
1834 }\r
1835\r
1836 break;\r
1837\r
7936fb6a 1838 case EFI_IFR_QUESTION_REF3_OP:\r
1839 if (OpCode->DevicePath == 0) {\r
1840 //\r
1841 // EFI_IFR_QUESTION_REF3\r
1842 // Pop an expression from the expression stack\r
1843 //\r
1844 Status = PopExpression (Value);\r
1845 if (EFI_ERROR (Status)) {\r
2573712e 1846 goto Done;\r
7936fb6a 1847 }\r
1848\r
1849 //\r
1850 // Validate the expression value\r
1851 //\r
1852 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
2573712e
LG
1853 Status = EFI_NOT_FOUND;\r
1854 goto Done;\r
7936fb6a 1855 }\r
1856\r
1857 Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
1858 if (Question == NULL) {\r
2573712e
LG
1859 Status = EFI_NOT_FOUND;\r
1860 goto Done;\r
7936fb6a 1861 }\r
1862\r
1863 //\r
1864 // push the questions' value on to the expression stack\r
1865 //\r
1866 Value = &Question->HiiValue;\r
1867 } else {\r
1868 //\r
1869 // BUGBUG: push 0 for EFI_IFR_QUESTION_REF3_2 and EFI_IFR_QUESTION_REF3_3,\r
1870 // since it is impractical to evaluate the value of a Question in another\r
1871 // Hii Package list.\r
1872 //\r
1873 ZeroMem (Value, sizeof (EFI_HII_VALUE));\r
1874 }\r
1875 break;\r
1876\r
1877 case EFI_IFR_RULE_REF_OP:\r
1878 //\r
1879 // Find expression for this rule\r
1880 //\r
1881 RuleExpression = RuleIdToExpression (Form, OpCode->RuleId);\r
1882 if (RuleExpression == NULL) {\r
2573712e
LG
1883 Status = EFI_NOT_FOUND;\r
1884 goto Done;\r
7936fb6a 1885 }\r
1886\r
1887 //\r
1888 // Evaluate this rule expression\r
1889 //\r
1890 Status = EvaluateExpression (FormSet, Form, RuleExpression);\r
1891 if (EFI_ERROR (Status)) {\r
2573712e 1892 goto Done;\r
7936fb6a 1893 }\r
1894\r
1895 Value = &RuleExpression->Result;\r
1896 break;\r
1897\r
1898 case EFI_IFR_STRING_REF1_OP:\r
1899 Value->Type = EFI_IFR_TYPE_STRING;\r
1900 Value->Value.string = OpCode->Value.Value.string;\r
1901 break;\r
1902\r
1903 //\r
1904 // Constant\r
1905 //\r
1906 case EFI_IFR_TRUE_OP:\r
1907 case EFI_IFR_FALSE_OP:\r
1908 case EFI_IFR_ONE_OP:\r
1909 case EFI_IFR_ONES_OP:\r
1910 case EFI_IFR_UINT8_OP:\r
1911 case EFI_IFR_UINT16_OP:\r
1912 case EFI_IFR_UINT32_OP:\r
1913 case EFI_IFR_UINT64_OP:\r
1914 case EFI_IFR_UNDEFINED_OP:\r
1915 case EFI_IFR_VERSION_OP:\r
1916 case EFI_IFR_ZERO_OP:\r
1917 Value = &OpCode->Value;\r
1918 break;\r
1919\r
1920 //\r
1921 // unary-op\r
1922 //\r
1923 case EFI_IFR_LENGTH_OP:\r
1924 Status = PopExpression (Value);\r
1925 if (EFI_ERROR (Status)) {\r
2573712e 1926 goto Done;\r
7936fb6a 1927 }\r
1928 if (Value->Type != EFI_IFR_TYPE_STRING) {\r
2573712e
LG
1929 Status = EFI_INVALID_PARAMETER;\r
1930 goto Done;\r
7936fb6a 1931 }\r
1932\r
1933 StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
1934 if (StrPtr == NULL) {\r
2573712e
LG
1935 Status = EFI_INVALID_PARAMETER;\r
1936 goto Done;\r
7936fb6a 1937 }\r
1938\r
1939 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1940 Value->Value.u64 = StrLen (StrPtr);\r
f4113e1f 1941 FreePool (StrPtr);\r
7936fb6a 1942 break;\r
1943\r
1944 case EFI_IFR_NOT_OP:\r
1945 Status = PopExpression (Value);\r
1946 if (EFI_ERROR (Status)) {\r
2573712e 1947 goto Done;\r
7936fb6a 1948 }\r
1949 if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {\r
2573712e
LG
1950 Status = EFI_INVALID_PARAMETER;\r
1951 goto Done;\r
7936fb6a 1952 }\r
1953 Value->Value.b = (BOOLEAN) (!Value->Value.b);\r
1954 break;\r
1955\r
1956 case EFI_IFR_QUESTION_REF2_OP:\r
1957 //\r
1958 // Pop an expression from the expression stack\r
1959 //\r
1960 Status = PopExpression (Value);\r
1961 if (EFI_ERROR (Status)) {\r
2573712e 1962 goto Done;\r
7936fb6a 1963 }\r
1964\r
1965 //\r
1966 // Validate the expression value\r
1967 //\r
1968 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
2573712e
LG
1969 Status = EFI_NOT_FOUND;\r
1970 goto Done;\r
7936fb6a 1971 }\r
1972\r
1973 Question = IdToQuestion (FormSet, Form, Value->Value.u16);\r
1974 if (Question == NULL) {\r
2573712e
LG
1975 Status = EFI_NOT_FOUND;\r
1976 goto Done;\r
7936fb6a 1977 }\r
1978\r
1979 Value = &Question->HiiValue;\r
1980 break;\r
1981\r
1982 case EFI_IFR_STRING_REF2_OP:\r
1983 //\r
1984 // Pop an expression from the expression stack\r
1985 //\r
1986 Status = PopExpression (Value);\r
1987 if (EFI_ERROR (Status)) {\r
2573712e 1988 goto Done;\r
7936fb6a 1989 }\r
1990\r
1991 //\r
1992 // Validate the expression value\r
1993 //\r
1994 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {\r
2573712e
LG
1995 Status = EFI_NOT_FOUND;\r
1996 goto Done;\r
7936fb6a 1997 }\r
1998\r
1999 Value->Type = EFI_IFR_TYPE_STRING;\r
2000 StrPtr = GetToken (Value->Value.u16, FormSet->HiiHandle);\r
2001 if (StrPtr == NULL) {\r
2002 //\r
2003 // If String not exit, push an empty string\r
2004 //\r
2005 Value->Value.string = NewString (gEmptyString, FormSet->HiiHandle);\r
2006 } else {\r
2007 Index = (UINT16) Value->Value.u64;\r
2008 Value->Value.string = Index;\r
f4113e1f 2009 FreePool (StrPtr);\r
7936fb6a 2010 }\r
2011 break;\r
2012\r
2013 case EFI_IFR_TO_BOOLEAN_OP:\r
2014 //\r
2015 // Pop an expression from the expression stack\r
2016 //\r
2017 Status = PopExpression (Value);\r
2018 if (EFI_ERROR (Status)) {\r
2573712e 2019 goto Done;\r
7936fb6a 2020 }\r
2021\r
2022 //\r
2023 // Convert an expression to a Boolean\r
2024 //\r
2025 if (Value->Type <= EFI_IFR_TYPE_DATE) {\r
2026 //\r
2027 // When converting from an unsigned integer, zero will be converted to\r
2028 // FALSE and any other value will be converted to TRUE.\r
2029 //\r
4140a663 2030 Value->Value.b = (BOOLEAN) (Value->Value.u64 != 0);\r
7936fb6a 2031\r
2032 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
2033 } else if (Value->Type == EFI_IFR_TYPE_STRING) {\r
2034 //\r
2035 // When converting from a string, if case-insensitive compare\r
2036 // with "true" is True, then push True. If a case-insensitive compare\r
39099cbd 2037 // with "false" is True, then push False. Otherwise, push Undefined. \r
7936fb6a 2038 //\r
2039 StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
2040 if (StrPtr == NULL) {\r
2573712e
LG
2041 Status = EFI_INVALID_PARAMETER;\r
2042 goto Done;\r
7936fb6a 2043 }\r
39099cbd
ED
2044 \r
2045 IfrStrToUpper (StrPtr);\r
2046 if (StrCmp (StrPtr, L"TRUE") == 0){\r
7936fb6a 2047 Value->Value.b = TRUE;\r
39099cbd 2048 } else if (StrCmp (StrPtr, L"FALSE") == 0) {\r
7936fb6a 2049 Value->Value.b = FALSE;\r
39099cbd
ED
2050 } else {\r
2051 Status = EFI_INVALID_PARAMETER;\r
2052 FreePool (StrPtr);\r
2053 goto Done;\r
7936fb6a 2054 }\r
f4113e1f 2055 FreePool (StrPtr);\r
7936fb6a 2056 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
2057 }\r
2058 break;\r
2059\r
2060 case EFI_IFR_TO_STRING_OP:\r
2061 Status = IfrToString (FormSet, OpCode->Format, Value);\r
2062 break;\r
2063\r
2064 case EFI_IFR_TO_UINT_OP:\r
2065 Status = IfrToUint (FormSet, Value);\r
2066 break;\r
2067\r
2068 case EFI_IFR_TO_LOWER_OP:\r
2069 case EFI_IFR_TO_UPPER_OP:\r
2070 Status = InitializeUnicodeCollationProtocol ();\r
2071 if (EFI_ERROR (Status)) {\r
2573712e 2072 goto Done;\r
7936fb6a 2073 }\r
2074\r
2075 Status = PopExpression (Value);\r
2076 if (EFI_ERROR (Status)) {\r
2573712e 2077 goto Done;\r
7936fb6a 2078 }\r
2079\r
2080 if (Value->Type != EFI_IFR_TYPE_STRING) {\r
2573712e
LG
2081 Status = EFI_UNSUPPORTED;\r
2082 goto Done;\r
7936fb6a 2083 }\r
2084\r
2085 StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);\r
2086 if (StrPtr == NULL) {\r
2573712e
LG
2087 Status = EFI_NOT_FOUND;\r
2088 goto Done;\r
7936fb6a 2089 }\r
2090\r
2091 if (OpCode->Operand == EFI_IFR_TO_LOWER_OP) {\r
2092 mUnicodeCollation->StrLwr (mUnicodeCollation, StrPtr);\r
2093 } else {\r
2094 mUnicodeCollation->StrUpr (mUnicodeCollation, StrPtr);\r
2095 }\r
2096 Value->Value.string = NewString (StrPtr, FormSet->HiiHandle);\r
f4113e1f 2097 FreePool (StrPtr);\r
7936fb6a 2098 break;\r
2099\r
2100 case EFI_IFR_BITWISE_NOT_OP:\r
2101 //\r
2102 // Pop an expression from the expression stack\r
2103 //\r
2104 Status = PopExpression (Value);\r
2105 if (EFI_ERROR (Status)) {\r
2573712e 2106 goto Done;\r
7936fb6a 2107 }\r
2108 if (Value->Type > EFI_IFR_TYPE_DATE) {\r
2573712e
LG
2109 Status = EFI_INVALID_PARAMETER;\r
2110 goto Done;\r
7936fb6a 2111 }\r
2112\r
2113 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
2114 Value->Value.u64 = ~Value->Value.u64;\r
2115 break;\r
2116\r
2573712e
LG
2117 case EFI_IFR_SET_OP:\r
2118 //\r
2119 // Pop an expression from the expression stack\r
2120 //\r
2121 Status = PopExpression (Value);\r
2122 if (EFI_ERROR (Status)) {\r
2123 goto Done;\r
2124 }\r
2125 Data1.Type = EFI_IFR_TYPE_BOOLEAN;\r
2126 Data1.Value.b = FALSE;\r
2127 //\r
2128 // Set value to var storage buffer\r
2129 //\r
2130 if (OpCode->VarStorage != NULL) {\r
2131 switch (OpCode->VarStorage->Type) {\r
2132 case EFI_HII_VARSTORE_BUFFER:\r
cce6230f 2133 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:\r
2573712e
LG
2134 CopyMem (OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth);\r
2135 Data1.Value.b = TRUE;\r
2136 break;\r
2137 case EFI_HII_VARSTORE_NAME_VALUE:\r
2138 if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {\r
2139 NameValue = AllocateZeroPool ((OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16));\r
2140 ASSERT (Value != NULL);\r
2141 //\r
2142 // Convert Buffer to Hex String\r
2143 //\r
2144 TempBuffer = (UINT8 *) &Value->Value + OpCode->ValueWidth - 1;\r
2145 StrPtr = NameValue;\r
2146 for (Index = 0; Index < OpCode->ValueWidth; Index ++, TempBuffer --) {\r
2147 StrPtr += UnicodeValueToString (StrPtr, PREFIX_ZERO | RADIX_HEX, *TempBuffer, 2);\r
2148 }\r
b18e7050 2149 Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, TRUE);\r
2573712e
LG
2150 FreePool (NameValue);\r
2151 if (!EFI_ERROR (Status)) {\r
2152 Data1.Value.b = TRUE;\r
2153 }\r
2154 }\r
2155 break;\r
2156 case EFI_HII_VARSTORE_EFI_VARIABLE:\r
2157 Status = gRT->SetVariable (\r
2158 OpCode->ValueName,\r
2159 &OpCode->VarStorage->Guid,\r
2160 OpCode->VarStorage->Attributes,\r
2161 OpCode->ValueWidth,\r
2162 &Value->Value\r
2163 );\r
2164 if (!EFI_ERROR (Status)) {\r
2165 Data1.Value.b = TRUE;\r
2166 }\r
2167 break;\r
2168 default:\r
2169 //\r
2170 // Not recognize storage.\r
2171 //\r
2172 Status = EFI_UNSUPPORTED;\r
2173 goto Done;\r
2174 break;\r
2175 }\r
2176 } else {\r
2177 //\r
2178 // For Time/Date Data\r
2179 //\r
2180 if (OpCode->ValueType != EFI_IFR_TYPE_DATE && OpCode->ValueType != EFI_IFR_TYPE_TIME) {\r
2181 //\r
2182 // Only support Data/Time data when storage doesn't exist.\r
2183 //\r
2184 Status = EFI_UNSUPPORTED;\r
2185 goto Done;\r
2186 }\r
2187 Status = gRT->GetTime (&EfiTime, NULL);\r
2188 if (!EFI_ERROR (Status)) {\r
2189 if (OpCode->ValueType == EFI_IFR_TYPE_DATE) {\r
2190 switch (OpCode->VarStoreInfo.VarOffset) {\r
2191 case 0x00:\r
2192 EfiTime.Year = Value->Value.u16;\r
2193 break;\r
2194 case 0x02:\r
2195 EfiTime.Month = Value->Value.u8;\r
2196 break;\r
2197 case 0x03:\r
2198 EfiTime.Day = Value->Value.u8;\r
2199 break;\r
2200 default:\r
2201 //\r
2202 // Invalid Date field.\r
2203 //\r
2204 Status = EFI_INVALID_PARAMETER;\r
2205 goto Done;\r
2206 }\r
2207 } else {\r
2208 switch (OpCode->VarStoreInfo.VarOffset) {\r
2209 case 0x00:\r
2210 EfiTime.Hour = Value->Value.u8;\r
2211 break;\r
2212 case 0x01:\r
2213 EfiTime.Minute = Value->Value.u8;\r
2214 break;\r
2215 case 0x02:\r
2216 EfiTime.Second = Value->Value.u8;\r
2217 break;\r
2218 default:\r
2219 //\r
2220 // Invalid Time field.\r
2221 //\r
2222 Status = EFI_INVALID_PARAMETER;\r
2223 goto Done;\r
2224 }\r
2225 }\r
2226 Status = gRT->SetTime (&EfiTime);\r
2227 if (!EFI_ERROR (Status)) {\r
2228 Data1.Value.b = TRUE;\r
2229 }\r
2230 }\r
2231 }\r
2232 Value = &Data1;\r
2233 break;\r
2234\r
7936fb6a 2235 //\r
2236 // binary-op\r
2237 //\r
2238 case EFI_IFR_ADD_OP:\r
2239 case EFI_IFR_SUBTRACT_OP:\r
2240 case EFI_IFR_MULTIPLY_OP:\r
2241 case EFI_IFR_DIVIDE_OP:\r
2242 case EFI_IFR_MODULO_OP:\r
2243 case EFI_IFR_BITWISE_AND_OP:\r
2244 case EFI_IFR_BITWISE_OR_OP:\r
2245 case EFI_IFR_SHIFT_LEFT_OP:\r
2246 case EFI_IFR_SHIFT_RIGHT_OP:\r
2247 //\r
2248 // Pop an expression from the expression stack\r
2249 //\r
2250 Status = PopExpression (&Data2);\r
2251 if (EFI_ERROR (Status)) {\r
2573712e 2252 goto Done;\r
7936fb6a 2253 }\r
2254 if (Data2.Type > EFI_IFR_TYPE_DATE) {\r
2573712e
LG
2255 Status = EFI_INVALID_PARAMETER;\r
2256 goto Done;\r
7936fb6a 2257 }\r
2258\r
2259 //\r
2260 // Pop another expression from the expression stack\r
2261 //\r
2262 Status = PopExpression (&Data1);\r
2263 if (EFI_ERROR (Status)) {\r
2573712e 2264 goto Done;\r
7936fb6a 2265 }\r
2266 if (Data1.Type > EFI_IFR_TYPE_DATE) {\r
2573712e
LG
2267 Status = EFI_INVALID_PARAMETER;\r
2268 goto Done;\r
7936fb6a 2269 }\r
2270\r
2271 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
2272\r
2273 switch (OpCode->Operand) {\r
2274 case EFI_IFR_ADD_OP:\r
2275 Value->Value.u64 = Data1.Value.u64 + Data2.Value.u64;\r
2276 break;\r
2277\r
2278 case EFI_IFR_SUBTRACT_OP:\r
2279 Value->Value.u64 = Data1.Value.u64 - Data2.Value.u64;\r
2280 break;\r
2281\r
2282 case EFI_IFR_MULTIPLY_OP:\r
2283 Value->Value.u64 = MultU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
2284 break;\r
2285\r
2286 case EFI_IFR_DIVIDE_OP:\r
2287 Value->Value.u64 = DivU64x32 (Data1.Value.u64, (UINT32) Data2.Value.u64);\r
2288 break;\r
2289\r
2290 case EFI_IFR_MODULO_OP:\r
2291 DivU64x32Remainder (Data1.Value.u64, (UINT32) Data2.Value.u64, &TempValue);\r
2292 Value->Value.u64 = TempValue;\r
2293 break;\r
2294\r
2295 case EFI_IFR_BITWISE_AND_OP:\r
2296 Value->Value.u64 = Data1.Value.u64 & Data2.Value.u64;\r
2297 break;\r
2298\r
2299 case EFI_IFR_BITWISE_OR_OP:\r
2300 Value->Value.u64 = Data1.Value.u64 | Data2.Value.u64;\r
2301 break;\r
2302\r
2303 case EFI_IFR_SHIFT_LEFT_OP:\r
2304 Value->Value.u64 = LShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
2305 break;\r
2306\r
2307 case EFI_IFR_SHIFT_RIGHT_OP:\r
2308 Value->Value.u64 = RShiftU64 (Data1.Value.u64, (UINTN) Data2.Value.u64);\r
2309 break;\r
2310\r
2311 default:\r
2312 break;\r
2313 }\r
2314 break;\r
2315\r
2316 case EFI_IFR_AND_OP:\r
2317 case EFI_IFR_OR_OP:\r
2318 //\r
2319 // Two Boolean operator\r
2320 //\r
2321 Status = PopExpression (&Data2);\r
2322 if (EFI_ERROR (Status)) {\r
2573712e 2323 goto Done;\r
7936fb6a 2324 }\r
2325 if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {\r
2573712e
LG
2326 Status = EFI_INVALID_PARAMETER;\r
2327 goto Done;\r
7936fb6a 2328 }\r
2329\r
2330 //\r
2331 // Pop another expression from the expression stack\r
2332 //\r
2333 Status = PopExpression (&Data1);\r
2334 if (EFI_ERROR (Status)) {\r
2573712e 2335 goto Done;\r
7936fb6a 2336 }\r
2337 if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
2573712e
LG
2338 Status = EFI_INVALID_PARAMETER;\r
2339 goto Done;\r
7936fb6a 2340 }\r
2341\r
2342 if (OpCode->Operand == EFI_IFR_AND_OP) {\r
2343 Value->Value.b = (BOOLEAN) (Data1.Value.b && Data2.Value.b);\r
2344 } else {\r
2345 Value->Value.b = (BOOLEAN) (Data1.Value.b || Data2.Value.b);\r
2346 }\r
2347 break;\r
2348\r
2349 case EFI_IFR_EQUAL_OP:\r
2350 case EFI_IFR_NOT_EQUAL_OP:\r
2351 case EFI_IFR_GREATER_EQUAL_OP:\r
2352 case EFI_IFR_GREATER_THAN_OP:\r
2353 case EFI_IFR_LESS_EQUAL_OP:\r
2354 case EFI_IFR_LESS_THAN_OP:\r
2355 //\r
2356 // Compare two integer, string, boolean or date/time\r
2357 //\r
2358 Status = PopExpression (&Data2);\r
2359 if (EFI_ERROR (Status)) {\r
2573712e 2360 goto Done;\r
7936fb6a 2361 }\r
2362 if (Data2.Type > EFI_IFR_TYPE_BOOLEAN && Data2.Type != EFI_IFR_TYPE_STRING) {\r
2573712e
LG
2363 Status = EFI_INVALID_PARAMETER;\r
2364 goto Done;\r
7936fb6a 2365 }\r
2366\r
2367 //\r
2368 // Pop another expression from the expression stack\r
2369 //\r
2370 Status = PopExpression (&Data1);\r
2371 if (EFI_ERROR (Status)) {\r
2573712e 2372 goto Done;\r
7936fb6a 2373 }\r
2374\r
2375 Result = CompareHiiValue (&Data1, &Data2, FormSet->HiiHandle);\r
2376 if (Result == EFI_INVALID_PARAMETER) {\r
2573712e
LG
2377 Status = EFI_INVALID_PARAMETER;\r
2378 goto Done;\r
7936fb6a 2379 }\r
2380\r
2381 switch (OpCode->Operand) {\r
2382 case EFI_IFR_EQUAL_OP:\r
2383 Value->Value.b = (BOOLEAN) ((Result == 0) ? TRUE : FALSE);\r
2384 break;\r
2385\r
2386 case EFI_IFR_NOT_EQUAL_OP:\r
7b9b2b92 2387 Value->Value.b = (BOOLEAN) ((Result != 0) ? TRUE : FALSE);\r
7936fb6a 2388 break;\r
2389\r
2390 case EFI_IFR_GREATER_EQUAL_OP:\r
2391 Value->Value.b = (BOOLEAN) ((Result >= 0) ? TRUE : FALSE);\r
2392 break;\r
2393\r
2394 case EFI_IFR_GREATER_THAN_OP:\r
2395 Value->Value.b = (BOOLEAN) ((Result > 0) ? TRUE : FALSE);\r
2396 break;\r
2397\r
2398 case EFI_IFR_LESS_EQUAL_OP:\r
2399 Value->Value.b = (BOOLEAN) ((Result <= 0) ? TRUE : FALSE);\r
2400 break;\r
2401\r
2402 case EFI_IFR_LESS_THAN_OP:\r
2403 Value->Value.b = (BOOLEAN) ((Result < 0) ? TRUE : FALSE);\r
2404 break;\r
2405\r
2406 default:\r
2407 break;\r
2408 }\r
2409 break;\r
2410\r
2411 case EFI_IFR_MATCH_OP:\r
2412 Status = IfrMatch (FormSet, Value);\r
2413 break;\r
2414\r
2415 case EFI_IFR_CATENATE_OP:\r
2416 Status = IfrCatenate (FormSet, Value);\r
2417 break;\r
2418\r
2419 //\r
2420 // ternary-op\r
2421 //\r
2422 case EFI_IFR_CONDITIONAL_OP:\r
2423 //\r
2424 // Pop third expression from the expression stack\r
2425 //\r
2426 Status = PopExpression (&Data3);\r
2427 if (EFI_ERROR (Status)) {\r
2573712e 2428 goto Done;\r
7936fb6a 2429 }\r
2430\r
2431 //\r
2432 // Pop second expression from the expression stack\r
2433 //\r
2434 Status = PopExpression (&Data2);\r
2435 if (EFI_ERROR (Status)) {\r
2573712e 2436 goto Done;\r
7936fb6a 2437 }\r
2438\r
2439 //\r
2440 // Pop first expression from the expression stack\r
2441 //\r
2442 Status = PopExpression (&Data1);\r
2443 if (EFI_ERROR (Status)) {\r
2573712e 2444 goto Done;\r
7936fb6a 2445 }\r
2446 if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {\r
2573712e
LG
2447 Status = EFI_INVALID_PARAMETER;\r
2448 goto Done;\r
7936fb6a 2449 }\r
2450\r
2451 if (Data1.Value.b) {\r
2452 Value = &Data3;\r
2453 } else {\r
2454 Value = &Data2;\r
2455 }\r
2456 break;\r
2457\r
2458 case EFI_IFR_FIND_OP:\r
2459 Status = IfrFind (FormSet, OpCode->Format, Value);\r
2460 break;\r
2461\r
2462 case EFI_IFR_MID_OP:\r
2463 Status = IfrMid (FormSet, Value);\r
2464 break;\r
2465\r
2466 case EFI_IFR_TOKEN_OP:\r
2467 Status = IfrToken (FormSet, Value);\r
2468 break;\r
2469\r
2470 case EFI_IFR_SPAN_OP:\r
2471 Status = IfrSpan (FormSet, OpCode->Flags, Value);\r
2472 break;\r
2473\r
2573712e
LG
2474 case EFI_IFR_MAP_OP:\r
2475 //\r
2476 // Pop the check value\r
2477 //\r
2478 Status = PopExpression (&Data1);\r
2479 if (EFI_ERROR (Status)) {\r
2480 goto Done;\r
2481 }\r
2482 //\r
2483 // Check MapExpression list is valid.\r
2484 //\r
2485 if (OpCode->MapExpressionList.ForwardLink == NULL) {\r
2486 Status = EFI_INVALID_PARAMETER;\r
2487 goto Done;\r
2488 }\r
2489 //\r
2490 // Go through map expression list.\r
2491 //\r
2492 SubExpressionLink = GetFirstNode(&OpCode->MapExpressionList);\r
2493 while (!IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
2494 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
2495 //\r
2496 // Evaluate the first expression in this pair.\r
2497 //\r
2498 Status = EvaluateExpression (FormSet, Form, SubExpression);\r
2499 if (EFI_ERROR (Status)) {\r
2500 goto Done;\r
2501 }\r
2502 //\r
2503 // Compare the expression value with current value\r
2504 //\r
2505 if (CompareHiiValue (&Data1, &SubExpression->Result, NULL) == 0) {\r
2506 //\r
2507 // Try get the map value.\r
2508 //\r
2509 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
2510 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
2511 Status = EFI_INVALID_PARAMETER;\r
2512 goto Done;\r
2513 }\r
2514 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);\r
2515 Status = EvaluateExpression (FormSet, Form, SubExpression);\r
2516 if (EFI_ERROR (Status)) {\r
2517 goto Done;\r
2518 }\r
2519 Value = &SubExpression->Result;\r
2520 break;\r
2521 }\r
2522 //\r
2523 // Skip the second expression on this pair.\r
2524 //\r
2525 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
2526 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
2527 Status = EFI_INVALID_PARAMETER;\r
2528 goto Done;\r
2529 }\r
2530 //\r
2531 // Goto the first expression on next pair.\r
2532 //\r
2533 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);\r
2534 }\r
2535\r
2536 //\r
2537 // No map value is found.\r
2538 //\r
2539 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {\r
2540 Value->Type = EFI_IFR_TYPE_UNDEFINED;\r
2541 Value->Value.u8 = 0;\r
2542 }\r
2543 break;\r
2544\r
7936fb6a 2545 default:\r
2546 break;\r
2547 }\r
2548 if (EFI_ERROR (Status)) {\r
2573712e 2549 goto Done;\r
7936fb6a 2550 }\r
2551\r
2552 Status = PushExpression (Value);\r
2553 if (EFI_ERROR (Status)) {\r
2573712e 2554 goto Done;\r
7936fb6a 2555 }\r
2556 }\r
2557\r
2558 //\r
2559 // Pop the final result from expression stack\r
2560 //\r
2561 Value = &Data1;\r
2562 Status = PopExpression (Value);\r
2563 if (EFI_ERROR (Status)) {\r
2573712e 2564 goto Done;\r
7936fb6a 2565 }\r
2566\r
2567 //\r
2568 // After evaluating an expression, there should be only one value left on the expression stack\r
2569 //\r
2570 if (PopExpression (Value) != EFI_ACCESS_DENIED) {\r
2573712e 2571 Status = EFI_INVALID_PARAMETER;\r
7936fb6a 2572 }\r
2573\r
2573712e
LG
2574Done:\r
2575 RestoreExpressionEvaluationStackOffset (StackOffset);\r
2576 if (!EFI_ERROR (Status)) {\r
2577 CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));\r
2578 }\r
7936fb6a 2579\r
2573712e 2580 return Status;\r
7936fb6a 2581}\r