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