Check In tool source code based on Build tool project revision r1655.
[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
5Copyright (c) 2004 - 2008, Intel Corporation \r
6All rights reserved. This program and the accompanying materials \r
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
28 IN CHAR8 *Msg\r
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
355 IN FILE *pFile,\r
356 IN UINT32 LineBytes,\r
357 IN CHAR8 *LineHeader,\r
358 IN CHAR8 *BlkBuf,\r
359 IN UINT32 BlkSize\r
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
378 IN FILE *pFile,\r
379 IN UINT32 LineBytes,\r
380 IN CHAR8 *LineHeader,\r
381 IN CHAR8 *BlkBuf,\r
382 IN UINT32 BlkSize\r
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
486 IN CHAR8 *Msg\r
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
564 EFI_VFR_RETURN_CODE ReturnCode;\r
565 EFI_VFR_VARSTORE_TYPE VarStoreType = EFI_VFR_VARSTORE_INVALID;\r
566\r
567 for (pNode = PendingAssignList; pNode != NULL; pNode = pNode->mNext) {\r
568 if (pNode->mFlag == PENDING) {\r
569 //\r
570 // declare this question as Numeric in SuppressIf True\r
571 //\r
572 // SuppressIf\r
573 CIfrSuppressIf SIObj;\r
574 SIObj.SetLineNo (LineNo);\r
575 \r
576 //TrueOpcode\r
577 CIfrTrue TObj (LineNo);\r
578 \r
579 //Numeric qeustion\r
580 CIfrNumeric CNObj;\r
581 EFI_VARSTORE_INFO Info; \r
582 EFI_QUESTION_ID QId = EFI_QUESTION_ID_INVALID;\r
583\r
584 CNObj.SetLineNo (LineNo);\r
585 CNObj.SetPrompt (0x0);\r
586 CNObj.SetHelp (0x0);\r
587\r
588 //\r
589 // Register this question, assume it is normal question, not date or time question\r
590 //\r
591 VarStr = pNode->mKey;\r
592 ReturnCode = lCVfrQuestionDB.RegisterQuestion (NULL, VarStr, QId);\r
593 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
594 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
595 return ReturnCode;\r
596 }\r
597 \r
598#ifdef VFREXP_DEBUG\r
599 printf ("Undefined Question name is %s and Id is 0x%x\n", VarStr, QId);\r
600#endif\r
601 //\r
602 // Get Question Info, framework vfr VarName == StructName\r
603 //\r
604 ReturnCode = lCVfrVarDataTypeDB.ExtractFieldNameAndArrary (VarStr, FName, ArrayIdx);\r
605 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
606 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, pNode->mKey, "Error", "Var string is not the valid C variable");\r
607 return ReturnCode;\r
608 }\r
609 //\r
610 // Get VarStoreType\r
611 //\r
612 ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType);\r
613 if (ReturnCode == VFR_RETURN_UNDEFINED) {\r
614 lCVfrDataStorage.DeclareBufferVarStore (\r
615 FName, \r
616 LocalFormSetGuid, \r
617 &lCVfrVarDataTypeDB, \r
618 FName,\r
619 EFI_VARSTORE_ID_INVALID,\r
620 FALSE\r
621 );\r
622 ReturnCode = lCVfrDataStorage.GetVarStoreType (FName, VarStoreType); \r
623 }\r
624 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
625 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
626 return ReturnCode;\r
627 }\r
628 \r
629 ReturnCode = lCVfrDataStorage.GetVarStoreId (FName, &Info.mVarStoreId);\r
630 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
631 gCVfrErrorHandle.PrintMsg (pNode->mLineNo, FName, "Error", "Var Store Type is not defined");\r
632 return ReturnCode;\r
633 }\r
634\r
635 if (*VarStr == '\0' && ArrayIdx != INVALID_ARRAY_INDEX) {\r
636 ReturnCode = lCVfrDataStorage.GetNameVarStoreInfo (&Info, ArrayIdx);\r
637 } else {\r
638 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
639 ReturnCode = lCVfrDataStorage.GetEfiVarStoreInfo (&Info);\r
640 } else if (VarStoreType == EFI_VFR_VARSTORE_BUFFER) {\r
641 VarStr = pNode->mKey;\r
642 ReturnCode = lCVfrVarDataTypeDB.GetDataFieldInfo (VarStr, Info.mInfo.mVarOffset, Info.mVarType, Info.mVarTotalSize);\r
643 } else {\r
644 ReturnCode = VFR_RETURN_UNSUPPORTED;\r
645 }\r
646 }\r
647 if (ReturnCode != VFR_RETURN_SUCCESS) {\r
648 gCVfrErrorHandle.HandleError (ReturnCode, pNode->mLineNo, pNode->mKey);\r
649 return ReturnCode;\r
650 }\r
651\r
652 CNObj.SetQuestionId (QId);\r
653 CNObj.SetVarStoreInfo (&Info);\r
654 CNObj.SetFlags (0, Info.mVarType);\r
655\r
656 //\r
657 // For undefined Efi VarStore type question\r
658 // Append the extended guided opcode to contain VarName\r
659 //\r
660 if (VarStoreType == EFI_VFR_VARSTORE_EFI) {\r
661 CIfrVarEqName CVNObj (QId, Info.mInfo.mVarName);\r
662 CVNObj.SetLineNo (LineNo);\r
663 }\r
664 \r
665 //\r
666 // End for Numeric\r
667 //\r
668 CIfrEnd CEObj; \r
669 CEObj.SetLineNo (LineNo);\r
670 //\r
671 // End for SuppressIf\r
672 //\r
673 CIfrEnd SEObj;\r
674 SEObj.SetLineNo (LineNo);\r
675 }\r
676 }\r
677 return VFR_RETURN_SUCCESS;\r
678}\r
679\r
680CFormPkg gCFormPkg;\r
681\r
682SIfrRecord::SIfrRecord (\r
683 VOID\r
684 )\r
685{\r
686 mIfrBinBuf = NULL;\r
687 mBinBufLen = 0;\r
688 mLineNo = 0xFFFFFFFF;\r
689 mOffset = 0xFFFFFFFF;\r
690 mNext = NULL;\r
691}\r
692\r
693SIfrRecord::~SIfrRecord (\r
694 VOID\r
695 )\r
696{\r
697 if (mIfrBinBuf != NULL) {\r
698 //delete mIfrBinBuf;\r
699 mIfrBinBuf = NULL;\r
700 }\r
701 mLineNo = 0xFFFFFFFF;\r
702 mOffset = 0xFFFFFFFF;\r
703 mBinBufLen = 0;\r
704 mNext = NULL;\r
705}\r
706\r
707CIfrRecordInfoDB::CIfrRecordInfoDB (\r
708 VOID\r
709 )\r
710{\r
711 mSwitch = TRUE;\r
712 mRecordCount = EFI_IFR_RECORDINFO_IDX_START;\r
713 mIfrRecordListHead = NULL;\r
714 mIfrRecordListTail = NULL;\r
715}\r
716\r
717CIfrRecordInfoDB::~CIfrRecordInfoDB (\r
718 VOID\r
719 )\r
720{\r
721 SIfrRecord *pNode;\r
722\r
723 while (mIfrRecordListHead != NULL) {\r
724 pNode = mIfrRecordListHead;\r
725 mIfrRecordListHead = mIfrRecordListHead->mNext;\r
726 delete pNode;\r
727 }\r
728}\r
729\r
730SIfrRecord *\r
731CIfrRecordInfoDB::GetRecordInfoFromIdx (\r
732 IN UINT32 RecordIdx\r
733 )\r
734{\r
735 UINT32 Idx;\r
736 SIfrRecord *pNode = NULL;\r
737\r
738 if (RecordIdx == EFI_IFR_RECORDINFO_IDX_INVALUD) {\r
739 return NULL;\r
740 }\r
741\r
742 for (Idx = (EFI_IFR_RECORDINFO_IDX_START + 1), pNode = mIfrRecordListHead;\r
743 (Idx != RecordIdx) && (pNode != NULL);\r
744 Idx++, pNode = pNode->mNext)\r
745 ;\r
746\r
747 return pNode;\r
748}\r
749\r
750UINT32\r
751CIfrRecordInfoDB::IfrRecordRegister (\r
752 IN UINT32 LineNo,\r
753 IN CHAR8 *IfrBinBuf,\r
754 IN UINT8 BinBufLen,\r
755 IN UINT32 Offset\r
756 )\r
757{\r
758 SIfrRecord *pNew;\r
759\r
760 if (mSwitch == FALSE) {\r
761 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
762 }\r
763\r
764 if ((pNew = new SIfrRecord) == NULL) {\r
765 return EFI_IFR_RECORDINFO_IDX_INVALUD;\r
766 }\r
767\r
768 if (mIfrRecordListHead == NULL) {\r
769 mIfrRecordListHead = pNew;\r
770 mIfrRecordListTail = pNew;\r
771 } else {\r
772 mIfrRecordListTail->mNext = pNew;\r
773 mIfrRecordListTail = pNew;\r
774 }\r
775 mRecordCount++;\r
776\r
777 return mRecordCount;\r
778}\r
779\r
780VOID\r
781CIfrRecordInfoDB::IfrRecordInfoUpdate (\r
782 IN UINT32 RecordIdx,\r
783 IN UINT32 LineNo,\r
784 IN CHAR8 *BinBuf,\r
785 IN UINT8 BinBufLen,\r
786 IN UINT32 Offset\r
787 )\r
788{\r
789 SIfrRecord *pNode;\r
790\r
791 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
792 return;\r
793 }\r
794\r
795 pNode->mLineNo = LineNo;\r
796 pNode->mOffset = Offset;\r
797 pNode->mBinBufLen = BinBufLen;\r
798 pNode->mIfrBinBuf = BinBuf;\r
799\r
800}\r
801\r
802VOID\r
803CIfrRecordInfoDB::IfrRecordOutput (\r
804 OUT PACKAGE_DATA &TBuffer\r
805 )\r
806{\r
807 CHAR8 *Temp;\r
808 SIfrRecord *pNode; \r
809\r
810 if (TBuffer.Buffer != NULL) {\r
811 delete TBuffer.Buffer;\r
812 }\r
813\r
814 TBuffer.Size = 0;\r
815 TBuffer.Buffer = NULL;\r
816\r
817\r
818 if (mSwitch == FALSE) {\r
819 return;\r
820 } \r
821 \r
822 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
823 TBuffer.Size += pNode->mBinBufLen;\r
824 }\r
825 \r
826 if (TBuffer.Size != 0) {\r
827 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
828 } else {\r
829 return;\r
830 }\r
831 \r
832 Temp = TBuffer.Buffer;\r
833\r
834 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
835 if (pNode->mIfrBinBuf != NULL) {\r
836 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);\r
837 Temp += pNode->mBinBufLen;\r
838 }\r
839 }\r
840\r
841 return; \r
842} \r
843\r
844VOID\r
845CIfrRecordInfoDB::IfrRecordOutput (\r
846 IN FILE *File,\r
847 IN UINT32 LineNo\r
848 )\r
849{\r
850 SIfrRecord *pNode;\r
851 UINT8 Index;\r
852 UINT32 TotalSize;\r
853\r
854 if (mSwitch == FALSE) {\r
855 return;\r
856 }\r
857\r
858 if (File == NULL) {\r
859 return;\r
860 }\r
861\r
862 TotalSize = 0;\r
863\r
864 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
865 if (pNode->mLineNo == LineNo || LineNo == 0) {\r
866 fprintf (File, ">%08X: ", pNode->mOffset);\r
867 TotalSize += pNode->mBinBufLen;\r
868 if (pNode->mIfrBinBuf != NULL) {\r
869 for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
870 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));\r
871 }\r
872 }\r
873 fprintf (File, "\n");\r
874 }\r
875 }\r
876 \r
877 if (LineNo == 0) {\r
878 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);\r
879 }\r
880}\r
881\r
882//\r
883// for framework vfr file\r
884// adjust opcode sequence for uefi IFR format\r
885// adjust inconsistent and varstore into the right position.\r
886//\r
887BOOLEAN\r
888CIfrRecordInfoDB::CheckQuestionOpCode (\r
889 IN UINT8 OpCode\r
890 )\r
891{\r
892 switch (OpCode) {\r
893 case EFI_IFR_CHECKBOX_OP:\r
894 case EFI_IFR_NUMERIC_OP:\r
895 case EFI_IFR_PASSWORD_OP:\r
896 case EFI_IFR_ONE_OF_OP:\r
897 case EFI_IFR_ACTION_OP:\r
898 case EFI_IFR_STRING_OP:\r
899 case EFI_IFR_DATE_OP:\r
900 case EFI_IFR_TIME_OP:\r
901 case EFI_IFR_ORDERED_LIST_OP:\r
902 return TRUE;\r
903 default:\r
904 return FALSE;\r
905 }\r
906}\r
907\r
908BOOLEAN\r
909CIfrRecordInfoDB::CheckIdOpCode (\r
910 IN UINT8 OpCode\r
911 )\r
912{\r
913 switch (OpCode) {\r
914 case EFI_IFR_EQ_ID_VAL_OP:\r
915 case EFI_IFR_EQ_ID_ID_OP:\r
916 case EFI_IFR_EQ_ID_LIST_OP:\r
917 case EFI_IFR_QUESTION_REF1_OP:\r
918 return TRUE;\r
919 default:\r
920 return FALSE;\r
921 }\r
922} \r
923\r
924EFI_QUESTION_ID\r
925CIfrRecordInfoDB::GetOpcodeQuestionId (\r
926 IN EFI_IFR_OP_HEADER *OpHead\r
927 )\r
928{\r
929 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
930 \r
931 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
932 \r
933 return QuestionHead->QuestionId;\r
934}\r
935\r
936EFI_VFR_RETURN_CODE\r
937CIfrRecordInfoDB::IfrRecordAdjust (\r
938 VOID\r
939 )\r
940{\r
941 SIfrRecord *pNode, *preNode;\r
942 SIfrRecord *uNode, *tNode;\r
943 EFI_IFR_OP_HEADER *OpHead, *tOpHead;\r
944 EFI_QUESTION_ID QuestionId;\r
945 UINT32 StackCount;\r
946 UINT32 QuestionScope;\r
947 UINT32 OpcodeOffset;\r
948 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
949 EFI_VFR_RETURN_CODE Status;\r
950\r
951 //\r
952 // Init local variable\r
953 //\r
954 Status = VFR_RETURN_SUCCESS;\r
955 pNode = mIfrRecordListHead;\r
956 preNode = pNode;\r
957 QuestionScope = 0;\r
958 while (pNode != NULL) {\r
959 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
960 \r
961 //\r
962 // make sure the inconsistent opcode in question scope\r
963 //\r
964 if (QuestionScope > 0) {\r
965 QuestionScope += OpHead->Scope;\r
966 if (OpHead->OpCode == EFI_IFR_END_OP) {\r
967 QuestionScope --;\r
968 }\r
969 }\r
970 \r
971 if (CheckQuestionOpCode (OpHead->OpCode)) {\r
972 QuestionScope = 1;\r
973 }\r
974 //\r
975 // for the inconsistent opcode not in question scope, adjust it\r
976 //\r
977 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
978 //\r
979 // for inconsistent opcode not in question scope\r
980 //\r
981\r
982 //\r
983 // Count inconsistent opcode Scope \r
984 //\r
985 StackCount = OpHead->Scope;\r
986 QuestionId = EFI_QUESTION_ID_INVALID;\r
987 tNode = pNode;\r
988 while (tNode != NULL && StackCount > 0) {\r
989 tNode = tNode->mNext;\r
990 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;\r
991 //\r
992 // Calculate Scope Number\r
993 //\r
994 StackCount += tOpHead->Scope;\r
995 if (tOpHead->OpCode == EFI_IFR_END_OP) {\r
996 StackCount --;\r
997 }\r
998 //\r
999 // by IdEqual opcode to get QuestionId\r
1000 //\r
1001 if (QuestionId == EFI_QUESTION_ID_INVALID && \r
1002 CheckIdOpCode (tOpHead->OpCode)) {\r
1003 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
1004 }\r
1005 }\r
1006 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {\r
1007 //\r
1008 // report error; not found\r
1009 //\r
1010 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);\r
1011 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1012 Status = VFR_RETURN_MISMATCHED;\r
1013 break;\r
1014 }\r
1015 //\r
1016 // extract inconsistent opcode list\r
1017 // pNode is Incosistent opcode, tNode is End Opcode\r
1018 //\r
1019 \r
1020 //\r
1021 // insert inconsistent opcode list into the right question scope by questionid\r
1022 //\r
1023 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
1024 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
1025 if (CheckQuestionOpCode (tOpHead->OpCode) && \r
1026 (QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
1027 break;\r
1028 }\r
1029 }\r
1030 //\r
1031 // insert inconsistent opcode list and check LATE_CHECK flag\r
1032 //\r
1033 if (uNode != NULL) {\r
1034 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {\r
1035 //\r
1036 // if LATE_CHECK flag is set, change inconsistent to nosumbit\r
1037 //\r
1038 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
1039 }\r
1040 \r
1041 //\r
1042 // skip the default storage for Date and Time\r
1043 //\r
1044 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {\r
1045 uNode = uNode->mNext;\r
1046 }\r
1047\r
1048 preNode->mNext = tNode->mNext;\r
1049 tNode->mNext = uNode->mNext;\r
1050 uNode->mNext = pNode;\r
1051 //\r
1052 // reset pNode to head list, scan the whole list again.\r
1053 //\r
1054 pNode = mIfrRecordListHead;\r
1055 preNode = pNode;\r
1056 QuestionScope = 0;\r
1057 continue;\r
1058 } else {\r
1059 //\r
1060 // not found matched question id, report error\r
1061 //\r
1062 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);\r
1063 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1064 Status = VFR_RETURN_MISMATCHED;\r
1065 break;\r
1066 }\r
1067 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || \r
1068 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
1069 //\r
1070 // for new added group of varstore opcode\r
1071 //\r
1072 tNode = pNode;\r
1073 while (tNode->mNext != NULL) {\r
1074 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
1075 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && \r
1076 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
1077 break; \r
1078 }\r
1079 tNode = tNode->mNext;\r
1080 }\r
1081\r
1082 if (tNode->mNext == NULL) {\r
1083 //\r
1084 // invalid IfrCode, IfrCode end by EndOpCode\r
1085 // \r
1086 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
1087 Status = VFR_RETURN_MISMATCHED;\r
1088 break;\r
1089 }\r
1090 \r
1091 if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
1092 //\r
1093 // not new added varstore, which are not needed to be adjust.\r
1094 //\r
1095 preNode = tNode;\r
1096 pNode = tNode->mNext;\r
1097 continue; \r
1098 } else {\r
1099 //\r
1100 // move new added varstore opcode to the position befor form opcode \r
1101 // varstore opcode between pNode and tNode\r
1102 //\r
1103\r
1104 //\r
1105 // search form opcode from begin\r
1106 //\r
1107 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {\r
1108 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;\r
1109 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {\r
1110 break;\r
1111 }\r
1112 }\r
1113 //\r
1114 // Insert varstore opcode beform form opcode if form opcode is found\r
1115 //\r
1116 if (uNode->mNext != NULL) {\r
1117 preNode->mNext = tNode->mNext;\r
1118 tNode->mNext = uNode->mNext;\r
1119 uNode->mNext = pNode;\r
1120 //\r
1121 // reset pNode to head list, scan the whole list again.\r
1122 //\r
1123 pNode = mIfrRecordListHead;\r
1124 preNode = pNode;\r
1125 QuestionScope = 0;\r
1126 continue;\r
1127 } else {\r
1128 //\r
1129 // not found form, continue scan IfrRecord list\r
1130 //\r
1131 preNode = tNode;\r
1132 pNode = tNode->mNext;\r
1133 continue;\r
1134 }\r
1135 }\r
1136 }\r
1137 //\r
1138 // next node\r
1139 //\r
1140 preNode = pNode;\r
1141 pNode = pNode->mNext; \r
1142 }\r
1143 \r
1144 //\r
1145 // Update Ifr Opcode Offset\r
1146 //\r
1147 if (Status == VFR_RETURN_SUCCESS) {\r
1148 OpcodeOffset = 0;\r
1149 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1150 pNode->mOffset = OpcodeOffset;\r
1151 OpcodeOffset += pNode->mBinBufLen;\r
1152 }\r
1153 }\r
1154 return Status;\r
1155}\r
1156\r
1157CIfrRecordInfoDB gCIfrRecordInfoDB;\r
1158\r
1159VOID\r
1160CIfrObj::_EMIT_PENDING_OBJ (\r
1161 VOID\r
1162 )\r
1163{\r
1164 CHAR8 *ObjBinBuf = NULL;\r
1165 \r
1166 //\r
1167 // do nothing\r
1168 //\r
1169 if (!mDelayEmit || !gCreateOp) {\r
1170 return;\r
1171 }\r
1172\r
1173 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1174 //\r
1175 // update data buffer to package data\r
1176 //\r
1177 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
1178 if (ObjBinBuf != NULL) {\r
1179 memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
1180 }\r
1181 \r
1182 //\r
1183 // update bin buffer to package data buffer\r
1184 //\r
1185 if (mObjBinBuf != NULL) {\r
1186 delete mObjBinBuf;\r
1187 mObjBinBuf = ObjBinBuf;\r
1188 }\r
1189 \r
1190 mDelayEmit = FALSE;\r
1191}\r
1192\r
1193/*\r
1194 * The definition of CIfrObj's member function\r
1195 */\r
1196static struct {\r
1197 UINT8 mSize;\r
1198 UINT8 mScope;\r
1199} gOpcodeSizesScopeTable[] = {\r
1200 { 0, 0 }, // EFI_IFR_INVALID - 0x00\r
1201 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP\r
1202 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP\r
1203 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP\r
1204 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP\r
1205 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05\r
1206 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP\r
1207 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP\r
1208 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP\r
1209 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP\r
1210 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A\r
1211 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP\r
1212 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP\r
1213 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP\r
1214 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE\r
1215 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP\r
1216 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
1217 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP\r
1218 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP\r
1219 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP\r
1220 { sizeof (EFI_IFR_EQ_ID_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
1221 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP\r
1222 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP\r
1223 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP\r
1224 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP\r
1225 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
1226 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP\r
1227 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP\r
1228 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP\r
1229 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP\r
1230 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E\r
1231 { 0, 0 }, // 0x1F\r
1232 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20\r
1233 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21\r
1234 { 0, 0 }, // 0x22\r
1235 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23\r
1236 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP\r
1237 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
1238 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP\r
1239 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP\r
1240 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28\r
1241 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP\r
1242 { sizeof (EFI_IFR_MATCH), 1 }, // EFI_IFR_MATCH_OP - 0x2A\r
1243 { 0, 0 }, { 0, 0} , { 0, 0} , { 0, 0} , // 0x2B ~ 0x2E\r
1244 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F\r
1245 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP\r
1246 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP\r
1247 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP\r
1248 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP\r
1249 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34\r
1250 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP\r
1251 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP\r
1252 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP\r
1253 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP\r
1254 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP\r
1255 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A\r
1256 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP\r
1257 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP\r
1258 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP\r
1259 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E\r
1260 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP\r
1261 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP\r
1262 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41\r
1263 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8\r
1264 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16\r
1265 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32\r
1266 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64\r
1267 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46\r
1268 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP\r
1269 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP\r
1270 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP\r
1271 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP\r
1272 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP\r
1273 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP\r
1274 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP\r
1275 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E\r
1276 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP\r
1277 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP\r
1278 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP\r
1279 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP\r
1280 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP\r
1281 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP\r
1282 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP\r
1283 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP\r
1284 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57\r
1285 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP\r
1286 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP\r
1287 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP\r
1288 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP\r
1289 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
1290 { 0, 0}, // 0x5D\r
1291 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
1292 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
1293};\r
1294\r
1295#ifdef CIFROBJ_DEUBG\r
1296static struct {\r
1297 CHAR8 *mIfrName;\r
1298} gIfrObjPrintDebugTable[] = {\r
1299 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",\r
1300 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",\r
1301 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",\r
1302 "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
1303 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",\r
1304 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_INVALID", "EFI_IFR_ORDERED_LIST",\r
1305 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
1306 "EFI_IFR_MATCH", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_INVALID", "EFI_IFR_EQUAL",\r
1307 "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
1308 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",\r
1309 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
1310 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",\r
1311 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",\r
1312 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
1313 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
1314 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_INVALID", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
1315};\r
1316\r
1317VOID\r
1318CIFROBJ_DEBUG_PRINT (\r
1319 IN UINT8 OpCode\r
1320 )\r
1321{\r
1322 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
1323}\r
1324#else\r
1325\r
1326#define CIFROBJ_DEBUG_PRINT(OpCode)\r
1327\r
1328#endif\r
1329\r
1330bool gCreateOp = TRUE;\r
1331\r
1332CIfrObj::CIfrObj (\r
1333 IN UINT8 OpCode,\r
1334 OUT CHAR8 **IfrObj,\r
1335 IN UINT8 ObjBinLen,\r
1336 IN BOOLEAN DelayEmit\r
1337 )\r
1338{\r
1339 mDelayEmit = DelayEmit;\r
1340 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1341 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
1342 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
1343 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1344\r
1345 if (IfrObj != NULL) {\r
1346 *IfrObj = mObjBinBuf;\r
1347 }\r
1348\r
1349 CIFROBJ_DEBUG_PRINT (OpCode);\r
1350}\r
1351\r
1352CIfrObj::~CIfrObj (\r
1353 VOID\r
1354 )\r
1355{\r
1356 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
1357 _EMIT_PENDING_OBJ ();\r
1358 }\r
1359\r
1360 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
1361}\r
1362\r
1363/*\r
1364 * The definition of CIfrObj's member function\r
1365 */\r
1366UINT8 gScopeCount = 0;\r
1367\r
1368CIfrOpHeader::CIfrOpHeader (\r
1369 IN UINT8 OpCode,\r
1370 IN VOID *StartAddr,\r
1371 IN UINT8 Length\r
1372 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)\r
1373{\r
1374 mHeader->OpCode = OpCode;\r
1375 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
1376 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
1377}\r
1378\r
1379CIfrOpHeader::CIfrOpHeader (\r
1380 IN CIfrOpHeader &OpHdr\r
1381 )\r
1382{\r
1383 mHeader = OpHdr.mHeader;\r
1384}\r
1385\r
1386UINT32 CIfrForm::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r