Fix a bug in secure boot configuration driver: Enroll DB/KEK will disable Attempt...
[mirror_edk2.git] / BaseTools / Source / C / VfrCompile / VfrFormPkg.cpp
CommitLineData
30fdf114
LG
1/** @file\r
2 \r
3 The definition of CFormPkg's member function\r
4\r
64b2609f 5Copyright (c) 2004 - 2012, Intel Corporation. All rights reserved.<BR>\r
40d841f6 6This program and the accompanying materials \r
30fdf114
LG
7are licensed and made available under the terms and conditions of the BSD License \r
8which accompanies this distribution. The full text of the license may be found at \r
9http://opensource.org/licenses/bsd-license.php \r
10 \r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
13\r
14**/\r
15\r
16#include "stdio.h"\r
17#include "VfrFormPkg.h"\r
18\r
19/*\r
20 * The definition of CFormPkg's member function\r
21 */\r
22\r
23SPendingAssign::SPendingAssign (\r
24 IN CHAR8 *Key, \r
25 IN VOID *Addr, \r
26 IN UINT32 Len, \r
27 IN UINT32 LineNo,\r
52302d4d 28 IN CONST CHAR8 *Msg\r
30fdf114
LG
29 )\r
30{\r
31 mKey = NULL;\r
32 mAddr = Addr;\r
33 mLen = Len;\r
34 mFlag = PENDING;\r
35 mLineNo = LineNo;\r
36 mMsg = NULL;\r
37 mNext = NULL;\r
38 if (Key != NULL) {\r
39 mKey = new CHAR8[strlen (Key) + 1];\r
40 if (mKey != NULL) {\r
41 strcpy (mKey, Key);\r
42 }\r
43 }\r
44\r
45 if (Msg != NULL) {\r
46 mMsg = new CHAR8[strlen (Msg) + 1];\r
47 if (mMsg != NULL) {\r
48 strcpy (mMsg, Msg);\r
49 }\r
50 }\r
51}\r
52\r
53SPendingAssign::~SPendingAssign (\r
54 VOID\r
55 )\r
56{\r
57 if (mKey != NULL) {\r
58 delete mKey;\r
59 }\r
60 mAddr = NULL;\r
61 mLen = 0;\r
62 mLineNo = 0;\r
63 if (mMsg != NULL) {\r
64 delete mMsg;\r
65 }\r
66 mNext = NULL;\r
67}\r
68\r
69VOID\r
70SPendingAssign::SetAddrAndLen (\r
71 IN VOID *Addr, \r
72 IN UINT32 LineNo\r
73 )\r
74{\r
75 mAddr = Addr;\r
76 mLineNo = LineNo;\r
77}\r
78\r
79VOID\r
80SPendingAssign::AssignValue (\r
81 IN VOID *Addr, \r
82 IN UINT32 Len\r
83 )\r
84{\r
85 memcpy (mAddr, Addr, (mLen < Len ? mLen : Len));\r
86 mFlag = ASSIGNED;\r
87}\r
88\r
89CHAR8 *\r
90SPendingAssign::GetKey (\r
91 VOID\r
92 )\r
93{\r
94 return mKey;\r
95}\r
96\r
97CFormPkg::CFormPkg (\r
98 IN UINT32 BufferSize = 4096\r
99 )\r
100{\r
101 CHAR8 *BufferStart;\r
102 CHAR8 *BufferEnd;\r
103 SBufferNode *Node;\r
104\r
105 mPkgLength = 0;\r
106 mBufferNodeQueueHead = NULL;\r
107 mCurrBufferNode = NULL;\r
108\r
109 Node = new SBufferNode;\r
110 if (Node == NULL) {\r
111 return ;\r
112 }\r
113 BufferStart = new CHAR8[BufferSize];\r
114 if (BufferStart == NULL) {\r
115 return;\r
116 }\r
117 BufferEnd = BufferStart + BufferSize;\r
118\r
119 memset (BufferStart, 0, BufferSize);\r
120 Node->mBufferStart = BufferStart;\r
121 Node->mBufferEnd = BufferEnd;\r
122 Node->mBufferFree = BufferStart;\r
123 Node->mNext = NULL;\r
124\r
125 mBufferSize = BufferSize;\r
126 mBufferNodeQueueHead = Node;\r
127 mBufferNodeQueueTail = Node;\r
128 mCurrBufferNode = Node;\r
129}\r
130\r
131CFormPkg::~CFormPkg ()\r
132{\r
133 SBufferNode *pBNode;\r
134 SPendingAssign *pPNode;\r
135\r
136 while (mBufferNodeQueueHead != NULL) {\r
137 pBNode = mBufferNodeQueueHead;\r
138 mBufferNodeQueueHead = mBufferNodeQueueHead->mNext;\r
139 if (pBNode->mBufferStart != NULL) {\r
140 delete pBNode->mBufferStart;\r
141 delete pBNode;\r
142 }\r
143 }\r
144 mBufferNodeQueueTail = NULL;\r
145 mCurrBufferNode = NULL;\r
146\r
147 while (PendingAssignList != NULL) {\r
148 pPNode = PendingAssignList;\r
149 PendingAssignList = PendingAssignList->mNext;\r
150 delete pPNode;\r
151 }\r
152 PendingAssignList = NULL;\r
153}\r
154\r
155CHAR8 *\r
156CFormPkg::IfrBinBufferGet (\r
157 IN UINT32 Len\r
158 )\r
159{\r
160 CHAR8 *BinBuffer = NULL;\r
161\r
162 if ((Len == 0) || (Len > mBufferSize)) {\r
163 return NULL;\r
164 }\r
165\r
166 if ((mCurrBufferNode->mBufferFree + Len) <= mCurrBufferNode->mBufferEnd) {\r
167 BinBuffer = mCurrBufferNode->mBufferFree;\r
168 mCurrBufferNode->mBufferFree += Len;\r
169 } else {\r
170 SBufferNode *Node;\r
171\r
172 Node = new SBufferNode;\r
173 if (Node == NULL) {\r
174 return NULL;\r
175 }\r
176\r
177 Node->mBufferStart = new CHAR8[mBufferSize];\r
178 if (Node->mBufferStart == NULL) {\r
179 delete Node;\r
180 return NULL;\r
181 } else {\r
182 memset (Node->mBufferStart, 0, mBufferSize);\r
183 Node->mBufferEnd = Node->mBufferStart + mBufferSize;\r
184 Node->mBufferFree = Node->mBufferStart;\r
185 Node->mNext = NULL;\r
186 }\r
187\r
188 if (mBufferNodeQueueTail == NULL) {\r
189 mBufferNodeQueueHead = mBufferNodeQueueTail = Node;\r
190 } else {\r
191 mBufferNodeQueueTail->mNext = Node;\r
192 mBufferNodeQueueTail = Node;\r
193 }\r
194 mCurrBufferNode = Node;\r
195\r
196 //\r
197 // Now try again.\r
198 //\r
199 BinBuffer = mCurrBufferNode->mBufferFree;\r
200 mCurrBufferNode->mBufferFree += Len;\r
201 }\r
202\r
203 mPkgLength += Len;\r
204\r
205 return BinBuffer;\r
206}\r
207\r
208inline\r
209UINT32\r
210CFormPkg::GetPkgLength (\r
211 VOID\r
212 )\r
213{\r
214 return mPkgLength;\r
215}\r
216\r
217VOID\r
218CFormPkg::Open (\r
219 VOID\r
220 )\r
221{\r
222 mReadBufferNode = mBufferNodeQueueHead;\r
223 mReadBufferOffset = 0;\r
224}\r
225\r
226VOID\r
227CFormPkg::Close (\r
228 VOID\r
229 )\r
230{\r
231 mReadBufferNode = NULL;\r
232 mReadBufferOffset = 0;\r
233}\r
234\r
235UINT32\r
236CFormPkg::Read (\r
237 IN CHAR8 *Buffer, \r
238 IN UINT32 Size\r
239 )\r
240{\r
241 UINT32 Index;\r
242\r
243 if ((Size == 0) || (Buffer == NULL)) {\r
244 return 0;\r
245 }\r
246\r
247 if (mReadBufferNode == NULL) {\r
248 return 0;\r
249 }\r
250\r
251 for (Index = 0; Index < Size; Index++) {\r
252 if ((mReadBufferNode->mBufferStart + mReadBufferOffset) < mReadBufferNode->mBufferFree) {\r
253 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
254 } else {\r
255 if ((mReadBufferNode = mReadBufferNode->mNext) == NULL) {\r
256 return Index;\r
257 } else {\r
258 mReadBufferOffset = 0;\r
259 Buffer[Index] = mReadBufferNode->mBufferStart[mReadBufferOffset++];\r
260 }\r
261 }\r
262 }\r
263\r
264 return Size;\r
265}\r
266\r
267EFI_VFR_RETURN_CODE\r
268CFormPkg::BuildPkgHdr (\r
269 OUT EFI_HII_PACKAGE_HEADER **PkgHdr\r
270 )\r
271{\r
272 if (PkgHdr == NULL) {\r
273 return VFR_RETURN_FATAL_ERROR;\r
274 }\r
275\r
276 if (((*PkgHdr) = new EFI_HII_PACKAGE_HEADER) == NULL) {\r
277 return VFR_RETURN_OUT_FOR_RESOURCES;\r
278 }\r
279\r
280 (*PkgHdr)->Type = EFI_HII_PACKAGE_FORM;\r
281 (*PkgHdr)->Length = mPkgLength + sizeof (EFI_HII_PACKAGE_HEADER);\r
282\r
283 return VFR_RETURN_SUCCESS;\r
284}\r
285\r
286EFI_VFR_RETURN_CODE\r
287CFormPkg::BuildPkg (\r
288 OUT PACKAGE_DATA &TBuffer\r
289 )\r
290{\r
291 \r
292 CHAR8 *Temp;\r
293 UINT32 Size;\r
294 CHAR8 Buffer[1024];\r
295\r
296 if (TBuffer.Buffer != NULL) {\r
297 delete TBuffer.Buffer;\r
298 }\r
299\r
300 TBuffer.Size = mPkgLength;\r
301 TBuffer.Buffer = NULL;\r
302 if (TBuffer.Size != 0) {\r
303 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
304 } else {\r
305 return VFR_RETURN_SUCCESS;\r
306 }\r
307\r
308 Temp = TBuffer.Buffer;\r
309 Open ();\r
310 while ((Size = Read (Buffer, 1024)) != 0) {\r
311 memcpy (Temp, Buffer, Size);\r
312 Temp += Size;\r
313 }\r
314 Close ();\r
315 return VFR_RETURN_SUCCESS;\r
316}\r
317\r
318\r
319EFI_VFR_RETURN_CODE\r
320CFormPkg::BuildPkg (\r
321 IN FILE *Output,\r
322 IN PACKAGE_DATA *PkgData\r
323 )\r
324{\r
325 EFI_VFR_RETURN_CODE Ret;\r
326 CHAR8 Buffer[1024];\r
327 UINT32 Size;\r
328 EFI_HII_PACKAGE_HEADER *PkgHdr;\r
329\r
330 if (Output == NULL) {\r
331 return VFR_RETURN_FATAL_ERROR;\r
332 }\r
333\r
334 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
335 return Ret;\r
336 }\r
337 fwrite (PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER), 1, Output);\r
338 delete PkgHdr;\r
339 \r
340 if (PkgData == NULL) {\r
341 Open ();\r
342 while ((Size = Read (Buffer, 1024)) != 0) {\r
343 fwrite (Buffer, Size, 1, Output);\r
344 }\r
345 Close ();\r
346 } else {\r
347 fwrite (PkgData->Buffer, PkgData->Size, 1, Output);\r
348 }\r
349\r
350 return VFR_RETURN_SUCCESS;\r
351}\r
352\r
353VOID\r
354CFormPkg::_WRITE_PKG_LINE (\r
52302d4d
LG
355 IN FILE *pFile,\r
356 IN UINT32 LineBytes,\r
357 IN CONST CHAR8 *LineHeader,\r
358 IN CHAR8 *BlkBuf,\r
359 IN UINT32 BlkSize\r
30fdf114
LG
360 )\r
361{\r
362 UINT32 Index;\r
363\r
364 if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
365 return;\r
366 }\r
367\r
368 for (Index = 0; Index < BlkSize; Index++) {\r
369 if ((Index % LineBytes) == 0) {\r
370 fprintf (pFile, "\n%s", LineHeader);\r
371 }\r
372 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
373 }\r
374}\r
375\r
376VOID\r
377CFormPkg::_WRITE_PKG_END (\r
52302d4d
LG
378 IN FILE *pFile,\r
379 IN UINT32 LineBytes,\r
380 IN CONST CHAR8 *LineHeader,\r
381 IN CHAR8 *BlkBuf,\r
382 IN UINT32 BlkSize\r
30fdf114
LG
383 )\r
384{\r
385 UINT32 Index;\r
386\r
387 if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {\r
388 return;\r
389 }\r
390\r
391 for (Index = 0; Index < BlkSize - 1; Index++) {\r
392 if ((Index % LineBytes) == 0) {\r
393 fprintf (pFile, "\n%s", LineHeader);\r
394 }\r
395 fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);\r
396 }\r
397\r
398 if ((Index % LineBytes) == 0) {\r
399 fprintf (pFile, "\n%s", LineHeader);\r
400 }\r
401 fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);\r
402}\r
403\r
404#define BYTES_PRE_LINE 0x10\r
405\r
406EFI_VFR_RETURN_CODE \r
407CFormPkg::GenCFile (\r
408 IN CHAR8 *BaseName,\r
409 IN FILE *pFile,\r
410 IN PACKAGE_DATA *PkgData\r
411 )\r
412{\r
413 EFI_VFR_RETURN_CODE Ret;\r
414 CHAR8 Buffer[BYTES_PRE_LINE * 8];\r
415 EFI_HII_PACKAGE_HEADER *PkgHdr;\r
416 UINT32 PkgLength = 0;\r
417 UINT32 ReadSize = 0;\r
418\r
419 if ((BaseName == NULL) || (pFile == NULL)) {\r
420 return VFR_RETURN_FATAL_ERROR;\r
421 }\r
422\r
423 fprintf (pFile, "\nunsigned char %sBin[] = {\n", BaseName);\r
424\r
425 if ((Ret = BuildPkgHdr(&PkgHdr)) != VFR_RETURN_SUCCESS) {\r
426 return Ret;\r
427 }\r
428\r
429 //\r
430 // For framework vfr file, the extension framework header will be added.\r
431 //\r
432 if (VfrCompatibleMode) {\r
433 fprintf (pFile, " // FRAMEWORK PACKAGE HEADER Length\n");\r
434 PkgLength = PkgHdr->Length + sizeof (UINT32) + 2;\r
435 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); \r
436 fprintf (pFile, "\n\n // FRAMEWORK PACKAGE HEADER Type\n");\r
437 PkgLength = 3;\r
438 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT16)); \r
439 } else {\r
440 fprintf (pFile, " // ARRAY LENGTH\n");\r
441 PkgLength = PkgHdr->Length + sizeof (UINT32);\r
442 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&PkgLength, sizeof (UINT32)); \r
443 }\r
444\r
445 fprintf (pFile, "\n\n // PACKAGE HEADER\n");\r
446 _WRITE_PKG_LINE(pFile, BYTES_PRE_LINE, " ", (CHAR8 *)PkgHdr, sizeof (EFI_HII_PACKAGE_HEADER));\r
447 PkgLength = sizeof (EFI_HII_PACKAGE_HEADER);\r
448\r
449 fprintf (pFile, "\n\n // PACKAGE DATA\n");\r
450 \r
451 if (PkgData == NULL) {\r
452 Open ();\r
453 while ((ReadSize = Read ((CHAR8 *)Buffer, BYTES_PRE_LINE * 8)) != 0) {\r
454 PkgLength += ReadSize;\r
455 if (PkgLength < PkgHdr->Length) {\r
456 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);\r
457 } else {\r
458 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", Buffer, ReadSize);\r
459 }\r
460 }\r
461 Close ();\r
462 } else {\r
463 if (PkgData->Size % BYTES_PRE_LINE != 0) {\r
464 PkgLength = PkgData->Size - (PkgData->Size % BYTES_PRE_LINE);\r
465 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);\r
466 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, PkgData->Size % BYTES_PRE_LINE);\r
467 } else {\r
468 PkgLength = PkgData->Size - BYTES_PRE_LINE;\r
469 _WRITE_PKG_LINE (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer, PkgLength);\r
470 _WRITE_PKG_END (pFile, BYTES_PRE_LINE, " ", PkgData->Buffer + PkgLength, BYTES_PRE_LINE);\r
471 }\r
472 }\r
473\r
474 delete PkgHdr;\r
475 fprintf (pFile, "\n};\n");\r
476\r
477 return VFR_RETURN_SUCCESS;\r
478}\r
479\r
480EFI_VFR_RETURN_CODE\r
481CFormPkg::AssignPending (\r
482 IN CHAR8 *Key, \r
483 IN VOID *ValAddr, \r
484 IN UINT32 ValLen,\r
485 IN UINT32 LineNo,\r
52302d4d 486 IN CONST CHAR8 *Msg\r
30fdf114
LG
487 )\r
488{\r
489 SPendingAssign *pNew;\r
490\r
491 pNew = new SPendingAssign (Key, ValAddr, ValLen, LineNo, Msg);\r
492 if (pNew == NULL) {\r
493 return VFR_RETURN_OUT_FOR_RESOURCES;\r
494 }\r
495\r
496 pNew->mNext = PendingAssignList;\r
497 PendingAssignList = pNew;\r
498 return VFR_RETURN_SUCCESS;\r
499}\r
500\r
501VOID\r
502CFormPkg::DoPendingAssign (\r
503 IN CHAR8 *Key, \r
504 IN VOID *ValAddr, \r
505 IN UINT32 ValLen\r
506 )\r
507{\r
508 SPendingAssign *pNode;\r
509\r
510 if ((Key == NULL) || (ValAddr == NULL)) {\r
511 return;\r
512 }\r
513\r
514 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
515 if (strcmp (pNode->mKey, Key) == 0) {\r
516 pNode->AssignValue (ValAddr, ValLen);\r
517 }\r
518 }\r
519}\r
520\r
521bool\r
522CFormPkg::HavePendingUnassigned (\r
523 VOID\r
524 )\r
525{\r
526 SPendingAssign *pNode;\r
527\r
528 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
529 if (pNode->mFlag == PENDING) {\r
530 return TRUE;\r
531 }\r
532 }\r
533\r
534 return FALSE;\r
535}\r
536\r
537VOID\r
538CFormPkg::PendingAssignPrintAll (\r
539 VOID\r
540 )\r
541{\r
542 SPendingAssign *pNode;\r
543\r
544 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
545 if (pNode->mFlag == PENDING) {\r
546 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", pNode->mMsg);\r
547 }\r
548 }\r
549}\r
550\r
551EFI_VFR_RETURN_CODE\r
552CFormPkg::DeclarePendingQuestion (\r
553 IN CVfrVarDataTypeDB &lCVfrVarDataTypeDB,\r
554 IN CVfrDataStorage &lCVfrDataStorage,\r
555 IN CVfrQuestionDB &lCVfrQuestionDB,\r
556 IN EFI_GUID *LocalFormSetGuid,\r
557 IN UINT32 LineNo\r
558 )\r
559{\r
560 SPendingAssign *pNode;\r
561 CHAR8 *VarStr;\r
562 UINT32 ArrayIdx;\r
563 CHAR8 FName[MAX_NAME_LEN];\r
b36d134f
LG
564 CHAR8 *SName;\r
565 CHAR8 *NewStr;\r
30fdf114
LG
566 EFI_VFR_RETURN_CODE ReturnCode;\r
567 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
568\r
b36d134f
LG
569 //\r
570 // Declare all questions as Numeric in DisableIf True\r
571 //\r
572 // DisableIf\r
573 CIfrDisableIf DIObj;\r
574 DIObj.SetLineNo (LineNo);\r
575 \r
576 //TrueOpcode\r
577 CIfrTrue TObj (LineNo);\r
578\r
579 // Declare Numeric qeustion for each undefined question.\r
30fdf114
LG
580 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
581 if (pNode->mFlag == PENDING) {\r
30fdf114
LG
582 CIfrNumeric CNObj;\r
583 EFI_VARSTORE_INFO Info; \r
584 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;\r
585\r
586 CNObj.SetLineNo (LineNo);\r
587 CNObj.SetPrompt (0x0);\r
588 CNObj.SetHelp (0x0);\r
589\r
590 //\r
591 // Register this question, assume it is normal question, not date or time question\r
592 //\r
593 VarStr = pNode->mKey;\r
594 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);\r
595 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
596 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
597 return ReturnCode;\r
598 }\r
599 \r
600#ifdef VFREXP_DEBUG\r
601 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);\r
602#endif\r
603 //\r
604 // Get Question Info, framework vfr VarName == StructName\r
605 //\r
606 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);\r
607 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
608 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");\r
609 return ReturnCode;\r
610 }\r
611 //\r
612 // Get VarStoreType\r
613 //\r
614 ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType);\r
615 if (ReturnCode == VFR_RETURN_UNDEFINED) {\r
616 lCVfrDataStorage.DeclareBufferVarStore (\r
617 FName, \r
618 LocalFormSetGuid, \r
619 &lCVfrVarDataTypeDB, \r
620 FName,\r
621 EFI_VARSTORE_ID_INVALID,\r
622 FALSE\r
623 );\r
624 ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType); \r
625 }\r
626 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
627 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
628 return ReturnCode;\r
629 }\r
630 \r
631 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
632 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
633 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
634 return ReturnCode;\r
635 }\r
636\r
637 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {\r
638 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);\r
639 } else {\r
640 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
641 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
642 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
643 VarStr = pNode->mKey;\r
b36d134f
LG
644 //convert VarStr with store name to VarStr with structure name\r
645 ReturnCode = lCVfrDataStorage.GetBufferVarStoreDataTypeName (FName, &SName);\r
646 if (ReturnCode == VFR_RETURN_SUCCESS) {\r
647 NewStr = new CHAR8[strlen (VarStr) + strlen (SName) + 1];\r
648 NewStr[0] = '\0';\r
649 strcpy (NewStr, SName);\r
650 strcat (NewStr, VarStr + strlen (FName));\r
651 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (NewStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
652 delete NewStr;\r
653 }\r
30fdf114
LG
654 } else {\r
655 ReturnCode = VFR_RETURN_UNSUPPORTED;\r
656 }\r
657 }\r
658 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
659 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
660 return ReturnCode;\r
661 }\r
662\r
663 CNObj.SetQuestionId (QId);\r
664 CNObj.SetVarStoreInfo (&Info);\r
0d2711a6
LG
665 //\r
666 // Numeric doesn't support BOOLEAN data type. \r
667 // BOOLEAN type has the same data size to UINT8. \r
668 //\r
669 if (Info.mVarType == EFI_IFR_TYPE_BOOLEAN) {\r
670 Info.mVarType = EFI_IFR_TYPE_NUM_SIZE_8;\r
671 }\r
30fdf114 672 CNObj.SetFlags (0, Info.mVarType);\r
2bcc713e
LG
673 //\r
674 // Use maximum value not to limit the vaild value for the undefined question.\r
675 //\r
676 switch (Info.mVarType) {\r
677 case EFI_IFR_TYPE_NUM_SIZE_64:\r
678 CNObj.SetMinMaxStepData ((UINT64) 0, (UINT64) -1 , (UINT64) 0);\r
679 break;\r
680 case EFI_IFR_TYPE_NUM_SIZE_32:\r
681 CNObj.SetMinMaxStepData ((UINT32) 0, (UINT32) -1 , (UINT32) 0);\r
682 break;\r
683 case EFI_IFR_TYPE_NUM_SIZE_16:\r
684 CNObj.SetMinMaxStepData ((UINT16) 0, (UINT16) -1 , (UINT16) 0);\r
685 break;\r
686 case EFI_IFR_TYPE_NUM_SIZE_8:\r
687 CNObj.SetMinMaxStepData ((UINT8) 0, (UINT8) -1 , (UINT8) 0);\r
688 break;\r
689 default:\r
690 break;\r
691 }\r
30fdf114
LG
692\r
693 //\r
694 // For undefined Efi VarStore type question\r
695 // Append the extended guided opcode to contain VarName\r
696 //\r
b36d134f 697 if (VarStoreType == EFI_VFR_VARSTORE_EFI || VfrCompatibleMode) {\r
30fdf114
LG
698 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
699 CVNObj.SetLineNo (LineNo);\r
700 }\r
701 \r
702 //\r
703 // End for Numeric\r
704 //\r
705 CIfrEnd CEObj; \r
706 CEObj.SetLineNo (LineNo);\r
30fdf114
LG
707 }\r
708 }\r
b36d134f
LG
709\r
710 //\r
711 // End for DisableIf\r
712 //\r
713 CIfrEnd SEObj;\r
714 SEObj.SetLineNo (LineNo);\r
715\r
30fdf114
LG
716 return VFR_RETURN_SUCCESS;\r
717}\r
718\r
719CFormPkg gCFormPkg;\r
720\r
721SIfrRecord::SIfrRecord (\r
722 VOID\r
723 )\r
724{\r
725 mIfrBinBuf = NULL;\r
726 mBinBufLen = 0;\r
727 mLineNo = 0xFFFFFFFF;\r
728 mOffset = 0xFFFFFFFF;\r
729 mNext = NULL;\r
730}\r
731\r
732SIfrRecord::~SIfrRecord (\r
733 VOID\r
734 )\r
735{\r
736 if (mIfrBinBuf != NULL) {\r
737 //delete mIfrBinBuf;\r
738 mIfrBinBuf = NULL;\r
739 }\r
740 mLineNo = 0xFFFFFFFF;\r
741 mOffset = 0xFFFFFFFF;\r
742 mBinBufLen = 0;\r
743 mNext = NULL;\r
744}\r
745\r
746CIfrRecordInfoDB::CIfrRecordInfoDB (\r
747 VOID\r
748 )\r
749{\r
750 mSwitch = TRUE;\r
751 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;\r
752 mIfrRecordListHead = NULL;\r
753 mIfrRecordListTail = NULL;\r
754}\r
755\r
756CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
757 VOID\r
758 )\r
759{\r
760 SIfrRecord *pNode;\r
761\r
762 while (mIfrRecordListHead != NULL) {\r
763 pNode = mIfrRecordListHead;\r
764 mIfrRecordListHead = mIfrRecordListHead->mNext;\r
765 delete pNode;\r
766 }\r
767}\r
768\r
769SIfrRecord *\r
770CIfrRecordInfoDB::GetRecordInfoFromIdx (\r
771 IN UINT32 RecordIdx\r
772 )\r
773{\r
774 UINT32 Idx;\r
775 SIfrRecord *pNode = NULL;\r
776\r
777 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {\r
778 return NULL;\r
779 }\r
780\r
781 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;\r
782 (Idx != RecordIdx) && (pNode != NULL);\r
783 Idx++, pNode = pNode->mNext)\r
784 ;\r
785\r
786 return pNode;\r
787}\r
788\r
789UINT32\r
790CIfrRecordInfoDB::IfrRecordRegister (\r
791 IN UINT32 LineNo,\r
792 IN CHAR8 *IfrBinBuf,\r
793 IN UINT8 BinBufLen,\r
794 IN UINT32 Offset\r
795 )\r
796{\r
797 SIfrRecord *pNew;\r
798\r
799 if (mSwitch == FALSE) {\r
800 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
801 }\r
802\r
803 if ((pNew = new SIfrRecord) == NULL) {\r
804 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
805 }\r
806\r
807 if (mIfrRecordListHead == NULL) {\r
808 mIfrRecordListHead = pNew;\r
809 mIfrRecordListTail = pNew;\r
810 } else {\r
811 mIfrRecordListTail->mNext = pNew;\r
812 mIfrRecordListTail = pNew;\r
813 }\r
814 mRecordCount++;\r
815\r
816 return mRecordCount;\r
817}\r
818\r
819VOID\r
820CIfrRecordInfoDB::IfrRecordInfoUpdate (\r
821 IN UINT32 RecordIdx,\r
822 IN UINT32 LineNo,\r
823 IN CHAR8 *BinBuf,\r
824 IN UINT8 BinBufLen,\r
825 IN UINT32 Offset\r
826 )\r
827{\r
828 SIfrRecord *pNode;\r
fd171542 829 SIfrRecord *Prev;\r
30fdf114
LG
830\r
831 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
832 return;\r
833 }\r
834\r
fd171542 835 if (LineNo == 0) {\r
836 //\r
837 // Line number is not specified explicitly, try to use line number of previous opcode\r
838 //\r
839 Prev = GetRecordInfoFromIdx (RecordIdx - 1);\r
840 if (Prev != NULL) {\r
841 LineNo = Prev->mLineNo;\r
842 }\r
843 }\r
844\r
30fdf114
LG
845 pNode->mLineNo = LineNo;\r
846 pNode->mOffset = Offset;\r
847 pNode->mBinBufLen = BinBufLen;\r
848 pNode->mIfrBinBuf = BinBuf;\r
849\r
850}\r
851\r
852VOID\r
853CIfrRecordInfoDB::IfrRecordOutput (\r
854 OUT PACKAGE_DATA &TBuffer\r
855 )\r
856{\r
857 CHAR8 *Temp;\r
858 SIfrRecord *pNode; \r
859\r
860 if (TBuffer.Buffer != NULL) {\r
861 delete TBuffer.Buffer;\r
862 }\r
863\r
864 TBuffer.Size = 0;\r
865 TBuffer.Buffer = NULL;\r
866\r
867\r
868 if (mSwitch == FALSE) {\r
869 return;\r
870 } \r
871 \r
872 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
873 TBuffer.Size += pNode->mBinBufLen;\r
874 }\r
875 \r
876 if (TBuffer.Size != 0) {\r
877 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
878 } else {\r
879 return;\r
880 }\r
881 \r
882 Temp = TBuffer.Buffer;\r
883\r
884 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
885 if (pNode->mIfrBinBuf != NULL) {\r
886 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);\r
887 Temp += pNode->mBinBufLen;\r
888 }\r
889 }\r
890\r
891 return; \r
892} \r
893\r
894VOID\r
895CIfrRecordInfoDB::IfrRecordOutput (\r
896 IN FILE *File,\r
897 IN UINT32 LineNo\r
898 )\r
899{\r
900 SIfrRecord *pNode;\r
901 UINT8 Index;\r
902 UINT32 TotalSize;\r
903\r
904 if (mSwitch == FALSE) {\r
905 return;\r
906 }\r
907\r
908 if (File == NULL) {\r
909 return;\r
910 }\r
911\r
912 TotalSize = 0;\r
913\r
914 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
915 if (pNode->mLineNo == LineNo || LineNo == 0) {\r
916 fprintf (File, ">%08X: ", pNode->mOffset);\r
917 TotalSize += pNode->mBinBufLen;\r
918 if (pNode->mIfrBinBuf != NULL) {\r
919 for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
920 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));\r
921 }\r
922 }\r
923 fprintf (File, "\n");\r
924 }\r
925 }\r
926 \r
927 if (LineNo == 0) {\r
928 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);\r
929 }\r
930}\r
931\r
932//\r
933// for framework vfr file\r
934// adjust opcode sequence for uefi IFR format\r
935// adjust inconsistent and varstore into the right position.\r
936//\r
937BOOLEAN\r
938CIfrRecordInfoDB::CheckQuestionOpCode (\r
939 IN UINT8 OpCode\r
940 )\r
941{\r
942 switch (OpCode) {\r
943 case EFI_IFR_CHECKBOX_OP:\r
944 case EFI_IFR_NUMERIC_OP:\r
945 case EFI_IFR_PASSWORD_OP:\r
946 case EFI_IFR_ONE_OF_OP:\r
947 case EFI_IFR_ACTION_OP:\r
948 case EFI_IFR_STRING_OP:\r
949 case EFI_IFR_DATE_OP:\r
950 case EFI_IFR_TIME_OP:\r
951 case EFI_IFR_ORDERED_LIST_OP:\r
952 return TRUE;\r
953 default:\r
954 return FALSE;\r
955 }\r
956}\r
957\r
958BOOLEAN\r
959CIfrRecordInfoDB::CheckIdOpCode (\r
960 IN UINT8 OpCode\r
961 )\r
962{\r
963 switch (OpCode) {\r
964 case EFI_IFR_EQ_ID_VAL_OP:\r
965 case EFI_IFR_EQ_ID_ID_OP:\r
64b2609f 966 case EFI_IFR_EQ_ID_VAL_LIST_OP:\r
30fdf114
LG
967 case EFI_IFR_QUESTION_REF1_OP:\r
968 return TRUE;\r
969 default:\r
970 return FALSE;\r
971 }\r
972} \r
973\r
974EFI_QUESTION_ID\r
975CIfrRecordInfoDB::GetOpcodeQuestionId (\r
976 IN EFI_IFR_OP_HEADER *OpHead\r
977 )\r
978{\r
979 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
980 \r
981 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
982 \r
983 return QuestionHead->QuestionId;\r
984}\r
985\r
986EFI_VFR_RETURN_CODE\r
987CIfrRecordInfoDB::IfrRecordAdjust (\r
988 VOID\r
989 )\r
990{\r
991 SIfrRecord *pNode, *preNode;\r
992 SIfrRecord *uNode, *tNode;\r
993 EFI_IFR_OP_HEADER *OpHead, *tOpHead;\r
994 EFI_QUESTION_ID QuestionId;\r
995 UINT32 StackCount;\r
996 UINT32 QuestionScope;\r
997 UINT32 OpcodeOffset;\r
998 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
999 EFI_VFR_RETURN_CODE Status;\r
1000\r
1001 //\r
1002 // Init local variable\r
1003 //\r
1004 Status = VFR_RETURN_SUCCESS;\r
1005 pNode = mIfrRecordListHead;\r
1006 preNode = pNode;\r
1007 QuestionScope = 0;\r
1008 while (pNode != NULL) {\r
1009 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
1010 \r
1011 //\r
1012 // make sure the inconsistent opcode in question scope\r
1013 //\r
1014 if (QuestionScope > 0) {\r
1015 QuestionScope += OpHead->Scope;\r
1016 if (OpHead->OpCode == EFI_IFR_END_OP) {\r
1017 QuestionScope --;\r
1018 }\r
1019 }\r
1020 \r
1021 if (CheckQuestionOpCode (OpHead->OpCode)) {\r
1022 QuestionScope = 1;\r
1023 }\r
1024 //\r
1025 // for the inconsistent opcode not in question scope, adjust it\r
1026 //\r
1027 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
1028 //\r
1029 // for inconsistent opcode not in question scope\r
1030 //\r
1031\r
1032 //\r
1033 // Count inconsistent opcode Scope \r
1034 //\r
1035 StackCount = OpHead->Scope;\r
1036 QuestionId = EFI_QUESTION_ID_INVALID;\r
1037 tNode = pNode;\r
1038 while (tNode != NULL && StackCount > 0) {\r
1039 tNode = tNode->mNext;\r
1040 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;\r
1041 //\r
1042 // Calculate Scope Number\r
1043 //\r
1044 StackCount += tOpHead->Scope;\r
1045 if (tOpHead->OpCode == EFI_IFR_END_OP) {\r
1046 StackCount --;\r
1047 }\r
1048 //\r
1049 // by IdEqual opcode to get QuestionId\r
1050 //\r
1051 if (QuestionId == EFI_QUESTION_ID_INVALID && \r
1052 CheckIdOpCode (tOpHead->OpCode)) {\r
1053 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
1054 }\r
1055 }\r
1056 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {\r
1057 //\r
1058 // report error; not found\r
1059 //\r
1060 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);\r
1061 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1062 Status = VFR_RETURN_MISMATCHED;\r
1063 break;\r
1064 }\r
1065 //\r
1066 // extract inconsistent opcode list\r
1067 // pNode is Incosistent opcode, tNode is End Opcode\r
1068 //\r
1069 \r
1070 //\r
1071 // insert inconsistent opcode list into the right question scope by questionid\r
1072 //\r
1073 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
1074 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
1075 if (CheckQuestionOpCode (tOpHead->OpCode) && \r
1076 (QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
1077 break;\r
1078 }\r
1079 }\r
1080 //\r
1081 // insert inconsistent opcode list and check LATE_CHECK flag\r
1082 //\r
1083 if (uNode != NULL) {\r
1084 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {\r
1085 //\r
1086 // if LATE_CHECK flag is set, change inconsistent to nosumbit\r
1087 //\r
1088 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
1089 }\r
1090 \r
1091 //\r
1092 // skip the default storage for Date and Time\r
1093 //\r
1094 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {\r
1095 uNode = uNode->mNext;\r
1096 }\r
1097\r
1098 preNode->mNext = tNode->mNext;\r
1099 tNode->mNext = uNode->mNext;\r
1100 uNode->mNext = pNode;\r
1101 //\r
1102 // reset pNode to head list, scan the whole list again.\r
1103 //\r
1104 pNode = mIfrRecordListHead;\r
1105 preNode = pNode;\r
1106 QuestionScope = 0;\r
1107 continue;\r
1108 } else {\r
1109 //\r
1110 // not found matched question id, report error\r
1111 //\r
1112 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);\r
1113 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1114 Status = VFR_RETURN_MISMATCHED;\r
1115 break;\r
1116 }\r
1117 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || \r
1118 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
1119 //\r
1120 // for new added group of varstore opcode\r
1121 //\r
1122 tNode = pNode;\r
1123 while (tNode->mNext != NULL) {\r
1124 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
1125 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && \r
1126 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
1127 break; \r
1128 }\r
1129 tNode = tNode->mNext;\r
1130 }\r
1131\r
1132 if (tNode->mNext == NULL) {\r
1133 //\r
1134 // invalid IfrCode, IfrCode end by EndOpCode\r
1135 // \r
1136 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
1137 Status = VFR_RETURN_MISMATCHED;\r
1138 break;\r
1139 }\r
1140 \r
1141 if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
1142 //\r
1143 // not new added varstore, which are not needed to be adjust.\r
1144 //\r
1145 preNode = tNode;\r
1146 pNode = tNode->mNext;\r
1147 continue; \r
1148 } else {\r
1149 //\r
1150 // move new added varstore opcode to the position befor form opcode \r
1151 // varstore opcode between pNode and tNode\r
1152 //\r
1153\r
1154 //\r
1155 // search form opcode from begin\r
1156 //\r
1157 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {\r
1158 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;\r
1159 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {\r
1160 break;\r
1161 }\r
1162 }\r
1163 //\r
1164 // Insert varstore opcode beform form opcode if form opcode is found\r
1165 //\r
1166 if (uNode->mNext != NULL) {\r
1167 preNode->mNext = tNode->mNext;\r
1168 tNode->mNext = uNode->mNext;\r
1169 uNode->mNext = pNode;\r
1170 //\r
1171 // reset pNode to head list, scan the whole list again.\r
1172 //\r
1173 pNode = mIfrRecordListHead;\r
1174 preNode = pNode;\r
1175 QuestionScope = 0;\r
1176 continue;\r
1177 } else {\r
1178 //\r
1179 // not found form, continue scan IfrRecord list\r
1180 //\r
1181 preNode = tNode;\r
1182 pNode = tNode->mNext;\r
1183 continue;\r
1184 }\r
1185 }\r
1186 }\r
1187 //\r
1188 // next node\r
1189 //\r
1190 preNode = pNode;\r
1191 pNode = pNode->mNext; \r
1192 }\r
1193 \r
1194 //\r
1195 // Update Ifr Opcode Offset\r
1196 //\r
1197 if (Status == VFR_RETURN_SUCCESS) {\r
1198 OpcodeOffset = 0;\r
1199 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1200 pNode->mOffset = OpcodeOffset;\r
1201 OpcodeOffset += pNode->mBinBufLen;\r
1202 }\r
1203 }\r
1204 return Status;\r
1205}\r
1206\r
1207CIfrRecordInfoDB gCIfrRecordInfoDB;\r
1208\r
1209VOID\r
1210CIfrObj::_EMIT_PENDING_OBJ (\r
1211 VOID\r
1212 )\r
1213{\r
1214 CHAR8 *ObjBinBuf = NULL;\r
1215 \r
1216 //\r
1217 // do nothing\r
1218 //\r
1219 if (!mDelayEmit || !gCreateOp) {\r
1220 return;\r
1221 }\r
1222\r
1223 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1224 //\r
1225 // update data buffer to package data\r
1226 //\r
1227 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
1228 if (ObjBinBuf != NULL) {\r
1229 memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
1230 }\r
1231 \r
1232 //\r
1233 // update bin buffer to package data buffer\r
1234 //\r
1235 if (mObjBinBuf != NULL) {\r
1236 delete mObjBinBuf;\r
1237 mObjBinBuf = ObjBinBuf;\r
1238 }\r
1239 \r
1240 mDelayEmit = FALSE;\r
1241}\r
1242\r
1243/*\r
1244 * The definition of CIfrObj's member function\r
1245 */\r
1246static struct {\r
1247 UINT8 mSize;\r
1248 UINT8 mScope;\r
1249} gOpcodeSizesScopeTable[] = {\r
1250 { 0, 0 }, // EFI_IFR_INVALID - 0x00\r
1251 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP\r
1252 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP\r
1253 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP\r
1254 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP\r
1255 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05\r
1256 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP\r
1257 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP\r
1258 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP\r
1259 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP\r
1260 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A\r
1261 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP\r
1262 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP\r
1263 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP\r
1264 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE\r
1265 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP\r
1266 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
1267 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP\r
1268 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP\r
1269 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP\r
b303ea72 1270 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
30fdf114
LG
1271 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP\r
1272 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP\r
1273 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP\r
1274 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP\r
1275 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
1276 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP\r
1277 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP\r
1278 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP\r
1279 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP\r
1280 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E\r
1281 { 0, 0 }, // 0x1F\r
1282 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20\r
1283 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21\r
52302d4d 1284 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22\r
30fdf114
LG
1285 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23\r
1286 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP\r
1287 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
1288 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP\r
1289 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP\r
1290 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28\r
1291 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP\r
52302d4d
LG
1292 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A\r
1293 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B\r
1294 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C\r
1295 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D\r
1296 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E\r
30fdf114
LG
1297 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F\r
1298 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP\r
1299 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP\r
1300 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP\r
1301 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP\r
1302 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34\r
1303 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP\r
1304 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP\r
1305 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP\r
1306 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP\r
1307 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP\r
1308 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A\r
1309 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP\r
1310 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP\r
1311 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP\r
1312 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E\r
1313 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP\r
1314 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP\r
1315 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41\r
1316 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8\r
1317 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16\r
1318 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32\r
1319 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64\r
1320 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46\r
1321 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP\r
1322 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP\r
1323 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP\r
1324 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP\r
1325 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP\r
1326 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP\r
1327 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP\r
1328 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E\r
1329 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP\r
1330 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP\r
1331 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP\r
1332 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP\r
1333 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP\r
1334 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP\r
1335 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP\r
1336 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP\r
1337 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57\r
1338 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP\r
1339 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP\r
1340 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP\r
1341 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP\r
1342 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
52302d4d 1343 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D\r
30fdf114
LG
1344 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
1345 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
a709adfa 1346 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60\r
4234283c
LG
1347 { sizeof (EFI_IFR_MODAL), 0}, // EFI_IFR_MODAL_OP - 0x61\r
1348 { sizeof (EFI_IFR_REFRESH_ID), 0}, // EFI_IFR_REFRESH_ID_OP - 0x62\r
30fdf114
LG
1349};\r
1350\r
1351#ifdef CIFROBJ_DEUBG\r
1352static struct {\r
1353 CHAR8 *mIfrName;\r
1354} gIfrObjPrintDebugTable[] = {\r
1355 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",\r
1356 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",\r
1357 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",\r
1358 "EFI_IFR_EQ_ID_VAL", "EFI_IFR_EQ_ID_ID", "EFI_IFR_EQ_ID_LIST", "EFI_IFR_AND", "EFI_IFR_OR", "EFI_IFR_NOT",\r
1359 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",\r
52302d4d 1360 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",\r
30fdf114 1361 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
52302d4d 1362 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",\r
30fdf114
LG
1363 "EFI_IFR_NOT_EQUAL", "EFI_IFR_GREATER_THAN", "EFI_IFR_GREATER_EQUAL", "EFI_IFR_LESS_THAN", "EFI_IFR_LESS_EQUAL", "EFI_IFR_BITWISE_AND",\r
1364 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",\r
1365 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
1366 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",\r
1367 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",\r
1368 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
1369 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
52302d4d 1370 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
4234283c 1371 "EFI_IFR_SECURITY", "EFI_IFR_MODAL", "EFI_IFR_REFRESH_ID",\r
30fdf114
LG
1372};\r
1373\r
1374VOID\r
1375CIFROBJ_DEBUG_PRINT (\r
1376 IN UINT8 OpCode\r
1377 )\r
1378{\r
1379 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
1380}\r
1381#else\r
1382\r
1383#define CIFROBJ_DEBUG_PRINT(OpCode)\r
1384\r
1385#endif\r
1386\r
52302d4d 1387BOOLEAN gCreateOp = TRUE;\r
30fdf114
LG
1388\r
1389CIfrObj::CIfrObj (\r
1390 IN UINT8 OpCode,\r
1391 OUT CHAR8 **IfrObj,\r
1392 IN UINT8 ObjBinLen,\r
1393 IN BOOLEAN DelayEmit\r
1394 )\r
1395{\r
1396 mDelayEmit = DelayEmit;\r
1397 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1398 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
1399 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
1400 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1401\r
1402 if (IfrObj != NULL) {\r
1403 *IfrObj = mObjBinBuf;\r
1404 }\r
1405\r
1406 CIFROBJ_DEBUG_PRINT (OpCode);\r
1407}\r
1408\r
1409CIfrObj::~CIfrObj (\r
1410 VOID\r
1411 )\r
1412{\r
1413 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
1414 _EMIT_PENDING_OBJ ();\r
1415 }\r
1416\r
1417 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
1418}\r
1419\r
1420/*\r
1421 * The definition of CIfrObj's member function\r
1422 */\r
1423UINT8 gScopeCount = 0;\r
1424\r
1425CIfrOpHeader::CIfrOpHeader (\r
1426 IN UINT8 OpCode,\r
1427 IN VOID *StartAddr,\r
1428 IN UINT8 Length\r
1429 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)\r
1430{\r
1431 mHeader->OpCode = OpCode;\r
1432 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
1433 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
1434}\r
1435\r
1436CIfrOpHeader::CIfrOpHeader (\r
1437 IN CIfrOpHeader &OpHdr\r
1438 )\r
1439{\r
1440 mHeader = OpHdr.mHeader;\r
1441}\r
1442\r
52302d4d 1443UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r