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