]> git.proxmox.com Git - mirror_edk2.git/blame - EdkCompatibilityPkg/Compatibility/FrameworkHiiToUefiHiiThunk/UefiIfrParser.c
Bug fixes for FrameworkHiiToUefiHiiThunk;
[mirror_edk2.git] / EdkCompatibilityPkg / Compatibility / FrameworkHiiToUefiHiiThunk / UefiIfrParser.c
CommitLineData
59336178 1/** @file\r
2Parser for IFR binary encoding.\r
3\r
4Copyright (c) 2008, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
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
15#include "UefiIfrParser.h"\r
16#include "UefiIfrParserExpression.h"\r
17#include "UefiIfrParserInternal.h"\r
18#include "UefiIfrParserCommon.h"\r
19\r
20\r
21UINT16 mStatementIndex;\r
22UINT16 mExpressionOpCodeIndex;\r
23\r
24BOOLEAN mInScopeSubtitle;\r
25BOOLEAN mInScopeSuppress;\r
26BOOLEAN mInScopeGrayOut;\r
27FORM_EXPRESSION *mSuppressExpression;\r
28FORM_EXPRESSION *mGrayOutExpression;\r
29\r
30EFI_GUID gZeroGuid = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}};\r
59336178 31\r
32/**\r
33 Initialize Statement header members.\r
34\r
35 @param OpCodeData Pointer of the raw OpCode data.\r
36 @param FormSet Pointer of the current FormSe.\r
37 @param Form Pointer of the current Form.\r
38\r
39 @return The Statement.\r
40\r
41**/\r
42FORM_BROWSER_STATEMENT *\r
43CreateStatement (\r
44 IN UINT8 *OpCodeData,\r
45 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
46 IN OUT FORM_BROWSER_FORM *Form\r
47 )\r
48{\r
49 FORM_BROWSER_STATEMENT *Statement;\r
50 EFI_IFR_STATEMENT_HEADER *StatementHdr;\r
51\r
52 if (Form == NULL) {\r
53 //\r
54 // We are currently not in a Form Scope, so just skip this Statement\r
55 //\r
56 return NULL;\r
57 }\r
58\r
59 Statement = &FormSet->StatementBuffer[mStatementIndex];\r
60 mStatementIndex++;\r
61\r
62 InitializeListHead (&Statement->DefaultListHead);\r
63 InitializeListHead (&Statement->OptionListHead);\r
64 InitializeListHead (&Statement->InconsistentListHead);\r
65 InitializeListHead (&Statement->NoSubmitListHead);\r
66\r
67 Statement->Signature = FORM_BROWSER_STATEMENT_SIGNATURE;\r
68\r
69 Statement->Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
70\r
71 StatementHdr = (EFI_IFR_STATEMENT_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
72 CopyMem (&Statement->Prompt, &StatementHdr->Prompt, sizeof (EFI_STRING_ID));\r
73 CopyMem (&Statement->Help, &StatementHdr->Help, sizeof (EFI_STRING_ID));\r
74\r
75 if (mInScopeSuppress) {\r
76 Statement->SuppressExpression = mSuppressExpression;\r
77 }\r
78\r
79 if (mInScopeGrayOut) {\r
80 Statement->GrayOutExpression = mGrayOutExpression;\r
81 }\r
82\r
83 Statement->InSubtitle = mInScopeSubtitle;\r
84\r
85 //\r
86 // Insert this Statement into current Form\r
87 //\r
88 InsertTailList (&Form->StatementListHead, &Statement->Link);\r
89\r
90 return Statement;\r
91}\r
92\r
93\r
94/**\r
95 Initialize Question's members.\r
96\r
97 @param OpCodeData Pointer of the raw OpCode data.\r
98 @param FormSet Pointer of the current FormSet.\r
99 @param Form Pointer of the current Form.\r
100\r
101 @return The Question.\r
102\r
103**/\r
104FORM_BROWSER_STATEMENT *\r
105CreateQuestion (\r
106 IN UINT8 *OpCodeData,\r
107 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
108 IN OUT FORM_BROWSER_FORM *Form\r
109 )\r
110{\r
111 FORM_BROWSER_STATEMENT *Statement;\r
112 EFI_IFR_QUESTION_HEADER *QuestionHdr;\r
113 LIST_ENTRY *Link;\r
114 FORMSET_STORAGE *Storage;\r
115 NAME_VALUE_NODE *NameValueNode;\r
116\r
117 Statement = CreateStatement (OpCodeData, FormSet, Form);\r
118 if (Statement == NULL) {\r
119 return NULL;\r
120 }\r
121\r
122 QuestionHdr = (EFI_IFR_QUESTION_HEADER *) (OpCodeData + sizeof (EFI_IFR_OP_HEADER));\r
123 CopyMem (&Statement->QuestionId, &QuestionHdr->QuestionId, sizeof (EFI_QUESTION_ID));\r
124 CopyMem (&Statement->VarStoreId, &QuestionHdr->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
125 CopyMem (&Statement->VarStoreInfo.VarOffset, &QuestionHdr->VarStoreInfo.VarOffset, sizeof (UINT16));\r
126\r
127 Statement->QuestionFlags = QuestionHdr->Flags;\r
128\r
129 if (Statement->VarStoreId == 0) {\r
130 //\r
131 // VarStoreId of zero indicates no variable storage\r
132 //\r
133 return Statement;\r
134 }\r
135\r
136 //\r
137 // Find Storage for this Question\r
138 //\r
139 Link = GetFirstNode (&FormSet->StorageListHead);\r
140 while (!IsNull (&FormSet->StorageListHead, Link)) {\r
141 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
142\r
143 if (Storage->VarStoreId == Statement->VarStoreId) {\r
144 Statement->Storage = Storage;\r
145 break;\r
146 }\r
147\r
148 Link = GetNextNode (&FormSet->StorageListHead, Link);\r
149 }\r
150 ASSERT (Statement->Storage != NULL);\r
151\r
152 //\r
153 // Initialilze varname for Name/Value or EFI Variable\r
154 //\r
155 if ((Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) ||\r
156 (Statement->Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE)) {\r
157 Statement->VariableName = GetToken (Statement->VarStoreInfo.VarName, FormSet->HiiHandle);\r
158 ASSERT (Statement->VariableName != NULL);\r
159\r
160 if (Statement->Storage->Type == EFI_HII_VARSTORE_NAME_VALUE) {\r
161 //\r
162 // Insert to Name/Value varstore list\r
163 //\r
164 NameValueNode = AllocateZeroPool (sizeof (NAME_VALUE_NODE));\r
165 ASSERT (NameValueNode != NULL);\r
166 NameValueNode->Signature = NAME_VALUE_NODE_SIGNATURE;\r
167 NameValueNode->Name = AllocateCopyPool (StrSize (Statement->VariableName), Statement->VariableName);\r
168 ASSERT (NameValueNode->Name != NULL);\r
169 NameValueNode->Value = AllocateZeroPool (0x10);\r
170 ASSERT (NameValueNode->Value != NULL);\r
171 NameValueNode->EditValue = AllocateZeroPool (0x10);\r
172 ASSERT (NameValueNode->EditValue != NULL);\r
173\r
174 InsertTailList (&Statement->Storage->NameValueListHead, &NameValueNode->Link);\r
175 }\r
176 }\r
177\r
178 return Statement;\r
179}\r
180\r
181\r
182/**\r
183 Allocate a FORM_EXPRESSION node.\r
184\r
185 @param Form The Form associated with this Expression\r
186\r
187 @return Pointer to a FORM_EXPRESSION data structure.\r
188\r
189**/\r
190FORM_EXPRESSION *\r
191CreateExpression (\r
192 IN OUT FORM_BROWSER_FORM *Form\r
193 )\r
194{\r
195 FORM_EXPRESSION *Expression;\r
196\r
197 Expression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
198 Expression->Signature = FORM_EXPRESSION_SIGNATURE;\r
199 InitializeListHead (&Expression->OpCodeListHead);\r
200\r
201 return Expression;\r
202}\r
203\r
204\r
205/**\r
206 Allocate a FORMSET_STORAGE data structure and insert to FormSet Storage List.\r
207\r
208 @param FormSet Pointer of the current FormSet\r
209\r
210 @return Pointer to a FORMSET_STORAGE data structure.\r
211\r
212**/\r
213FORMSET_STORAGE *\r
214CreateStorage (\r
215 IN FORM_BROWSER_FORMSET *FormSet\r
216 )\r
217{\r
218 FORMSET_STORAGE *Storage;\r
219\r
220 Storage = AllocateZeroPool (sizeof (FORMSET_STORAGE));\r
221 Storage->Signature = FORMSET_STORAGE_SIGNATURE;\r
222 InitializeListHead (&Storage->NameValueListHead);\r
223 InsertTailList (&FormSet->StorageListHead, &Storage->Link);\r
224\r
225 return Storage;\r
226}\r
227\r
228\r
229/**\r
230 Create ConfigHdr string for a storage.\r
231\r
232 @param FormSet Pointer of the current FormSet\r
233 @param Storage Pointer of the storage\r
234\r
235 @retval EFI_SUCCESS Initialize ConfigHdr success\r
236\r
237**/\r
238EFI_STATUS\r
239InitializeConfigHdr (\r
240 IN FORM_BROWSER_FORMSET *FormSet,\r
241 IN OUT FORMSET_STORAGE *Storage\r
242 )\r
243{\r
244 EFI_STATUS Status;\r
245 UINTN StrBufferLen;\r
246 CHAR16 *Name;\r
247\r
248 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
249 Name = Storage->Name;\r
250 } else {\r
251 Name = NULL;\r
252 }\r
253\r
254 StrBufferLen = 0;\r
255 Status = ConstructConfigHdr (\r
256 Storage->ConfigHdr,\r
257 &StrBufferLen,\r
258 &Storage->Guid,\r
259 Name,\r
260 FormSet->DriverHandle\r
261 );\r
262 if (Status == EFI_BUFFER_TOO_SMALL) {\r
263 Storage->ConfigHdr = AllocateZeroPool (StrBufferLen);\r
264 Status = ConstructConfigHdr (\r
265 Storage->ConfigHdr,\r
266 &StrBufferLen,\r
267 &Storage->Guid,\r
268 Name,\r
269 FormSet->DriverHandle\r
270 );\r
271 }\r
272\r
273 if (EFI_ERROR (Status)) {\r
274 return Status;\r
275 }\r
276\r
277 Storage->ConfigRequest = AllocateCopyPool (StrBufferLen, Storage->ConfigHdr);\r
278 Storage->SpareStrLen = 0;\r
279\r
280 return EFI_SUCCESS;\r
281}\r
282\r
283\r
284/**\r
285 Initialize Request Element of a Question. <RequestElement> ::= '&'<BlockName> | '&'<Label>\r
286\r
287 @param FormSet Pointer of the current FormSet.\r
288 @param Question The Question to be initialized.\r
289\r
290 @retval EFI_SUCCESS Function success.\r
291 @retval EFI_INVALID_PARAMETER No storage associated with the Question.\r
292\r
293**/\r
294EFI_STATUS\r
295InitializeRequestElement (\r
296 IN OUT FORM_BROWSER_FORMSET *FormSet,\r
297 IN OUT FORM_BROWSER_STATEMENT *Question\r
298 )\r
299{\r
300 FORMSET_STORAGE *Storage;\r
301 UINTN StrLen;\r
302 UINTN StringSize;\r
303 CHAR16 *NewStr;\r
304 CHAR16 RequestElement[30];\r
305\r
306 Storage = Question->Storage;\r
307 if (Storage == NULL) {\r
308 return EFI_INVALID_PARAMETER;\r
309 }\r
310\r
311 if (Storage->Type == EFI_HII_VARSTORE_EFI_VARIABLE) {\r
312 //\r
313 // <ConfigRequest> is unnecessary for EFI variable storage,\r
314 // GetVariable()/SetVariable() will be used to retrieve/save values\r
315 //\r
316 return EFI_SUCCESS;\r
317 }\r
318\r
319 //\r
320 // Prepare <RequestElement>\r
321 //\r
322 if (Storage->Type == EFI_HII_VARSTORE_BUFFER) {\r
323 StrLen = UnicodeSPrint (\r
324 RequestElement,\r
325 30 * sizeof (CHAR16),\r
326 L"&OFFSET=%x&WIDTH=%x",\r
327 Question->VarStoreInfo.VarOffset,\r
328 Question->StorageWidth\r
329 );\r
330 Question->BlockName = AllocateCopyPool ((StrLen + 1) * sizeof (CHAR16), RequestElement);\r
331 } else {\r
332 StrLen = UnicodeSPrint (RequestElement, 30 * sizeof (CHAR16), L"&%s", Question->VariableName);\r
333 }\r
334\r
335 if ((Question->Operand == EFI_IFR_PASSWORD_OP) && (Question->QuestionFlags & EFI_IFR_FLAG_CALLBACK)) {\r
336 //\r
337 // Password with CALLBACK flag is stored in encoded format,\r
338 // so don't need to append it to <ConfigRequest>\r
339 //\r
340 return EFI_SUCCESS;\r
341 }\r
342\r
343 //\r
344 // Append <RequestElement> to <ConfigRequest>\r
345 //\r
346 if (StrLen > Storage->SpareStrLen) {\r
347 //\r
348 // Old String buffer is not sufficient for RequestElement, allocate a new one\r
349 //\r
350 StringSize = (Storage->ConfigRequest != NULL) ? StrSize (Storage->ConfigRequest) : sizeof (CHAR16);\r
351 NewStr = AllocateZeroPool (StringSize + CONFIG_REQUEST_STRING_INCREMENTAL * sizeof (CHAR16));\r
352 if (Storage->ConfigRequest != NULL) {\r
353 CopyMem (NewStr, Storage->ConfigRequest, StringSize);\r
354 gBS->FreePool (Storage->ConfigRequest);\r
355 }\r
356 Storage->ConfigRequest = NewStr;\r
357 Storage->SpareStrLen = CONFIG_REQUEST_STRING_INCREMENTAL;\r
358 }\r
359\r
360 StrCat (Storage->ConfigRequest, RequestElement);\r
361 Storage->ElementCount++;\r
362 Storage->SpareStrLen -= StrLen;\r
363\r
364 return EFI_SUCCESS;\r
365}\r
366\r
367\r
368/**\r
369 Free resources of a Expression\r
370\r
371 @param FormSet Pointer of the Expression\r
372\r
373 @return None.\r
374\r
375**/\r
376VOID\r
377DestroyExpression (\r
378 IN FORM_EXPRESSION *Expression\r
379 )\r
380{\r
381 LIST_ENTRY *Link;\r
382 EXPRESSION_OPCODE *OpCode;\r
383\r
384 while (!IsListEmpty (&Expression->OpCodeListHead)) {\r
385 Link = GetFirstNode (&Expression->OpCodeListHead);\r
386 OpCode = EXPRESSION_OPCODE_FROM_LINK (Link);\r
387 RemoveEntryList (&OpCode->Link);\r
388\r
389 SafeFreePool (OpCode->ValueList);\r
390 }\r
391\r
392 //\r
393 // Free this Expression\r
394 //\r
395 gBS->FreePool (Expression);\r
396}\r
397\r
398\r
399/**\r
400 Free resources of a storage\r
401\r
402 @param Storage Pointer of the storage\r
403\r
404 @return None.\r
405\r
406**/\r
407VOID\r
408DestroyStorage (\r
409 IN FORMSET_STORAGE *Storage\r
410 )\r
411{\r
412 LIST_ENTRY *Link;\r
413 NAME_VALUE_NODE *NameValueNode;\r
414\r
415 if (Storage == NULL) {\r
416 return;\r
417 }\r
418\r
419 SafeFreePool (Storage->Name);\r
420 SafeFreePool (Storage->Buffer);\r
421 SafeFreePool (Storage->EditBuffer);\r
422\r
423 while (!IsListEmpty (&Storage->NameValueListHead)) {\r
424 Link = GetFirstNode (&Storage->NameValueListHead);\r
425 NameValueNode = NAME_VALUE_NODE_FROM_LINK (Link);\r
426 RemoveEntryList (&NameValueNode->Link);\r
427\r
428 SafeFreePool (NameValueNode->Name);\r
429 SafeFreePool (NameValueNode->Value);\r
430 SafeFreePool (NameValueNode->EditValue);\r
431 SafeFreePool (NameValueNode);\r
432 }\r
433\r
434 SafeFreePool (Storage->ConfigHdr);\r
435 SafeFreePool (Storage->ConfigRequest);\r
436\r
437 gBS->FreePool (Storage);\r
438}\r
439\r
440\r
441/**\r
442 Free resources of a Statement\r
443\r
444 @param Statement Pointer of the Statement\r
445\r
446 @return None.\r
447\r
448**/\r
449VOID\r
450DestroyStatement (\r
451 IN OUT FORM_BROWSER_STATEMENT *Statement\r
452 )\r
453{\r
454 LIST_ENTRY *Link;\r
455 QUESTION_DEFAULT *Default;\r
456 QUESTION_OPTION *Option;\r
457 FORM_EXPRESSION *Expression;\r
458\r
459 //\r
460 // Free Default value List\r
461 //\r
462 while (!IsListEmpty (&Statement->DefaultListHead)) {\r
463 Link = GetFirstNode (&Statement->DefaultListHead);\r
464 Default = QUESTION_DEFAULT_FROM_LINK (Link);\r
465 RemoveEntryList (&Default->Link);\r
466\r
467 gBS->FreePool (Default);\r
468 }\r
469\r
470 //\r
471 // Free Options List\r
472 //\r
473 while (!IsListEmpty (&Statement->OptionListHead)) {\r
474 Link = GetFirstNode (&Statement->OptionListHead);\r
475 Option = QUESTION_OPTION_FROM_LINK (Link);\r
476 RemoveEntryList (&Option->Link);\r
477\r
478 gBS->FreePool (Option);\r
479 }\r
480\r
481 //\r
482 // Free Inconsistent List\r
483 //\r
484 while (!IsListEmpty (&Statement->InconsistentListHead)) {\r
485 Link = GetFirstNode (&Statement->InconsistentListHead);\r
486 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
487 RemoveEntryList (&Expression->Link);\r
488\r
489 DestroyExpression (Expression);\r
490 }\r
491\r
492 //\r
493 // Free NoSubmit List\r
494 //\r
495 while (!IsListEmpty (&Statement->NoSubmitListHead)) {\r
496 Link = GetFirstNode (&Statement->NoSubmitListHead);\r
497 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
498 RemoveEntryList (&Expression->Link);\r
499\r
500 DestroyExpression (Expression);\r
501 }\r
502\r
503 SafeFreePool (Statement->VariableName);\r
504 SafeFreePool (Statement->BlockName);\r
505}\r
506\r
507\r
508/**\r
509 Free resources of a Form\r
510\r
511 @param Form Pointer of the Form\r
512\r
513 @return None.\r
514\r
515**/\r
516VOID\r
517DestroyForm (\r
518 IN OUT FORM_BROWSER_FORM *Form\r
519 )\r
520{\r
521 LIST_ENTRY *Link;\r
522 FORM_EXPRESSION *Expression;\r
523 FORM_BROWSER_STATEMENT *Statement;\r
524\r
525 //\r
526 // Free Form Expressions\r
527 //\r
528 while (!IsListEmpty (&Form->ExpressionListHead)) {\r
529 Link = GetFirstNode (&Form->ExpressionListHead);\r
530 Expression = FORM_EXPRESSION_FROM_LINK (Link);\r
531 RemoveEntryList (&Expression->Link);\r
532\r
533 DestroyExpression (Expression);\r
534 }\r
535\r
536 //\r
537 // Free Statements/Questions\r
538 //\r
539 while (!IsListEmpty (&Form->StatementListHead)) {\r
540 Link = GetFirstNode (&Form->StatementListHead);\r
541 Statement = FORM_BROWSER_STATEMENT_FROM_LINK (Link);\r
542 RemoveEntryList (&Statement->Link);\r
543\r
544 DestroyStatement (Statement);\r
545 }\r
546\r
547 //\r
548 // Free this Form\r
549 //\r
550 gBS->FreePool (Form);\r
551}\r
552\r
553\r
554/**\r
555 Free resources allocated for a FormSet\r
556\r
557 @param FormSet Pointer of the FormSet\r
558\r
559 @return None.\r
560\r
561**/\r
562VOID\r
563DestroyFormSet (\r
564 IN OUT FORM_BROWSER_FORMSET *FormSet\r
565 )\r
566{\r
567 LIST_ENTRY *Link;\r
568 FORMSET_STORAGE *Storage;\r
569 FORMSET_DEFAULTSTORE *DefaultStore;\r
570 FORM_BROWSER_FORM *Form;\r
571\r
572 //\r
573 // Free IFR binary buffer\r
574 //\r
575 SafeFreePool (FormSet->IfrBinaryData);\r
576\r
577 //\r
578 // Free FormSet Storage\r
579 //\r
580 if (FormSet->StorageListHead.ForwardLink != NULL) {\r
581 while (!IsListEmpty (&FormSet->StorageListHead)) {\r
582 Link = GetFirstNode (&FormSet->StorageListHead);\r
583 Storage = FORMSET_STORAGE_FROM_LINK (Link);\r
584 RemoveEntryList (&Storage->Link);\r
585\r
586 DestroyStorage (Storage);\r
587 }\r
588 }\r
589\r
590 //\r
591 // Free FormSet Default Store\r
592 //\r
593 if (FormSet->DefaultStoreListHead.ForwardLink != NULL) {\r
594 while (!IsListEmpty (&FormSet->DefaultStoreListHead)) {\r
595 Link = GetFirstNode (&FormSet->DefaultStoreListHead);\r
596 DefaultStore = FORMSET_DEFAULTSTORE_FROM_LINK (Link);\r
597 RemoveEntryList (&DefaultStore->Link);\r
598\r
599 gBS->FreePool (DefaultStore);\r
600 }\r
601 }\r
602\r
603 //\r
604 // Free Forms\r
605 //\r
606 if (FormSet->FormListHead.ForwardLink != NULL) {\r
607 while (!IsListEmpty (&FormSet->FormListHead)) {\r
608 Link = GetFirstNode (&FormSet->FormListHead);\r
609 Form = FORM_BROWSER_FORM_FROM_LINK (Link);\r
610 RemoveEntryList (&Form->Link);\r
611\r
612 DestroyForm (Form);\r
613 }\r
614 }\r
615\r
616 SafeFreePool (FormSet->StatementBuffer);\r
617 SafeFreePool (FormSet->ExpressionBuffer);\r
618\r
619 SafeFreePool (FormSet);\r
620}\r
621\r
622\r
623/**\r
624 Tell whether this Operand is an Expression OpCode or not\r
625\r
626 @param Operand Operand of an IFR OpCode.\r
627\r
628 @retval TRUE This is an Expression OpCode.\r
629 @retval FALSE Not an Expression OpCode.\r
630\r
631**/\r
632BOOLEAN\r
633IsExpressionOpCode (\r
634 IN UINT8 Operand\r
635 )\r
636{\r
637 if (((Operand >= EFI_IFR_EQ_ID_VAL_OP) && (Operand <= EFI_IFR_NOT_OP)) ||\r
638 ((Operand >= EFI_IFR_MATCH_OP) && (Operand <= EFI_IFR_SPAN_OP)) ||\r
639 (Operand == EFI_IFR_CATENATE_OP)\r
640 ) {\r
641 return TRUE;\r
642 } else {\r
643 return FALSE;\r
644 }\r
645}\r
646\r
647\r
648/**\r
649 Calculate number of Statemens(Questions) and Expression OpCodes.\r
650\r
651 @param FormSet The FormSet to be counted.\r
652 @param NumberOfStatement Number of Statemens(Questions)\r
653 @param NumberOfExpression Number of Expression OpCodes\r
654\r
655 @return None.\r
656\r
657**/\r
658VOID\r
659CountOpCodes (\r
660 IN FORM_BROWSER_FORMSET *FormSet,\r
661 IN OUT UINT16 *NumberOfStatement,\r
662 IN OUT UINT16 *NumberOfExpression\r
663 )\r
664{\r
665 UINT16 StatementCount;\r
666 UINT16 ExpressionCount;\r
667 UINT8 *OpCodeData;\r
668 UINTN Offset;\r
669 UINTN OpCodeLen;\r
670\r
671 Offset = 0;\r
672 StatementCount = 0;\r
673 ExpressionCount = 0;\r
674\r
675 while (Offset < FormSet->IfrBinaryLength) {\r
676 OpCodeData = FormSet->IfrBinaryData + Offset;\r
677 OpCodeLen = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
678 Offset += OpCodeLen;\r
679\r
680 if (IsExpressionOpCode (((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode)) {\r
681 ExpressionCount++;\r
682 } else {\r
683 StatementCount++;\r
684 }\r
685 }\r
686\r
687 *NumberOfStatement = StatementCount;\r
688 *NumberOfExpression = ExpressionCount;\r
689}\r
690\r
691\r
692/**\r
693 Parse opcodes in the formset IFR binary.\r
694\r
695 @param FormSet Pointer of the FormSet data structure.\r
696\r
697 @retval EFI_SUCCESS Opcode parse success.\r
698 @retval Other Opcode parse fail.\r
699\r
700**/\r
701EFI_STATUS\r
702ParseOpCodes (\r
703 IN FORM_BROWSER_FORMSET *FormSet\r
704 )\r
705{\r
706 EFI_STATUS Status;\r
707 UINT16 Index;\r
708 FORM_BROWSER_FORM *CurrentForm;\r
709 FORM_BROWSER_STATEMENT *CurrentStatement;\r
710 EXPRESSION_OPCODE *ExpressionOpCode;\r
711 FORM_EXPRESSION *CurrentExpression;\r
712 UINT8 Operand;\r
713 UINT8 Scope;\r
714 UINTN OpCodeOffset;\r
715 UINTN OpCodeLength;\r
716 UINT8 *OpCodeData;\r
717 UINT8 ScopeOpCode;\r
718 FORMSET_STORAGE *Storage;\r
719 FORMSET_DEFAULTSTORE *DefaultStore;\r
720 QUESTION_DEFAULT *CurrentDefault;\r
721 QUESTION_OPTION *CurrentOption;\r
722 CHAR8 *AsciiString;\r
723 UINT16 NumberOfStatement;\r
724 UINT16 NumberOfExpression;\r
725 EFI_IMAGE_ID *ImageId;\r
726 BOOLEAN SuppressForOption;\r
727 BOOLEAN InScopeOptionSuppress;\r
728 FORM_EXPRESSION *OptionSuppressExpression;\r
729 BOOLEAN InScopeDisable;\r
730 UINT16 DepthOfDisable;\r
731 BOOLEAN OpCodeDisabled;\r
732 BOOLEAN SingleOpCodeExpression;\r
733 BOOLEAN InScopeDefault;\r
734 EFI_HII_VALUE *Value;\r
735\r
736 mInScopeSubtitle = FALSE;\r
737 SuppressForOption = FALSE;\r
738 mInScopeSuppress = FALSE;\r
739 InScopeOptionSuppress = FALSE;\r
740 mInScopeGrayOut = FALSE;\r
741 InScopeDisable = FALSE;\r
742 DepthOfDisable = 0;\r
743 OpCodeDisabled = FALSE;\r
744 SingleOpCodeExpression = FALSE;\r
745 InScopeDefault = FALSE;\r
746 CurrentExpression = NULL;\r
747 CurrentDefault = NULL;\r
748 CurrentOption = NULL;\r
749 OptionSuppressExpression = NULL;\r
750\r
751 //\r
752 // Get the number of Statements and Expressions\r
753 //\r
754 CountOpCodes (FormSet, &NumberOfStatement, &NumberOfExpression);\r
755\r
756 mStatementIndex = 0;\r
757 FormSet->StatementBuffer = AllocateZeroPool (NumberOfStatement * sizeof (FORM_BROWSER_STATEMENT));\r
758 if (FormSet->StatementBuffer == NULL) {\r
759 return EFI_OUT_OF_RESOURCES;\r
760 }\r
761\r
762 mExpressionOpCodeIndex = 0;\r
763 FormSet->ExpressionBuffer = AllocateZeroPool (NumberOfExpression * sizeof (EXPRESSION_OPCODE));\r
764 if (FormSet->ExpressionBuffer == NULL) {\r
765 return EFI_OUT_OF_RESOURCES;\r
766 }\r
767\r
768 InitializeListHead (&FormSet->StorageListHead);\r
769 InitializeListHead (&FormSet->DefaultStoreListHead);\r
770 InitializeListHead (&FormSet->FormListHead);\r
771\r
772 CurrentForm = NULL;\r
773 CurrentStatement = NULL;\r
774\r
775 ResetScopeStack ();\r
776\r
777 OpCodeOffset = 0;\r
778 while (OpCodeOffset < FormSet->IfrBinaryLength) {\r
779 OpCodeData = FormSet->IfrBinaryData + OpCodeOffset;\r
780\r
781 OpCodeLength = ((EFI_IFR_OP_HEADER *) OpCodeData)->Length;\r
782 OpCodeOffset += OpCodeLength;\r
783 Operand = ((EFI_IFR_OP_HEADER *) OpCodeData)->OpCode;\r
784 Scope = ((EFI_IFR_OP_HEADER *) OpCodeData)->Scope;\r
785\r
786 //\r
787 // If scope bit set, push onto scope stack\r
788 //\r
789 if (Scope) {\r
790 PushScope (Operand);\r
791 }\r
792\r
793 if (OpCodeDisabled) {\r
794 //\r
795 // DisableIf Expression is evaluated to be TRUE, try to find its end.\r
796 // Here only cares the EFI_IFR_DISABLE_IF and EFI_IFR_END\r
797 //\r
798 if (Operand == EFI_IFR_DISABLE_IF_OP) {\r
799 DepthOfDisable++;\r
800 } else if (Operand == EFI_IFR_END_OP) {\r
801 Status = PopScope (&ScopeOpCode);\r
802 if (EFI_ERROR (Status)) {\r
803 return Status;\r
804 }\r
805\r
806 if (ScopeOpCode == EFI_IFR_DISABLE_IF_OP) {\r
807 if (DepthOfDisable == 0) {\r
808 InScopeDisable = FALSE;\r
809 OpCodeDisabled = FALSE;\r
810 } else {\r
811 DepthOfDisable--;\r
812 }\r
813 }\r
814 }\r
815 continue;\r
816 }\r
817\r
818 if (IsExpressionOpCode (Operand)) {\r
819 ExpressionOpCode = &FormSet->ExpressionBuffer[mExpressionOpCodeIndex];\r
820 mExpressionOpCodeIndex++;\r
821\r
822 ExpressionOpCode->Signature = EXPRESSION_OPCODE_SIGNATURE;\r
823 ExpressionOpCode->Operand = Operand;\r
824 Value = &ExpressionOpCode->Value;\r
825\r
826 switch (Operand) {\r
827 case EFI_IFR_EQ_ID_VAL_OP:\r
828 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
829\r
830 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
831 CopyMem (&Value->Value.u16, &((EFI_IFR_EQ_ID_VAL *) OpCodeData)->Value, sizeof (UINT16));\r
832 break;\r
833\r
834 case EFI_IFR_EQ_ID_ID_OP:\r
835 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId1, sizeof (EFI_QUESTION_ID));\r
836 CopyMem (&ExpressionOpCode->QuestionId2, &((EFI_IFR_EQ_ID_ID *) OpCodeData)->QuestionId2, sizeof (EFI_QUESTION_ID));\r
837 break;\r
838\r
839 case EFI_IFR_EQ_ID_LIST_OP:\r
840 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
841 CopyMem (&ExpressionOpCode->ListLength, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ListLength, sizeof (UINT16));\r
842 ExpressionOpCode->ValueList = AllocateCopyPool (ExpressionOpCode->ListLength * sizeof (UINT16), &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->ValueList);\r
843 break;\r
844\r
845 case EFI_IFR_TO_STRING_OP:\r
846 case EFI_IFR_FIND_OP:\r
847 ExpressionOpCode->Format = (( EFI_IFR_TO_STRING *) OpCodeData)->Format;\r
848 break;\r
849\r
850 case EFI_IFR_STRING_REF1_OP:\r
851 Value->Type = EFI_IFR_TYPE_STRING;\r
852 CopyMem (&Value->Value.string, &(( EFI_IFR_STRING_REF1 *) OpCodeData)->StringId, sizeof (EFI_STRING_ID));\r
853 break;\r
854\r
855 case EFI_IFR_RULE_REF_OP:\r
856 ExpressionOpCode->RuleId = (( EFI_IFR_RULE_REF *) OpCodeData)->RuleId;\r
857 break;\r
858\r
859 case EFI_IFR_SPAN_OP:\r
860 ExpressionOpCode->Flags = (( EFI_IFR_SPAN *) OpCodeData)->Flags;\r
861 break;\r
862\r
863 case EFI_IFR_THIS_OP:\r
864 ExpressionOpCode->QuestionId = CurrentStatement->QuestionId;\r
865 break;\r
866\r
867 case EFI_IFR_QUESTION_REF1_OP:\r
868 CopyMem (&ExpressionOpCode->QuestionId, &((EFI_IFR_EQ_ID_LIST *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
869 break;\r
870\r
871 case EFI_IFR_QUESTION_REF3_OP:\r
872 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_2)) {\r
873 CopyMem (&ExpressionOpCode->DevicePath, &(( EFI_IFR_QUESTION_REF3_2 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
874\r
875 if (OpCodeLength >= sizeof (EFI_IFR_QUESTION_REF3_3)) {\r
876 CopyMem (&ExpressionOpCode->Guid, &(( EFI_IFR_QUESTION_REF3_3 *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
877 }\r
878 }\r
879 break;\r
880\r
881 //\r
882 // constant\r
883 //\r
884 case EFI_IFR_TRUE_OP:\r
885 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
886 Value->Value.b = TRUE;\r
887 break;\r
888\r
889 case EFI_IFR_FALSE_OP:\r
890 Value->Type = EFI_IFR_TYPE_BOOLEAN;\r
891 Value->Value.b = FALSE;\r
892 break;\r
893\r
894 case EFI_IFR_ONE_OP:\r
895 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
896 Value->Value.u8 = 1;\r
897 break;\r
898\r
899 case EFI_IFR_ZERO_OP:\r
900 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
901 Value->Value.u8 = 0;\r
902 break;\r
903\r
904 case EFI_IFR_ONES_OP:\r
905 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
906 Value->Value.u64 = 0xffffffffffffffffULL;\r
907 break;\r
908\r
909 case EFI_IFR_UINT8_OP:\r
910 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
911 Value->Value.u8 = (( EFI_IFR_UINT8 *) OpCodeData)->Value;\r
912 break;\r
913\r
914 case EFI_IFR_UINT16_OP:\r
915 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
916 CopyMem (&Value->Value.u16, &(( EFI_IFR_UINT16 *) OpCodeData)->Value, sizeof (UINT16));\r
917 break;\r
918\r
919 case EFI_IFR_UINT32_OP:\r
920 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
921 CopyMem (&Value->Value.u32, &(( EFI_IFR_UINT32 *) OpCodeData)->Value, sizeof (UINT32));\r
922 break;\r
923\r
924 case EFI_IFR_UINT64_OP:\r
925 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
926 CopyMem (&Value->Value.u64, &(( EFI_IFR_UINT64 *) OpCodeData)->Value, sizeof (UINT64));\r
927 break;\r
928\r
929 case EFI_IFR_UNDEFINED_OP:\r
930 Value->Type = EFI_IFR_TYPE_OTHER;\r
931 break;\r
932\r
933 case EFI_IFR_VERSION_OP:\r
934 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
935 Value->Value.u16 = EFI_IFR_SPECIFICATION_VERSION;\r
936 break;\r
937\r
938 default:\r
939 break;\r
940 }\r
941\r
942 InsertTailList (&CurrentExpression->OpCodeListHead, &ExpressionOpCode->Link);\r
943\r
944 if (SingleOpCodeExpression) {\r
945 //\r
946 // There are two cases to indicate the end of an Expression:\r
947 // for single OpCode expression: one Expression OpCode\r
948 // for expression consists of more than one OpCode: EFI_IFR_END\r
949 //\r
950 SingleOpCodeExpression = FALSE;\r
951\r
952 if (InScopeDisable) {\r
953 //\r
954 // Evaluate DisableIf expression\r
955 //\r
956 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
957 if (EFI_ERROR (Status)) {\r
958 return Status;\r
959 }\r
960 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
961 return EFI_INVALID_PARAMETER;\r
962 }\r
963\r
964 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
965 }\r
966\r
967 CurrentExpression = NULL;\r
968 }\r
969\r
970 continue;\r
971 }\r
972\r
973 //\r
974 // Parse the Opcode\r
975 //\r
976 switch (Operand) {\r
977\r
978 case EFI_IFR_FORM_SET_OP:\r
979 //\r
980 // check the formset GUID\r
981 //\r
982 if (CompareMem (&FormSet->Guid, &((EFI_IFR_FORM_SET *) OpCodeData)->Guid, sizeof (EFI_GUID)) != 0) {\r
983 return EFI_INVALID_PARAMETER;\r
984 }\r
985\r
986 CopyMem (&FormSet->FormSetTitle, &((EFI_IFR_FORM_SET *) OpCodeData)->FormSetTitle, sizeof (EFI_STRING_ID));\r
987 CopyMem (&FormSet->Help, &((EFI_IFR_FORM_SET *) OpCodeData)->Help, sizeof (EFI_STRING_ID));\r
988 break;\r
989\r
990 case EFI_IFR_FORM_OP:\r
991 //\r
992 // Create a new Form for this FormSet\r
993 //\r
994 CurrentForm = AllocateZeroPool (sizeof (FORM_BROWSER_FORM));\r
995 CurrentForm->Signature = FORM_BROWSER_FORM_SIGNATURE;\r
996 InitializeListHead (&CurrentForm->ExpressionListHead);\r
997 InitializeListHead (&CurrentForm->StatementListHead);\r
998\r
999 CopyMem (&CurrentForm->FormId, &((EFI_IFR_FORM *) OpCodeData)->FormId, sizeof (UINT16));\r
1000 CopyMem (&CurrentForm->FormTitle, &((EFI_IFR_FORM *) OpCodeData)->FormTitle, sizeof (EFI_STRING_ID));\r
1001\r
1002 //\r
1003 // Insert into Form list of this FormSet\r
1004 //\r
1005 InsertTailList (&FormSet->FormListHead, &CurrentForm->Link);\r
1006 break;\r
1007\r
1008 //\r
1009 // Storage\r
1010 //\r
1011 case EFI_IFR_VARSTORE_OP:\r
1012 //\r
1013 // Create a buffer Storage for this FormSet\r
1014 //\r
1015 Storage = CreateStorage (FormSet);\r
1016 Storage->Type = EFI_HII_VARSTORE_BUFFER;\r
1017\r
1018 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1019 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1020 CopyMem (&Storage->Size, &((EFI_IFR_VARSTORE *) OpCodeData)->Size, sizeof (UINT16));\r
1021\r
1022 Storage->Buffer = AllocateZeroPool (Storage->Size);\r
1023 Storage->EditBuffer = AllocateZeroPool (Storage->Size);\r
1024\r
1025 AsciiString = (CHAR8 *) ((EFI_IFR_VARSTORE *) OpCodeData)->Name;\r
1026 Storage->Name = AllocateZeroPool (AsciiStrSize (AsciiString) * 2);\r
1027 ASSERT (Storage->Name != NULL);\r
1028 for (Index = 0; AsciiString[Index] != 0; Index++) {\r
1029 Storage->Name[Index] = (CHAR16) AsciiString[Index];\r
1030 }\r
1031\r
1032 //\r
1033 // Initialize <ConfigHdr>\r
1034 //\r
1035 InitializeConfigHdr (FormSet, Storage);\r
1036 break;\r
1037\r
1038 case EFI_IFR_VARSTORE_NAME_VALUE_OP:\r
1039 //\r
1040 // Create a name/value Storage for this FormSet\r
1041 //\r
1042 Storage = CreateStorage (FormSet);\r
1043 Storage->Type = EFI_HII_VARSTORE_NAME_VALUE;\r
1044\r
1045 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1046 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_NAME_VALUE *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1047\r
1048 //\r
1049 // Initialize <ConfigHdr>\r
1050 //\r
1051 InitializeConfigHdr (FormSet, Storage);\r
1052 break;\r
1053\r
1054 case EFI_IFR_VARSTORE_EFI_OP:\r
1055 //\r
1056 // Create a EFI variable Storage for this FormSet\r
1057 //\r
1058 Storage = CreateStorage (FormSet);\r
1059 Storage->Type = EFI_HII_VARSTORE_EFI_VARIABLE;\r
1060\r
1061 CopyMem (&Storage->VarStoreId, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->VarStoreId, sizeof (EFI_VARSTORE_ID));\r
1062 CopyMem (&Storage->Guid, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Guid, sizeof (EFI_GUID));\r
1063 CopyMem (&Storage->Attributes, &((EFI_IFR_VARSTORE_EFI *) OpCodeData)->Attributes, sizeof (UINT32));\r
1064 break;\r
1065\r
1066 //\r
1067 // DefaultStore\r
1068 //\r
1069 case EFI_IFR_DEFAULTSTORE_OP:\r
1070 DefaultStore = AllocateZeroPool (sizeof (FORMSET_DEFAULTSTORE));\r
1071 DefaultStore->Signature = FORMSET_DEFAULTSTORE_SIGNATURE;\r
1072\r
1073 CopyMem (&DefaultStore->DefaultId, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1074 CopyMem (&DefaultStore->DefaultName, &((EFI_IFR_DEFAULTSTORE *) OpCodeData)->DefaultName, sizeof (EFI_STRING_ID));\r
1075\r
1076 //\r
1077 // Insert to DefaultStore list of this Formset\r
1078 //\r
1079 InsertTailList (&FormSet->DefaultStoreListHead, &DefaultStore->Link);\r
1080 break;\r
1081\r
1082 //\r
1083 // Statements\r
1084 //\r
1085 case EFI_IFR_SUBTITLE_OP:\r
1086 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1087 CurrentStatement->Flags = ((EFI_IFR_SUBTITLE *) OpCodeData)->Flags;\r
1088\r
1089 if (Scope) {\r
1090 mInScopeSubtitle = TRUE;\r
1091 }\r
1092 break;\r
1093\r
1094 case EFI_IFR_TEXT_OP:\r
1095 CurrentStatement = CreateStatement (OpCodeData, FormSet, CurrentForm);\r
1096\r
1097 CopyMem (&CurrentStatement->TextTwo, &((EFI_IFR_TEXT *) OpCodeData)->TextTwo, sizeof (EFI_STRING_ID));\r
1098 break;\r
1099\r
1100 //\r
1101 // Questions\r
1102 //\r
1103 case EFI_IFR_ACTION_OP:\r
1104 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1105\r
1106 if (OpCodeLength == sizeof (EFI_IFR_ACTION_1)) {\r
1107 //\r
1108 // No QuestionConfig present, so no configuration string will be processed\r
1109 //\r
1110 CurrentStatement->QuestionConfig = 0;\r
1111 } else {\r
1112 CopyMem (&CurrentStatement->QuestionConfig, &((EFI_IFR_ACTION *) OpCodeData)->QuestionConfig, sizeof (EFI_STRING_ID));\r
1113 }\r
1114 break;\r
1115\r
1116 case EFI_IFR_RESET_BUTTON_OP:\r
1117 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1118\r
1119 CopyMem (&CurrentStatement->DefaultId, &((EFI_IFR_RESET_BUTTON *) OpCodeData)->DefaultId, sizeof (EFI_DEFAULT_ID));\r
1120 break;\r
1121\r
1122 case EFI_IFR_REF_OP:\r
1123 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1124\r
1125 CopyMem (&CurrentStatement->RefFormId, &((EFI_IFR_REF *) OpCodeData)->FormId, sizeof (EFI_FORM_ID));\r
1126 if (OpCodeLength >= sizeof (EFI_IFR_REF2)) {\r
1127 CopyMem (&CurrentStatement->RefQuestionId, &((EFI_IFR_REF2 *) OpCodeData)->QuestionId, sizeof (EFI_QUESTION_ID));\r
1128\r
1129 if (OpCodeLength >= sizeof (EFI_IFR_REF3)) {\r
1130 CopyMem (&CurrentStatement->RefFormSetId, &((EFI_IFR_REF3 *) OpCodeData)->FormSetId, sizeof (EFI_GUID));\r
1131\r
1132 if (OpCodeLength >= sizeof (EFI_IFR_REF4)) {\r
1133 CopyMem (&CurrentStatement->RefDevicePath, &((EFI_IFR_REF4 *) OpCodeData)->DevicePath, sizeof (EFI_STRING_ID));\r
1134 }\r
1135 }\r
1136 }\r
1137 break;\r
1138\r
1139 case EFI_IFR_ONE_OF_OP:\r
1140 case EFI_IFR_NUMERIC_OP:\r
1141 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1142\r
1143 CurrentStatement->Flags = ((EFI_IFR_ONE_OF *) OpCodeData)->Flags;\r
1144 Value = &CurrentStatement->HiiValue;\r
1145\r
1146 switch (CurrentStatement->Flags & EFI_IFR_NUMERIC_SIZE) {\r
1147 case EFI_IFR_NUMERIC_SIZE_1:\r
1148 CurrentStatement->Minimum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MinValue;\r
1149 CurrentStatement->Maximum = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.MaxValue;\r
1150 CurrentStatement->Step = ((EFI_IFR_NUMERIC *) OpCodeData)->data.u8.Step;\r
1151 CurrentStatement->StorageWidth = sizeof (UINT8);\r
1152 Value->Type = EFI_IFR_TYPE_NUM_SIZE_8;\r
1153 break;\r
1154\r
1155 case EFI_IFR_NUMERIC_SIZE_2:\r
1156 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MinValue, sizeof (UINT16));\r
1157 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.MaxValue, sizeof (UINT16));\r
1158 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u16.Step, sizeof (UINT16));\r
1159 CurrentStatement->StorageWidth = sizeof (UINT16);\r
1160 Value->Type = EFI_IFR_TYPE_NUM_SIZE_16;\r
1161 break;\r
1162\r
1163 case EFI_IFR_NUMERIC_SIZE_4:\r
1164 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MinValue, sizeof (UINT32));\r
1165 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.MaxValue, sizeof (UINT32));\r
1166 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u32.Step, sizeof (UINT32));\r
1167 CurrentStatement->StorageWidth = sizeof (UINT32);\r
1168 Value->Type = EFI_IFR_TYPE_NUM_SIZE_32;\r
1169 break;\r
1170\r
1171 case EFI_IFR_NUMERIC_SIZE_8:\r
1172 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MinValue, sizeof (UINT64));\r
1173 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.MaxValue, sizeof (UINT64));\r
1174 CopyMem (&CurrentStatement->Step, &((EFI_IFR_NUMERIC *) OpCodeData)->data.u64.Step, sizeof (UINT64));\r
1175 CurrentStatement->StorageWidth = sizeof (UINT64);\r
1176 Value->Type = EFI_IFR_TYPE_NUM_SIZE_64;\r
1177 break;\r
1178\r
1179 default:\r
1180 break;\r
1181 }\r
1182\r
1183 InitializeRequestElement (FormSet, CurrentStatement);\r
1184\r
1185 if ((Operand == EFI_IFR_ONE_OF_OP) && Scope) {\r
1186 SuppressForOption = TRUE;\r
1187 }\r
1188 break;\r
1189\r
1190 case EFI_IFR_ORDERED_LIST_OP:\r
1191 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1192\r
1193 CurrentStatement->Flags = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->Flags;\r
1194 CurrentStatement->MaxContainers = ((EFI_IFR_ORDERED_LIST *) OpCodeData)->MaxContainers;\r
1195 CurrentStatement->StorageWidth = (UINT16)(CurrentStatement->MaxContainers * sizeof (UINT8));\r
1196 InitializeRequestElement (FormSet, CurrentStatement);\r
1197\r
1198 //\r
1199 // No buffer type is defined in EFI_IFR_TYPE_VALUE, so a Configuration Driver\r
1200 // has to use FormBrowser2.Callback() to retrieve the uncommited data for\r
1201 // an interactive orderedlist (i.e. with EFI_IFR_FLAG_CALLBACK flag set).\r
1202 //\r
1203 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_OTHER;\r
1204 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1205\r
1206 if (Scope) {\r
1207 SuppressForOption = TRUE;\r
1208 }\r
1209 break;\r
1210\r
1211 case EFI_IFR_CHECKBOX_OP:\r
1212 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1213\r
1214 CurrentStatement->Flags = ((EFI_IFR_CHECKBOX *) OpCodeData)->Flags;\r
1215 CurrentStatement->StorageWidth = sizeof (BOOLEAN);\r
1216 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_BOOLEAN;\r
1217\r
1218 InitializeRequestElement (FormSet, CurrentStatement);\r
1219 break;\r
1220\r
1221 case EFI_IFR_STRING_OP:\r
1222 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1223\r
1224 //\r
1225 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1226 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1227 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1228 //\r
1229 CurrentStatement->Minimum = ((EFI_IFR_STRING *) OpCodeData)->MinSize;\r
1230 CurrentStatement->Maximum = ((EFI_IFR_STRING *) OpCodeData)->MaxSize;\r
1231 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));\r
1232 CurrentStatement->Flags = ((EFI_IFR_STRING *) OpCodeData)->Flags;\r
1233\r
1234 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1235 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1236\r
1237 InitializeRequestElement (FormSet, CurrentStatement);\r
1238 break;\r
1239\r
1240 case EFI_IFR_PASSWORD_OP:\r
1241 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1242\r
1243 //\r
1244 // MinSize is the minimum number of characters that can be accepted for this opcode,\r
1245 // MaxSize is the maximum number of characters that can be accepted for this opcode.\r
1246 // The characters are stored as Unicode, so the storage width should multiply 2.\r
1247 //\r
1248 CopyMem (&CurrentStatement->Minimum, &((EFI_IFR_PASSWORD *) OpCodeData)->MinSize, sizeof (UINT16));\r
1249 CopyMem (&CurrentStatement->Maximum, &((EFI_IFR_PASSWORD *) OpCodeData)->MaxSize, sizeof (UINT16));\r
1250 CurrentStatement->StorageWidth = (UINT16)((UINTN) CurrentStatement->Maximum * sizeof (UINT16));\r
1251\r
1252 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_STRING;\r
1253 CurrentStatement->BufferValue = AllocateZeroPool (CurrentStatement->StorageWidth);\r
1254\r
1255 InitializeRequestElement (FormSet, CurrentStatement);\r
1256 break;\r
1257\r
1258 case EFI_IFR_DATE_OP:\r
1259 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1260\r
1261 CurrentStatement->Flags = ((EFI_IFR_DATE *) OpCodeData)->Flags;\r
1262 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_DATE;\r
1263\r
1264 if ((CurrentStatement->Flags & EFI_QF_DATE_STORAGE) == QF_DATE_STORAGE_NORMAL) {\r
1265 CurrentStatement->StorageWidth = sizeof (EFI_HII_DATE);\r
1266\r
1267 InitializeRequestElement (FormSet, CurrentStatement);\r
1268 } else {\r
1269 //\r
1270 // Don't assign storage for RTC type of date/time\r
1271 //\r
1272 CurrentStatement->Storage = NULL;\r
1273 CurrentStatement->StorageWidth = 0;\r
1274 }\r
1275 break;\r
1276\r
1277 case EFI_IFR_TIME_OP:\r
1278 CurrentStatement = CreateQuestion (OpCodeData, FormSet, CurrentForm);\r
1279\r
1280 CurrentStatement->Flags = ((EFI_IFR_TIME *) OpCodeData)->Flags;\r
1281 CurrentStatement->HiiValue.Type = EFI_IFR_TYPE_TIME;\r
1282\r
1283 if ((CurrentStatement->Flags & QF_TIME_STORAGE) == QF_TIME_STORAGE_NORMAL) {\r
1284 CurrentStatement->StorageWidth = sizeof (EFI_IFR_TIME);\r
1285\r
1286 InitializeRequestElement (FormSet, CurrentStatement);\r
1287 } else {\r
1288 //\r
1289 // Don't assign storage for RTC type of date/time\r
1290 //\r
1291 CurrentStatement->Storage = NULL;\r
1292 CurrentStatement->StorageWidth = 0;\r
1293 }\r
1294 break;\r
1295\r
1296 //\r
1297 // Default\r
1298 //\r
1299 case EFI_IFR_DEFAULT_OP:\r
1300 //\r
1301 // EFI_IFR_DEFAULT appear in scope of a Question,\r
1302 // It creates a default value for the current question.\r
1303 // A Question may have more than one Default value which have different default types.\r
1304 //\r
1305 CurrentDefault = AllocateZeroPool (sizeof (QUESTION_DEFAULT));\r
1306 CurrentDefault->Signature = QUESTION_DEFAULT_SIGNATURE;\r
1307\r
1308 CurrentDefault->Value.Type = ((EFI_IFR_DEFAULT *) OpCodeData)->Type;\r
1309 CopyMem (&CurrentDefault->DefaultId, &((EFI_IFR_DEFAULT *) OpCodeData)->DefaultId, sizeof (UINT16));\r
1310 CopyMem (&CurrentDefault->Value.Value, &((EFI_IFR_DEFAULT *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1311 ExtendValueToU64 (&CurrentDefault->Value);\r
1312\r
1313 //\r
1314 // Insert to Default Value list of current Question\r
1315 //\r
1316 InsertTailList (&CurrentStatement->DefaultListHead, &CurrentDefault->Link);\r
1317\r
1318 if (Scope) {\r
1319 InScopeDefault = TRUE;\r
1320 }\r
1321 break;\r
1322\r
1323 //\r
1324 // Option\r
1325 //\r
1326 case EFI_IFR_ONE_OF_OPTION_OP:\r
1327 //\r
1328 // EFI_IFR_ONE_OF_OPTION appear in scope of a Question.\r
1329 // It create a selection for use in current Question.\r
1330 //\r
1331 CurrentOption = AllocateZeroPool (sizeof (QUESTION_OPTION));\r
1332 CurrentOption->Signature = QUESTION_OPTION_SIGNATURE;\r
1333\r
1334 CurrentOption->Flags = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Flags;\r
1335 CurrentOption->Value.Type = ((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Type;\r
1336 CopyMem (&CurrentOption->Text, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Option, sizeof (EFI_STRING_ID));\r
1337 CopyMem (&CurrentOption->Value.Value, &((EFI_IFR_ONE_OF_OPTION *) OpCodeData)->Value, sizeof (EFI_IFR_TYPE_VALUE));\r
1338 ExtendValueToU64 (&CurrentOption->Value);\r
1339\r
1340 if (InScopeOptionSuppress) {\r
1341 CurrentOption->SuppressExpression = OptionSuppressExpression;\r
1342 }\r
1343\r
1344 //\r
1345 // Insert to Option list of current Question\r
1346 //\r
1347 InsertTailList (&CurrentStatement->OptionListHead, &CurrentOption->Link);\r
1348 break;\r
1349\r
1350 //\r
1351 // Conditional\r
1352 //\r
1353 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1354 case EFI_IFR_INCONSISTENT_IF_OP:\r
1355 //\r
1356 // Create an Expression node\r
1357 //\r
1358 CurrentExpression = CreateExpression (CurrentForm);\r
1359 CopyMem (&CurrentExpression->Error, &((EFI_IFR_INCONSISTENT_IF *) OpCodeData)->Error, sizeof (EFI_STRING_ID));\r
1360\r
1361 if (Operand == EFI_IFR_NO_SUBMIT_IF_OP) {\r
1362 CurrentExpression->Type = EFI_HII_EXPRESSION_NO_SUBMIT_IF;\r
1363 InsertTailList (&CurrentStatement->NoSubmitListHead, &CurrentExpression->Link);\r
1364 } else {\r
1365 CurrentExpression->Type = EFI_HII_EXPRESSION_INCONSISTENT_IF;\r
1366 InsertTailList (&CurrentStatement->InconsistentListHead, &CurrentExpression->Link);\r
1367 }\r
1368 break;\r
1369\r
1370 case EFI_IFR_SUPPRESS_IF_OP:\r
1371 //\r
1372 // Question and Option will appear in scope of this OpCode\r
1373 //\r
1374 CurrentExpression = CreateExpression (CurrentForm);\r
1375 CurrentExpression->Type = EFI_HII_EXPRESSION_SUPPRESS_IF;\r
1376 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1377\r
1378 if (SuppressForOption) {\r
1379 InScopeOptionSuppress = TRUE;\r
1380 OptionSuppressExpression = CurrentExpression;\r
1381 } else {\r
1382 mInScopeSuppress = TRUE;\r
1383 mSuppressExpression = CurrentExpression;\r
1384 }\r
1385 break;\r
1386\r
1387 case EFI_IFR_GRAY_OUT_IF_OP:\r
1388 //\r
1389 // Questions will appear in scope of this OpCode\r
1390 //\r
1391 CurrentExpression = CreateExpression (CurrentForm);\r
1392 CurrentExpression->Type = EFI_HII_EXPRESSION_GRAY_OUT_IF;\r
1393 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1394\r
1395 mInScopeGrayOut = TRUE;\r
1396 mGrayOutExpression = CurrentExpression;\r
1397 break;\r
1398\r
1399 case EFI_IFR_DISABLE_IF_OP:\r
1400 //\r
1401 // The DisableIf expression should only rely on constant, so it could be\r
1402 // evaluated at initialization and it will not be queued\r
1403 //\r
1404 CurrentExpression = AllocateZeroPool (sizeof (FORM_EXPRESSION));\r
1405 CurrentExpression->Signature = FORM_EXPRESSION_SIGNATURE;\r
1406 CurrentExpression->Type = EFI_HII_EXPRESSION_DISABLE_IF;\r
1407 InitializeListHead (&CurrentExpression->OpCodeListHead);\r
1408\r
1409 InScopeDisable = TRUE;\r
1410 OpCodeDisabled = FALSE;\r
1411\r
1412 //\r
1413 // Take a look at next OpCode to see whether current expression consists\r
1414 // of single OpCode\r
1415 //\r
1416 if (((EFI_IFR_OP_HEADER *) (OpCodeData + OpCodeLength))->Scope == 0) {\r
1417 SingleOpCodeExpression = TRUE;\r
1418 }\r
1419 break;\r
1420\r
1421 //\r
1422 // Expression\r
1423 //\r
1424 case EFI_IFR_VALUE_OP:\r
1425 CurrentExpression = CreateExpression (CurrentForm);\r
1426 CurrentExpression->Type = EFI_HII_EXPRESSION_VALUE;\r
1427 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1428\r
1429 if (InScopeDefault) {\r
1430 //\r
1431 // Used for default (EFI_IFR_DEFAULT)\r
1432 //\r
1433 CurrentDefault->ValueExpression = CurrentExpression;\r
1434 } else {\r
1435 //\r
1436 // If used for a question, then the question will be read-only\r
1437 //\r
1438 CurrentStatement->ValueExpression = CurrentExpression;\r
1439 }\r
1440 break;\r
1441\r
1442 case EFI_IFR_RULE_OP:\r
1443 CurrentExpression = CreateExpression (CurrentForm);\r
1444 CurrentExpression->Type = EFI_HII_EXPRESSION_RULE;\r
1445\r
1446 CurrentExpression->RuleId = ((EFI_IFR_RULE *) OpCodeData)->RuleId;\r
1447 InsertTailList (&CurrentForm->ExpressionListHead, &CurrentExpression->Link);\r
1448 break;\r
1449\r
1450 //\r
1451 // Image\r
1452 //\r
1453 case EFI_IFR_IMAGE_OP:\r
1454 //\r
1455 // Get ScopeOpcode from top of stack\r
1456 //\r
1457 PopScope (&ScopeOpCode);\r
1458 PushScope (ScopeOpCode);\r
1459\r
1460 switch (ScopeOpCode) {\r
1461 case EFI_IFR_FORM_SET_OP:\r
1462 ImageId = &FormSet->ImageId;\r
1463 break;\r
1464\r
1465 case EFI_IFR_FORM_OP:\r
1466 ImageId = &CurrentForm->ImageId;\r
1467 break;\r
1468\r
1469 case EFI_IFR_ONE_OF_OPTION_OP:\r
1470 ImageId = &CurrentOption->ImageId;\r
1471 break;\r
1472\r
1473 default:\r
1474 ImageId = &CurrentStatement->ImageId;\r
1475 break;\r
1476 }\r
1477\r
1478 CopyMem (ImageId, &((EFI_IFR_IMAGE *) OpCodeData)->Id, sizeof (EFI_IMAGE_ID));\r
1479 break;\r
1480\r
1481 //\r
1482 // Refresh\r
1483 //\r
1484 case EFI_IFR_REFRESH_OP:\r
1485 CurrentStatement->RefreshInterval = ((EFI_IFR_REFRESH *) OpCodeData)->RefreshInterval;\r
1486 break;\r
1487\r
1488 //\r
1489 // Vendor specific\r
1490 //\r
1491 case EFI_IFR_GUID_OP:\r
1492 if (CompareGuid (&gTianoHiiIfrGuid, (EFI_GUID *)(OpCodeData + sizeof (EFI_IFR_OP_HEADER)))) {\r
1493 //\r
1494 // Tiano specific GUIDed opcodes\r
1495 //\r
1496 switch (((EFI_IFR_GUID_LABEL *) OpCodeData)->ExtendOpCode) {\r
1497 case EFI_IFR_EXTEND_OP_LABEL:\r
1498 //\r
1499 // just ignore label\r
1500 //\r
1501 break;\r
1502\r
1503#if 0\r
1504 case EFI_IFR_EXTEND_OP_BANNER:\r
1505 if (FormSet->SubClass == EFI_FRONT_PAGE_SUBCLASS) {\r
1506 CopyMem (\r
1507 &BannerData->Banner[((EFI_IFR_GUID_BANNER *) OpCodeData)->LineNumber][\r
1508 ((EFI_IFR_GUID_BANNER *) OpCodeData)->Alignment],\r
1509 &((EFI_IFR_GUID_BANNER *) OpCodeData)->Title,\r
1510 sizeof (EFI_STRING_ID)\r
1511 );\r
1512 }\r
1513 break;\r
1514#endif\r
1515\r
1516 case EFI_IFR_EXTEND_OP_CLASS:\r
1517 CopyMem (&FormSet->Class, &((EFI_IFR_GUID_CLASS *) OpCodeData)->Class, sizeof (UINT16));\r
1518 break;\r
1519\r
1520 case EFI_IFR_EXTEND_OP_SUBCLASS:\r
1521 CopyMem (&FormSet->SubClass, &((EFI_IFR_GUID_SUBCLASS *) OpCodeData)->SubClass, sizeof (UINT16));\r
1522 break;\r
1523\r
1524 default:\r
1525 break;\r
1526 }\r
1527 }\r
1528 break;\r
1529\r
1530 //\r
1531 // Scope End\r
1532 //\r
1533 case EFI_IFR_END_OP:\r
1534 Status = PopScope (&ScopeOpCode);\r
1535 if (EFI_ERROR (Status)) {\r
1536 ResetScopeStack ();\r
1537 return Status;\r
1538 }\r
1539\r
1540 switch (ScopeOpCode) {\r
1541 case EFI_IFR_FORM_SET_OP:\r
1542 //\r
1543 // End of FormSet, update FormSet IFR binary length\r
1544 // to stop parsing substantial OpCodes\r
1545 //\r
1546 FormSet->IfrBinaryLength = OpCodeOffset;\r
1547 break;\r
1548\r
1549 case EFI_IFR_FORM_OP:\r
1550 //\r
1551 // End of Form\r
1552 //\r
1553 CurrentForm = NULL;\r
1554 break;\r
1555\r
1556 case EFI_IFR_ONE_OF_OPTION_OP:\r
1557 //\r
1558 // End of Option\r
1559 //\r
1560 CurrentOption = NULL;\r
1561 break;\r
1562\r
1563 case EFI_IFR_SUBTITLE_OP:\r
1564 mInScopeSubtitle = FALSE;\r
1565 break;\r
1566\r
1567 case EFI_IFR_NO_SUBMIT_IF_OP:\r
1568 case EFI_IFR_INCONSISTENT_IF_OP:\r
1569 //\r
1570 // Ignore end of EFI_IFR_NO_SUBMIT_IF and EFI_IFR_INCONSISTENT_IF\r
1571 //\r
1572 break;\r
1573\r
1574 case EFI_IFR_SUPPRESS_IF_OP:\r
1575 if (SuppressForOption) {\r
1576 InScopeOptionSuppress = FALSE;\r
1577 } else {\r
1578 mInScopeSuppress = FALSE;\r
1579 }\r
1580 break;\r
1581\r
1582 case EFI_IFR_GRAY_OUT_IF_OP:\r
1583 mInScopeGrayOut = FALSE;\r
1584 break;\r
1585\r
1586 case EFI_IFR_DISABLE_IF_OP:\r
1587 InScopeDisable = FALSE;\r
1588 OpCodeDisabled = FALSE;\r
1589 break;\r
1590\r
1591 case EFI_IFR_ONE_OF_OP:\r
1592 case EFI_IFR_ORDERED_LIST_OP:\r
1593 SuppressForOption = FALSE;\r
1594 break;\r
1595\r
1596 case EFI_IFR_DEFAULT_OP:\r
1597 InScopeDefault = FALSE;\r
1598 break;\r
1599\r
1600 default:\r
1601 if (IsExpressionOpCode (ScopeOpCode)) {\r
1602 if (InScopeDisable) {\r
1603 //\r
1604 // Evaluate DisableIf expression\r
1605 //\r
1606 Status = EvaluateExpression (FormSet, CurrentForm, CurrentExpression);\r
1607 if (EFI_ERROR (Status)) {\r
1608 return Status;\r
1609 }\r
1610 if (CurrentExpression->Result.Type != EFI_IFR_TYPE_BOOLEAN) {\r
1611 return EFI_INVALID_PARAMETER;\r
1612 }\r
1613\r
1614 OpCodeDisabled = CurrentExpression->Result.Value.b;\r
1615 //\r
1616 // DisableIf Expression is only used once and not quequed, free it\r
1617 //\r
1618 DestroyExpression (CurrentExpression);\r
1619 }\r
1620\r
1621 //\r
1622 // End of current Expression\r
1623 //\r
1624 CurrentExpression = NULL;\r
1625 }\r
1626 break;\r
1627 }\r
1628 break;\r
1629\r
1630 default:\r
1631 break;\r
1632 }\r
1633 }\r
1634\r
1635 return EFI_SUCCESS;\r
1636}\r
1637\r
1638\r
1639\r
1640\r