]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/C/VfrCompile/VfrFormPkg.cpp
MdeModulePkg:
[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
52302d4d 5Copyright (c) 2004 - 2010, Intel Corporation \r
30fdf114
LG
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
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
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
fd171542 790 SIfrRecord *Prev;\r
30fdf114
LG
791\r
792 if ((pNode = GetRecordInfoFromIdx (RecordIdx)) == NULL) {\r
793 return;\r
794 }\r
795\r
fd171542 796 if (LineNo == 0) {\r
797 //\r
798 // Line number is not specified explicitly, try to use line number of previous opcode\r
799 //\r
800 Prev = GetRecordInfoFromIdx (RecordIdx - 1);\r
801 if (Prev != NULL) {\r
802 LineNo = Prev->mLineNo;\r
803 }\r
804 }\r
805\r
30fdf114
LG
806 pNode->mLineNo = LineNo;\r
807 pNode->mOffset = Offset;\r
808 pNode->mBinBufLen = BinBufLen;\r
809 pNode->mIfrBinBuf = BinBuf;\r
810\r
811}\r
812\r
813VOID\r
814CIfrRecordInfoDB::IfrRecordOutput (\r
815 OUT PACKAGE_DATA &TBuffer\r
816 )\r
817{\r
818 CHAR8 *Temp;\r
819 SIfrRecord *pNode; \r
820\r
821 if (TBuffer.Buffer != NULL) {\r
822 delete TBuffer.Buffer;\r
823 }\r
824\r
825 TBuffer.Size = 0;\r
826 TBuffer.Buffer = NULL;\r
827\r
828\r
829 if (mSwitch == FALSE) {\r
830 return;\r
831 } \r
832 \r
833 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
834 TBuffer.Size += pNode->mBinBufLen;\r
835 }\r
836 \r
837 if (TBuffer.Size != 0) {\r
838 TBuffer.Buffer = new CHAR8[TBuffer.Size];\r
839 } else {\r
840 return;\r
841 }\r
842 \r
843 Temp = TBuffer.Buffer;\r
844\r
845 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
846 if (pNode->mIfrBinBuf != NULL) {\r
847 memcpy (Temp, pNode->mIfrBinBuf, pNode->mBinBufLen);\r
848 Temp += pNode->mBinBufLen;\r
849 }\r
850 }\r
851\r
852 return; \r
853} \r
854\r
855VOID\r
856CIfrRecordInfoDB::IfrRecordOutput (\r
857 IN FILE *File,\r
858 IN UINT32 LineNo\r
859 )\r
860{\r
861 SIfrRecord *pNode;\r
862 UINT8 Index;\r
863 UINT32 TotalSize;\r
864\r
865 if (mSwitch == FALSE) {\r
866 return;\r
867 }\r
868\r
869 if (File == NULL) {\r
870 return;\r
871 }\r
872\r
873 TotalSize = 0;\r
874\r
875 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
876 if (pNode->mLineNo == LineNo || LineNo == 0) {\r
877 fprintf (File, ">%08X: ", pNode->mOffset);\r
878 TotalSize += pNode->mBinBufLen;\r
879 if (pNode->mIfrBinBuf != NULL) {\r
880 for (Index = 0; Index < pNode->mBinBufLen; Index++) {\r
881 fprintf (File, "%02X ", (UINT8)(pNode->mIfrBinBuf[Index]));\r
882 }\r
883 }\r
884 fprintf (File, "\n");\r
885 }\r
886 }\r
887 \r
888 if (LineNo == 0) {\r
889 fprintf (File, "\nTotal Size of all record is 0x%08X\n", TotalSize);\r
890 }\r
891}\r
892\r
893//\r
894// for framework vfr file\r
895// adjust opcode sequence for uefi IFR format\r
896// adjust inconsistent and varstore into the right position.\r
897//\r
898BOOLEAN\r
899CIfrRecordInfoDB::CheckQuestionOpCode (\r
900 IN UINT8 OpCode\r
901 )\r
902{\r
903 switch (OpCode) {\r
904 case EFI_IFR_CHECKBOX_OP:\r
905 case EFI_IFR_NUMERIC_OP:\r
906 case EFI_IFR_PASSWORD_OP:\r
907 case EFI_IFR_ONE_OF_OP:\r
908 case EFI_IFR_ACTION_OP:\r
909 case EFI_IFR_STRING_OP:\r
910 case EFI_IFR_DATE_OP:\r
911 case EFI_IFR_TIME_OP:\r
912 case EFI_IFR_ORDERED_LIST_OP:\r
913 return TRUE;\r
914 default:\r
915 return FALSE;\r
916 }\r
917}\r
918\r
919BOOLEAN\r
920CIfrRecordInfoDB::CheckIdOpCode (\r
921 IN UINT8 OpCode\r
922 )\r
923{\r
924 switch (OpCode) {\r
925 case EFI_IFR_EQ_ID_VAL_OP:\r
926 case EFI_IFR_EQ_ID_ID_OP:\r
927 case EFI_IFR_EQ_ID_LIST_OP:\r
928 case EFI_IFR_QUESTION_REF1_OP:\r
929 return TRUE;\r
930 default:\r
931 return FALSE;\r
932 }\r
933} \r
934\r
935EFI_QUESTION_ID\r
936CIfrRecordInfoDB::GetOpcodeQuestionId (\r
937 IN EFI_IFR_OP_HEADER *OpHead\r
938 )\r
939{\r
940 EFI_IFR_QUESTION_HEADER *QuestionHead;\r
941 \r
942 QuestionHead = (EFI_IFR_QUESTION_HEADER *) (OpHead + 1);\r
943 \r
944 return QuestionHead->QuestionId;\r
945}\r
946\r
947EFI_VFR_RETURN_CODE\r
948CIfrRecordInfoDB::IfrRecordAdjust (\r
949 VOID\r
950 )\r
951{\r
952 SIfrRecord *pNode, *preNode;\r
953 SIfrRecord *uNode, *tNode;\r
954 EFI_IFR_OP_HEADER *OpHead, *tOpHead;\r
955 EFI_QUESTION_ID QuestionId;\r
956 UINT32 StackCount;\r
957 UINT32 QuestionScope;\r
958 UINT32 OpcodeOffset;\r
959 CHAR8 ErrorMsg[MAX_STRING_LEN] = {0, };\r
960 EFI_VFR_RETURN_CODE Status;\r
961\r
962 //\r
963 // Init local variable\r
964 //\r
965 Status = VFR_RETURN_SUCCESS;\r
966 pNode = mIfrRecordListHead;\r
967 preNode = pNode;\r
968 QuestionScope = 0;\r
969 while (pNode != NULL) {\r
970 OpHead = (EFI_IFR_OP_HEADER *) pNode->mIfrBinBuf;\r
971 \r
972 //\r
973 // make sure the inconsistent opcode in question scope\r
974 //\r
975 if (QuestionScope > 0) {\r
976 QuestionScope += OpHead->Scope;\r
977 if (OpHead->OpCode == EFI_IFR_END_OP) {\r
978 QuestionScope --;\r
979 }\r
980 }\r
981 \r
982 if (CheckQuestionOpCode (OpHead->OpCode)) {\r
983 QuestionScope = 1;\r
984 }\r
985 //\r
986 // for the inconsistent opcode not in question scope, adjust it\r
987 //\r
988 if (OpHead->OpCode == EFI_IFR_INCONSISTENT_IF_OP && QuestionScope == 0) {\r
989 //\r
990 // for inconsistent opcode not in question scope\r
991 //\r
992\r
993 //\r
994 // Count inconsistent opcode Scope \r
995 //\r
996 StackCount = OpHead->Scope;\r
997 QuestionId = EFI_QUESTION_ID_INVALID;\r
998 tNode = pNode;\r
999 while (tNode != NULL && StackCount > 0) {\r
1000 tNode = tNode->mNext;\r
1001 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mIfrBinBuf;\r
1002 //\r
1003 // Calculate Scope Number\r
1004 //\r
1005 StackCount += tOpHead->Scope;\r
1006 if (tOpHead->OpCode == EFI_IFR_END_OP) {\r
1007 StackCount --;\r
1008 }\r
1009 //\r
1010 // by IdEqual opcode to get QuestionId\r
1011 //\r
1012 if (QuestionId == EFI_QUESTION_ID_INVALID && \r
1013 CheckIdOpCode (tOpHead->OpCode)) {\r
1014 QuestionId = *(EFI_QUESTION_ID *) (tOpHead + 1);\r
1015 }\r
1016 }\r
1017 if (tNode == NULL || QuestionId == EFI_QUESTION_ID_INVALID) {\r
1018 //\r
1019 // report error; not found\r
1020 //\r
1021 sprintf (ErrorMsg, "Inconsistent OpCode Record list invalid QuestionId is 0x%X", QuestionId);\r
1022 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1023 Status = VFR_RETURN_MISMATCHED;\r
1024 break;\r
1025 }\r
1026 //\r
1027 // extract inconsistent opcode list\r
1028 // pNode is Incosistent opcode, tNode is End Opcode\r
1029 //\r
1030 \r
1031 //\r
1032 // insert inconsistent opcode list into the right question scope by questionid\r
1033 //\r
1034 for (uNode = mIfrRecordListHead; uNode != NULL; uNode = uNode->mNext) {\r
1035 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mIfrBinBuf;\r
1036 if (CheckQuestionOpCode (tOpHead->OpCode) && \r
1037 (QuestionId == GetOpcodeQuestionId (tOpHead))) {\r
1038 break;\r
1039 }\r
1040 }\r
1041 //\r
1042 // insert inconsistent opcode list and check LATE_CHECK flag\r
1043 //\r
1044 if (uNode != NULL) {\r
1045 if ((((EFI_IFR_QUESTION_HEADER *)(tOpHead + 1))->Flags & 0x20) != 0) {\r
1046 //\r
1047 // if LATE_CHECK flag is set, change inconsistent to nosumbit\r
1048 //\r
1049 OpHead->OpCode = EFI_IFR_NO_SUBMIT_IF_OP;\r
1050 }\r
1051 \r
1052 //\r
1053 // skip the default storage for Date and Time\r
1054 //\r
1055 if ((uNode->mNext != NULL) && (*uNode->mNext->mIfrBinBuf == EFI_IFR_DEFAULT_OP)) {\r
1056 uNode = uNode->mNext;\r
1057 }\r
1058\r
1059 preNode->mNext = tNode->mNext;\r
1060 tNode->mNext = uNode->mNext;\r
1061 uNode->mNext = pNode;\r
1062 //\r
1063 // reset pNode to head list, scan the whole list again.\r
1064 //\r
1065 pNode = mIfrRecordListHead;\r
1066 preNode = pNode;\r
1067 QuestionScope = 0;\r
1068 continue;\r
1069 } else {\r
1070 //\r
1071 // not found matched question id, report error\r
1072 //\r
1073 sprintf (ErrorMsg, "QuestionId required by Inconsistent OpCode is not found. QuestionId is 0x%X", QuestionId);\r
1074 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", ErrorMsg);\r
1075 Status = VFR_RETURN_MISMATCHED;\r
1076 break;\r
1077 }\r
1078 } else if (OpHead->OpCode == EFI_IFR_VARSTORE_OP || \r
1079 OpHead->OpCode == EFI_IFR_VARSTORE_EFI_OP) {\r
1080 //\r
1081 // for new added group of varstore opcode\r
1082 //\r
1083 tNode = pNode;\r
1084 while (tNode->mNext != NULL) {\r
1085 tOpHead = (EFI_IFR_OP_HEADER *) tNode->mNext->mIfrBinBuf;\r
1086 if (tOpHead->OpCode != EFI_IFR_VARSTORE_OP && \r
1087 tOpHead->OpCode != EFI_IFR_VARSTORE_EFI_OP) {\r
1088 break; \r
1089 }\r
1090 tNode = tNode->mNext;\r
1091 }\r
1092\r
1093 if (tNode->mNext == NULL) {\r
1094 //\r
1095 // invalid IfrCode, IfrCode end by EndOpCode\r
1096 // \r
1097 gCVfrErrorHandle.PrintMsg (0, NULL, "Error", "No found End Opcode in the end");\r
1098 Status = VFR_RETURN_MISMATCHED;\r
1099 break;\r
1100 }\r
1101 \r
1102 if (tOpHead->OpCode != EFI_IFR_END_OP) {\r
1103 //\r
1104 // not new added varstore, which are not needed to be adjust.\r
1105 //\r
1106 preNode = tNode;\r
1107 pNode = tNode->mNext;\r
1108 continue; \r
1109 } else {\r
1110 //\r
1111 // move new added varstore opcode to the position befor form opcode \r
1112 // varstore opcode between pNode and tNode\r
1113 //\r
1114\r
1115 //\r
1116 // search form opcode from begin\r
1117 //\r
1118 for (uNode = mIfrRecordListHead; uNode->mNext != NULL; uNode = uNode->mNext) {\r
1119 tOpHead = (EFI_IFR_OP_HEADER *) uNode->mNext->mIfrBinBuf;\r
1120 if (tOpHead->OpCode == EFI_IFR_FORM_OP) {\r
1121 break;\r
1122 }\r
1123 }\r
1124 //\r
1125 // Insert varstore opcode beform form opcode if form opcode is found\r
1126 //\r
1127 if (uNode->mNext != NULL) {\r
1128 preNode->mNext = tNode->mNext;\r
1129 tNode->mNext = uNode->mNext;\r
1130 uNode->mNext = pNode;\r
1131 //\r
1132 // reset pNode to head list, scan the whole list again.\r
1133 //\r
1134 pNode = mIfrRecordListHead;\r
1135 preNode = pNode;\r
1136 QuestionScope = 0;\r
1137 continue;\r
1138 } else {\r
1139 //\r
1140 // not found form, continue scan IfrRecord list\r
1141 //\r
1142 preNode = tNode;\r
1143 pNode = tNode->mNext;\r
1144 continue;\r
1145 }\r
1146 }\r
1147 }\r
1148 //\r
1149 // next node\r
1150 //\r
1151 preNode = pNode;\r
1152 pNode = pNode->mNext; \r
1153 }\r
1154 \r
1155 //\r
1156 // Update Ifr Opcode Offset\r
1157 //\r
1158 if (Status == VFR_RETURN_SUCCESS) {\r
1159 OpcodeOffset = 0;\r
1160 for (pNode = mIfrRecordListHead; pNode != NULL; pNode = pNode->mNext) {\r
1161 pNode->mOffset = OpcodeOffset;\r
1162 OpcodeOffset += pNode->mBinBufLen;\r
1163 }\r
1164 }\r
1165 return Status;\r
1166}\r
1167\r
1168CIfrRecordInfoDB gCIfrRecordInfoDB;\r
1169\r
1170VOID\r
1171CIfrObj::_EMIT_PENDING_OBJ (\r
1172 VOID\r
1173 )\r
1174{\r
1175 CHAR8 *ObjBinBuf = NULL;\r
1176 \r
1177 //\r
1178 // do nothing\r
1179 //\r
1180 if (!mDelayEmit || !gCreateOp) {\r
1181 return;\r
1182 }\r
1183\r
1184 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1185 //\r
1186 // update data buffer to package data\r
1187 //\r
1188 ObjBinBuf = gCFormPkg.IfrBinBufferGet (mObjBinLen);\r
1189 if (ObjBinBuf != NULL) {\r
1190 memcpy (ObjBinBuf, mObjBinBuf, mObjBinLen);\r
1191 }\r
1192 \r
1193 //\r
1194 // update bin buffer to package data buffer\r
1195 //\r
1196 if (mObjBinBuf != NULL) {\r
1197 delete mObjBinBuf;\r
1198 mObjBinBuf = ObjBinBuf;\r
1199 }\r
1200 \r
1201 mDelayEmit = FALSE;\r
1202}\r
1203\r
1204/*\r
1205 * The definition of CIfrObj's member function\r
1206 */\r
1207static struct {\r
1208 UINT8 mSize;\r
1209 UINT8 mScope;\r
1210} gOpcodeSizesScopeTable[] = {\r
1211 { 0, 0 }, // EFI_IFR_INVALID - 0x00\r
1212 { sizeof (EFI_IFR_FORM), 1 }, // EFI_IFR_FORM_OP\r
1213 { sizeof (EFI_IFR_SUBTITLE), 1 }, // EFI_IFR_SUBTITLE_OP\r
1214 { sizeof (EFI_IFR_TEXT), 0 }, // EFI_IFR_TEXT_OP\r
1215 { sizeof (EFI_IFR_IMAGE), 0 }, // EFI_IFR_IMAGE_OP\r
1216 { sizeof (EFI_IFR_ONE_OF), 1 }, // EFI_IFR_ONE_OF_OP - 0x05\r
1217 { sizeof (EFI_IFR_CHECKBOX), 1}, // EFI_IFR_CHECKBOX_OP\r
1218 { sizeof (EFI_IFR_NUMERIC), 1 }, // EFI_IFR_NUMERIC_OP\r
1219 { sizeof (EFI_IFR_PASSWORD), 1 }, // EFI_IFR_PASSWORD_OP\r
1220 { sizeof (EFI_IFR_ONE_OF_OPTION), 0 }, // EFI_IFR_ONE_OF_OPTION_OP\r
1221 { sizeof (EFI_IFR_SUPPRESS_IF), 1 }, // EFI_IFR_SUPPRESS_IF - 0x0A\r
1222 { sizeof (EFI_IFR_LOCKED), 0 }, // EFI_IFR_LOCKED_OP\r
1223 { sizeof (EFI_IFR_ACTION), 1 }, // EFI_IFR_ACTION_OP\r
1224 { sizeof (EFI_IFR_RESET_BUTTON), 1 }, // EFI_IFR_RESET_BUTTON_OP\r
1225 { sizeof (EFI_IFR_FORM_SET), 1 }, // EFI_IFR_FORM_SET_OP -0xE\r
1226 { sizeof (EFI_IFR_REF), 0 }, // EFI_IFR_REF_OP\r
1227 { sizeof (EFI_IFR_NO_SUBMIT_IF), 1}, // EFI_IFR_NO_SUBMIT_IF_OP -0x10\r
1228 { sizeof (EFI_IFR_INCONSISTENT_IF), 1 }, // EFI_IFR_INCONSISTENT_IF_OP\r
1229 { sizeof (EFI_IFR_EQ_ID_VAL), 0 }, // EFI_IFR_EQ_ID_VAL_OP\r
1230 { sizeof (EFI_IFR_EQ_ID_ID), 0 }, // EFI_IFR_EQ_ID_ID_OP\r
b303ea72 1231 { sizeof (EFI_IFR_EQ_ID_VAL_LIST), 0 }, // EFI_IFR_EQ_ID_LIST_OP - 0x14\r
30fdf114
LG
1232 { sizeof (EFI_IFR_AND), 0 }, // EFI_IFR_AND_OP\r
1233 { sizeof (EFI_IFR_OR), 0 }, // EFI_IFR_OR_OP\r
1234 { sizeof (EFI_IFR_NOT), 0 }, // EFI_IFR_NOT_OP\r
1235 { sizeof (EFI_IFR_RULE), 1 }, // EFI_IFR_RULE_OP\r
1236 { sizeof (EFI_IFR_GRAY_OUT_IF), 1 }, // EFI_IFR_GRAYOUT_IF_OP - 0x19\r
1237 { sizeof (EFI_IFR_DATE), 1 }, // EFI_IFR_DATE_OP\r
1238 { sizeof (EFI_IFR_TIME), 1 }, // EFI_IFR_TIME_OP\r
1239 { sizeof (EFI_IFR_STRING), 1 }, // EFI_IFR_STRING_OP\r
1240 { sizeof (EFI_IFR_REFRESH), 0 }, // EFI_IFR_REFRESH_OP\r
1241 { sizeof (EFI_IFR_DISABLE_IF), 1 }, // EFI_IFR_DISABLE_IF_OP - 0x1E\r
1242 { 0, 0 }, // 0x1F\r
1243 { sizeof (EFI_IFR_TO_LOWER), 0 }, // EFI_IFR_TO_LOWER_OP - 0x20\r
1244 { sizeof (EFI_IFR_TO_UPPER), 0 }, // EFI_IFR_TO_UPPER_OP - 0x21\r
52302d4d 1245 { sizeof (EFI_IFR_MAP), 1 }, // EFI_IFR_MAP - 0x22\r
30fdf114
LG
1246 { sizeof (EFI_IFR_ORDERED_LIST), 1 }, // EFI_IFR_ORDERED_LIST_OP - 0x23\r
1247 { sizeof (EFI_IFR_VARSTORE), 0 }, // EFI_IFR_VARSTORE_OP\r
1248 { sizeof (EFI_IFR_VARSTORE_NAME_VALUE), 0 }, // EFI_IFR_VARSTORE_NAME_VALUE_OP\r
1249 { sizeof (EFI_IFR_VARSTORE_EFI), 0 }, // EFI_IFR_VARSTORE_EFI_OP\r
1250 { sizeof (EFI_IFR_VARSTORE_DEVICE), 1 }, // EFI_IFR_VARSTORE_DEVICE_OP\r
1251 { sizeof (EFI_IFR_VERSION), 0 }, // EFI_IFR_VERSION_OP - 0x28\r
1252 { sizeof (EFI_IFR_END), 0 }, // EFI_IFR_END_OP\r
52302d4d
LG
1253 { sizeof (EFI_IFR_MATCH), 0 }, // EFI_IFR_MATCH_OP - 0x2A\r
1254 { sizeof (EFI_IFR_GET), 0 }, // EFI_IFR_GET - 0x2B\r
1255 { sizeof (EFI_IFR_SET), 0 }, // EFI_IFR_SET - 0x2C\r
1256 { sizeof (EFI_IFR_READ), 0 }, // EFI_IFR_READ - 0x2D\r
1257 { sizeof (EFI_IFR_WRITE), 0 }, // EFI_IFR_WRITE - 0x2E\r
30fdf114
LG
1258 { sizeof (EFI_IFR_EQUAL), 0 }, // EFI_IFR_EQUAL_OP - 0x2F\r
1259 { sizeof (EFI_IFR_NOT_EQUAL), 0 }, // EFI_IFR_NOT_EQUAL_OP\r
1260 { sizeof (EFI_IFR_GREATER_THAN), 0 }, // EFI_IFR_GREATER_THAN_OP\r
1261 { sizeof (EFI_IFR_GREATER_EQUAL), 0 }, // EFI_IFR_GREATER_EQUAL_OP\r
1262 { sizeof (EFI_IFR_LESS_THAN), 0 }, // EFI_IFR_LESS_THAN_OP\r
1263 { sizeof (EFI_IFR_LESS_EQUAL), 0 }, // EFI_IFR_LESS_EQUAL_OP - 0x34\r
1264 { sizeof (EFI_IFR_BITWISE_AND), 0 }, // EFI_IFR_BITWISE_AND_OP\r
1265 { sizeof (EFI_IFR_BITWISE_OR), 0 }, // EFI_IFR_BITWISE_OR_OP\r
1266 { sizeof (EFI_IFR_BITWISE_NOT), 0 }, // EFI_IFR_BITWISE_NOT_OP\r
1267 { sizeof (EFI_IFR_SHIFT_LEFT), 0 }, // EFI_IFR_SHIFT_LEFT_OP\r
1268 { sizeof (EFI_IFR_SHIFT_RIGHT), 0 }, // EFI_IFR_SHIFT_RIGHT_OP\r
1269 { sizeof (EFI_IFR_ADD), 0 }, // EFI_IFR_ADD_OP - 0x3A\r
1270 { sizeof (EFI_IFR_SUBTRACT), 0 }, // EFI_IFR_SUBTRACT_OP\r
1271 { sizeof (EFI_IFR_MULTIPLY), 0 }, // EFI_IFR_MULTIPLY_OP\r
1272 { sizeof (EFI_IFR_DIVIDE), 0 }, // EFI_IFR_DIVIDE_OP\r
1273 { sizeof (EFI_IFR_MODULO), 0 }, // EFI_IFR_MODULO_OP - 0x3E\r
1274 { sizeof (EFI_IFR_RULE_REF), 0 }, // EFI_IFR_RULE_REF_OP\r
1275 { sizeof (EFI_IFR_QUESTION_REF1), 0 }, // EFI_IFR_QUESTION_REF1_OP\r
1276 { sizeof (EFI_IFR_QUESTION_REF2), 0 }, // EFI_IFR_QUESTION_REF2_OP - 0x41\r
1277 { sizeof (EFI_IFR_UINT8), 0}, // EFI_IFR_UINT8\r
1278 { sizeof (EFI_IFR_UINT16), 0}, // EFI_IFR_UINT16\r
1279 { sizeof (EFI_IFR_UINT32), 0}, // EFI_IFR_UINT32\r
1280 { sizeof (EFI_IFR_UINT64), 0}, // EFI_IFR_UTNT64\r
1281 { sizeof (EFI_IFR_TRUE), 0 }, // EFI_IFR_TRUE_OP - 0x46\r
1282 { sizeof (EFI_IFR_FALSE), 0 }, // EFI_IFR_FALSE_OP\r
1283 { sizeof (EFI_IFR_TO_UINT), 0 }, // EFI_IFR_TO_UINT_OP\r
1284 { sizeof (EFI_IFR_TO_STRING), 0 }, // EFI_IFR_TO_STRING_OP\r
1285 { sizeof (EFI_IFR_TO_BOOLEAN), 0 }, // EFI_IFR_TO_BOOLEAN_OP\r
1286 { sizeof (EFI_IFR_MID), 0 }, // EFI_IFR_MID_OP\r
1287 { sizeof (EFI_IFR_FIND), 0 }, // EFI_IFR_FIND_OP\r
1288 { sizeof (EFI_IFR_TOKEN), 0 }, // EFI_IFR_TOKEN_OP\r
1289 { sizeof (EFI_IFR_STRING_REF1), 0 }, // EFI_IFR_STRING_REF1_OP - 0x4E\r
1290 { sizeof (EFI_IFR_STRING_REF2), 0 }, // EFI_IFR_STRING_REF2_OP\r
1291 { sizeof (EFI_IFR_CONDITIONAL), 0 }, // EFI_IFR_CONDITIONAL_OP\r
1292 { sizeof (EFI_IFR_QUESTION_REF3), 0 }, // EFI_IFR_QUESTION_REF3_OP\r
1293 { sizeof (EFI_IFR_ZERO), 0 }, // EFI_IFR_ZERO_OP\r
1294 { sizeof (EFI_IFR_ONE), 0 }, // EFI_IFR_ONE_OP\r
1295 { sizeof (EFI_IFR_ONES), 0 }, // EFI_IFR_ONES_OP\r
1296 { sizeof (EFI_IFR_UNDEFINED), 0 }, // EFI_IFR_UNDEFINED_OP\r
1297 { sizeof (EFI_IFR_LENGTH), 0 }, // EFI_IFR_LENGTH_OP\r
1298 { sizeof (EFI_IFR_DUP), 0 }, // EFI_IFR_DUP_OP - 0x57\r
1299 { sizeof (EFI_IFR_THIS), 0 }, // EFI_IFR_THIS_OP\r
1300 { sizeof (EFI_IFR_SPAN), 0 }, // EFI_IFR_SPAN_OP\r
1301 { sizeof (EFI_IFR_VALUE), 1 }, // EFI_IFR_VALUE_OP\r
1302 { sizeof (EFI_IFR_DEFAULT), 0 }, // EFI_IFR_DEFAULT_OP\r
1303 { sizeof (EFI_IFR_DEFAULTSTORE), 0 }, // EFI_IFR_DEFAULTSTORE_OP - 0x5C\r
52302d4d 1304 { sizeof (EFI_IFR_FORM_MAP), 1}, // EFI_IFR_FORM_MAP_OP - 0x5D\r
30fdf114
LG
1305 { sizeof (EFI_IFR_CATENATE), 0 }, // EFI_IFR_CATENATE_OP\r
1306 { sizeof (EFI_IFR_GUID), 0 }, // EFI_IFR_GUID_OP\r
a709adfa 1307 { sizeof (EFI_IFR_SECURITY), 0 }, // EFI_IFR_SECURITY_OP - 0x60\r
30fdf114
LG
1308};\r
1309\r
1310#ifdef CIFROBJ_DEUBG\r
1311static struct {\r
1312 CHAR8 *mIfrName;\r
1313} gIfrObjPrintDebugTable[] = {\r
1314 "EFI_IFR_INVALID", "EFI_IFR_FORM", "EFI_IFR_SUBTITLE", "EFI_IFR_TEXT", "EFI_IFR_IMAGE", "EFI_IFR_ONE_OF",\r
1315 "EFI_IFR_CHECKBOX", "EFI_IFR_NUMERIC", "EFI_IFR_PASSWORD", "EFI_IFR_ONE_OF_OPTION", "EFI_IFR_SUPPRESS_IF", "EFI_IFR_LOCKED",\r
1316 "EFI_IFR_ACTION", "EFI_IFR_RESET_BUTTON", "EFI_IFR_FORM_SET", "EFI_IFR_REF", "EFI_IFR_NO_SUBMIT_IF", "EFI_IFR_INCONSISTENT_IF",\r
1317 "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
1318 "EFI_IFR_RULE", "EFI_IFR_GRAY_OUT_IF", "EFI_IFR_DATE", "EFI_IFR_TIME", "EFI_IFR_STRING", "EFI_IFR_REFRESH",\r
52302d4d 1319 "EFI_IFR_DISABLE_IF", "EFI_IFR_INVALID", "EFI_IFR_TO_LOWER", "EFI_IFR_TO_UPPER", "EFI_IFR_MAP", "EFI_IFR_ORDERED_LIST",\r
30fdf114 1320 "EFI_IFR_VARSTORE", "EFI_IFR_VARSTORE_NAME_VALUE", "EFI_IFR_VARSTORE_EFI", "EFI_IFR_VARSTORE_DEVICE", "EFI_IFR_VERSION", "EFI_IFR_END",\r
52302d4d 1321 "EFI_IFR_MATCH", "EFI_IFR_GET", "EFI_IFR_SET", "EFI_IFR_READ", "EFI_IFR_WRITE", "EFI_IFR_EQUAL",\r
30fdf114
LG
1322 "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
1323 "EFI_IFR_BITWISE_OR", "EFI_IFR_BITWISE_NOT", "EFI_IFR_SHIFT_LEFT", "EFI_IFR_SHIFT_RIGHT", "EFI_IFR_ADD", "EFI_IFR_SUBTRACT",\r
1324 "EFI_IFR_MULTIPLY", "EFI_IFR_DIVIDE", "EFI_IFR_MODULO", "EFI_IFR_RULE_REF", "EFI_IFR_QUESTION_REF1", "EFI_IFR_QUESTION_REF2",\r
1325 "EFI_IFR_UINT8", "EFI_IFR_UINT16", "EFI_IFR_UINT32", "EFI_IFR_UINT64", "EFI_IFR_TRUE", "EFI_IFR_FALSE",\r
1326 "EFI_IFR_TO_UINT", "EFI_IFR_TO_STRING", "EFI_IFR_TO_BOOLEAN", "EFI_IFR_MID", "EFI_IFR_FIND", "EFI_IFR_TOKEN",\r
1327 "EFI_IFR_STRING_REF1","EFI_IFR_STRING_REF2", "EFI_IFR_CONDITIONAL", "EFI_IFR_QUESTION_REF3", "EFI_IFR_ZERO", "EFI_IFR_ONE",\r
1328 "EFI_IFR_ONES", "EFI_IFR_UNDEFINED", "EFI_IFR_LENGTH", "EFI_IFR_DUP", "EFI_IFR_THIS", "EFI_IFR_SPAN",\r
52302d4d 1329 "EFI_IFR_VALUE", "EFI_IFR_DEFAULT", "EFI_IFR_DEFAULTSTORE", "EFI_IFR_FORM_MAP", "EFI_IFR_CATENATE", "EFI_IFR_GUID",\r
a709adfa 1330 "EFI_IFR_SECURITY",\r
30fdf114
LG
1331};\r
1332\r
1333VOID\r
1334CIFROBJ_DEBUG_PRINT (\r
1335 IN UINT8 OpCode\r
1336 )\r
1337{\r
1338 printf ("======Create IFR [%s]\n", gIfrObjPrintDebugTable[OpCode].mIfrName);\r
1339}\r
1340#else\r
1341\r
1342#define CIFROBJ_DEBUG_PRINT(OpCode)\r
1343\r
1344#endif\r
1345\r
52302d4d 1346BOOLEAN gCreateOp = TRUE;\r
30fdf114
LG
1347\r
1348CIfrObj::CIfrObj (\r
1349 IN UINT8 OpCode,\r
1350 OUT CHAR8 **IfrObj,\r
1351 IN UINT8 ObjBinLen,\r
1352 IN BOOLEAN DelayEmit\r
1353 )\r
1354{\r
1355 mDelayEmit = DelayEmit;\r
1356 mPkgOffset = gCFormPkg.GetPkgLength ();\r
1357 mObjBinLen = (ObjBinLen == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : ObjBinLen;\r
1358 mObjBinBuf = ((DelayEmit == FALSE) && (gCreateOp == TRUE)) ? gCFormPkg.IfrBinBufferGet (mObjBinLen) : new CHAR8[EFI_IFR_MAX_LENGTH];\r
1359 mRecordIdx = (gCreateOp == TRUE) ? gCIfrRecordInfoDB.IfrRecordRegister (0xFFFFFFFF, mObjBinBuf, mObjBinLen, mPkgOffset) : EFI_IFR_RECORDINFO_IDX_INVALUD;\r
1360\r
1361 if (IfrObj != NULL) {\r
1362 *IfrObj = mObjBinBuf;\r
1363 }\r
1364\r
1365 CIFROBJ_DEBUG_PRINT (OpCode);\r
1366}\r
1367\r
1368CIfrObj::~CIfrObj (\r
1369 VOID\r
1370 )\r
1371{\r
1372 if ((mDelayEmit == TRUE) && ((gCreateOp == TRUE))) {\r
1373 _EMIT_PENDING_OBJ ();\r
1374 }\r
1375\r
1376 gCIfrRecordInfoDB.IfrRecordInfoUpdate (mRecordIdx, mLineNo, mObjBinBuf, mObjBinLen, mPkgOffset);\r
1377}\r
1378\r
1379/*\r
1380 * The definition of CIfrObj's member function\r
1381 */\r
1382UINT8 gScopeCount = 0;\r
1383\r
1384CIfrOpHeader::CIfrOpHeader (\r
1385 IN UINT8 OpCode,\r
1386 IN VOID *StartAddr,\r
1387 IN UINT8 Length\r
1388 ) : mHeader ((EFI_IFR_OP_HEADER *)StartAddr)\r
1389{\r
1390 mHeader->OpCode = OpCode;\r
1391 mHeader->Length = (Length == 0) ? gOpcodeSizesScopeTable[OpCode].mSize : Length;\r
1392 mHeader->Scope = (gOpcodeSizesScopeTable[OpCode].mScope + gScopeCount > 0) ? 1 : 0;\r
1393}\r
1394\r
1395CIfrOpHeader::CIfrOpHeader (\r
1396 IN CIfrOpHeader &OpHdr\r
1397 )\r
1398{\r
1399 mHeader = OpHdr.mHeader;\r
1400}\r
1401\r
52302d4d 1402UINT32 CIfrFormId::FormIdBitMap[EFI_FREE_FORM_ID_BITMAP_SIZE] = {0, };\r