TianoCore EDK2 master
Loading...
Searching...
No Matches
Expression.c
Go to the documentation of this file.
1
9#include "Setup.h"
10
11//
12// Global stack used to evaluate boolean expresions
13//
14EFI_HII_VALUE *mOpCodeScopeStack = NULL;
15EFI_HII_VALUE *mOpCodeScopeStackEnd = NULL;
16EFI_HII_VALUE *mOpCodeScopeStackPointer = NULL;
17
18EFI_HII_VALUE *mExpressionEvaluationStack = NULL;
19EFI_HII_VALUE *mExpressionEvaluationStackEnd = NULL;
20EFI_HII_VALUE *mExpressionEvaluationStackPointer = NULL;
21UINTN mExpressionEvaluationStackOffset = 0;
22
23EFI_HII_VALUE *mCurrentExpressionStack = NULL;
24EFI_HII_VALUE *mCurrentExpressionEnd = NULL;
25EFI_HII_VALUE *mCurrentExpressionPointer = NULL;
26
27EFI_HII_VALUE *mMapExpressionListStack = NULL;
28EFI_HII_VALUE *mMapExpressionListEnd = NULL;
29EFI_HII_VALUE *mMapExpressionListPointer = NULL;
30
31FORM_EXPRESSION **mFormExpressionStack = NULL;
32FORM_EXPRESSION **mFormExpressionEnd = NULL;
33FORM_EXPRESSION **mFormExpressionPointer = NULL;
34
35FORM_EXPRESSION **mStatementExpressionStack = NULL;
36FORM_EXPRESSION **mStatementExpressionEnd = NULL;
37FORM_EXPRESSION **mStatementExpressionPointer = NULL;
38
39FORM_EXPRESSION **mOptionExpressionStack = NULL;
40FORM_EXPRESSION **mOptionExpressionEnd = NULL;
41FORM_EXPRESSION **mOptionExpressionPointer = NULL;
42
43//
44// Unicode collation protocol interface
45//
46EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL;
47EFI_USER_MANAGER_PROTOCOL *mUserManager = NULL;
48
65 IN OUT EFI_HII_VALUE **Stack,
66 IN OUT EFI_HII_VALUE **StackPtr,
67 IN OUT EFI_HII_VALUE **StackEnd
68 )
69{
70 UINTN Size;
71 EFI_HII_VALUE *NewStack;
72
73 Size = EXPRESSION_STACK_SIZE_INCREMENT;
74 if (*StackPtr != NULL) {
75 Size = Size + (*StackEnd - *Stack);
76 }
77
78 NewStack = AllocatePool (Size * sizeof (EFI_HII_VALUE));
79 if (NewStack == NULL) {
80 return EFI_OUT_OF_RESOURCES;
81 }
82
83 if (*StackPtr != NULL) {
84 //
85 // Copy from Old Stack to the New Stack
86 //
87 CopyMem (
88 NewStack,
89 *Stack,
90 (*StackEnd - *Stack) * sizeof (EFI_HII_VALUE)
91 );
92
93 //
94 // Free The Old Stack
95 //
96 FreePool (*Stack);
97 }
98
99 //
100 // Make the Stack pointer point to the old data in the new stack
101 //
102 *StackPtr = NewStack + (*StackPtr - *Stack);
103 *Stack = NewStack;
104 *StackEnd = NewStack + Size;
105
106 return EFI_SUCCESS;
107}
108
123 IN OUT EFI_HII_VALUE **Stack,
124 IN OUT EFI_HII_VALUE **StackPtr,
125 IN OUT EFI_HII_VALUE **StackEnd,
126 IN EFI_HII_VALUE *Data
127 )
128{
129 EFI_STATUS Status;
130
131 //
132 // Check for a stack overflow condition
133 //
134 if (*StackPtr >= *StackEnd) {
135 //
136 // Grow the stack
137 //
138 Status = GrowStack (Stack, StackPtr, StackEnd);
139 if (EFI_ERROR (Status)) {
140 return Status;
141 }
142 }
143
144 //
145 // Push the item onto the stack
146 //
147 CopyMem (*StackPtr, Data, sizeof (EFI_HII_VALUE));
148 if (Data->Type == EFI_IFR_TYPE_BUFFER) {
149 (*StackPtr)->Buffer = AllocateCopyPool (Data->BufferLen, Data->Buffer);
150 ASSERT ((*StackPtr)->Buffer != NULL);
151 }
152
153 *StackPtr = *StackPtr + 1;
154
155 return EFI_SUCCESS;
156}
157
171 IN EFI_HII_VALUE *Stack,
172 IN OUT EFI_HII_VALUE **StackPtr,
173 OUT EFI_HII_VALUE *Data
174 )
175{
176 //
177 // Check for a stack underflow condition
178 //
179 if (*StackPtr == Stack) {
180 return EFI_ACCESS_DENIED;
181 }
182
183 //
184 // Pop the item off the stack
185 //
186 *StackPtr = *StackPtr - 1;
187 CopyMem (Data, *StackPtr, sizeof (EFI_HII_VALUE));
188 return EFI_SUCCESS;
189}
190
195VOID
197 VOID
198 )
199{
200 mCurrentExpressionPointer = mCurrentExpressionStack;
201 mFormExpressionPointer = mFormExpressionStack;
202 mStatementExpressionPointer = mStatementExpressionStack;
203 mOptionExpressionPointer = mOptionExpressionStack;
204}
205
217 IN VOID *Pointer
218 )
219{
220 EFI_HII_VALUE Data;
221
222 Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;
223 Data.Value.u64 = (UINT64)(UINTN)Pointer;
224
225 return PushStack (
226 &mCurrentExpressionStack,
227 &mCurrentExpressionPointer,
228 &mCurrentExpressionEnd,
229 &Data
230 );
231}
232
244 OUT VOID **Pointer
245 )
246{
247 EFI_STATUS Status;
248 EFI_HII_VALUE Data;
249
250 Status = PopStack (
251 mCurrentExpressionStack,
252 &mCurrentExpressionPointer,
253 &Data
254 );
255
256 *Pointer = (VOID *)(UINTN)Data.Value.u64;
257
258 return Status;
259}
260
265VOID
267 VOID
268 )
269{
270 mMapExpressionListPointer = mMapExpressionListStack;
271}
272
290 IN OUT FORM_EXPRESSION ***Stack,
291 IN OUT FORM_EXPRESSION ***StackPtr,
292 IN OUT FORM_EXPRESSION ***StackEnd,
293 IN UINTN MemberSize
294 )
295{
296 UINTN Size;
297 FORM_EXPRESSION **NewStack;
298
299 Size = EXPRESSION_STACK_SIZE_INCREMENT;
300 if (*StackPtr != NULL) {
301 Size = Size + (*StackEnd - *Stack);
302 }
303
304 NewStack = AllocatePool (Size * MemberSize);
305 if (NewStack == NULL) {
306 return EFI_OUT_OF_RESOURCES;
307 }
308
309 if (*StackPtr != NULL) {
310 //
311 // Copy from Old Stack to the New Stack
312 //
313 CopyMem (
314 NewStack,
315 *Stack,
316 (*StackEnd - *Stack) * MemberSize
317 );
318
319 //
320 // Free The Old Stack
321 //
322 FreePool (*Stack);
323 }
324
325 //
326 // Make the Stack pointer point to the old data in the new stack
327 //
328 *StackPtr = NewStack + (*StackPtr - *Stack);
329 *Stack = NewStack;
330 *StackEnd = NewStack + Size;
331
332 return EFI_SUCCESS;
333}
334
349 IN OUT FORM_EXPRESSION ***Stack,
350 IN OUT FORM_EXPRESSION ***StackPtr,
351 IN OUT FORM_EXPRESSION ***StackEnd,
352 IN FORM_EXPRESSION **Data
353 )
354{
355 EFI_STATUS Status;
356
357 //
358 // Check for a stack overflow condition
359 //
360 if (*StackPtr >= *StackEnd) {
361 //
362 // Grow the stack
363 //
364 Status = GrowConditionalStack (Stack, StackPtr, StackEnd, sizeof (FORM_EXPRESSION *));
365 if (EFI_ERROR (Status)) {
366 return Status;
367 }
368 }
369
370 //
371 // Push the item onto the stack
372 //
373 CopyMem (*StackPtr, Data, sizeof (FORM_EXPRESSION *));
374 *StackPtr = *StackPtr + 1;
375
376 return EFI_SUCCESS;
377}
378
392 IN FORM_EXPRESSION **Stack,
393 IN OUT FORM_EXPRESSION ***StackPtr,
394 OUT FORM_EXPRESSION **Data
395 )
396{
397 //
398 // Check for a stack underflow condition
399 //
400 if (*StackPtr == Stack) {
401 return EFI_ACCESS_DENIED;
402 }
403
404 //
405 // Pop the item off the stack
406 //
407 *StackPtr = *StackPtr - 1;
408 CopyMem (Data, *StackPtr, sizeof (FORM_EXPRESSION *));
409 return EFI_SUCCESS;
410}
411
422INTN
424 IN EXPRESS_LEVEL Level
425 )
426{
427 switch (Level) {
428 case ExpressForm:
429 return mFormExpressionPointer - mFormExpressionStack;
430 case ExpressStatement:
431 return mStatementExpressionPointer - mStatementExpressionStack;
432 case ExpressOption:
433 return mOptionExpressionPointer - mOptionExpressionStack;
434 default:
435 ASSERT (FALSE);
436 return -1;
437 }
438}
439
451 IN EXPRESS_LEVEL Level
452 )
453{
454 switch (Level) {
455 case ExpressForm:
456 return mFormExpressionStack;
457 case ExpressStatement:
458 return mStatementExpressionStack;
459 case ExpressOption:
460 return mOptionExpressionStack;
461 default:
462 ASSERT (FALSE);
463 return NULL;
464 }
465}
466
480 IN FORM_EXPRESSION *Pointer,
481 IN EXPRESS_LEVEL Level
482 )
483{
484 switch (Level) {
485 case ExpressForm:
486 return PushConditionalStack (
487 &mFormExpressionStack,
488 &mFormExpressionPointer,
489 &mFormExpressionEnd,
490 &Pointer
491 );
492 case ExpressStatement:
493 return PushConditionalStack (
494 &mStatementExpressionStack,
495 &mStatementExpressionPointer,
496 &mStatementExpressionEnd,
497 &Pointer
498 );
499 case ExpressOption:
500 return PushConditionalStack (
501 &mOptionExpressionStack,
502 &mOptionExpressionPointer,
503 &mOptionExpressionEnd,
504 &Pointer
505 );
506 default:
507 ASSERT (FALSE);
508 return EFI_INVALID_PARAMETER;
509 }
510}
511
524 IN EXPRESS_LEVEL Level
525 )
526{
527 FORM_EXPRESSION *Pointer;
528
529 switch (Level) {
530 case ExpressForm:
531 return PopConditionalStack (
532 mFormExpressionStack,
533 &mFormExpressionPointer,
534 &Pointer
535 );
536
537 case ExpressStatement:
538 return PopConditionalStack (
539 mStatementExpressionStack,
540 &mStatementExpressionPointer,
541 &Pointer
542 );
543
544 case ExpressOption:
545 return PopConditionalStack (
546 mOptionExpressionStack,
547 &mOptionExpressionPointer,
548 &Pointer
549 );
550
551 default:
552 ASSERT (FALSE);
553 return EFI_INVALID_PARAMETER;
554 }
555}
556
568 IN VOID *Pointer
569 )
570{
571 EFI_HII_VALUE Data;
572
573 Data.Type = EFI_IFR_TYPE_NUM_SIZE_64;
574 Data.Value.u64 = (UINT64)(UINTN)Pointer;
575
576 return PushStack (
577 &mMapExpressionListStack,
578 &mMapExpressionListPointer,
579 &mMapExpressionListEnd,
580 &Data
581 );
582}
583
595 OUT VOID **Pointer
596 )
597{
598 EFI_STATUS Status;
599 EFI_HII_VALUE Data;
600
601 Status = PopStack (
602 mMapExpressionListStack,
603 &mMapExpressionListPointer,
604 &Data
605 );
606
607 *Pointer = (VOID *)(UINTN)Data.Value.u64;
608
609 return Status;
610}
611
616VOID
618 VOID
619 )
620{
621 mOpCodeScopeStackPointer = mOpCodeScopeStack;
622}
623
636 IN UINT8 Operand
637 )
638{
639 EFI_HII_VALUE Data;
640
641 Data.Type = EFI_IFR_TYPE_NUM_SIZE_8;
642 Data.Value.u8 = Operand;
643
644 return PushStack (
645 &mOpCodeScopeStack,
646 &mOpCodeScopeStackPointer,
647 &mOpCodeScopeStackEnd,
648 &Data
649 );
650}
651
664 OUT UINT8 *Operand
665 )
666{
667 EFI_STATUS Status;
668 EFI_HII_VALUE Data;
669
670 Status = PopStack (
671 mOpCodeScopeStack,
672 &mOpCodeScopeStackPointer,
673 &Data
674 );
675
676 *Operand = Data.Value.u8;
677
678 return Status;
679}
680
693 IN EFI_HII_VALUE *Value
694 )
695{
696 return PushStack (
697 &mExpressionEvaluationStack,
698 &mExpressionEvaluationStackPointer,
699 &mExpressionEvaluationStackEnd,
700 Value
701 );
702}
703
715 OUT EFI_HII_VALUE *Value
716 )
717{
718 return PopStack (
719 mExpressionEvaluationStack + mExpressionEvaluationStackOffset,
720 &mExpressionEvaluationStackPointer,
721 Value
722 );
723}
724
730UINTN
732 VOID
733 )
734{
735 UINTN TempStackOffset;
736
737 TempStackOffset = mExpressionEvaluationStackOffset;
738 mExpressionEvaluationStackOffset = mExpressionEvaluationStackPointer - mExpressionEvaluationStack;
739 return TempStackOffset;
740}
741
748VOID
750 UINTN StackOffset
751 )
752{
753 mExpressionEvaluationStackOffset = StackOffset;
754}
755
768 IN FORM_BROWSER_FORMSET *FormSet,
769 IN UINT16 FormId
770 )
771{
772 LIST_ENTRY *Link;
773 FORM_BROWSER_FORM *Form;
774
775 Link = GetFirstNode (&FormSet->FormListHead);
776 while (!IsNull (&FormSet->FormListHead, Link)) {
777 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
778
779 if (Form->FormId == FormId) {
780 return Form;
781 }
782
783 Link = GetNextNode (&FormSet->FormListHead, Link);
784 }
785
786 return NULL;
787}
788
801 IN FORM_BROWSER_FORM *Form,
802 IN UINT16 QuestionId
803 )
804{
805 LIST_ENTRY *Link;
806 FORM_BROWSER_STATEMENT *Question;
807
808 if ((QuestionId == 0) || (Form == NULL)) {
809 //
810 // The value of zero is reserved
811 //
812 return NULL;
813 }
814
815 Link = GetFirstNode (&Form->StatementListHead);
816 while (!IsNull (&Form->StatementListHead, Link)) {
817 Question = FORM_BROWSER_STATEMENT_FROM_LINK (Link);
818
819 if (Question->QuestionId == QuestionId) {
820 return Question;
821 }
822
823 Link = GetNextNode (&Form->StatementListHead, Link);
824 }
825
826 return NULL;
827}
828
842 IN FORM_BROWSER_FORMSET *FormSet,
843 IN FORM_BROWSER_FORM *Form,
844 IN UINT16 QuestionId
845 )
846{
847 LIST_ENTRY *Link;
848 FORM_BROWSER_STATEMENT *Question;
849
850 //
851 // Search in the form scope first
852 //
853 Question = IdToQuestion2 (Form, QuestionId);
854 if (Question != NULL) {
855 return Question;
856 }
857
858 //
859 // Search in the formset scope
860 //
861 Link = GetFirstNode (&FormSet->FormListHead);
862 while (!IsNull (&FormSet->FormListHead, Link)) {
863 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
864
865 Question = IdToQuestion2 (Form, QuestionId);
866 if (Question != NULL) {
867 //
868 // EFI variable storage may be updated by Callback() asynchronous,
869 // to keep synchronous, always reload the Question Value.
870 //
871 if (Question->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {
872 GetQuestionValue (FormSet, Form, Question, GetSetValueWithHiiDriver);
873 }
874
875 return Question;
876 }
877
878 Link = GetNextNode (&FormSet->FormListHead, Link);
879 }
880
881 return NULL;
882}
883
896 IN FORM_BROWSER_FORM *Form,
897 IN UINT8 RuleId
898 )
899{
900 LIST_ENTRY *Link;
901 FORM_EXPRESSION *Expression;
902
903 Link = GetFirstNode (&Form->ExpressionListHead);
904 while (!IsNull (&Form->ExpressionListHead, Link)) {
905 Expression = FORM_EXPRESSION_FROM_LINK (Link);
906
907 if ((Expression->Type == EFI_HII_EXPRESSION_RULE) && (Expression->RuleId == RuleId)) {
908 return Expression;
909 }
910
911 Link = GetNextNode (&Form->ExpressionListHead, Link);
912 }
913
914 return NULL;
915}
916
926 VOID
927 )
928{
929 EFI_STATUS Status;
930
931 if (mUnicodeCollation != NULL) {
932 return EFI_SUCCESS;
933 }
934
935 //
936 // BUGBUG: Proper impelmentation is to locate all Unicode Collation Protocol
937 // instances first and then select one which support English language.
938 // Current implementation just pick the first instance.
939 //
940 Status = gBS->LocateProtocol (
941 &gEfiUnicodeCollation2ProtocolGuid,
942 NULL,
943 (VOID **)&mUnicodeCollation
944 );
945 return Status;
946}
947
954VOID
956 IN CHAR16 *String
957 )
958{
959 while (*String != 0) {
960 if ((*String >= 'a') && (*String <= 'z')) {
961 *String = (UINT16)((*String) & ((UINT16) ~0x20));
962 }
963
964 String++;
965 }
966}
967
980BOOLEAN
982 IN EFI_HII_VALUE *Value
983 )
984{
985 switch (Value->Type) {
986 case EFI_IFR_TYPE_BUFFER:
987 case EFI_IFR_TYPE_DATE:
988 case EFI_IFR_TYPE_TIME:
989 case EFI_IFR_TYPE_REF:
990 return TRUE;
991
992 default:
993 return FALSE;
994 }
995}
996
1006BOOLEAN
1008 IN EFI_HII_VALUE *Value
1009 )
1010{
1011 switch (Value->Type) {
1012 case EFI_IFR_TYPE_NUM_SIZE_8:
1013 case EFI_IFR_TYPE_NUM_SIZE_16:
1014 case EFI_IFR_TYPE_NUM_SIZE_32:
1015 case EFI_IFR_TYPE_NUM_SIZE_64:
1016 case EFI_IFR_TYPE_BOOLEAN:
1017 return TRUE;
1018
1019 default:
1020 return FALSE;
1021 }
1022}
1023
1035UINT16
1037 IN EFI_HII_VALUE *Value
1038 )
1039{
1040 switch (Value->Type) {
1041 case EFI_IFR_TYPE_BUFFER:
1042 return Value->BufferLen;
1043
1044 case EFI_IFR_TYPE_DATE:
1045 return (UINT16)sizeof (EFI_HII_DATE);
1046
1047 case EFI_IFR_TYPE_TIME:
1048 return (UINT16)sizeof (EFI_HII_TIME);
1049
1050 case EFI_IFR_TYPE_REF:
1051 return (UINT16)sizeof (EFI_HII_REF);
1052
1053 default:
1054 return 0;
1055 }
1056}
1057
1069UINT8 *
1071 IN EFI_HII_VALUE *Value
1072 )
1073{
1074 switch (Value->Type) {
1075 case EFI_IFR_TYPE_BUFFER:
1076 return Value->Buffer;
1077
1078 case EFI_IFR_TYPE_DATE:
1079 return (UINT8 *)(&Value->Value.date);
1080
1081 case EFI_IFR_TYPE_TIME:
1082 return (UINT8 *)(&Value->Value.time);
1083
1084 case EFI_IFR_TYPE_REF:
1085 return (UINT8 *)(&Value->Value.ref);
1086
1087 default:
1088 return NULL;
1089 }
1090}
1091
1105 IN FORM_BROWSER_FORMSET *FormSet,
1106 IN UINT8 Format,
1107 OUT EFI_HII_VALUE *Result
1108 )
1109{
1110 EFI_STATUS Status;
1111 EFI_HII_VALUE Value;
1112 CHAR16 *String;
1113 CHAR16 *PrintFormat;
1114 CHAR16 Buffer[MAXIMUM_VALUE_CHARACTERS];
1115 UINT8 *TmpBuf;
1116 UINT8 *SrcBuf;
1117 UINTN SrcLen;
1118 UINTN BufferSize;
1119
1120 Status = PopExpression (&Value);
1121 if (EFI_ERROR (Status)) {
1122 return Status;
1123 }
1124
1125 switch (Value.Type) {
1126 case EFI_IFR_TYPE_NUM_SIZE_8:
1127 case EFI_IFR_TYPE_NUM_SIZE_16:
1128 case EFI_IFR_TYPE_NUM_SIZE_32:
1129 case EFI_IFR_TYPE_NUM_SIZE_64:
1130 BufferSize = MAXIMUM_VALUE_CHARACTERS * sizeof (CHAR16);
1131 switch (Format) {
1133 case EFI_IFR_STRING_SIGNED_DEC:
1134 PrintFormat = L"%ld";
1135 break;
1136
1137 case EFI_IFR_STRING_LOWERCASE_HEX:
1138 PrintFormat = L"%lx";
1139 break;
1140
1141 case EFI_IFR_STRING_UPPERCASE_HEX:
1142 PrintFormat = L"%lX";
1143 break;
1144
1145 default:
1146 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1147 return EFI_SUCCESS;
1148 }
1149
1150 UnicodeSPrint (Buffer, BufferSize, PrintFormat, Value.Value.u64);
1151 String = Buffer;
1152 break;
1153
1154 case EFI_IFR_TYPE_STRING:
1155 CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));
1156 return EFI_SUCCESS;
1157
1158 case EFI_IFR_TYPE_BOOLEAN:
1159 String = (Value.Value.b) ? L"True" : L"False";
1160 break;
1161
1162 case EFI_IFR_TYPE_BUFFER:
1163 case EFI_IFR_TYPE_DATE:
1164 case EFI_IFR_TYPE_TIME:
1165 case EFI_IFR_TYPE_REF:
1166 //
1167 // + 3 is base on the unicode format, the length may be odd number,
1168 // so need 1 byte to align, also need 2 bytes for L'\0'.
1169 //
1170 if (Value.Type == EFI_IFR_TYPE_BUFFER) {
1171 SrcLen = Value.BufferLen;
1172 SrcBuf = Value.Buffer;
1173 } else {
1174 SrcBuf = GetBufferForValue (&Value);
1175 SrcLen = GetLengthForValue (&Value);
1176 }
1177
1178 TmpBuf = AllocateZeroPool (SrcLen + 3);
1179 ASSERT (TmpBuf != NULL);
1180 if (Format == EFI_IFR_STRING_ASCII) {
1181 CopyMem (TmpBuf, SrcBuf, SrcLen);
1182 PrintFormat = L"%a";
1183 } else {
1184 // Format == EFI_IFR_STRING_UNICODE
1185 CopyMem (TmpBuf, SrcBuf, SrcLen * sizeof (CHAR16));
1186 PrintFormat = L"%s";
1187 }
1188
1189 UnicodeSPrint (Buffer, sizeof (Buffer), PrintFormat, TmpBuf);
1190 String = Buffer;
1191 FreePool (TmpBuf);
1192 if (Value.Type == EFI_IFR_TYPE_BUFFER) {
1193 FreePool (Value.Buffer);
1194 }
1195
1196 break;
1197
1198 default:
1199 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1200 return EFI_SUCCESS;
1201 }
1202
1203 Result->Type = EFI_IFR_TYPE_STRING;
1204 Result->Value.string = NewString (String, FormSet->HiiHandle);
1205 return EFI_SUCCESS;
1206}
1207
1220 IN FORM_BROWSER_FORMSET *FormSet,
1221 OUT EFI_HII_VALUE *Result
1222 )
1223{
1224 EFI_STATUS Status;
1225 EFI_HII_VALUE Value;
1226 CHAR16 *String;
1227 CHAR16 *StringPtr;
1228
1229 Status = PopExpression (&Value);
1230 if (EFI_ERROR (Status)) {
1231 return Status;
1232 }
1233
1234 if ((Value.Type >= EFI_IFR_TYPE_OTHER) && !IsTypeInBuffer (&Value)) {
1235 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1236 return EFI_SUCCESS;
1237 }
1238
1239 Status = EFI_SUCCESS;
1240 if (Value.Type == EFI_IFR_TYPE_STRING) {
1241 String = GetToken (Value.Value.string, FormSet->HiiHandle);
1242 if (String == NULL) {
1243 return EFI_NOT_FOUND;
1244 }
1245
1246 IfrStrToUpper (String);
1247 StringPtr = StrStr (String, L"0X");
1248 if (StringPtr != NULL) {
1249 //
1250 // Hex string
1251 //
1252 Result->Value.u64 = StrHexToUint64 (String);
1253 } else {
1254 //
1255 // decimal string
1256 //
1257 Result->Value.u64 = StrDecimalToUint64 (String);
1258 }
1259
1260 FreePool (String);
1261 } else if (IsTypeInBuffer (&Value)) {
1262 if (GetLengthForValue (&Value) > 8) {
1263 if (Value.Type == EFI_IFR_TYPE_BUFFER) {
1264 FreePool (Value.Buffer);
1265 }
1266
1267 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1268 return EFI_SUCCESS;
1269 }
1270
1271 ASSERT (GetBufferForValue (&Value) != NULL);
1272 Result->Value.u64 = *(UINT64 *)GetBufferForValue (&Value);
1273
1274 if (Value.Type == EFI_IFR_TYPE_BUFFER) {
1275 FreePool (Value.Buffer);
1276 }
1277 } else {
1278 CopyMem (Result, &Value, sizeof (EFI_HII_VALUE));
1279 }
1280
1281 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1282 return Status;
1283}
1284
1297 IN FORM_BROWSER_FORMSET *FormSet,
1298 OUT EFI_HII_VALUE *Result
1299 )
1300{
1301 EFI_STATUS Status;
1302 EFI_HII_VALUE Value[2];
1303 CHAR16 *String[2];
1304 UINTN Index;
1305 CHAR16 *StringPtr;
1306 UINTN Size;
1307 UINT16 Length0;
1308 UINT16 Length1;
1309 UINT8 *TmpBuf;
1310 UINTN MaxLen;
1311
1312 //
1313 // String[0] - The second string
1314 // String[1] - The first string
1315 //
1316 String[0] = NULL;
1317 String[1] = NULL;
1318 StringPtr = NULL;
1319 Status = EFI_SUCCESS;
1320 ZeroMem (Value, sizeof (Value));
1321
1322 Status = PopExpression (&Value[0]);
1323 if (EFI_ERROR (Status)) {
1324 goto Done;
1325 }
1326
1327 Status = PopExpression (&Value[1]);
1328 if (EFI_ERROR (Status)) {
1329 goto Done;
1330 }
1331
1332 for (Index = 0; Index < 2; Index++) {
1333 if ((Value[Index].Type != EFI_IFR_TYPE_STRING) && !IsTypeInBuffer (&Value[Index])) {
1334 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1335 Status = EFI_SUCCESS;
1336 goto Done;
1337 }
1338
1339 if (Value[Index].Type == EFI_IFR_TYPE_STRING) {
1340 String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);
1341 if (String[Index] == NULL) {
1342 Status = EFI_NOT_FOUND;
1343 goto Done;
1344 }
1345 }
1346 }
1347
1348 if (Value[0].Type == EFI_IFR_TYPE_STRING) {
1349 Size = StrSize (String[0]);
1350 MaxLen = (StrSize (String[1]) + Size) / sizeof (CHAR16);
1351 StringPtr = AllocatePool (MaxLen * sizeof (CHAR16));
1352 ASSERT (StringPtr != NULL);
1353 StrCpyS (StringPtr, MaxLen, String[1]);
1354 StrCatS (StringPtr, MaxLen, String[0]);
1355
1356 Result->Type = EFI_IFR_TYPE_STRING;
1357 Result->Value.string = NewString (StringPtr, FormSet->HiiHandle);
1358 } else {
1359 Result->Type = EFI_IFR_TYPE_BUFFER;
1360 Length0 = GetLengthForValue (&Value[0]);
1361 Length1 = GetLengthForValue (&Value[1]);
1362 Result->BufferLen = (UINT16)(Length0 + Length1);
1363
1364 Result->Buffer = AllocateZeroPool (Result->BufferLen);
1365 ASSERT (Result->Buffer != NULL);
1366
1367 TmpBuf = GetBufferForValue (&Value[0]);
1368 ASSERT (TmpBuf != NULL);
1369 CopyMem (Result->Buffer, TmpBuf, Length0);
1370 TmpBuf = GetBufferForValue (&Value[1]);
1371 ASSERT (TmpBuf != NULL);
1372 CopyMem (&Result->Buffer[Length0], TmpBuf, Length1);
1373 }
1374
1375Done:
1376 if (Value[0].Buffer != NULL) {
1377 FreePool (Value[0].Buffer);
1378 }
1379
1380 if (Value[1].Buffer != NULL) {
1381 FreePool (Value[1].Buffer);
1382 }
1383
1384 if (String[0] != NULL) {
1385 FreePool (String[0]);
1386 }
1387
1388 if (String[1] != NULL) {
1389 FreePool (String[1]);
1390 }
1391
1392 if (StringPtr != NULL) {
1393 FreePool (StringPtr);
1394 }
1395
1396 return Status;
1397}
1398
1411 IN FORM_BROWSER_FORMSET *FormSet,
1412 OUT EFI_HII_VALUE *Result
1413 )
1414{
1415 EFI_STATUS Status;
1416 EFI_HII_VALUE Value[2];
1417 CHAR16 *String[2];
1418 UINTN Index;
1419
1420 //
1421 // String[0] - The string to search
1422 // String[1] - pattern
1423 //
1424 String[0] = NULL;
1425 String[1] = NULL;
1426 Status = EFI_SUCCESS;
1427 ZeroMem (Value, sizeof (Value));
1428
1429 Status = PopExpression (&Value[0]);
1430 if (EFI_ERROR (Status)) {
1431 goto Done;
1432 }
1433
1434 Status = PopExpression (&Value[1]);
1435 if (EFI_ERROR (Status)) {
1436 goto Done;
1437 }
1438
1439 for (Index = 0; Index < 2; Index++) {
1440 if (Value[Index].Type != EFI_IFR_TYPE_STRING) {
1441 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1442 Status = EFI_SUCCESS;
1443 goto Done;
1444 }
1445
1446 String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);
1447 if (String[Index] == NULL) {
1448 Status = EFI_NOT_FOUND;
1449 goto Done;
1450 }
1451 }
1452
1453 Result->Type = EFI_IFR_TYPE_BOOLEAN;
1454 Result->Value.b = mUnicodeCollation->MetaiMatch (mUnicodeCollation, String[0], String[1]);
1455
1456Done:
1457 if (String[0] != NULL) {
1458 FreePool (String[0]);
1459 }
1460
1461 if (String[1] != NULL) {
1462 FreePool (String[1]);
1463 }
1464
1465 return Status;
1466}
1467
1481 IN FORM_BROWSER_FORMSET *FormSet,
1482 IN EFI_GUID *SyntaxType,
1483 OUT EFI_HII_VALUE *Result
1484 )
1485{
1486 EFI_STATUS Status;
1487 EFI_HII_VALUE Value[2];
1488 CHAR16 *String[2];
1489 UINTN Index;
1490 UINTN GuidIndex;
1491 EFI_HANDLE *HandleBuffer;
1492 UINTN BufferSize;
1493 EFI_REGULAR_EXPRESSION_PROTOCOL *RegularExpressionProtocol;
1494 UINTN RegExSyntaxTypeListSize;
1495 EFI_REGEX_SYNTAX_TYPE *RegExSyntaxTypeList;
1496 UINTN CapturesCount;
1497
1498 //
1499 // String[0] - The string to search
1500 // String[1] - pattern
1501 //
1502 String[0] = NULL;
1503 String[1] = NULL;
1504 HandleBuffer = NULL;
1505 RegExSyntaxTypeList = NULL;
1506 Status = EFI_SUCCESS;
1507 ZeroMem (Value, sizeof (Value));
1508
1509 Status = PopExpression (&Value[0]);
1510 if (EFI_ERROR (Status)) {
1511 goto Done;
1512 }
1513
1514 Status = PopExpression (&Value[1]);
1515 if (EFI_ERROR (Status)) {
1516 goto Done;
1517 }
1518
1519 for (Index = 0; Index < 2; Index++) {
1520 if (Value[Index].Type != EFI_IFR_TYPE_STRING) {
1521 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1522 Status = EFI_SUCCESS;
1523 goto Done;
1524 }
1525
1526 String[Index] = GetToken (Value[Index].Value.string, FormSet->HiiHandle);
1527 if (String[Index] == NULL) {
1528 Status = EFI_NOT_FOUND;
1529 goto Done;
1530 }
1531 }
1532
1533 BufferSize = 0;
1534 HandleBuffer = NULL;
1535 Status = gBS->LocateHandle (
1536 ByProtocol,
1537 &gEfiRegularExpressionProtocolGuid,
1538 NULL,
1539 &BufferSize,
1540 HandleBuffer
1541 );
1542 if (Status == EFI_BUFFER_TOO_SMALL) {
1543 HandleBuffer = AllocateZeroPool (BufferSize);
1544 if (HandleBuffer == NULL) {
1545 Status = EFI_OUT_OF_RESOURCES;
1546 goto Done;
1547 }
1548
1549 Status = gBS->LocateHandle (
1550 ByProtocol,
1551 &gEfiRegularExpressionProtocolGuid,
1552 NULL,
1553 &BufferSize,
1554 HandleBuffer
1555 );
1556 }
1557
1558 if (EFI_ERROR (Status)) {
1559 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1560 Status = EFI_SUCCESS;
1561 goto Done;
1562 }
1563
1564 ASSERT (HandleBuffer != NULL);
1565 for ( Index = 0; Index < BufferSize / sizeof (EFI_HANDLE); Index++) {
1566 Status = gBS->HandleProtocol (
1567 HandleBuffer[Index],
1568 &gEfiRegularExpressionProtocolGuid,
1569 (VOID **)&RegularExpressionProtocol
1570 );
1571 if (EFI_ERROR (Status)) {
1572 goto Done;
1573 }
1574
1575 RegExSyntaxTypeListSize = 0;
1576 RegExSyntaxTypeList = NULL;
1577
1578 Status = RegularExpressionProtocol->GetInfo (
1579 RegularExpressionProtocol,
1580 &RegExSyntaxTypeListSize,
1581 RegExSyntaxTypeList
1582 );
1583 if (Status == EFI_BUFFER_TOO_SMALL) {
1584 RegExSyntaxTypeList = AllocateZeroPool (RegExSyntaxTypeListSize);
1585 if (RegExSyntaxTypeList == NULL) {
1586 Status = EFI_OUT_OF_RESOURCES;
1587 goto Done;
1588 }
1589
1590 Status = RegularExpressionProtocol->GetInfo (
1591 RegularExpressionProtocol,
1592 &RegExSyntaxTypeListSize,
1593 RegExSyntaxTypeList
1594 );
1595 } else if (EFI_ERROR (Status)) {
1596 goto Done;
1597 }
1598
1599 for (GuidIndex = 0; GuidIndex < RegExSyntaxTypeListSize / sizeof (EFI_GUID); GuidIndex++) {
1600 if (CompareGuid (&RegExSyntaxTypeList[GuidIndex], SyntaxType)) {
1601 //
1602 // Find the match type, return the value.
1603 //
1604 Result->Type = EFI_IFR_TYPE_BOOLEAN;
1605 Status = RegularExpressionProtocol->MatchString (
1606 RegularExpressionProtocol,
1607 String[0],
1608 String[1],
1609 SyntaxType,
1610 &Result->Value.b,
1611 NULL,
1612 &CapturesCount
1613 );
1614 goto Done;
1615 }
1616 }
1617
1618 if (RegExSyntaxTypeList != NULL) {
1619 FreePool (RegExSyntaxTypeList);
1620 }
1621 }
1622
1623 //
1624 // Type specified by SyntaxType is not supported
1625 // in any of the EFI_REGULAR_EXPRESSION_PROTOCOL instances.
1626 //
1627 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1628 Status = EFI_SUCCESS;
1629
1630Done:
1631 if (String[0] != NULL) {
1632 FreePool (String[0]);
1633 }
1634
1635 if (String[1] != NULL) {
1636 FreePool (String[1]);
1637 }
1638
1639 if (RegExSyntaxTypeList != NULL) {
1640 FreePool (RegExSyntaxTypeList);
1641 }
1642
1643 if (HandleBuffer != NULL) {
1644 FreePool (HandleBuffer);
1645 }
1646
1647 return Status;
1648}
1649
1663 IN FORM_BROWSER_FORMSET *FormSet,
1664 IN UINT8 Format,
1665 OUT EFI_HII_VALUE *Result
1666 )
1667{
1668 EFI_STATUS Status;
1669 EFI_HII_VALUE Value[3];
1670 CHAR16 *String[2];
1671 UINTN Base;
1672 CHAR16 *StringPtr;
1673 UINTN Index;
1674
1675 ZeroMem (Value, sizeof (Value));
1676
1677 if (Format > EFI_IFR_FF_CASE_INSENSITIVE) {
1678 return EFI_INVALID_PARAMETER;
1679 }
1680
1681 Status = PopExpression (&Value[0]);
1682 if (EFI_ERROR (Status)) {
1683 return Status;
1684 }
1685
1686 Status = PopExpression (&Value[1]);
1687 if (EFI_ERROR (Status)) {
1688 return Status;
1689 }
1690
1691 Status = PopExpression (&Value[2]);
1692 if (EFI_ERROR (Status)) {
1693 return Status;
1694 }
1695
1696 if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
1697 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1698 return EFI_SUCCESS;
1699 }
1700
1701 Base = (UINTN)Value[0].Value.u64;
1702
1703 //
1704 // String[0] - sub-string
1705 // String[1] - The string to search
1706 //
1707 String[0] = NULL;
1708 String[1] = NULL;
1709 for (Index = 0; Index < 2; Index++) {
1710 if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
1711 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1712 Status = EFI_SUCCESS;
1713 goto Done;
1714 }
1715
1716 String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);
1717 if (String[Index] == NULL) {
1718 Status = EFI_NOT_FOUND;
1719 goto Done;
1720 }
1721
1722 if (Format == EFI_IFR_FF_CASE_INSENSITIVE) {
1723 //
1724 // Case insensitive, convert both string to upper case
1725 //
1726 IfrStrToUpper (String[Index]);
1727 }
1728 }
1729
1730 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;
1731 if (Base >= StrLen (String[1])) {
1732 Result->Value.u64 = 0xFFFFFFFFFFFFFFFFULL;
1733 } else {
1734 StringPtr = StrStr (String[1] + Base, String[0]);
1735 Result->Value.u64 = (StringPtr == NULL) ? 0xFFFFFFFFFFFFFFFFULL : (StringPtr - String[1]);
1736 }
1737
1738Done:
1739 if (String[0] != NULL) {
1740 FreePool (String[0]);
1741 }
1742
1743 if (String[1] != NULL) {
1744 FreePool (String[1]);
1745 }
1746
1747 return Status;
1748}
1749
1762 IN FORM_BROWSER_FORMSET *FormSet,
1763 OUT EFI_HII_VALUE *Result
1764 )
1765{
1766 EFI_STATUS Status;
1767 EFI_HII_VALUE Value[3];
1768 CHAR16 *String;
1769 UINTN Base;
1770 UINTN Length;
1771 CHAR16 *SubString;
1772 UINT16 BufferLen;
1773 UINT8 *Buffer;
1774
1775 ZeroMem (Value, sizeof (Value));
1776
1777 Status = PopExpression (&Value[0]);
1778 if (EFI_ERROR (Status)) {
1779 return Status;
1780 }
1781
1782 Status = PopExpression (&Value[1]);
1783 if (EFI_ERROR (Status)) {
1784 return Status;
1785 }
1786
1787 Status = PopExpression (&Value[2]);
1788 if (EFI_ERROR (Status)) {
1789 return Status;
1790 }
1791
1792 if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
1793 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1794 return EFI_SUCCESS;
1795 }
1796
1797 Length = (UINTN)Value[0].Value.u64;
1798
1799 if (Value[1].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
1800 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1801 return EFI_SUCCESS;
1802 }
1803
1804 Base = (UINTN)Value[1].Value.u64;
1805
1806 if ((Value[2].Type != EFI_IFR_TYPE_STRING) && !IsTypeInBuffer (&Value[2])) {
1807 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1808 return EFI_SUCCESS;
1809 }
1810
1811 if (Value[2].Type == EFI_IFR_TYPE_STRING) {
1812 String = GetToken (Value[2].Value.string, FormSet->HiiHandle);
1813 if (String == NULL) {
1814 return EFI_NOT_FOUND;
1815 }
1816
1817 if ((Length == 0) || (Base >= StrLen (String))) {
1818 SubString = gEmptyString;
1819 } else {
1820 SubString = String + Base;
1821 if ((Base + Length) < StrLen (String)) {
1822 SubString[Length] = L'\0';
1823 }
1824 }
1825
1826 Result->Type = EFI_IFR_TYPE_STRING;
1827 Result->Value.string = NewString (SubString, FormSet->HiiHandle);
1828
1829 FreePool (String);
1830 } else {
1831 BufferLen = GetLengthForValue (&Value[2]);
1832 Buffer = GetBufferForValue (&Value[2]);
1833
1834 Result->Type = EFI_IFR_TYPE_BUFFER;
1835 if ((Length == 0) || (Base >= BufferLen)) {
1836 Result->BufferLen = 0;
1837 Result->Buffer = NULL;
1838 } else {
1839 Result->BufferLen = (UINT16)((BufferLen - Base) < Length ? (BufferLen - Base) : Length);
1840 Result->Buffer = AllocateZeroPool (Result->BufferLen);
1841 ASSERT (Result->Buffer != NULL);
1842 CopyMem (Result->Buffer, &Buffer[Base], Result->BufferLen);
1843 }
1844
1845 if (Value[2].Type == EFI_IFR_TYPE_BUFFER) {
1846 FreePool (Value[2].Buffer);
1847 }
1848 }
1849
1850 return Status;
1851}
1852
1865 IN FORM_BROWSER_FORMSET *FormSet,
1866 OUT EFI_HII_VALUE *Result
1867 )
1868{
1869 EFI_STATUS Status;
1870 EFI_HII_VALUE Value[3];
1871 CHAR16 *String[2];
1872 UINTN Count;
1873 CHAR16 *Delimiter;
1874 CHAR16 *SubString;
1875 CHAR16 *StringPtr;
1876 UINTN Index;
1877
1878 ZeroMem (Value, sizeof (Value));
1879
1880 Status = PopExpression (&Value[0]);
1881 if (EFI_ERROR (Status)) {
1882 return Status;
1883 }
1884
1885 Status = PopExpression (&Value[1]);
1886 if (EFI_ERROR (Status)) {
1887 return Status;
1888 }
1889
1890 Status = PopExpression (&Value[2]);
1891 if (EFI_ERROR (Status)) {
1892 return Status;
1893 }
1894
1895 if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
1896 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1897 return EFI_SUCCESS;
1898 }
1899
1900 Count = (UINTN)Value[0].Value.u64;
1901
1902 //
1903 // String[0] - Delimiter
1904 // String[1] - The string to search
1905 //
1906 String[0] = NULL;
1907 String[1] = NULL;
1908 for (Index = 0; Index < 2; Index++) {
1909 if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
1910 Result->Type = EFI_IFR_TYPE_UNDEFINED;
1911 Status = EFI_SUCCESS;
1912 goto Done;
1913 }
1914
1915 String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);
1916 if (String[Index] == NULL) {
1917 Status = EFI_NOT_FOUND;
1918 goto Done;
1919 }
1920 }
1921
1922 Delimiter = String[0];
1923 SubString = String[1];
1924 while (Count > 0) {
1925 SubString = StrStr (SubString, Delimiter);
1926 if (SubString != NULL) {
1927 //
1928 // Skip over the delimiter
1929 //
1930 SubString = SubString + StrLen (Delimiter);
1931 } else {
1932 break;
1933 }
1934
1935 Count--;
1936 }
1937
1938 if (SubString == NULL) {
1939 //
1940 // nth delimited sub-string not found, push an empty string
1941 //
1942 SubString = gEmptyString;
1943 } else {
1944 //
1945 // Put a NULL terminator for nth delimited sub-string
1946 //
1947 StringPtr = StrStr (SubString, Delimiter);
1948 if (StringPtr != NULL) {
1949 *StringPtr = L'\0';
1950 }
1951 }
1952
1953 Result->Type = EFI_IFR_TYPE_STRING;
1954 Result->Value.string = NewString (SubString, FormSet->HiiHandle);
1955
1956Done:
1957 if (String[0] != NULL) {
1958 FreePool (String[0]);
1959 }
1960
1961 if (String[1] != NULL) {
1962 FreePool (String[1]);
1963 }
1964
1965 return Status;
1966}
1967
1981 IN FORM_BROWSER_FORMSET *FormSet,
1982 IN UINT8 Flags,
1983 OUT EFI_HII_VALUE *Result
1984 )
1985{
1986 EFI_STATUS Status;
1987 EFI_HII_VALUE Value[3];
1988 CHAR16 *String[2];
1989 CHAR16 *Charset;
1990 UINTN Base;
1991 UINTN Index;
1992 CHAR16 *StringPtr;
1993 BOOLEAN Found;
1994
1995 ZeroMem (Value, sizeof (Value));
1996
1997 Status = PopExpression (&Value[0]);
1998 if (EFI_ERROR (Status)) {
1999 return Status;
2000 }
2001
2002 Status = PopExpression (&Value[1]);
2003 if (EFI_ERROR (Status)) {
2004 return Status;
2005 }
2006
2007 Status = PopExpression (&Value[2]);
2008 if (EFI_ERROR (Status)) {
2009 return Status;
2010 }
2011
2012 if (Value[0].Type > EFI_IFR_TYPE_NUM_SIZE_64) {
2013 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2014 return EFI_SUCCESS;
2015 }
2016
2017 Base = (UINTN)Value[0].Value.u64;
2018
2019 //
2020 // String[0] - Charset
2021 // String[1] - The string to search
2022 //
2023 String[0] = NULL;
2024 String[1] = NULL;
2025 for (Index = 0; Index < 2; Index++) {
2026 if (Value[Index + 1].Type != EFI_IFR_TYPE_STRING) {
2027 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2028 Status = EFI_SUCCESS;
2029 goto Done;
2030 }
2031
2032 String[Index] = GetToken (Value[Index + 1].Value.string, FormSet->HiiHandle);
2033 if (String[Index] == NULL) {
2034 Status = EFI_NOT_FOUND;
2035 goto Done;
2036 }
2037 }
2038
2039 if (Base >= StrLen (String[1])) {
2040 Result->Type = EFI_IFR_TYPE_UNDEFINED;
2041 Status = EFI_SUCCESS;
2042 goto Done;
2043 }
2044
2045 Found = FALSE;
2046 StringPtr = String[1] + Base;
2047 Charset = String[0];
2048 while (*StringPtr != 0 && !Found) {
2049 Index = 0;
2050 while (Charset[Index] != 0) {
2051 if ((*StringPtr >= Charset[Index]) && (*StringPtr <= Charset[Index + 1])) {
2052 if (Flags == EFI_IFR_FLAGS_FIRST_MATCHING) {
2053 Found = TRUE;
2054 break;
2055 }
2056 } else {
2057 if (Flags == EFI_IFR_FLAGS_FIRST_NON_MATCHING) {
2058 Found = TRUE;
2059 break;
2060 }
2061 }
2062
2063 //
2064 // Skip characters pair representing low-end of a range and high-end of a range
2065 //
2066 Index += 2;
2067 }
2068
2069 if (!Found) {
2070 StringPtr++;
2071 }
2072 }
2073
2074 Result->Type = EFI_IFR_TYPE_NUM_SIZE_64;
2075 Result->Value.u64 = StringPtr - String[1];
2076
2077Done:
2078 if (String[0] != NULL) {
2079 FreePool (String[0]);
2080 }
2081
2082 if (String[1] != NULL) {
2083 FreePool (String[1]);
2084 }
2085
2086 return Status;
2087}
2088
2095VOID
2097 IN EFI_HII_VALUE *Value
2098 )
2099{
2100 UINT64 Temp;
2101
2102 Temp = 0;
2103 switch (Value->Type) {
2104 case EFI_IFR_TYPE_NUM_SIZE_8:
2105 Temp = Value->Value.u8;
2106 break;
2107
2108 case EFI_IFR_TYPE_NUM_SIZE_16:
2109 Temp = Value->Value.u16;
2110 break;
2111
2112 case EFI_IFR_TYPE_NUM_SIZE_32:
2113 Temp = Value->Value.u32;
2114 break;
2115
2116 case EFI_IFR_TYPE_BOOLEAN:
2117 Temp = Value->Value.b;
2118 break;
2119
2120 case EFI_IFR_TYPE_TIME:
2121 Temp = Value->Value.u32 & 0xffffff;
2122 break;
2123
2124 case EFI_IFR_TYPE_DATE:
2125 Temp = Value->Value.u32;
2126 break;
2127
2128 default:
2129 return;
2130 }
2131
2132 Value->Value.u64 = Temp;
2133}
2134
2143UINT64
2145 IN EFI_HII_VALUE *Value
2146 )
2147{
2148 UINT64 RetVal;
2149
2150 RetVal = 0;
2151
2152 switch (Value->Type) {
2153 case EFI_IFR_TYPE_NUM_SIZE_8:
2154 RetVal = Value->Value.u8;
2155 break;
2156
2157 case EFI_IFR_TYPE_NUM_SIZE_16:
2158 RetVal = Value->Value.u16;
2159 break;
2160
2161 case EFI_IFR_TYPE_NUM_SIZE_32:
2162 RetVal = Value->Value.u32;
2163 break;
2164
2165 case EFI_IFR_TYPE_BOOLEAN:
2166 RetVal = Value->Value.b;
2167 break;
2168
2169 case EFI_IFR_TYPE_DATE:
2170 RetVal = *(UINT64 *)&Value->Value.date;
2171 break;
2172
2173 case EFI_IFR_TYPE_TIME:
2174 RetVal = (*(UINT64 *)&Value->Value.time) & 0xffffff;
2175 break;
2176
2177 default:
2178 RetVal = Value->Value.u64;
2179 break;
2180 }
2181
2182 return RetVal;
2183}
2184
2202 IN EFI_HII_VALUE *Value1,
2203 IN EFI_HII_VALUE *Value2,
2204 OUT INTN *Result,
2205 IN EFI_HII_HANDLE HiiHandle OPTIONAL
2206 )
2207{
2208 INT64 Temp64;
2209 CHAR16 *Str1;
2210 CHAR16 *Str2;
2211 UINTN Len;
2212 UINT8 *Buf1;
2213 UINT16 Buf1Len;
2214 UINT8 *Buf2;
2215 UINT16 Buf2Len;
2216
2217 if ((Value1->Type == EFI_IFR_TYPE_STRING) && (Value2->Type == EFI_IFR_TYPE_STRING)) {
2218 if ((Value1->Value.string == 0) || (Value2->Value.string == 0)) {
2219 //
2220 // StringId 0 is reserved
2221 //
2222 return EFI_INVALID_PARAMETER;
2223 }
2224
2225 if (Value1->Value.string == Value2->Value.string) {
2226 *Result = 0;
2227 return EFI_SUCCESS;
2228 }
2229
2230 Str1 = GetToken (Value1->Value.string, HiiHandle);
2231 if (Str1 == NULL) {
2232 //
2233 // String not found
2234 //
2235 return EFI_NOT_FOUND;
2236 }
2237
2238 Str2 = GetToken (Value2->Value.string, HiiHandle);
2239 if (Str2 == NULL) {
2240 FreePool (Str1);
2241 return EFI_NOT_FOUND;
2242 }
2243
2244 *Result = StrCmp (Str1, Str2);
2245
2246 FreePool (Str1);
2247 FreePool (Str2);
2248
2249 return EFI_SUCCESS;
2250 }
2251
2252 //
2253 // Take types(date, time, ref, buffer) as buffer
2254 //
2255 if (IsTypeInBuffer (Value1) && IsTypeInBuffer (Value2)) {
2256 Buf1 = GetBufferForValue (Value1);
2257 Buf1Len = GetLengthForValue (Value1);
2258 Buf2 = GetBufferForValue (Value2);
2259 Buf2Len = GetLengthForValue (Value2);
2260
2261 Len = Buf1Len > Buf2Len ? Buf2Len : Buf1Len;
2262 *Result = CompareMem (Buf1, Buf2, Len);
2263 if ((*Result == 0) && (Buf1Len != Buf2Len)) {
2264 //
2265 // In this case, means base on samll number buffer, the data is same
2266 // So which value has more data, which value is bigger.
2267 //
2268 *Result = Buf1Len > Buf2Len ? 1 : -1;
2269 }
2270
2271 return EFI_SUCCESS;
2272 }
2273
2274 //
2275 // Take types(integer, boolean) as integer
2276 //
2277 if (IsTypeInUINT64 (Value1) && IsTypeInUINT64 (Value2)) {
2278 Temp64 = HiiValueToUINT64 (Value1) - HiiValueToUINT64 (Value2);
2279 if (Temp64 > 0) {
2280 *Result = 1;
2281 } else if (Temp64 < 0) {
2282 *Result = -1;
2283 } else {
2284 *Result = 0;
2285 }
2286
2287 return EFI_SUCCESS;
2288 }
2289
2290 return EFI_UNSUPPORTED;
2291}
2292
2301BOOLEAN
2303 IN EFI_GUID *Guid
2304 )
2305{
2306 EFI_STATUS Status;
2307 EFI_USER_PROFILE_HANDLE UserProfileHandle;
2308 EFI_USER_INFO_HANDLE UserInfoHandle;
2309 EFI_USER_INFO *UserInfo;
2310 EFI_GUID *UserPermissionsGuid;
2311 UINTN UserInfoSize;
2312 UINTN AccessControlDataSize;
2313 EFI_USER_INFO_ACCESS_CONTROL *AccessControl;
2314 UINTN RemainSize;
2315
2316 if (mUserManager == NULL) {
2317 Status = gBS->LocateProtocol (
2318 &gEfiUserManagerProtocolGuid,
2319 NULL,
2320 (VOID **)&mUserManager
2321 );
2322 if (EFI_ERROR (Status)) {
2328 return TRUE;
2329 }
2330 }
2331
2332 Status = mUserManager->Current (mUserManager, &UserProfileHandle);
2333 ASSERT_EFI_ERROR (Status);
2334
2339
2340 for (UserInfoHandle = NULL; ;) {
2341 Status = mUserManager->GetNextInfo (mUserManager, UserProfileHandle, &UserInfoHandle);
2342 if (EFI_ERROR (Status)) {
2343 break;
2344 }
2345
2346 UserInfoSize = 0;
2347 Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, NULL, &UserInfoSize);
2348 if (Status != EFI_BUFFER_TOO_SMALL) {
2349 continue;
2350 }
2351
2352 UserInfo = (EFI_USER_INFO *)AllocatePool (UserInfoSize);
2353 if (UserInfo == NULL) {
2354 break;
2355 }
2356
2357 Status = mUserManager->GetInfo (mUserManager, UserProfileHandle, UserInfoHandle, UserInfo, &UserInfoSize);
2358 if (EFI_ERROR (Status) ||
2360 (UserInfo->InfoSize <= sizeof (EFI_USER_INFO)))
2361 {
2362 FreePool (UserInfo);
2363 continue;
2364 }
2365
2366 RemainSize = UserInfo->InfoSize - sizeof (EFI_USER_INFO);
2367 AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)(UserInfo + 1);
2368 while (RemainSize >= sizeof (EFI_USER_INFO_ACCESS_CONTROL)) {
2369 if ((RemainSize < AccessControl->Size) || (AccessControl->Size < sizeof (EFI_USER_INFO_ACCESS_CONTROL))) {
2370 break;
2371 }
2372
2373 if (AccessControl->Type == EFI_USER_INFO_ACCESS_SETUP) {
2377
2378 UserPermissionsGuid = (EFI_GUID *)(AccessControl + 1);
2379 AccessControlDataSize = AccessControl->Size - sizeof (EFI_USER_INFO_ACCESS_CONTROL);
2380 while (AccessControlDataSize >= sizeof (EFI_GUID)) {
2381 if (CompareGuid (Guid, UserPermissionsGuid)) {
2382 FreePool (UserInfo);
2383 return TRUE;
2384 }
2385
2386 UserPermissionsGuid++;
2387 AccessControlDataSize -= sizeof (EFI_GUID);
2388 }
2389 }
2390
2391 RemainSize -= AccessControl->Size;
2392 AccessControl = (EFI_USER_INFO_ACCESS_CONTROL *)((UINT8 *)AccessControl + AccessControl->Size);
2393 }
2394
2395 FreePool (UserInfo);
2396 }
2397
2398 return FALSE;
2399}
2400
2413BOOLEAN
2415 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
2416 IN EFI_HII_HANDLE InputHiiHandle,
2417 IN EFI_GUID *FormSetGuid,
2418 IN EFI_QUESTION_ID QuestionId,
2419 OUT EFI_HII_VALUE *Value
2420 )
2421{
2422 EFI_STATUS Status;
2423 EFI_HII_HANDLE HiiHandle;
2424 FORM_BROWSER_STATEMENT *Question;
2425 FORM_BROWSER_FORMSET *FormSet;
2426 FORM_BROWSER_FORM *Form;
2427 BOOLEAN GetTheVal;
2428 LIST_ENTRY *Link;
2429
2430 //
2431 // The input parameter DevicePath or InputHiiHandle must have one valid input.
2432 //
2433 ASSERT (
2434 (DevicePath != NULL && InputHiiHandle == NULL) ||
2435 (DevicePath == NULL && InputHiiHandle != NULL)
2436 );
2437
2438 GetTheVal = TRUE;
2439 HiiHandle = NULL;
2440 Question = NULL;
2441 Form = NULL;
2442
2443 //
2444 // Get HiiHandle.
2445 //
2446 if (DevicePath != NULL) {
2447 HiiHandle = DevicePathToHiiHandle (DevicePath, FormSetGuid);
2448 if (HiiHandle == NULL) {
2449 return FALSE;
2450 }
2451 } else {
2452 HiiHandle = InputHiiHandle;
2453 }
2454
2455 ASSERT (HiiHandle != NULL);
2456
2457 //
2458 // Get the formset data include this question.
2459 //
2460 FormSet = AllocateZeroPool (sizeof (FORM_BROWSER_FORMSET));
2461 ASSERT (FormSet != NULL);
2462 Status = InitializeFormSet (HiiHandle, FormSetGuid, FormSet);
2463 if (EFI_ERROR (Status)) {
2464 GetTheVal = FALSE;
2465 goto Done;
2466 }
2467
2468 //
2469 // Base on the Question Id to get the question info.
2470 //
2471 Question = IdToQuestion (FormSet, NULL, QuestionId);
2472 if (Question == NULL) {
2473 GetTheVal = FALSE;
2474 goto Done;
2475 }
2476
2477 //
2478 // Search form in the formset scope
2479 //
2480 Link = GetFirstNode (&FormSet->FormListHead);
2481 while (!IsNull (&FormSet->FormListHead, Link)) {
2482 Form = FORM_BROWSER_FORM_FROM_LINK (Link);
2483
2484 Question = IdToQuestion2 (Form, QuestionId);
2485 if (Question != NULL) {
2486 break;
2487 }
2488
2489 Link = GetNextNode (&FormSet->FormListHead, Link);
2490 Form = NULL;
2491 }
2492
2493 ASSERT (Form != NULL);
2494
2495 //
2496 // Get the question value.
2497 //
2498 Status = GetQuestionValue (FormSet, Form, Question, GetSetValueWithEditBuffer);
2499 if (EFI_ERROR (Status)) {
2500 GetTheVal = FALSE;
2501 goto Done;
2502 }
2503
2504 CopyMem (Value, &Question->HiiValue, sizeof (EFI_HII_VALUE));
2505
2506Done:
2507 //
2508 // Clean the formset structure and restore the global parameter.
2509 //
2510 if (FormSet != NULL) {
2511 DestroyFormSet (FormSet);
2512 }
2513
2514 return GetTheVal;
2515}
2516
2537 IN FORM_BROWSER_FORMSET *FormSet,
2538 IN FORM_BROWSER_FORM *Form,
2539 IN OUT FORM_EXPRESSION *Expression
2540 )
2541{
2542 EFI_STATUS Status;
2543 LIST_ENTRY *Link;
2544 EXPRESSION_OPCODE *OpCode;
2545 FORM_BROWSER_STATEMENT *Question;
2546 FORM_BROWSER_STATEMENT *Question2;
2547 UINT16 Index;
2548 EFI_HII_VALUE Data1;
2549 EFI_HII_VALUE Data2;
2550 EFI_HII_VALUE Data3;
2551 FORM_EXPRESSION *RuleExpression;
2552 EFI_HII_VALUE *Value;
2553 INTN Result;
2554 CHAR16 *StrPtr;
2555 CHAR16 *NameValue;
2556 UINT32 TempValue;
2557 LIST_ENTRY *SubExpressionLink;
2558 FORM_EXPRESSION *SubExpression;
2559 UINTN StackOffset;
2560 UINTN TempLength;
2561 CHAR16 TempStr[5];
2562 UINT8 DigitUint8;
2563 UINT8 *TempBuffer;
2564 EFI_TIME EfiTime;
2565 EFI_HII_VALUE QuestionVal;
2566 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
2567
2568 StrPtr = NULL;
2569
2570 //
2571 // Save current stack offset.
2572 //
2573 StackOffset = SaveExpressionEvaluationStackOffset ();
2574
2575 ASSERT (Expression != NULL);
2576 Expression->Result.Type = EFI_IFR_TYPE_OTHER;
2577
2578 Link = GetFirstNode (&Expression->OpCodeListHead);
2579 while (!IsNull (&Expression->OpCodeListHead, Link)) {
2580 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);
2581
2582 Link = GetNextNode (&Expression->OpCodeListHead, Link);
2583
2584 ZeroMem (&Data1, sizeof (EFI_HII_VALUE));
2585 ZeroMem (&Data2, sizeof (EFI_HII_VALUE));
2586 ZeroMem (&Data3, sizeof (EFI_HII_VALUE));
2587
2588 Value = &Data3;
2589 Value->Type = EFI_IFR_TYPE_BOOLEAN;
2590 Status = EFI_SUCCESS;
2591
2592 switch (OpCode->Operand) {
2593 //
2594 // Built-in functions
2595 //
2596 case EFI_IFR_EQ_ID_VAL_OP:
2597 Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
2598 if (Question == NULL) {
2599 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2600 break;
2601 }
2602
2603 Status = CompareHiiValue (&Question->HiiValue, &OpCode->Value, &Result, NULL);
2604 if (Status == EFI_UNSUPPORTED) {
2605 Status = EFI_SUCCESS;
2606 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2607 break;
2608 }
2609
2610 if (EFI_ERROR (Status)) {
2611 goto Done;
2612 }
2613
2614 Value->Value.b = (BOOLEAN)((Result == 0) ? TRUE : FALSE);
2615 break;
2616
2617 case EFI_IFR_EQ_ID_ID_OP:
2618 Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
2619 if (Question == NULL) {
2620 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2621 break;
2622 }
2623
2624 Question2 = IdToQuestion (FormSet, Form, OpCode->QuestionId2);
2625 if (Question2 == NULL) {
2626 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2627 break;
2628 }
2629
2630 Status = CompareHiiValue (&Question->HiiValue, &Question2->HiiValue, &Result, FormSet->HiiHandle);
2631 if (Status == EFI_UNSUPPORTED) {
2632 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2633 Status = EFI_SUCCESS;
2634 break;
2635 }
2636
2637 if (EFI_ERROR (Status)) {
2638 goto Done;
2639 }
2640
2641 Value->Value.b = (BOOLEAN)((Result == 0) ? TRUE : FALSE);
2642 break;
2643
2644 case EFI_IFR_EQ_ID_VAL_LIST_OP:
2645 Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
2646 if (Question == NULL) {
2647 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2648 break;
2649 }
2650
2651 Value->Value.b = FALSE;
2652 for (Index = 0; Index < OpCode->ListLength; Index++) {
2653 if (Question->HiiValue.Value.u16 == OpCode->ValueList[Index]) {
2654 Value->Value.b = TRUE;
2655 break;
2656 }
2657 }
2658
2659 break;
2660
2661 case EFI_IFR_DUP_OP:
2662 Status = PopExpression (Value);
2663 if (EFI_ERROR (Status)) {
2664 goto Done;
2665 }
2666
2667 Status = PushExpression (Value);
2668 break;
2669
2670 case EFI_IFR_QUESTION_REF1_OP:
2671 case EFI_IFR_THIS_OP:
2672 Question = IdToQuestion (FormSet, Form, OpCode->QuestionId);
2673 if (Question == NULL) {
2674 Status = EFI_NOT_FOUND;
2675 goto Done;
2676 }
2677
2678 Value = &Question->HiiValue;
2679 break;
2680
2681 case EFI_IFR_SECURITY_OP:
2682 Value->Value.b = CheckUserPrivilege (&OpCode->Guid);
2683 break;
2684
2685 case EFI_IFR_GET_OP:
2686 //
2687 // Get Value from VarStore buffer, EFI VarStore, Name/Value VarStore.
2688 //
2689 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2690 Value->Value.u8 = 0;
2691 if (OpCode->VarStorage != NULL) {
2692 switch (OpCode->VarStorage->Type) {
2693 case EFI_HII_VARSTORE_BUFFER:
2694 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
2695 //
2696 // Get value from Edit Buffer
2697 //
2698 Value->Type = OpCode->ValueType;
2699 CopyMem (&Value->Value, OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, OpCode->ValueWidth);
2700 break;
2701 case EFI_HII_VARSTORE_NAME_VALUE:
2702 if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {
2703 //
2704 // Get value from string except for STRING value.
2705 //
2706 Status = GetValueByName (OpCode->VarStorage, OpCode->ValueName, &StrPtr, GetSetValueWithEditBuffer);
2707 if (!EFI_ERROR (Status)) {
2708 ASSERT (StrPtr != NULL);
2709 TempLength = StrLen (StrPtr);
2710 if (OpCode->ValueWidth >= ((TempLength + 1) / 2)) {
2711 Value->Type = OpCode->ValueType;
2712 TempBuffer = (UINT8 *)&Value->Value;
2713 ZeroMem (TempStr, sizeof (TempStr));
2714 for (Index = 0; Index < TempLength; Index++) {
2715 TempStr[0] = StrPtr[TempLength - Index - 1];
2716 DigitUint8 = (UINT8)StrHexToUint64 (TempStr);
2717 if ((Index & 1) == 0) {
2718 TempBuffer[Index/2] = DigitUint8;
2719 } else {
2720 TempBuffer[Index/2] = (UINT8)((DigitUint8 << 4) + TempBuffer[Index/2]);
2721 }
2722 }
2723 }
2724 }
2725 }
2726
2727 break;
2728 case EFI_HII_VARSTORE_EFI_VARIABLE:
2729 //
2730 // Get value from variable.
2731 //
2732 TempLength = OpCode->ValueWidth;
2733 Value->Type = OpCode->ValueType;
2734 Status = gRT->GetVariable (
2735 OpCode->ValueName,
2736 &OpCode->VarStorage->Guid,
2737 NULL,
2738 &TempLength,
2739 &Value->Value
2740 );
2741 if (EFI_ERROR (Status)) {
2742 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2743 Value->Value.u8 = 0;
2744 }
2745
2746 break;
2747 default:
2748 //
2749 // Not recognize storage.
2750 //
2751 Status = EFI_UNSUPPORTED;
2752 goto Done;
2753 }
2754 } else {
2755 //
2756 // For Time/Date Data
2757 //
2758 if ((OpCode->ValueType != EFI_IFR_TYPE_DATE) && (OpCode->ValueType != EFI_IFR_TYPE_TIME)) {
2759 //
2760 // Only support Data/Time data when storage doesn't exist.
2761 //
2762 Status = EFI_UNSUPPORTED;
2763 goto Done;
2764 }
2765
2766 Status = gRT->GetTime (&EfiTime, NULL);
2767 if (!EFI_ERROR (Status)) {
2768 if (OpCode->ValueType == EFI_IFR_TYPE_DATE) {
2769 switch (OpCode->VarStoreInfo.VarOffset) {
2770 case 0x00:
2771 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;
2772 Value->Value.u16 = EfiTime.Year;
2773 break;
2774 case 0x02:
2775 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
2776 Value->Value.u8 = EfiTime.Month;
2777 break;
2778 case 0x03:
2779 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
2780 Value->Value.u8 = EfiTime.Day;
2781 break;
2782 default:
2783 //
2784 // Invalid Date field.
2785 //
2786 Status = EFI_INVALID_PARAMETER;
2787 goto Done;
2788 }
2789 } else {
2790 switch (OpCode->VarStoreInfo.VarOffset) {
2791 case 0x00:
2792 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
2793 Value->Value.u8 = EfiTime.Hour;
2794 break;
2795 case 0x01:
2796 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
2797 Value->Value.u8 = EfiTime.Minute;
2798 break;
2799 case 0x02:
2800 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;
2801 Value->Value.u8 = EfiTime.Second;
2802 break;
2803 default:
2804 //
2805 // Invalid Time field.
2806 //
2807 Status = EFI_INVALID_PARAMETER;
2808 goto Done;
2809 }
2810 }
2811 }
2812 }
2813
2814 break;
2815
2816 case EFI_IFR_QUESTION_REF3_OP:
2817 //
2818 // EFI_IFR_QUESTION_REF3
2819 // Pop an expression from the expression stack
2820 //
2821 Status = PopExpression (Value);
2822 if (EFI_ERROR (Status)) {
2823 goto Done;
2824 }
2825
2826 //
2827 // Validate the expression value
2828 //
2829 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
2830 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2831 break;
2832 }
2833
2834 if (OpCode->DevicePath != 0) {
2835 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2836
2837 StrPtr = GetToken (OpCode->DevicePath, FormSet->HiiHandle);
2838 if ((StrPtr != NULL) && (mPathFromText != NULL)) {
2839 DevicePath = mPathFromText->ConvertTextToDevicePath (StrPtr);
2840 if ((DevicePath != NULL) && GetQuestionValueFromForm (DevicePath, NULL, &OpCode->Guid, Value->Value.u16, &QuestionVal)) {
2841 Value = &QuestionVal;
2842 }
2843
2844 if (DevicePath != NULL) {
2845 FreePool (DevicePath);
2846 }
2847 }
2848
2849 if (StrPtr != NULL) {
2850 FreePool (StrPtr);
2851 }
2852 } else if (IsZeroGuid (&OpCode->Guid)) {
2853 if (!GetQuestionValueFromForm (NULL, FormSet->HiiHandle, &OpCode->Guid, Value->Value.u16, &QuestionVal)) {
2854 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2855 break;
2856 }
2857
2858 Value = &QuestionVal;
2859 } else {
2860 Question = IdToQuestion (FormSet, Form, Value->Value.u16);
2861 if (Question == NULL) {
2862 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2863 break;
2864 }
2865
2866 //
2867 // push the questions' value on to the expression stack
2868 //
2869 Value = &Question->HiiValue;
2870 }
2871
2872 break;
2873
2874 case EFI_IFR_RULE_REF_OP:
2875 //
2876 // Find expression for this rule
2877 //
2878 RuleExpression = RuleIdToExpression (Form, OpCode->RuleId);
2879 if (RuleExpression == NULL) {
2880 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2881 break;
2882 }
2883
2884 //
2885 // Evaluate this rule expression
2886 //
2887 Status = EvaluateExpression (FormSet, Form, RuleExpression);
2888 if (EFI_ERROR (Status) || (RuleExpression->Result.Type == EFI_IFR_TYPE_UNDEFINED)) {
2889 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2890 break;
2891 }
2892
2893 Value = &RuleExpression->Result;
2894 break;
2895
2896 case EFI_IFR_STRING_REF1_OP:
2897 Value->Type = EFI_IFR_TYPE_STRING;
2898 Value->Value.string = OpCode->Value.Value.string;
2899 break;
2900
2901 //
2902 // Constant
2903 //
2904 case EFI_IFR_TRUE_OP:
2905 case EFI_IFR_FALSE_OP:
2906 case EFI_IFR_ONE_OP:
2907 case EFI_IFR_ONES_OP:
2908 case EFI_IFR_UINT8_OP:
2909 case EFI_IFR_UINT16_OP:
2910 case EFI_IFR_UINT32_OP:
2911 case EFI_IFR_UINT64_OP:
2912 case EFI_IFR_UNDEFINED_OP:
2913 case EFI_IFR_VERSION_OP:
2914 case EFI_IFR_ZERO_OP:
2915 Value = &OpCode->Value;
2916 break;
2917
2918 //
2919 // unary-op
2920 //
2921 case EFI_IFR_LENGTH_OP:
2922 Status = PopExpression (Value);
2923 if (EFI_ERROR (Status)) {
2924 goto Done;
2925 }
2926
2927 if ((Value->Type != EFI_IFR_TYPE_STRING) && !IsTypeInBuffer (Value)) {
2928 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2929 break;
2930 }
2931
2932 if (Value->Type == EFI_IFR_TYPE_STRING) {
2933 StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);
2934 if (StrPtr == NULL) {
2935 Status = EFI_INVALID_PARAMETER;
2936 goto Done;
2937 }
2938
2939 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
2940 Value->Value.u64 = StrLen (StrPtr);
2941 FreePool (StrPtr);
2942 } else {
2943 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
2944 Value->Value.u64 = GetLengthForValue (Value);
2945 FreePool (Value->Buffer);
2946 }
2947
2948 break;
2949
2950 case EFI_IFR_NOT_OP:
2951 Status = PopExpression (Value);
2952 if (EFI_ERROR (Status)) {
2953 goto Done;
2954 }
2955
2956 if (Value->Type != EFI_IFR_TYPE_BOOLEAN) {
2957 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2958 break;
2959 }
2960
2961 Value->Value.b = (BOOLEAN)(!Value->Value.b);
2962 break;
2963
2964 case EFI_IFR_QUESTION_REF2_OP:
2965 //
2966 // Pop an expression from the expression stack
2967 //
2968 Status = PopExpression (Value);
2969 if (EFI_ERROR (Status)) {
2970 goto Done;
2971 }
2972
2973 //
2974 // Validate the expression value
2975 //
2976 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
2977 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2978 break;
2979 }
2980
2981 Question = IdToQuestion (FormSet, Form, Value->Value.u16);
2982 if (Question == NULL) {
2983 Value->Type = EFI_IFR_TYPE_UNDEFINED;
2984 break;
2985 }
2986
2987 Value = &Question->HiiValue;
2988 break;
2989
2990 case EFI_IFR_STRING_REF2_OP:
2991 //
2992 // Pop an expression from the expression stack
2993 //
2994 Status = PopExpression (Value);
2995 if (EFI_ERROR (Status)) {
2996 goto Done;
2997 }
2998
2999 //
3000 // Validate the expression value
3001 //
3002 if ((Value->Type > EFI_IFR_TYPE_NUM_SIZE_64) || (Value->Value.u64 > 0xffff)) {
3003 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3004 break;
3005 }
3006
3007 Value->Type = EFI_IFR_TYPE_STRING;
3008 StrPtr = GetToken (Value->Value.u16, FormSet->HiiHandle);
3009 if (StrPtr == NULL) {
3010 //
3011 // If String not exit, push an empty string
3012 //
3013 Value->Value.string = NewString (gEmptyString, FormSet->HiiHandle);
3014 } else {
3015 Index = (UINT16)Value->Value.u64;
3016 Value->Value.string = Index;
3017 FreePool (StrPtr);
3018 }
3019
3020 break;
3021
3022 case EFI_IFR_TO_BOOLEAN_OP:
3023 //
3024 // Pop an expression from the expression stack
3025 //
3026 Status = PopExpression (Value);
3027 if (EFI_ERROR (Status)) {
3028 goto Done;
3029 }
3030
3031 //
3032 // Convert an expression to a Boolean
3033 //
3034 if (Value->Type <= EFI_IFR_TYPE_DATE) {
3035 //
3036 // When converting from an unsigned integer, zero will be converted to
3037 // FALSE and any other value will be converted to TRUE.
3038 //
3039 Value->Value.b = (BOOLEAN)(HiiValueToUINT64 (Value) != 0);
3040
3041 Value->Type = EFI_IFR_TYPE_BOOLEAN;
3042 } else if (Value->Type == EFI_IFR_TYPE_STRING) {
3043 //
3044 // When converting from a string, if case-insensitive compare
3045 // with "true" is True, then push True. If a case-insensitive compare
3046 // with "false" is True, then push False. Otherwise, push Undefined.
3047 //
3048 StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);
3049 if (StrPtr == NULL) {
3050 Status = EFI_INVALID_PARAMETER;
3051 goto Done;
3052 }
3053
3054 IfrStrToUpper (StrPtr);
3055 if (StrCmp (StrPtr, L"TRUE") == 0) {
3056 Value->Value.b = TRUE;
3057 Value->Type = EFI_IFR_TYPE_BOOLEAN;
3058 } else if (StrCmp (StrPtr, L"FALSE") == 0) {
3059 Value->Value.b = FALSE;
3060 Value->Type = EFI_IFR_TYPE_BOOLEAN;
3061 } else {
3062 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3063 }
3064
3065 FreePool (StrPtr);
3066 } else if (Value->Type == EFI_IFR_TYPE_BUFFER) {
3067 //
3068 // When converting from a buffer, if the buffer is all zeroes,
3069 // then push False. Otherwise push True.
3070 //
3071 for (Index = 0; Index < Value->BufferLen; Index++) {
3072 if (Value->Buffer[Index] != 0) {
3073 break;
3074 }
3075 }
3076
3077 if (Index >= Value->BufferLen) {
3078 Value->Value.b = FALSE;
3079 } else {
3080 Value->Value.b = TRUE;
3081 }
3082
3083 Value->Type = EFI_IFR_TYPE_BOOLEAN;
3084 FreePool (Value->Buffer);
3085 }
3086
3087 break;
3088
3089 case EFI_IFR_TO_STRING_OP:
3090 Status = IfrToString (FormSet, OpCode->Format, Value);
3091 break;
3092
3093 case EFI_IFR_TO_UINT_OP:
3094 Status = IfrToUint (FormSet, Value);
3095 break;
3096
3097 case EFI_IFR_TO_LOWER_OP:
3098 case EFI_IFR_TO_UPPER_OP:
3100 if (EFI_ERROR (Status)) {
3101 goto Done;
3102 }
3103
3104 Status = PopExpression (Value);
3105 if (EFI_ERROR (Status)) {
3106 goto Done;
3107 }
3108
3109 if (Value->Type != EFI_IFR_TYPE_STRING) {
3110 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3111 break;
3112 }
3113
3114 StrPtr = GetToken (Value->Value.string, FormSet->HiiHandle);
3115 if (StrPtr == NULL) {
3116 Status = EFI_NOT_FOUND;
3117 goto Done;
3118 }
3119
3120 if (OpCode->Operand == EFI_IFR_TO_LOWER_OP) {
3121 mUnicodeCollation->StrLwr (mUnicodeCollation, StrPtr);
3122 } else {
3123 mUnicodeCollation->StrUpr (mUnicodeCollation, StrPtr);
3124 }
3125
3126 Value->Value.string = NewString (StrPtr, FormSet->HiiHandle);
3127 FreePool (StrPtr);
3128 break;
3129
3130 case EFI_IFR_BITWISE_NOT_OP:
3131 //
3132 // Pop an expression from the expression stack
3133 //
3134 Status = PopExpression (Value);
3135 if (EFI_ERROR (Status)) {
3136 goto Done;
3137 }
3138
3139 if (Value->Type > EFI_IFR_TYPE_DATE) {
3140 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3141 break;
3142 }
3143
3144 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
3145 Value->Value.u64 = ~HiiValueToUINT64(Value);
3146 break;
3147
3148 case EFI_IFR_SET_OP:
3149 //
3150 // Pop an expression from the expression stack
3151 //
3152 Status = PopExpression (Value);
3153 if (EFI_ERROR (Status)) {
3154 goto Done;
3155 }
3156
3157 Data1.Type = EFI_IFR_TYPE_BOOLEAN;
3158 Data1.Value.b = FALSE;
3159 //
3160 // Set value to var storage buffer
3161 //
3162 if (OpCode->VarStorage != NULL) {
3163 switch (OpCode->VarStorage->Type) {
3164 case EFI_HII_VARSTORE_BUFFER:
3165 case EFI_HII_VARSTORE_EFI_VARIABLE_BUFFER:
3166 CopyMem (OpCode->VarStorage->EditBuffer + OpCode->VarStoreInfo.VarOffset, &Value->Value, OpCode->ValueWidth);
3167 Data1.Value.b = TRUE;
3168 break;
3169 case EFI_HII_VARSTORE_NAME_VALUE:
3170 if (OpCode->ValueType != EFI_IFR_TYPE_STRING) {
3171 NameValue = AllocateZeroPool ((OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16));
3172 ASSERT (NameValue != NULL);
3173 //
3174 // Convert Buffer to Hex String
3175 //
3176 TempBuffer = (UINT8 *)&Value->Value + OpCode->ValueWidth - 1;
3177 StrPtr = NameValue;
3178 for (Index = 0; Index < OpCode->ValueWidth; Index++, TempBuffer--) {
3180 StrPtr,
3181 (OpCode->ValueWidth * 2 + 1) * sizeof (CHAR16) - ((UINTN)StrPtr - (UINTN)NameValue),
3182 PREFIX_ZERO | RADIX_HEX,
3183 *TempBuffer,
3184 2
3185 );
3186 StrPtr += StrnLenS (StrPtr, OpCode->ValueWidth * 2 + 1 - ((UINTN)StrPtr - (UINTN)NameValue) / sizeof (CHAR16));
3187 }
3188
3189 Status = SetValueByName (OpCode->VarStorage, OpCode->ValueName, NameValue, GetSetValueWithEditBuffer, NULL);
3190 FreePool (NameValue);
3191 if (!EFI_ERROR (Status)) {
3192 Data1.Value.b = TRUE;
3193 }
3194 }
3195
3196 break;
3197 case EFI_HII_VARSTORE_EFI_VARIABLE:
3198 Status = gRT->SetVariable (
3199 OpCode->ValueName,
3200 &OpCode->VarStorage->Guid,
3201 OpCode->VarStorage->Attributes,
3202 OpCode->ValueWidth,
3203 &Value->Value
3204 );
3205 if (!EFI_ERROR (Status)) {
3206 Data1.Value.b = TRUE;
3207 }
3208
3209 break;
3210 default:
3211 //
3212 // Not recognize storage.
3213 //
3214 Status = EFI_UNSUPPORTED;
3215 goto Done;
3216 }
3217 } else {
3218 //
3219 // For Time/Date Data
3220 //
3221 if ((OpCode->ValueType != EFI_IFR_TYPE_DATE) && (OpCode->ValueType != EFI_IFR_TYPE_TIME)) {
3222 //
3223 // Only support Data/Time data when storage doesn't exist.
3224 //
3225 Status = EFI_UNSUPPORTED;
3226 goto Done;
3227 }
3228
3229 Status = gRT->GetTime (&EfiTime, NULL);
3230 if (!EFI_ERROR (Status)) {
3231 if (OpCode->ValueType == EFI_IFR_TYPE_DATE) {
3232 switch (OpCode->VarStoreInfo.VarOffset) {
3233 case 0x00:
3234 EfiTime.Year = Value->Value.u16;
3235 break;
3236 case 0x02:
3237 EfiTime.Month = Value->Value.u8;
3238 break;
3239 case 0x03:
3240 EfiTime.Day = Value->Value.u8;
3241 break;
3242 default:
3243 //
3244 // Invalid Date field.
3245 //
3246 Status = EFI_INVALID_PARAMETER;
3247 goto Done;
3248 }
3249 } else {
3250 switch (OpCode->VarStoreInfo.VarOffset) {
3251 case 0x00:
3252 EfiTime.Hour = Value->Value.u8;
3253 break;
3254 case 0x01:
3255 EfiTime.Minute = Value->Value.u8;
3256 break;
3257 case 0x02:
3258 EfiTime.Second = Value->Value.u8;
3259 break;
3260 default:
3261 //
3262 // Invalid Time field.
3263 //
3264 Status = EFI_INVALID_PARAMETER;
3265 goto Done;
3266 }
3267 }
3268
3269 Status = gRT->SetTime (&EfiTime);
3270 if (!EFI_ERROR (Status)) {
3271 Data1.Value.b = TRUE;
3272 }
3273 }
3274 }
3275
3276 Value = &Data1;
3277 break;
3278
3279 //
3280 // binary-op
3281 //
3282 case EFI_IFR_ADD_OP:
3283 case EFI_IFR_SUBTRACT_OP:
3284 case EFI_IFR_MULTIPLY_OP:
3285 case EFI_IFR_DIVIDE_OP:
3286 case EFI_IFR_MODULO_OP:
3287 case EFI_IFR_BITWISE_AND_OP:
3288 case EFI_IFR_BITWISE_OR_OP:
3289 case EFI_IFR_SHIFT_LEFT_OP:
3290 case EFI_IFR_SHIFT_RIGHT_OP:
3291 //
3292 // Pop an expression from the expression stack
3293 //
3294 Status = PopExpression (&Data2);
3295 if (EFI_ERROR (Status)) {
3296 goto Done;
3297 }
3298
3299 //
3300 // Pop another expression from the expression stack
3301 //
3302 Status = PopExpression (&Data1);
3303 if (EFI_ERROR (Status)) {
3304 goto Done;
3305 }
3306
3307 if (Data2.Type > EFI_IFR_TYPE_DATE) {
3308 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3309 break;
3310 }
3311
3312 if (Data1.Type > EFI_IFR_TYPE_DATE) {
3313 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3314 break;
3315 }
3316
3317 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;
3318
3319 switch (OpCode->Operand) {
3320 case EFI_IFR_ADD_OP:
3321 Value->Value.u64 = HiiValueToUINT64 (&Data1) + HiiValueToUINT64 (&Data2);
3322 break;
3323
3324 case EFI_IFR_SUBTRACT_OP:
3325 Value->Value.u64 = HiiValueToUINT64 (&Data1) - HiiValueToUINT64 (&Data2);
3326 break;
3327
3328 case EFI_IFR_MULTIPLY_OP:
3329 Value->Value.u64 = MultU64x32 (HiiValueToUINT64 (&Data1), (UINT32)HiiValueToUINT64 (&Data2));
3330 break;
3331
3332 case EFI_IFR_DIVIDE_OP:
3333 Value->Value.u64 = DivU64x32 (HiiValueToUINT64 (&Data1), (UINT32)HiiValueToUINT64 (&Data2));
3334 break;
3335
3336 case EFI_IFR_MODULO_OP:
3337 DivU64x32Remainder (HiiValueToUINT64 (&Data1), (UINT32)HiiValueToUINT64 (&Data2), &TempValue);
3338 Value->Value.u64 = TempValue;
3339 break;
3340
3341 case EFI_IFR_BITWISE_AND_OP:
3342 Value->Value.u64 = HiiValueToUINT64 (&Data1) & HiiValueToUINT64 (&Data2);
3343 break;
3344
3345 case EFI_IFR_BITWISE_OR_OP:
3346 Value->Value.u64 = HiiValueToUINT64 (&Data1) | HiiValueToUINT64 (&Data2);
3347 break;
3348
3349 case EFI_IFR_SHIFT_LEFT_OP:
3350 Value->Value.u64 = LShiftU64 (HiiValueToUINT64 (&Data1), (UINTN)HiiValueToUINT64 (&Data2));
3351 break;
3352
3353 case EFI_IFR_SHIFT_RIGHT_OP:
3354 Value->Value.u64 = RShiftU64 (HiiValueToUINT64 (&Data1), (UINTN)HiiValueToUINT64 (&Data2));
3355 break;
3356
3357 default:
3358 break;
3359 }
3360
3361 break;
3362
3363 case EFI_IFR_AND_OP:
3364 case EFI_IFR_OR_OP:
3365 //
3366 // Two Boolean operator
3367 //
3368 Status = PopExpression (&Data2);
3369 if (EFI_ERROR (Status)) {
3370 goto Done;
3371 }
3372
3373 //
3374 // Pop another expression from the expression stack
3375 //
3376 Status = PopExpression (&Data1);
3377 if (EFI_ERROR (Status)) {
3378 goto Done;
3379 }
3380
3381 if (Data2.Type != EFI_IFR_TYPE_BOOLEAN) {
3382 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3383 break;
3384 }
3385
3386 if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {
3387 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3388 break;
3389 }
3390
3391 if (OpCode->Operand == EFI_IFR_AND_OP) {
3392 Value->Value.b = (BOOLEAN)(Data1.Value.b && Data2.Value.b);
3393 } else {
3394 Value->Value.b = (BOOLEAN)(Data1.Value.b || Data2.Value.b);
3395 }
3396
3397 break;
3398
3399 case EFI_IFR_EQUAL_OP:
3400 case EFI_IFR_NOT_EQUAL_OP:
3401 case EFI_IFR_GREATER_EQUAL_OP:
3402 case EFI_IFR_GREATER_THAN_OP:
3403 case EFI_IFR_LESS_EQUAL_OP:
3404 case EFI_IFR_LESS_THAN_OP:
3405 //
3406 // Compare two integer, string, boolean or date/time
3407 //
3408 Status = PopExpression (&Data2);
3409 if (EFI_ERROR (Status)) {
3410 goto Done;
3411 }
3412
3413 //
3414 // Pop another expression from the expression stack
3415 //
3416 Status = PopExpression (&Data1);
3417 if (EFI_ERROR (Status)) {
3418 goto Done;
3419 }
3420
3421 if ((Data2.Type > EFI_IFR_TYPE_BOOLEAN) &&
3422 (Data2.Type != EFI_IFR_TYPE_STRING) &&
3423 !IsTypeInBuffer (&Data2))
3424 {
3425 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3426 break;
3427 }
3428
3429 if ((Data1.Type > EFI_IFR_TYPE_BOOLEAN) &&
3430 (Data1.Type != EFI_IFR_TYPE_STRING) &&
3431 !IsTypeInBuffer (&Data1))
3432 {
3433 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3434 break;
3435 }
3436
3437 Status = CompareHiiValue (&Data1, &Data2, &Result, FormSet->HiiHandle);
3438 if (Data1.Type == EFI_IFR_TYPE_BUFFER) {
3439 FreePool (Data1.Buffer);
3440 }
3441
3442 if (Data2.Type == EFI_IFR_TYPE_BUFFER) {
3443 FreePool (Data2.Buffer);
3444 }
3445
3446 if (Status == EFI_UNSUPPORTED) {
3447 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3448 Status = EFI_SUCCESS;
3449 break;
3450 }
3451
3452 if (EFI_ERROR (Status)) {
3453 goto Done;
3454 }
3455
3456 switch (OpCode->Operand) {
3457 case EFI_IFR_EQUAL_OP:
3458 Value->Value.b = (BOOLEAN)((Result == 0) ? TRUE : FALSE);
3459 break;
3460
3461 case EFI_IFR_NOT_EQUAL_OP:
3462 Value->Value.b = (BOOLEAN)((Result != 0) ? TRUE : FALSE);
3463 break;
3464
3465 case EFI_IFR_GREATER_EQUAL_OP:
3466 Value->Value.b = (BOOLEAN)((Result >= 0) ? TRUE : FALSE);
3467 break;
3468
3469 case EFI_IFR_GREATER_THAN_OP:
3470 Value->Value.b = (BOOLEAN)((Result > 0) ? TRUE : FALSE);
3471 break;
3472
3473 case EFI_IFR_LESS_EQUAL_OP:
3474 Value->Value.b = (BOOLEAN)((Result <= 0) ? TRUE : FALSE);
3475 break;
3476
3477 case EFI_IFR_LESS_THAN_OP:
3478 Value->Value.b = (BOOLEAN)((Result < 0) ? TRUE : FALSE);
3479 break;
3480
3481 default:
3482 break;
3483 }
3484
3485 break;
3486
3487 case EFI_IFR_MATCH_OP:
3489 if (EFI_ERROR (Status)) {
3490 goto Done;
3491 }
3492
3493 Status = IfrMatch (FormSet, Value);
3494 break;
3495
3496 case EFI_IFR_MATCH2_OP:
3497 Status = IfrMatch2 (FormSet, &OpCode->Guid, Value);
3498 break;
3499
3500 case EFI_IFR_CATENATE_OP:
3501 Status = IfrCatenate (FormSet, Value);
3502 break;
3503
3504 //
3505 // ternary-op
3506 //
3507 case EFI_IFR_CONDITIONAL_OP:
3508 //
3509 // Pop third expression from the expression stack
3510 //
3511 Status = PopExpression (&Data3);
3512 if (EFI_ERROR (Status)) {
3513 goto Done;
3514 }
3515
3516 //
3517 // Pop second expression from the expression stack
3518 //
3519 Status = PopExpression (&Data2);
3520 if (EFI_ERROR (Status)) {
3521 goto Done;
3522 }
3523
3524 //
3525 // Pop first expression from the expression stack
3526 //
3527 Status = PopExpression (&Data1);
3528 if (EFI_ERROR (Status)) {
3529 goto Done;
3530 }
3531
3532 if (Data1.Type != EFI_IFR_TYPE_BOOLEAN) {
3533 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3534 break;
3535 }
3536
3537 if (Data1.Value.b) {
3538 Value = &Data3;
3539 } else {
3540 Value = &Data2;
3541 }
3542
3543 break;
3544
3545 case EFI_IFR_FIND_OP:
3546 Status = IfrFind (FormSet, OpCode->Format, Value);
3547 break;
3548
3549 case EFI_IFR_MID_OP:
3550 Status = IfrMid (FormSet, Value);
3551 break;
3552
3553 case EFI_IFR_TOKEN_OP:
3554 Status = IfrToken (FormSet, Value);
3555 break;
3556
3557 case EFI_IFR_SPAN_OP:
3558 Status = IfrSpan (FormSet, OpCode->Flags, Value);
3559 break;
3560
3561 case EFI_IFR_MAP_OP:
3562 //
3563 // Pop the check value
3564 //
3565 Status = PopExpression (&Data1);
3566 if (EFI_ERROR (Status)) {
3567 goto Done;
3568 }
3569
3570 //
3571 // Check MapExpression list is valid.
3572 //
3573 if (OpCode->MapExpressionList.ForwardLink == NULL) {
3574 Status = EFI_INVALID_PARAMETER;
3575 goto Done;
3576 }
3577
3578 //
3579 // Go through map expression list.
3580 //
3581 SubExpressionLink = GetFirstNode (&OpCode->MapExpressionList);
3582 while (!IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {
3583 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
3584 //
3585 // Evaluate the first expression in this pair.
3586 //
3587 Status = EvaluateExpression (FormSet, Form, SubExpression);
3588 if (EFI_ERROR (Status)) {
3589 goto Done;
3590 }
3591
3592 //
3593 // Compare the expression value with current value
3594 //
3595 if ((CompareHiiValue (&Data1, &SubExpression->Result, &Result, NULL) == EFI_SUCCESS) && (Result == 0)) {
3596 //
3597 // Try get the map value.
3598 //
3599 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);
3600 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {
3601 Status = EFI_INVALID_PARAMETER;
3602 goto Done;
3603 }
3604
3605 SubExpression = FORM_EXPRESSION_FROM_LINK (SubExpressionLink);
3606 Status = EvaluateExpression (FormSet, Form, SubExpression);
3607 if (EFI_ERROR (Status)) {
3608 goto Done;
3609 }
3610
3611 Value = &SubExpression->Result;
3612 break;
3613 }
3614
3615 //
3616 // Skip the second expression on this pair.
3617 //
3618 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);
3619 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {
3620 Status = EFI_INVALID_PARAMETER;
3621 goto Done;
3622 }
3623
3624 //
3625 // Goto the first expression on next pair.
3626 //
3627 SubExpressionLink = GetNextNode (&OpCode->MapExpressionList, SubExpressionLink);
3628 }
3629
3630 //
3631 // No map value is found.
3632 //
3633 if (IsNull (&OpCode->MapExpressionList, SubExpressionLink)) {
3634 Value->Type = EFI_IFR_TYPE_UNDEFINED;
3635 Value->Value.u8 = 0;
3636 }
3637
3638 break;
3639
3640 default:
3641 break;
3642 }
3643
3644 if (EFI_ERROR (Status) || (Value->Type == EFI_IFR_TYPE_UNDEFINED)) {
3645 goto Done;
3646 }
3647
3648 Status = PushExpression (Value);
3649 if (EFI_ERROR (Status)) {
3650 goto Done;
3651 }
3652 }
3653
3654 //
3655 // Pop the final result from expression stack
3656 //
3657 Value = &Data1;
3658 Status = PopExpression (Value);
3659 if (EFI_ERROR (Status)) {
3660 goto Done;
3661 }
3662
3663 //
3664 // After evaluating an expression, there should be only one value left on the expression stack
3665 //
3666 if (PopExpression (Value) != EFI_ACCESS_DENIED) {
3667 Status = EFI_INVALID_PARAMETER;
3668 }
3669
3670Done:
3672 if (!EFI_ERROR (Status)) {
3673 CopyMem (&Expression->Result, Value, sizeof (EFI_HII_VALUE));
3674 }
3675
3676 return Status;
3677}
3678
3691BOOLEAN
3693 IN EFI_HII_VALUE *Result
3694 )
3695{
3696 switch (Result->Type) {
3697 case EFI_IFR_TYPE_BOOLEAN:
3698 return Result->Value.b;
3699
3700 case EFI_IFR_TYPE_NUM_SIZE_8:
3701 return (BOOLEAN)(Result->Value.u8 != 0);
3702
3703 case EFI_IFR_TYPE_NUM_SIZE_16:
3704 return (BOOLEAN)(Result->Value.u16 != 0);
3705
3706 case EFI_IFR_TYPE_NUM_SIZE_32:
3707 return (BOOLEAN)(Result->Value.u32 != 0);
3708
3709 case EFI_IFR_TYPE_NUM_SIZE_64:
3710 return (BOOLEAN)(Result->Value.u64 != 0);
3711
3712 default:
3713 return FALSE;
3714 }
3715}
3716
3731EXPRESS_RESULT
3733 IN FORM_EXPRESSION_LIST *ExpList,
3734 IN BOOLEAN Evaluate,
3735 IN FORM_BROWSER_FORMSET *FormSet OPTIONAL,
3736 IN FORM_BROWSER_FORM *Form OPTIONAL
3737 )
3738{
3739 UINTN Index;
3740 EXPRESS_RESULT ReturnVal;
3741 EXPRESS_RESULT CompareOne;
3742 EFI_STATUS Status;
3743
3744 if (ExpList == NULL) {
3745 return ExpressFalse;
3746 }
3747
3748 ASSERT (ExpList->Signature == FORM_EXPRESSION_LIST_SIGNATURE);
3749 Index = 0;
3750
3751 //
3752 // Check whether need to evaluate the expression first.
3753 //
3754 if (Evaluate) {
3755 while (ExpList->Count > Index) {
3756 Status = EvaluateExpression (FormSet, Form, ExpList->Expression[Index++]);
3757 if (EFI_ERROR (Status)) {
3758 return ExpressFalse;
3759 }
3760 }
3761 }
3762
3763 //
3764 // Run the list of expressions.
3765 //
3766 ReturnVal = ExpressFalse;
3767 for (Index = 0; Index < ExpList->Count; Index++) {
3768 if (IsTrue (&ExpList->Expression[Index]->Result)) {
3769 switch (ExpList->Expression[Index]->Type) {
3770 case EFI_HII_EXPRESSION_SUPPRESS_IF:
3771 CompareOne = ExpressSuppress;
3772 break;
3773
3774 case EFI_HII_EXPRESSION_GRAY_OUT_IF:
3775 CompareOne = ExpressGrayOut;
3776 break;
3777
3778 case EFI_HII_EXPRESSION_DISABLE_IF:
3779 CompareOne = ExpressDisable;
3780 break;
3781
3782 default:
3783 return ExpressFalse;
3784 }
3785
3786 ReturnVal = ReturnVal < CompareOne ? CompareOne : ReturnVal;
3787 }
3788 }
3789
3790 return ReturnVal;
3791}
UINT64 UINTN
INT64 INTN
UINT64 EFIAPI StrHexToUint64(IN CONST CHAR16 *String)
Definition: String.c:560
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:443
UINTN EFIAPI StrSize(IN CONST CHAR16 *String)
Definition: String.c:72
RETURN_STATUS EFIAPI StrCpyS(OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:226
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
Definition: LinkedList.c:333
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
INTN EFIAPI StrCmp(IN CONST CHAR16 *FirstString, IN CONST CHAR16 *SecondString)
Definition: String.c:109
UINT64 EFIAPI StrDecimalToUint64(IN CONST CHAR16 *String)
Definition: String.c:456
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
Definition: LinkedList.c:298
RETURN_STATUS EFIAPI StrCatS(IN OUT CHAR16 *Destination, IN UINTN DestMax, IN CONST CHAR16 *Source)
Definition: SafeString.c:405
UINTN EFIAPI StrnLenS(IN CONST CHAR16 *String, IN UINTN MaxSize)
Definition: SafeString.c:119
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
Definition: MultU64x32.c:27
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
UINTN EFIAPI StrLen(IN CONST CHAR16 *String)
Definition: String.c:30
CHAR16 *EFIAPI StrStr(IN CONST CHAR16 *String, IN CONST CHAR16 *SearchString)
Definition: String.c:224
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI IsZeroGuid(IN CONST GUID *Guid)
Definition: MemLibGuid.c:156
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
BOOLEAN GetQuestionValueFromForm(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN EFI_HII_HANDLE InputHiiHandle, IN EFI_GUID *FormSetGuid, IN EFI_QUESTION_ID QuestionId, OUT EFI_HII_VALUE *Value)
Definition: Expression.c:2414
EFI_STATUS IfrMid(IN FORM_BROWSER_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1761
EFI_STATUS CompareHiiValue(IN EFI_HII_VALUE *Value1, IN EFI_HII_VALUE *Value2, OUT INTN *Result, IN EFI_HII_HANDLE HiiHandle OPTIONAL)
Definition: Expression.c:2201
EFI_STATUS GrowConditionalStack(IN OUT FORM_EXPRESSION ***Stack, IN OUT FORM_EXPRESSION ***StackPtr, IN OUT FORM_EXPRESSION ***StackEnd, IN UINTN MemberSize)
Definition: Expression.c:289
EFI_STATUS IfrMatch(IN FORM_BROWSER_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1410
EFI_STATUS EvaluateExpression(IN FORM_BROWSER_FORMSET *FormSet, IN FORM_BROWSER_FORM *Form, IN OUT FORM_EXPRESSION *Expression)
Definition: Expression.c:2536
EFI_STATUS PopMapExpressionList(OUT VOID **Pointer)
Definition: Expression.c:594
VOID ResetScopeStack(VOID)
Definition: Expression.c:617
EXPRESS_RESULT EvaluateExpressionList(IN FORM_EXPRESSION_LIST *ExpList, IN BOOLEAN Evaluate, IN FORM_BROWSER_FORMSET *FormSet OPTIONAL, IN FORM_BROWSER_FORM *Form OPTIONAL)
Definition: Expression.c:3732
VOID ExtendValueToU64(IN EFI_HII_VALUE *Value)
Definition: Expression.c:2096
EFI_STATUS PushConditionalStack(IN OUT FORM_EXPRESSION ***Stack, IN OUT FORM_EXPRESSION ***StackPtr, IN OUT FORM_EXPRESSION ***StackEnd, IN FORM_EXPRESSION **Data)
Definition: Expression.c:348
UINT8 * GetBufferForValue(IN EFI_HII_VALUE *Value)
Definition: Expression.c:1070
EFI_STATUS IfrMatch2(IN FORM_BROWSER_FORMSET *FormSet, IN EFI_GUID *SyntaxType, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1480
VOID RestoreExpressionEvaluationStackOffset(UINTN StackOffset)
Definition: Expression.c:749
EFI_STATUS PushCurrentExpression(IN VOID *Pointer)
Definition: Expression.c:216
VOID ResetCurrentExpressionStack(VOID)
Definition: Expression.c:196
EFI_STATUS PopExpression(OUT EFI_HII_VALUE *Value)
Definition: Expression.c:714
EFI_STATUS PushStack(IN OUT EFI_HII_VALUE **Stack, IN OUT EFI_HII_VALUE **StackPtr, IN OUT EFI_HII_VALUE **StackEnd, IN EFI_HII_VALUE *Data)
Definition: Expression.c:122
BOOLEAN IsTypeInUINT64(IN EFI_HII_VALUE *Value)
Definition: Expression.c:1007
EFI_STATUS PushConditionalExpression(IN FORM_EXPRESSION *Pointer, IN EXPRESS_LEVEL Level)
Definition: Expression.c:479
EFI_STATUS PushScope(IN UINT8 Operand)
Definition: Expression.c:635
FORM_BROWSER_FORM * IdToForm(IN FORM_BROWSER_FORMSET *FormSet, IN UINT16 FormId)
Definition: Expression.c:767
UINT64 HiiValueToUINT64(IN EFI_HII_VALUE *Value)
Definition: Expression.c:2144
EFI_STATUS IfrToken(IN FORM_BROWSER_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1864
EFI_STATUS IfrFind(IN FORM_BROWSER_FORMSET *FormSet, IN UINT8 Format, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1662
FORM_BROWSER_STATEMENT * IdToQuestion(IN FORM_BROWSER_FORMSET *FormSet, IN FORM_BROWSER_FORM *Form, IN UINT16 QuestionId)
Definition: Expression.c:841
EFI_STATUS IfrToString(IN FORM_BROWSER_FORMSET *FormSet, IN UINT8 Format, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1104
BOOLEAN CheckUserPrivilege(IN EFI_GUID *Guid)
Definition: Expression.c:2302
BOOLEAN IsTypeInBuffer(IN EFI_HII_VALUE *Value)
Definition: Expression.c:981
EFI_STATUS IfrCatenate(IN FORM_BROWSER_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1296
EFI_STATUS IfrToUint(IN FORM_BROWSER_FORMSET *FormSet, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1219
FORM_EXPRESSION * RuleIdToExpression(IN FORM_BROWSER_FORM *Form, IN UINT8 RuleId)
Definition: Expression.c:895
EFI_STATUS IfrSpan(IN FORM_BROWSER_FORMSET *FormSet, IN UINT8 Flags, OUT EFI_HII_VALUE *Result)
Definition: Expression.c:1980
EFI_STATUS PopConditionalExpression(IN EXPRESS_LEVEL Level)
Definition: Expression.c:523
INTN GetConditionalExpressionCount(IN EXPRESS_LEVEL Level)
Definition: Expression.c:423
EFI_STATUS PopCurrentExpression(OUT VOID **Pointer)
Definition: Expression.c:243
VOID IfrStrToUpper(IN CHAR16 *String)
Definition: Expression.c:955
EFI_STATUS PushMapExpressionList(IN VOID *Pointer)
Definition: Expression.c:567
EFI_STATUS GrowStack(IN OUT EFI_HII_VALUE **Stack, IN OUT EFI_HII_VALUE **StackPtr, IN OUT EFI_HII_VALUE **StackEnd)
Definition: Expression.c:64
EFI_STATUS PopScope(OUT UINT8 *Operand)
Definition: Expression.c:663
FORM_EXPRESSION ** GetConditionalExpressionList(IN EXPRESS_LEVEL Level)
Definition: Expression.c:450
EFI_STATUS PopConditionalStack(IN FORM_EXPRESSION **Stack, IN OUT FORM_EXPRESSION ***StackPtr, OUT FORM_EXPRESSION **Data)
Definition: Expression.c:391
EFI_STATUS InitializeUnicodeCollationProtocol(VOID)
Definition: Expression.c:925
EFI_STATUS PushExpression(IN EFI_HII_VALUE *Value)
Definition: Expression.c:692
VOID ResetMapExpressionListStack(VOID)
Definition: Expression.c:266
UINT16 GetLengthForValue(IN EFI_HII_VALUE *Value)
Definition: Expression.c:1036
FORM_BROWSER_STATEMENT * IdToQuestion2(IN FORM_BROWSER_FORM *Form, IN UINT16 QuestionId)
Definition: Expression.c:800
BOOLEAN IsTrue(IN EFI_HII_VALUE *Result)
Definition: Expression.c:3692
UINTN SaveExpressionEvaluationStackOffset(VOID)
Definition: Expression.c:731
EFI_STATUS PopStack(IN EFI_HII_VALUE *Stack, IN OUT EFI_HII_VALUE **StackPtr, OUT EFI_HII_VALUE *Data)
Definition: Expression.c:170
CHAR16 * GetToken(IN EFI_STRING_ID Token, IN EFI_HII_HANDLE HiiHandle)
Definition: FormDisplay.c:191
VOID DestroyFormSet(IN OUT FORM_BROWSER_FORMSET *FormSet)
Definition: IfrParse.c:943
RETURN_STATUS EFIAPI UnicodeValueToStringS(IN OUT CHAR16 *Buffer, IN UINTN BufferSize, IN UINTN Flags, IN INT64 Value, IN UINTN Width)
Definition: PrintLib.c:652
UINTN EFIAPI UnicodeSPrint(OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR16 *FormatString,...)
Definition: PrintLib.c:408
EFI_RUNTIME_SERVICES * gRT
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_HII_HANDLE DevicePathToHiiHandle(IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN EFI_GUID *FormsetGuid)
#define MAXIMUM_VALUE_CHARACTERS
Definition: PrintLib.h:189
EFI_STATUS SetValueByName(IN BROWSER_STORAGE *Storage, IN CHAR16 *Name, IN CHAR16 *Value, IN GET_SET_QUESTION_VALUE_WITH SetValueTo, OUT NAME_VALUE_NODE **ReturnNode)
Definition: Setup.c:1163
EFI_STATUS InitializeFormSet(IN EFI_HII_HANDLE Handle, IN OUT EFI_GUID *FormSetGuid, OUT FORM_BROWSER_FORMSET *FormSet)
Definition: Setup.c:6011
EFI_STATUS GetValueByName(IN BROWSER_STORAGE *Storage, IN CHAR16 *Name, IN OUT CHAR16 **Value, IN GET_SET_QUESTION_VALUE_WITH GetValueFrom)
Definition: Setup.c:1113
EFI_STATUS GetQuestionValue(IN FORM_BROWSER_FORMSET *FormSet, IN FORM_BROWSER_FORM *Form, IN OUT FORM_BROWSER_STATEMENT *Question, IN GET_SET_QUESTION_VALUE_WITH GetValueFrom)
Definition: Setup.c:1581
EFI_STRING_ID NewString(IN CHAR16 *String, IN EFI_HII_HANDLE HiiHandle)
Definition: Setup.c:981
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
GUID EFI_GUID
Definition: UefiBaseType.h:25
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
#define EFI_IFR_STRING_UNSIGNED_DEC
#define EFI_IFR_STRING_ASCII
VOID * EFI_HII_HANDLE
@ ByProtocol
Definition: UefiSpec.h:1518
#define EFI_USER_INFO_ACCESS_SETUP
Definition: UserManager.h:216
#define EFI_USER_INFO_ACCESS_POLICY_RECORD
Definition: UserManager.h:175
UINT32 Size
Specifies the size of the user access control record, in bytes, including this header.
Definition: UserManager.h:179
UINT32 Type
Specifies the type of user access control.
Definition: UserManager.h:178
UINT8 InfoType
Definition: UserManager.h:57
UINT32 InfoSize
Definition: UserManager.h:69
Definition: Base.h:213
EFI_STRING_ID string
EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION.