VfrUtilityLib.cpp 103 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972
  1. /** @file
  2. Vfr common library functions.
  3. Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
  4. This program and the accompanying materials
  5. are licensed and made available under the terms and conditions of the BSD License
  6. which accompanies this distribution. The full text of the license may be found at
  7. http://opensource.org/licenses/bsd-license.php
  8. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  10. **/
  11. #include "stdio.h"
  12. #include "stdlib.h"
  13. #include "assert.h"
  14. #include "CommonLib.h"
  15. #include "VfrUtilityLib.h"
  16. #include "VfrFormPkg.h"
  17. VOID
  18. CVfrBinaryOutput::WriteLine (
  19. IN FILE *pFile,
  20. IN UINT32 LineBytes,
  21. IN CONST CHAR8 *LineHeader,
  22. IN CHAR8 *BlkBuf,
  23. IN UINT32 BlkSize
  24. )
  25. {
  26. UINT32 Index;
  27. if ((pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
  28. return;
  29. }
  30. for (Index = 0; Index < BlkSize; Index++) {
  31. if ((Index % LineBytes) == 0) {
  32. fprintf (pFile, "\n%s", LineHeader);
  33. }
  34. fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
  35. }
  36. }
  37. VOID
  38. CVfrBinaryOutput::WriteEnd (
  39. IN FILE *pFile,
  40. IN UINT32 LineBytes,
  41. IN CONST CHAR8 *LineHeader,
  42. IN CHAR8 *BlkBuf,
  43. IN UINT32 BlkSize
  44. )
  45. {
  46. UINT32 Index;
  47. if ((BlkSize == 0) || (pFile == NULL) || (LineHeader == NULL) || (BlkBuf == NULL)) {
  48. return;
  49. }
  50. for (Index = 0; Index < BlkSize - 1; Index++) {
  51. if ((Index % LineBytes) == 0) {
  52. fprintf (pFile, "\n%s", LineHeader);
  53. }
  54. fprintf (pFile, "0x%02X, ", (UINT8)BlkBuf[Index]);
  55. }
  56. if ((Index % LineBytes) == 0) {
  57. fprintf (pFile, "\n%s", LineHeader);
  58. }
  59. fprintf (pFile, "0x%02X\n", (UINT8)BlkBuf[Index]);
  60. }
  61. SConfigInfo::SConfigInfo (
  62. IN UINT8 Type,
  63. IN UINT16 Offset,
  64. IN UINT32 Width,
  65. IN EFI_IFR_TYPE_VALUE Value
  66. )
  67. {
  68. mNext = NULL;
  69. mOffset = Offset;
  70. mWidth = (UINT16)Width;
  71. mValue = new UINT8[mWidth];
  72. if (mValue == NULL) {
  73. return;
  74. }
  75. switch (Type) {
  76. case EFI_IFR_TYPE_NUM_SIZE_8 :
  77. memcpy (mValue, &Value.u8, mWidth);
  78. break;
  79. case EFI_IFR_TYPE_NUM_SIZE_16 :
  80. memcpy (mValue, &Value.u16, mWidth);
  81. break;
  82. case EFI_IFR_TYPE_NUM_SIZE_32 :
  83. memcpy (mValue, &Value.u32, mWidth);
  84. break;
  85. case EFI_IFR_TYPE_NUM_SIZE_64 :
  86. memcpy (mValue, &Value.u64, mWidth);
  87. break;
  88. case EFI_IFR_TYPE_BOOLEAN :
  89. memcpy (mValue, &Value.b, mWidth);
  90. break;
  91. case EFI_IFR_TYPE_TIME :
  92. memcpy (mValue, &Value.time, mWidth);
  93. break;
  94. case EFI_IFR_TYPE_DATE :
  95. memcpy (mValue, &Value.date, mWidth);
  96. break;
  97. case EFI_IFR_TYPE_STRING :
  98. memcpy (mValue, &Value.string, mWidth);
  99. break;
  100. case EFI_IFR_TYPE_BUFFER :
  101. memcpy (mValue, &Value.u8, mWidth);
  102. break;
  103. case EFI_IFR_TYPE_OTHER :
  104. return;
  105. }
  106. }
  107. SConfigInfo::~SConfigInfo (
  108. VOID
  109. )
  110. {
  111. ARRAY_SAFE_FREE (mValue);
  112. }
  113. SConfigItem::SConfigItem (
  114. IN CHAR8 *Name,
  115. IN EFI_GUID *Guid,
  116. IN CHAR8 *Id
  117. )
  118. {
  119. mName = NULL;
  120. mGuid = NULL;
  121. mId = NULL;
  122. mInfoStrList = NULL;
  123. mNext = NULL;
  124. if (Name != NULL) {
  125. if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
  126. strcpy (mName, Name);
  127. }
  128. }
  129. if (Guid != NULL) {
  130. if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
  131. memcpy (mGuid, Guid, sizeof (EFI_GUID));
  132. }
  133. }
  134. if (Id != NULL) {
  135. if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
  136. strcpy (mId, Id);
  137. }
  138. }
  139. }
  140. SConfigItem::SConfigItem (
  141. IN CHAR8 *Name,
  142. IN EFI_GUID *Guid,
  143. IN CHAR8 *Id,
  144. IN UINT8 Type,
  145. IN UINT16 Offset,
  146. IN UINT16 Width,
  147. IN EFI_IFR_TYPE_VALUE Value
  148. )
  149. {
  150. mName = NULL;
  151. mGuid = NULL;
  152. mId = NULL;
  153. mInfoStrList = NULL;
  154. mNext = NULL;
  155. if (Name != NULL) {
  156. if ((mName = new CHAR8[strlen (Name) + 1]) != NULL) {
  157. strcpy (mName, Name);
  158. }
  159. }
  160. if (Guid != NULL) {
  161. if ((mGuid = (EFI_GUID *) new CHAR8[sizeof (EFI_GUID)]) != NULL) {
  162. memcpy (mGuid, Guid, sizeof (EFI_GUID));
  163. }
  164. }
  165. if (Id != NULL) {
  166. if ((mId = new CHAR8[strlen (Id) + 1]) != NULL) {
  167. strcpy (mId, Id);
  168. }
  169. }
  170. mInfoStrList = new SConfigInfo(Type, Offset, Width, Value);
  171. }
  172. SConfigItem::~SConfigItem (
  173. VOID
  174. )
  175. {
  176. SConfigInfo *Info;
  177. ARRAY_SAFE_FREE (mName);
  178. ARRAY_SAFE_FREE (mGuid);
  179. ARRAY_SAFE_FREE (mId);
  180. while (mInfoStrList != NULL) {
  181. Info = mInfoStrList;
  182. mInfoStrList = mInfoStrList->mNext;
  183. BUFFER_SAFE_FREE (Info);
  184. }
  185. }
  186. UINT8
  187. CVfrBufferConfig::Register (
  188. IN CHAR8 *Name,
  189. IN EFI_GUID *Guid,
  190. IN CHAR8 *Id
  191. )
  192. {
  193. SConfigItem *pNew;
  194. if (Select (Name, Guid) == 0) {
  195. return 1;
  196. }
  197. if ((pNew = new SConfigItem (Name, Guid, Id)) == NULL) {
  198. return 2;
  199. }
  200. if (mItemListHead == NULL) {
  201. mItemListHead = pNew;
  202. mItemListTail = pNew;
  203. } else {
  204. mItemListTail->mNext = pNew;
  205. mItemListTail = pNew;
  206. }
  207. mItemListPos = pNew;
  208. return 0;
  209. }
  210. VOID
  211. CVfrBufferConfig::Open (
  212. VOID
  213. )
  214. {
  215. mItemListPos = mItemListHead;
  216. }
  217. BOOLEAN
  218. CVfrBufferConfig::Eof(
  219. VOID
  220. )
  221. {
  222. return (mItemListPos == NULL) ? TRUE : FALSE;
  223. }
  224. UINT8
  225. CVfrBufferConfig::Select (
  226. IN CHAR8 *Name,
  227. IN EFI_GUID *Guid,
  228. IN CHAR8 *Id
  229. )
  230. {
  231. SConfigItem *p;
  232. if (Name == NULL || Guid == NULL) {
  233. mItemListPos = mItemListHead;
  234. return 0;
  235. } else {
  236. for (p = mItemListHead; p != NULL; p = p->mNext) {
  237. if ((strcmp (p->mName, Name) != 0) || (memcmp (p->mGuid, Guid, sizeof (EFI_GUID)) != 0)) {
  238. continue;
  239. }
  240. if (Id != NULL) {
  241. if (p->mId == NULL || strcmp (p->mId, Id) != 0) {
  242. continue;
  243. }
  244. } else if (p->mId != NULL) {
  245. continue;
  246. }
  247. mItemListPos = p;
  248. return 0;
  249. }
  250. }
  251. return 1;
  252. }
  253. UINT8
  254. CVfrBufferConfig::Write (
  255. IN CONST CHAR8 Mode,
  256. IN CHAR8 *Name,
  257. IN EFI_GUID *Guid,
  258. IN CHAR8 *Id,
  259. IN UINT8 Type,
  260. IN UINT16 Offset,
  261. IN UINT32 Width,
  262. IN EFI_IFR_TYPE_VALUE Value
  263. )
  264. {
  265. UINT8 Ret;
  266. SConfigItem *pItem;
  267. SConfigInfo *pInfo;
  268. if ((Ret = Select (Name, Guid)) != 0) {
  269. return Ret;
  270. }
  271. switch (Mode) {
  272. case 'a' : // add
  273. if (Select (Name, Guid, Id) != 0) {
  274. if ((pItem = new SConfigItem (Name, Guid, Id, Type, Offset, (UINT16) Width, Value)) == NULL) {
  275. return 2;
  276. }
  277. if (mItemListHead == NULL) {
  278. mItemListHead = pItem;
  279. mItemListTail = pItem;
  280. } else {
  281. mItemListTail->mNext = pItem;
  282. mItemListTail = pItem;
  283. }
  284. mItemListPos = pItem;
  285. } else {
  286. // tranverse the list to find out if there's already the value for the same offset
  287. for (pInfo = mItemListPos->mInfoStrList; pInfo != NULL; pInfo = pInfo->mNext) {
  288. if (pInfo->mOffset == Offset) {
  289. return 0;
  290. }
  291. }
  292. if((pInfo = new SConfigInfo (Type, Offset, Width, Value)) == NULL) {
  293. return 2;
  294. }
  295. pInfo->mNext = mItemListPos->mInfoStrList;
  296. mItemListPos->mInfoStrList = pInfo;
  297. }
  298. break;
  299. case 'd' : // delete
  300. if (mItemListHead == mItemListPos) {
  301. mItemListHead = mItemListPos->mNext;
  302. delete mItemListPos;
  303. break;
  304. }
  305. for (pItem = mItemListHead; pItem->mNext != mItemListPos; pItem = pItem->mNext)
  306. ;
  307. pItem->mNext = mItemListPos->mNext;
  308. if (mItemListTail == mItemListPos) {
  309. mItemListTail = pItem;
  310. }
  311. delete mItemListPos;
  312. mItemListPos = pItem->mNext;
  313. break;
  314. case 'i' : // set info
  315. if (mItemListPos->mId != NULL) {
  316. delete[] mItemListPos->mId;
  317. }
  318. mItemListPos->mId = NULL;
  319. if (Id != NULL) {
  320. if ((mItemListPos->mId = new CHAR8[strlen (Id) + 1]) == NULL) {
  321. return 2;
  322. }
  323. strcpy (mItemListPos->mId, Id);
  324. }
  325. break;
  326. default :
  327. return 1;
  328. }
  329. return 0;
  330. }
  331. VOID
  332. CVfrBufferConfig::Close (
  333. VOID
  334. )
  335. {
  336. mItemListPos = NULL;
  337. }
  338. #define BYTES_PRE_LINE 0x10
  339. VOID
  340. CVfrBufferConfig::OutputCFile (
  341. IN FILE *pFile,
  342. IN CHAR8 *BaseName
  343. )
  344. {
  345. CVfrBinaryOutput Output;
  346. SConfigItem *Item;
  347. SConfigInfo *Info;
  348. UINT32 TotalLen;
  349. if (pFile == NULL) {
  350. return;
  351. }
  352. for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
  353. if (Item->mId != NULL || Item->mInfoStrList == NULL) {
  354. continue;
  355. }
  356. fprintf (pFile, "\nunsigned char %s%sBlockName[] = {", BaseName, Item->mName);
  357. TotalLen = sizeof (UINT32);
  358. for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
  359. TotalLen += sizeof (UINT16) * 2;
  360. }
  361. Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
  362. for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
  363. fprintf (pFile, "\n");
  364. Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
  365. Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
  366. }
  367. fprintf (pFile, "\n};\n");
  368. }
  369. for (Item = mItemListHead; Item != NULL; Item = Item->mNext) {
  370. if (Item->mId != NULL && Item->mInfoStrList != NULL) {
  371. fprintf (pFile, "\nunsigned char %s%sDefault%s[] = {", BaseName, Item->mName, Item->mId);
  372. TotalLen = sizeof (UINT32);
  373. for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
  374. TotalLen += Info->mWidth + sizeof (UINT16) * 2;
  375. }
  376. Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&TotalLen, sizeof (UINT32));
  377. for (Info = Item->mInfoStrList; Info != NULL; Info = Info->mNext) {
  378. fprintf (pFile, "\n");
  379. Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mOffset, sizeof (UINT16));
  380. Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)&Info->mWidth, sizeof (UINT16));
  381. if (Info->mNext == NULL) {
  382. Output.WriteEnd (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
  383. } else {
  384. Output.WriteLine (pFile, BYTES_PRE_LINE, " ", (CHAR8 *)Info->mValue, Info->mWidth);
  385. }
  386. }
  387. fprintf (pFile, "\n};\n");
  388. }
  389. }
  390. }
  391. CVfrBufferConfig::CVfrBufferConfig (
  392. VOID
  393. )
  394. {
  395. mItemListHead = NULL;
  396. mItemListTail = NULL;
  397. mItemListPos = NULL;
  398. }
  399. CVfrBufferConfig::~CVfrBufferConfig (
  400. VOID
  401. )
  402. {
  403. SConfigItem *p;
  404. while (mItemListHead != NULL) {
  405. p = mItemListHead;
  406. mItemListHead = mItemListHead->mNext;
  407. delete p;
  408. }
  409. mItemListHead = NULL;
  410. mItemListTail = NULL;
  411. mItemListPos = NULL;
  412. }
  413. CVfrBufferConfig gCVfrBufferConfig;
  414. static struct {
  415. CONST CHAR8 *mTypeName;
  416. UINT8 mType;
  417. UINT32 mSize;
  418. UINT32 mAlign;
  419. } gInternalTypesTable [] = {
  420. {"UINT64", EFI_IFR_TYPE_NUM_SIZE_64, sizeof (UINT64), sizeof (UINT64)},
  421. {"UINT32", EFI_IFR_TYPE_NUM_SIZE_32, sizeof (UINT32), sizeof (UINT32)},
  422. {"UINT16", EFI_IFR_TYPE_NUM_SIZE_16, sizeof (UINT16), sizeof (UINT16)},
  423. {"UINT8", EFI_IFR_TYPE_NUM_SIZE_8, sizeof (UINT8), sizeof (UINT8)},
  424. {"BOOLEAN", EFI_IFR_TYPE_BOOLEAN, sizeof (BOOLEAN), sizeof (BOOLEAN)},
  425. {"EFI_HII_DATE", EFI_IFR_TYPE_DATE, sizeof (EFI_HII_DATE), sizeof (UINT16)},
  426. {"EFI_STRING_ID", EFI_IFR_TYPE_STRING, sizeof (EFI_STRING_ID),sizeof (EFI_STRING_ID)},
  427. {"EFI_HII_TIME", EFI_IFR_TYPE_TIME, sizeof (EFI_HII_TIME), sizeof (UINT8)},
  428. {"EFI_HII_REF", EFI_IFR_TYPE_REF, sizeof (EFI_HII_REF), sizeof (EFI_GUID)},
  429. {NULL, EFI_IFR_TYPE_OTHER, 0, 0}
  430. };
  431. STATIC
  432. BOOLEAN
  433. _IS_INTERNAL_TYPE (
  434. IN CHAR8 *TypeName
  435. )
  436. {
  437. UINT32 Index;
  438. if (TypeName == NULL) {
  439. return FALSE;
  440. }
  441. for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
  442. if (strcmp (TypeName, gInternalTypesTable[Index].mTypeName) == 0) {
  443. return TRUE;
  444. }
  445. }
  446. return FALSE;
  447. }
  448. STATIC
  449. CHAR8 *
  450. TrimHex (
  451. IN CHAR8 *Str,
  452. OUT bool *IsHex
  453. )
  454. {
  455. *IsHex = FALSE;
  456. while (*Str && *Str == ' ') {
  457. Str++;
  458. }
  459. while (*Str && *Str == '0') {
  460. Str++;
  461. }
  462. if (*Str && (*Str == 'x' || *Str == 'X')) {
  463. Str++;
  464. *IsHex = TRUE;
  465. }
  466. return Str;
  467. }
  468. UINT32
  469. _STR2U32 (
  470. IN CHAR8 *Str
  471. )
  472. {
  473. bool IsHex;
  474. UINT32 Value;
  475. CHAR8 c;
  476. Str = TrimHex (Str, &IsHex);
  477. for (Value = 0; (c = *Str) != '\0'; Str++) {
  478. //
  479. // BUG: does not handle overflow here
  480. //
  481. (IsHex == TRUE) ? (Value <<= 4) : (Value *= 10);
  482. if ((IsHex == TRUE) && (c >= 'a') && (c <= 'f')) {
  483. Value += (c - 'a' + 10);
  484. }
  485. if ((IsHex == TRUE) && (c >= 'A') && (c <= 'F')) {
  486. Value += (c - 'A' + 10);
  487. }
  488. if (c >= '0' && c <= '9') {
  489. Value += (c - '0');
  490. }
  491. }
  492. return Value;
  493. }
  494. VOID
  495. CVfrVarDataTypeDB::RegisterNewType (
  496. IN SVfrDataType *New
  497. )
  498. {
  499. New->mNext = mDataTypeList;
  500. mDataTypeList = New;
  501. }
  502. EFI_VFR_RETURN_CODE
  503. CVfrVarDataTypeDB::ExtractStructTypeName (
  504. IN CHAR8 *&VarStr,
  505. OUT CHAR8 *TName
  506. )
  507. {
  508. if (TName == NULL) {
  509. return VFR_RETURN_FATAL_ERROR;
  510. }
  511. while((*VarStr != '\0') && (*VarStr != '.')) {
  512. *TName = *VarStr;
  513. VarStr++;
  514. TName++;
  515. }
  516. *TName = '\0';
  517. if (*VarStr == '.') {
  518. VarStr++;
  519. }
  520. return VFR_RETURN_SUCCESS;
  521. }
  522. /**
  523. Check whether the DataType contain bit field.
  524. @param TypeName The name of the type.
  525. **/
  526. BOOLEAN
  527. CVfrVarDataTypeDB::DataTypeHasBitField (
  528. IN CHAR8 *TypeName
  529. )
  530. {
  531. SVfrDataType *pType = NULL;
  532. SVfrDataField *pTmp;
  533. GetDataType (TypeName, &pType);
  534. if (pType == NULL){
  535. return FALSE;
  536. }
  537. for (pTmp = pType->mMembers; pTmp!= NULL; pTmp = pTmp->mNext) {
  538. if (pTmp->mIsBitField) {
  539. return TRUE;
  540. }
  541. }
  542. return FALSE;
  543. }
  544. /**
  545. Check whether the field is bit field or not.
  546. @param VarStr Point to the field name which may contain the structure name.
  547. **/
  548. BOOLEAN
  549. CVfrVarDataTypeDB::IsThisBitField (
  550. IN CHAR8 *VarStr
  551. )
  552. {
  553. CHAR8 FName[MAX_NAME_LEN];
  554. CHAR8 TName[MAX_NAME_LEN];
  555. UINT32 ArrayIdx;
  556. SVfrDataType *pType = NULL;
  557. SVfrDataField *pField = NULL;
  558. CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
  559. CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
  560. while (*VarStr != '\0') {
  561. CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
  562. CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
  563. pType = pField->mFieldType;
  564. }
  565. if (pField != NULL && pField->mIsBitField) {
  566. return TRUE;
  567. } else {
  568. return FALSE;
  569. }
  570. }
  571. EFI_VFR_RETURN_CODE
  572. CVfrVarDataTypeDB::ExtractFieldNameAndArrary (
  573. IN CHAR8 *&VarStr,
  574. IN CHAR8 *FName,
  575. OUT UINT32 &ArrayIdx
  576. )
  577. {
  578. UINT32 Idx;
  579. CHAR8 ArrayStr[MAX_NAME_LEN + 1];
  580. ArrayIdx = INVALID_ARRAY_INDEX;
  581. if (FName == NULL) {
  582. return VFR_RETURN_FATAL_ERROR;
  583. }
  584. while((*VarStr != '\0') &&
  585. (*VarStr != '.') &&
  586. (*VarStr != '[') &&
  587. (*VarStr != ']')) {
  588. *FName = *VarStr;
  589. VarStr++;
  590. FName++;
  591. }
  592. *FName = '\0';
  593. switch (*VarStr) {
  594. case '.' :
  595. VarStr++;
  596. case '\0':
  597. return VFR_RETURN_SUCCESS;
  598. case '[' :
  599. VarStr++;
  600. for (Idx = 0; (Idx < MAX_NAME_LEN) && (*VarStr != '\0') && (*VarStr != ']'); VarStr++, Idx++) {
  601. ArrayStr[Idx] = *VarStr;
  602. }
  603. ArrayStr[Idx] = '\0';
  604. if ((*VarStr != ']') && (ArrayStr[0] == '\0')) {
  605. return VFR_RETURN_DATA_STRING_ERROR;
  606. }
  607. ArrayIdx = _STR2U32 (ArrayStr);
  608. if (*VarStr == ']') {
  609. VarStr++;
  610. }
  611. if (*VarStr == '.') {
  612. VarStr++;
  613. }
  614. return VFR_RETURN_SUCCESS;
  615. case ']':
  616. return VFR_RETURN_DATA_STRING_ERROR;
  617. }
  618. return VFR_RETURN_SUCCESS;
  619. }
  620. EFI_VFR_RETURN_CODE
  621. CVfrVarDataTypeDB::GetTypeField (
  622. IN CONST CHAR8 *FName,
  623. IN SVfrDataType *Type,
  624. OUT SVfrDataField *&Field
  625. )
  626. {
  627. SVfrDataField *pField = NULL;
  628. if ((FName == NULL) || (Type == NULL)) {
  629. return VFR_RETURN_FATAL_ERROR;
  630. }
  631. for (pField = Type->mMembers; pField != NULL; pField = pField->mNext) {
  632. //
  633. // For type EFI_IFR_TYPE_TIME, because field name is not correctly wrote,
  634. // add code to adjust it.
  635. //
  636. if (Type->mType == EFI_IFR_TYPE_TIME) {
  637. if (strcmp (FName, "Hour") == 0) {
  638. FName = "Hours";
  639. } else if (strcmp (FName, "Minute") == 0) {
  640. FName = "Minuts";
  641. } else if (strcmp (FName, "Second") == 0) {
  642. FName = "Seconds";
  643. }
  644. }
  645. if (strcmp (pField->mFieldName, FName) == 0) {
  646. Field = pField;
  647. return VFR_RETURN_SUCCESS;
  648. }
  649. }
  650. return VFR_RETURN_UNDEFINED;
  651. }
  652. EFI_VFR_RETURN_CODE
  653. CVfrVarDataTypeDB::GetFieldOffset (
  654. IN SVfrDataField *Field,
  655. IN UINT32 ArrayIdx,
  656. OUT UINT32 &Offset,
  657. IN BOOLEAN IsBitField
  658. )
  659. {
  660. if (Field == NULL) {
  661. return VFR_RETURN_FATAL_ERROR;
  662. }
  663. //
  664. // Framework Vfr file Array Index is from 1.
  665. // But Uefi Vfr file Array Index is from 0.
  666. //
  667. if (VfrCompatibleMode && ArrayIdx != INVALID_ARRAY_INDEX) {
  668. if (ArrayIdx == 0) {
  669. return VFR_RETURN_ERROR_ARRARY_NUM;
  670. }
  671. ArrayIdx = ArrayIdx - 1;
  672. }
  673. if ((ArrayIdx != INVALID_ARRAY_INDEX) && ((Field->mArrayNum == 0) || (Field->mArrayNum <= ArrayIdx))) {
  674. return VFR_RETURN_ERROR_ARRARY_NUM;
  675. }
  676. //
  677. // Be compatible with the current usage
  678. // If ArraryIdx is not specified, the first one is used.
  679. //
  680. // if ArrayNum is larger than zero, ArraryIdx must be specified.
  681. //
  682. // if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum > 0)) {
  683. // return VFR_RETURN_ERROR_ARRARY_NUM;
  684. // }
  685. //
  686. if (IsBitField) {
  687. Offset = Field->mBitOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx) * 8;
  688. } else {
  689. Offset = Field->mOffset + Field->mFieldType->mTotalSize * ((ArrayIdx == INVALID_ARRAY_INDEX) ? 0 : ArrayIdx);
  690. }
  691. return VFR_RETURN_SUCCESS;
  692. }
  693. UINT8
  694. CVfrVarDataTypeDB::GetFieldWidth (
  695. IN SVfrDataField *Field
  696. )
  697. {
  698. if (Field == NULL) {
  699. return 0;
  700. }
  701. return Field->mFieldType->mType;
  702. }
  703. UINT32
  704. CVfrVarDataTypeDB::GetFieldSize (
  705. IN SVfrDataField *Field,
  706. IN UINT32 ArrayIdx,
  707. IN BOOLEAN BitField
  708. )
  709. {
  710. if (Field == NULL) {
  711. return VFR_RETURN_FATAL_ERROR;
  712. }
  713. if ((ArrayIdx == INVALID_ARRAY_INDEX) && (Field->mArrayNum != 0)) {
  714. return Field->mFieldType->mTotalSize * Field->mArrayNum;
  715. } else {
  716. if (BitField) {
  717. return Field->mBitWidth;
  718. } else {
  719. return Field->mFieldType->mTotalSize;
  720. }
  721. }
  722. }
  723. VOID
  724. CVfrVarDataTypeDB::InternalTypesListInit (
  725. VOID
  726. )
  727. {
  728. SVfrDataType *New = NULL;
  729. UINT32 Index;
  730. for (Index = 0; gInternalTypesTable[Index].mTypeName != NULL; Index++) {
  731. New = new SVfrDataType;
  732. if (New != NULL) {
  733. assert (strlen (gInternalTypesTable[Index].mTypeName) < MAX_NAME_LEN);
  734. strncpy (New->mTypeName, gInternalTypesTable[Index].mTypeName, MAX_NAME_LEN - 1);
  735. New->mTypeName[MAX_NAME_LEN - 1] = 0;
  736. New->mType = gInternalTypesTable[Index].mType;
  737. New->mAlign = gInternalTypesTable[Index].mAlign;
  738. New->mTotalSize = gInternalTypesTable[Index].mSize;
  739. if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_DATE") == 0) {
  740. SVfrDataField *pYearField = new SVfrDataField;
  741. SVfrDataField *pMonthField = new SVfrDataField;
  742. SVfrDataField *pDayField = new SVfrDataField;
  743. strcpy (pYearField->mFieldName, "Year");
  744. GetDataType ((CHAR8 *)"UINT16", &pYearField->mFieldType);
  745. pYearField->mOffset = 0;
  746. pYearField->mNext = pMonthField;
  747. pYearField->mArrayNum = 0;
  748. pYearField->mIsBitField = FALSE;
  749. strcpy (pMonthField->mFieldName, "Month");
  750. GetDataType ((CHAR8 *)"UINT8", &pMonthField->mFieldType);
  751. pMonthField->mOffset = 2;
  752. pMonthField->mNext = pDayField;
  753. pMonthField->mArrayNum = 0;
  754. pMonthField->mIsBitField = FALSE;
  755. strcpy (pDayField->mFieldName, "Day");
  756. GetDataType ((CHAR8 *)"UINT8", &pDayField->mFieldType);
  757. pDayField->mOffset = 3;
  758. pDayField->mNext = NULL;
  759. pDayField->mArrayNum = 0;
  760. pDayField->mIsBitField = FALSE;
  761. New->mMembers = pYearField;
  762. } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_TIME") == 0) {
  763. SVfrDataField *pHoursField = new SVfrDataField;
  764. SVfrDataField *pMinutesField = new SVfrDataField;
  765. SVfrDataField *pSecondsField = new SVfrDataField;
  766. strcpy (pHoursField->mFieldName, "Hours");
  767. GetDataType ((CHAR8 *)"UINT8", &pHoursField->mFieldType);
  768. pHoursField->mOffset = 0;
  769. pHoursField->mNext = pMinutesField;
  770. pHoursField->mArrayNum = 0;
  771. pHoursField->mIsBitField = FALSE;
  772. strcpy (pMinutesField->mFieldName, "Minutes");
  773. GetDataType ((CHAR8 *)"UINT8", &pMinutesField->mFieldType);
  774. pMinutesField->mOffset = 1;
  775. pMinutesField->mNext = pSecondsField;
  776. pMinutesField->mArrayNum = 0;
  777. pMinutesField->mIsBitField = FALSE;
  778. strcpy (pSecondsField->mFieldName, "Seconds");
  779. GetDataType ((CHAR8 *)"UINT8", &pSecondsField->mFieldType);
  780. pSecondsField->mOffset = 2;
  781. pSecondsField->mNext = NULL;
  782. pSecondsField->mArrayNum = 0;
  783. pSecondsField->mIsBitField = FALSE;
  784. New->mMembers = pHoursField;
  785. } else if (strcmp (gInternalTypesTable[Index].mTypeName, "EFI_HII_REF") == 0) {
  786. SVfrDataField *pQuestionIdField = new SVfrDataField;
  787. SVfrDataField *pFormIdField = new SVfrDataField;
  788. SVfrDataField *pFormSetGuidField = new SVfrDataField;
  789. SVfrDataField *pDevicePathField = new SVfrDataField;
  790. strcpy (pQuestionIdField->mFieldName, "QuestionId");
  791. GetDataType ((CHAR8 *)"UINT16", &pQuestionIdField->mFieldType);
  792. pQuestionIdField->mOffset = 0;
  793. pQuestionIdField->mNext = pFormIdField;
  794. pQuestionIdField->mArrayNum = 0;
  795. pQuestionIdField->mIsBitField = FALSE;
  796. strcpy (pFormIdField->mFieldName, "FormId");
  797. GetDataType ((CHAR8 *)"UINT16", &pFormIdField->mFieldType);
  798. pFormIdField->mOffset = 2;
  799. pFormIdField->mNext = pFormSetGuidField;
  800. pFormIdField->mArrayNum = 0;
  801. pFormIdField->mIsBitField = FALSE;
  802. strcpy (pFormSetGuidField->mFieldName, "FormSetGuid");
  803. GetDataType ((CHAR8 *)"EFI_GUID", &pFormSetGuidField->mFieldType);
  804. pFormSetGuidField->mOffset = 4;
  805. pFormSetGuidField->mNext = pDevicePathField;
  806. pFormSetGuidField->mArrayNum = 0;
  807. pFormSetGuidField->mIsBitField = FALSE;
  808. strcpy (pDevicePathField->mFieldName, "DevicePath");
  809. GetDataType ((CHAR8 *)"EFI_STRING_ID", &pDevicePathField->mFieldType);
  810. pDevicePathField->mOffset = 20;
  811. pDevicePathField->mNext = NULL;
  812. pDevicePathField->mArrayNum = 0;
  813. pDevicePathField->mIsBitField = FALSE;
  814. New->mMembers = pQuestionIdField;
  815. } else {
  816. New->mMembers = NULL;
  817. }
  818. New->mNext = NULL;
  819. RegisterNewType (New);
  820. New = NULL;
  821. }
  822. }
  823. }
  824. CVfrVarDataTypeDB::CVfrVarDataTypeDB (
  825. VOID
  826. )
  827. {
  828. mDataTypeList = NULL;
  829. mNewDataType = NULL;
  830. mCurrDataField = NULL;
  831. mPackAlign = DEFAULT_PACK_ALIGN;
  832. mPackStack = NULL;
  833. mFirstNewDataTypeName = NULL;
  834. mCurrDataType = NULL;
  835. InternalTypesListInit ();
  836. }
  837. CVfrVarDataTypeDB::~CVfrVarDataTypeDB (
  838. VOID
  839. )
  840. {
  841. SVfrDataType *pType;
  842. SVfrDataField *pField;
  843. SVfrPackStackNode *pPack;
  844. if (mNewDataType != NULL) {
  845. delete mNewDataType;
  846. }
  847. while (mDataTypeList != NULL) {
  848. pType = mDataTypeList;
  849. mDataTypeList = mDataTypeList->mNext;
  850. while(pType->mMembers != NULL) {
  851. pField = pType->mMembers;
  852. pType->mMembers = pType->mMembers->mNext;
  853. delete pField;
  854. }
  855. delete pType;
  856. }
  857. while (mPackStack != NULL) {
  858. pPack = mPackStack;
  859. mPackStack = mPackStack->mNext;
  860. delete pPack;
  861. }
  862. }
  863. EFI_VFR_RETURN_CODE
  864. CVfrVarDataTypeDB::Pack (
  865. IN UINT32 LineNum,
  866. IN UINT8 Action,
  867. IN CHAR8 *Identifier,
  868. IN UINT32 Number
  869. )
  870. {
  871. UINT32 PackAlign;
  872. CHAR8 Msg[MAX_STRING_LEN] = {0, };
  873. if (Action & VFR_PACK_SHOW) {
  874. sprintf (Msg, "value of pragma pack(show) == %d", mPackAlign);
  875. gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Warning", Msg);
  876. }
  877. if (Action & VFR_PACK_PUSH) {
  878. SVfrPackStackNode *pNew = NULL;
  879. if ((pNew = new SVfrPackStackNode (Identifier, mPackAlign)) == NULL) {
  880. return VFR_RETURN_FATAL_ERROR;
  881. }
  882. pNew->mNext = mPackStack;
  883. mPackStack = pNew;
  884. }
  885. if (Action & VFR_PACK_POP) {
  886. SVfrPackStackNode *pNode = NULL;
  887. if (mPackStack == NULL) {
  888. gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "#pragma pack(pop...) : more pops than pushes");
  889. }
  890. for (pNode = mPackStack; pNode != NULL; pNode = pNode->mNext) {
  891. if (pNode->Match (Identifier) == TRUE) {
  892. mPackAlign = pNode->mNumber;
  893. mPackStack = pNode->mNext;
  894. }
  895. }
  896. }
  897. if (Action & VFR_PACK_ASSIGN) {
  898. PackAlign = (Number > 1) ? Number + Number % 2 : Number;
  899. if ((PackAlign == 0) || (PackAlign > 16)) {
  900. gCVfrErrorHandle.PrintMsg (LineNum, NULL, "Error", "expected pragma parameter to be '1', '2', '4', '8', or '16'");
  901. } else {
  902. mPackAlign = PackAlign;
  903. }
  904. }
  905. return VFR_RETURN_SUCCESS;
  906. }
  907. VOID
  908. CVfrVarDataTypeDB::DeclareDataTypeBegin (
  909. VOID
  910. )
  911. {
  912. SVfrDataType *pNewType = NULL;
  913. pNewType = new SVfrDataType;
  914. pNewType->mTypeName[0] = '\0';
  915. pNewType->mType = EFI_IFR_TYPE_OTHER;
  916. pNewType->mAlign = DEFAULT_ALIGN;
  917. pNewType->mTotalSize = 0;
  918. pNewType->mMembers = NULL;
  919. pNewType->mNext = NULL;
  920. pNewType->mHasBitField = FALSE;
  921. mNewDataType = pNewType;
  922. }
  923. EFI_VFR_RETURN_CODE
  924. CVfrVarDataTypeDB::SetNewTypeName (
  925. IN CHAR8 *TypeName
  926. )
  927. {
  928. SVfrDataType *pType;
  929. if (mNewDataType == NULL) {
  930. return VFR_RETURN_ERROR_SKIPED;
  931. }
  932. if (TypeName == NULL) {
  933. return VFR_RETURN_FATAL_ERROR;
  934. }
  935. if (strlen(TypeName) >= MAX_NAME_LEN) {
  936. return VFR_RETURN_INVALID_PARAMETER;
  937. }
  938. for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
  939. if (strcmp(pType->mTypeName, TypeName) == 0) {
  940. return VFR_RETURN_REDEFINED;
  941. }
  942. }
  943. strncpy(mNewDataType->mTypeName, TypeName, MAX_NAME_LEN - 1);
  944. mNewDataType->mTypeName[MAX_NAME_LEN - 1] = 0;
  945. return VFR_RETURN_SUCCESS;
  946. }
  947. /**
  948. Record the bit field info in the data type.
  949. @param FieldName Point to the field name.
  950. @param TypeName Point to the type name.
  951. @param Width The bit width.
  952. @param FieldInUnion The filed is in Union type or Structure type.
  953. **/
  954. EFI_VFR_RETURN_CODE
  955. CVfrVarDataTypeDB::DataTypeAddBitField (
  956. IN CHAR8 *FieldName,
  957. IN CHAR8 *TypeName,
  958. IN UINT32 Width,
  959. IN BOOLEAN FieldInUnion
  960. )
  961. {
  962. SVfrDataField *pNewField = NULL;
  963. SVfrDataType *pFieldType = NULL;
  964. SVfrDataField *pTmp;
  965. UINT32 Align;
  966. UINT32 MaxDataTypeSize;
  967. BOOLEAN UpdateTotalSize;
  968. CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
  969. if (Width > MAX_BIT_WIDTH) {
  970. return VFR_RETURN_BIT_WIDTH_ERROR;
  971. }
  972. if (Width > pFieldType->mTotalSize * 8) {
  973. return VFR_RETURN_BIT_WIDTH_ERROR;
  974. }
  975. if (FieldName != NULL && strlen (FieldName) >= MAX_NAME_LEN) {
  976. return VFR_RETURN_INVALID_PARAMETER;
  977. }
  978. if (Width == 0 && FieldName != NULL) {
  979. return VFR_RETURN_INVALID_PARAMETER;
  980. }
  981. for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
  982. if (FieldName != NULL && strcmp (pTmp->mFieldName, FieldName) == 0) {
  983. return VFR_RETURN_REDEFINED;
  984. }
  985. }
  986. Align = MIN (mPackAlign, pFieldType->mAlign);
  987. UpdateTotalSize = FALSE;
  988. if ((pNewField = new SVfrDataField) == NULL) {
  989. return VFR_RETURN_OUT_FOR_RESOURCES;
  990. }
  991. MaxDataTypeSize = mNewDataType->mTotalSize;
  992. if (FieldName != NULL) {
  993. strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);
  994. pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;
  995. }
  996. pNewField->mFieldType = pFieldType;
  997. pNewField->mIsBitField = TRUE;
  998. pNewField->mBitWidth = Width;
  999. pNewField->mArrayNum = 0;
  1000. pNewField->mBitOffset = 0;
  1001. pNewField->mOffset = 0;
  1002. if (mNewDataType->mMembers == NULL) {
  1003. mNewDataType->mMembers = pNewField;
  1004. pNewField->mNext = NULL;
  1005. } else {
  1006. for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
  1007. ;
  1008. pTmp->mNext = pNewField;
  1009. pNewField->mNext = NULL;
  1010. }
  1011. if (FieldInUnion) {
  1012. pNewField->mOffset = 0;
  1013. if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
  1014. mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
  1015. }
  1016. } else {
  1017. //
  1018. // Check whether the bit fields can be contained within one FieldType.
  1019. //
  1020. if (pTmp != NULL && pTmp->mIsBitField && strcmp (pTmp->mFieldType->mTypeName, pNewField->mFieldType->mTypeName) == 0 &&
  1021. (pTmp->mBitOffset - pTmp->mOffset * 8) + pTmp->mBitWidth + pNewField->mBitWidth <= pNewField->mFieldType->mTotalSize * 8) {
  1022. pNewField->mBitOffset = pTmp->mBitOffset + pTmp->mBitWidth;
  1023. pNewField->mOffset = pTmp->mOffset;
  1024. //
  1025. // If BitWidth=0,used to force alignment at the next word boundary.
  1026. // So make this bit field occupy the remaing bit width of current field type.
  1027. //
  1028. if (pNewField->mBitWidth == 0) {
  1029. pNewField->mBitWidth = pNewField->mFieldType->mTotalSize * 8 - (pNewField->mBitOffset - pTmp->mOffset * 8);
  1030. }
  1031. } else {
  1032. //
  1033. // The bit filed start a new memory
  1034. //
  1035. pNewField->mBitOffset = mNewDataType->mTotalSize * 8;
  1036. UpdateTotalSize = TRUE;
  1037. }
  1038. }
  1039. if (UpdateTotalSize){
  1040. if ((mNewDataType->mTotalSize % Align) == 0) {
  1041. pNewField->mOffset = mNewDataType->mTotalSize;
  1042. } else {
  1043. pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
  1044. }
  1045. mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize);
  1046. }
  1047. mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
  1048. mNewDataType->mHasBitField = TRUE;
  1049. return VFR_RETURN_SUCCESS;
  1050. }
  1051. EFI_VFR_RETURN_CODE
  1052. CVfrVarDataTypeDB::DataTypeAddField (
  1053. IN CHAR8 *FieldName,
  1054. IN CHAR8 *TypeName,
  1055. IN UINT32 ArrayNum,
  1056. IN BOOLEAN FieldInUnion
  1057. )
  1058. {
  1059. SVfrDataField *pNewField = NULL;
  1060. SVfrDataType *pFieldType = NULL;
  1061. SVfrDataField *pTmp;
  1062. UINT32 Align;
  1063. UINT32 MaxDataTypeSize;
  1064. CHECK_ERROR_RETURN (GetDataType (TypeName, &pFieldType), VFR_RETURN_SUCCESS);
  1065. MaxDataTypeSize = mNewDataType->mTotalSize;
  1066. if (strlen (FieldName) >= MAX_NAME_LEN) {
  1067. return VFR_RETURN_INVALID_PARAMETER;
  1068. }
  1069. for (pTmp = mNewDataType->mMembers; pTmp != NULL; pTmp = pTmp->mNext) {
  1070. if (strcmp (pTmp->mFieldName, FieldName) == 0) {
  1071. return VFR_RETURN_REDEFINED;
  1072. }
  1073. }
  1074. Align = MIN (mPackAlign, pFieldType->mAlign);
  1075. if ((pNewField = new SVfrDataField) == NULL) {
  1076. return VFR_RETURN_OUT_FOR_RESOURCES;
  1077. }
  1078. strncpy (pNewField->mFieldName, FieldName, MAX_NAME_LEN - 1);
  1079. pNewField->mFieldName[MAX_NAME_LEN - 1] = 0;
  1080. pNewField->mFieldType = pFieldType;
  1081. pNewField->mArrayNum = ArrayNum;
  1082. pNewField->mIsBitField = FALSE;
  1083. if ((mNewDataType->mTotalSize % Align) == 0) {
  1084. pNewField->mOffset = mNewDataType->mTotalSize;
  1085. } else {
  1086. pNewField->mOffset = mNewDataType->mTotalSize + ALIGN_STUFF(mNewDataType->mTotalSize, Align);
  1087. }
  1088. if (mNewDataType->mMembers == NULL) {
  1089. mNewDataType->mMembers = pNewField;
  1090. pNewField->mNext = NULL;
  1091. } else {
  1092. for (pTmp = mNewDataType->mMembers; pTmp->mNext != NULL; pTmp = pTmp->mNext)
  1093. ;
  1094. pTmp->mNext = pNewField;
  1095. pNewField->mNext = NULL;
  1096. }
  1097. mNewDataType->mAlign = MIN (mPackAlign, MAX (pFieldType->mAlign, mNewDataType->mAlign));
  1098. if (FieldInUnion) {
  1099. if (MaxDataTypeSize < pNewField->mFieldType->mTotalSize) {
  1100. mNewDataType->mTotalSize = pNewField->mFieldType->mTotalSize;
  1101. }
  1102. pNewField->mOffset = 0;
  1103. } else {
  1104. mNewDataType->mTotalSize = pNewField->mOffset + (pNewField->mFieldType->mTotalSize) * ((ArrayNum == 0) ? 1 : ArrayNum);
  1105. }
  1106. return VFR_RETURN_SUCCESS;
  1107. }
  1108. VOID
  1109. CVfrVarDataTypeDB::DeclareDataTypeEnd (
  1110. VOID
  1111. )
  1112. {
  1113. if (mNewDataType->mTypeName[0] == '\0') {
  1114. return;
  1115. }
  1116. if ((mNewDataType->mTotalSize % mNewDataType->mAlign) !=0) {
  1117. mNewDataType->mTotalSize += ALIGN_STUFF (mNewDataType->mTotalSize, mNewDataType->mAlign);
  1118. }
  1119. RegisterNewType (mNewDataType);
  1120. if (mFirstNewDataTypeName == NULL) {
  1121. mFirstNewDataTypeName = mNewDataType->mTypeName;
  1122. }
  1123. mNewDataType = NULL;
  1124. }
  1125. EFI_VFR_RETURN_CODE
  1126. CVfrVarDataTypeDB::GetDataType (
  1127. IN CHAR8 *TypeName,
  1128. OUT SVfrDataType **DataType
  1129. )
  1130. {
  1131. SVfrDataType *pDataType = NULL;
  1132. if (TypeName == NULL) {
  1133. return VFR_RETURN_ERROR_SKIPED;
  1134. }
  1135. if (DataType == NULL) {
  1136. return VFR_RETURN_FATAL_ERROR;
  1137. }
  1138. *DataType = NULL;
  1139. for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
  1140. if (strcmp (TypeName, pDataType->mTypeName) == 0) {
  1141. *DataType = pDataType;
  1142. return VFR_RETURN_SUCCESS;
  1143. }
  1144. }
  1145. return VFR_RETURN_UNDEFINED;
  1146. }
  1147. EFI_VFR_RETURN_CODE
  1148. CVfrVarDataTypeDB::GetDataTypeSize (
  1149. IN UINT8 DataType,
  1150. OUT UINT32 *Size
  1151. )
  1152. {
  1153. SVfrDataType *pDataType = NULL;
  1154. if (Size == NULL) {
  1155. return VFR_RETURN_FATAL_ERROR;
  1156. }
  1157. *Size = 0;
  1158. DataType = DataType & 0x0F;
  1159. //
  1160. // For user defined data type, the size can't be got by this function.
  1161. //
  1162. if (DataType == EFI_IFR_TYPE_OTHER) {
  1163. return VFR_RETURN_SUCCESS;
  1164. }
  1165. for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
  1166. if (DataType == pDataType->mType) {
  1167. *Size = pDataType->mTotalSize;
  1168. return VFR_RETURN_SUCCESS;
  1169. }
  1170. }
  1171. return VFR_RETURN_UNDEFINED;
  1172. }
  1173. EFI_VFR_RETURN_CODE
  1174. CVfrVarDataTypeDB::GetDataTypeSize (
  1175. IN CHAR8 *TypeName,
  1176. OUT UINT32 *Size
  1177. )
  1178. {
  1179. SVfrDataType *pDataType = NULL;
  1180. if (Size == NULL) {
  1181. return VFR_RETURN_FATAL_ERROR;
  1182. }
  1183. *Size = 0;
  1184. for (pDataType = mDataTypeList; pDataType != NULL; pDataType = pDataType->mNext) {
  1185. if (strcmp (TypeName, pDataType->mTypeName) == 0) {
  1186. *Size = pDataType->mTotalSize;
  1187. return VFR_RETURN_SUCCESS;
  1188. }
  1189. }
  1190. return VFR_RETURN_UNDEFINED;
  1191. }
  1192. EFI_VFR_RETURN_CODE
  1193. CVfrVarDataTypeDB::GetDataFieldInfo (
  1194. IN CHAR8 *VarStr,
  1195. OUT UINT16 &Offset,
  1196. OUT UINT8 &Type,
  1197. OUT UINT32 &Size,
  1198. OUT BOOLEAN &BitField
  1199. )
  1200. {
  1201. CHAR8 TName[MAX_NAME_LEN], FName[MAX_NAME_LEN];
  1202. UINT32 ArrayIdx, Tmp;
  1203. SVfrDataType *pType = NULL;
  1204. SVfrDataField *pField = NULL;
  1205. CHAR8 *VarStrName;
  1206. Offset = 0;
  1207. Type = EFI_IFR_TYPE_OTHER;
  1208. Size = 0;
  1209. VarStrName = VarStr;
  1210. CHECK_ERROR_RETURN (ExtractStructTypeName (VarStr, TName), VFR_RETURN_SUCCESS);
  1211. CHECK_ERROR_RETURN (GetDataType (TName, &pType), VFR_RETURN_SUCCESS);
  1212. BitField = IsThisBitField (VarStrName);
  1213. //
  1214. // if it is not struct data type
  1215. //
  1216. Type = pType->mType;
  1217. Size = pType->mTotalSize;
  1218. while (*VarStr != '\0') {
  1219. CHECK_ERROR_RETURN(ExtractFieldNameAndArrary(VarStr, FName, ArrayIdx), VFR_RETURN_SUCCESS);
  1220. CHECK_ERROR_RETURN(GetTypeField (FName, pType, pField), VFR_RETURN_SUCCESS);
  1221. pType = pField->mFieldType;
  1222. CHECK_ERROR_RETURN(GetFieldOffset (pField, ArrayIdx, Tmp, pField->mIsBitField), VFR_RETURN_SUCCESS);
  1223. if (BitField && !pField->mIsBitField) {
  1224. Offset = (UINT16) (Offset + Tmp * 8);
  1225. } else {
  1226. Offset = (UINT16) (Offset + Tmp);
  1227. }
  1228. Type = GetFieldWidth (pField);
  1229. Size = GetFieldSize (pField, ArrayIdx, BitField);
  1230. }
  1231. return VFR_RETURN_SUCCESS;
  1232. }
  1233. EFI_VFR_RETURN_CODE
  1234. CVfrVarDataTypeDB::GetUserDefinedTypeNameList (
  1235. OUT CHAR8 ***NameList,
  1236. OUT UINT32 *ListSize
  1237. )
  1238. {
  1239. UINT32 Index;
  1240. SVfrDataType *pType;
  1241. if ((NameList == NULL) || (ListSize == NULL)) {
  1242. return VFR_RETURN_FATAL_ERROR;
  1243. }
  1244. *NameList = NULL;
  1245. *ListSize = 0;
  1246. for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
  1247. if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
  1248. (*ListSize)++;
  1249. }
  1250. }
  1251. if (*ListSize == 0) {
  1252. return VFR_RETURN_SUCCESS;
  1253. }
  1254. if ((*NameList = new CHAR8*[*ListSize]) == NULL) {
  1255. *ListSize = 0;
  1256. return VFR_RETURN_OUT_FOR_RESOURCES;
  1257. }
  1258. for (Index = 0, pType = mDataTypeList; pType != NULL; pType = pType->mNext, Index++) {
  1259. if (_IS_INTERNAL_TYPE(pType->mTypeName) == FALSE) {
  1260. (*NameList)[Index] = pType->mTypeName;
  1261. }
  1262. }
  1263. return VFR_RETURN_SUCCESS;
  1264. }
  1265. BOOLEAN
  1266. CVfrVarDataTypeDB::IsTypeNameDefined (
  1267. IN CHAR8 *TypeName
  1268. )
  1269. {
  1270. SVfrDataType *pType;
  1271. if (TypeName == NULL) {
  1272. return FALSE;
  1273. }
  1274. for (pType = mDataTypeList; pType != NULL; pType = pType->mNext) {
  1275. if (strcmp (pType->mTypeName, TypeName) == 0) {
  1276. return TRUE;
  1277. }
  1278. }
  1279. return FALSE;
  1280. }
  1281. VOID
  1282. CVfrVarDataTypeDB::Dump (
  1283. IN FILE *File
  1284. )
  1285. {
  1286. SVfrDataType *pTNode;
  1287. SVfrDataField *pFNode;
  1288. fprintf (File, "\n\n***************************************************************\n");
  1289. fprintf (File, "\t\tmPackAlign = %x\n", mPackAlign);
  1290. for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
  1291. fprintf (File, "\t\tstruct %s : mAlign [%d] mTotalSize [0x%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
  1292. fprintf (File, "\t\tstruct %s {\n", pTNode->mTypeName);
  1293. for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
  1294. if (pFNode->mArrayNum > 0) {
  1295. fprintf (File, "\t\t\t+%08d[%08x] %s[%d] <%s>\n", pFNode->mOffset, pFNode->mOffset,
  1296. pFNode->mFieldName, pFNode->mArrayNum, pFNode->mFieldType->mTypeName);
  1297. } else {
  1298. fprintf (File, "\t\t\t+%08d[%08x] %s <%s>\n", pFNode->mOffset, pFNode->mOffset,
  1299. pFNode->mFieldName, pFNode->mFieldType->mTypeName);
  1300. }
  1301. }
  1302. fprintf (File, "\t\t};\n");
  1303. fprintf (File, "---------------------------------------------------------------\n");
  1304. }
  1305. fprintf (File, "***************************************************************\n");
  1306. }
  1307. #ifdef CVFR_VARDATATYPEDB_DEBUG
  1308. VOID
  1309. CVfrVarDataTypeDB::ParserDB (
  1310. VOID
  1311. )
  1312. {
  1313. SVfrDataType *pTNode;
  1314. SVfrDataField *pFNode;
  1315. printf ("***************************************************************\n");
  1316. printf ("\t\tmPackAlign = %x\n", mPackAlign);
  1317. for (pTNode = mDataTypeList; pTNode != NULL; pTNode = pTNode->mNext) {
  1318. printf ("\t\tstruct %s : mAlign [%x] mTotalSize [%x]\n\n", pTNode->mTypeName, pTNode->mAlign, pTNode->mTotalSize);
  1319. printf ("\t\tstruct %s {\n", pTNode->mTypeName);
  1320. for (pFNode = pTNode->mMembers; pFNode != NULL; pFNode = pFNode->mNext) {
  1321. printf ("\t\t\t%s\t%s\n", pFNode->mFieldType->mTypeName, pFNode->mFieldName);
  1322. }
  1323. printf ("\t\t};\n");
  1324. printf ("---------------------------------------------------------------\n");
  1325. }
  1326. printf ("***************************************************************\n");
  1327. }
  1328. #endif
  1329. SVfrVarStorageNode::SVfrVarStorageNode (
  1330. IN EFI_GUID *Guid,
  1331. IN CHAR8 *StoreName,
  1332. IN EFI_VARSTORE_ID VarStoreId,
  1333. IN EFI_STRING_ID VarName,
  1334. IN UINT32 VarSize,
  1335. IN BOOLEAN Flag
  1336. )
  1337. {
  1338. if (Guid != NULL) {
  1339. mGuid = *Guid;
  1340. } else {
  1341. memset (&mGuid, 0, sizeof (EFI_GUID));
  1342. }
  1343. if (StoreName != NULL) {
  1344. mVarStoreName = new CHAR8[strlen(StoreName) + 1];
  1345. strcpy (mVarStoreName, StoreName);
  1346. } else {
  1347. mVarStoreName = NULL;
  1348. }
  1349. mNext = NULL;
  1350. mVarStoreId = VarStoreId;
  1351. mVarStoreType = EFI_VFR_VARSTORE_EFI;
  1352. mStorageInfo.mEfiVar.mEfiVarName = VarName;
  1353. mStorageInfo.mEfiVar.mEfiVarSize = VarSize;
  1354. mAssignedFlag = Flag;
  1355. }
  1356. SVfrVarStorageNode::SVfrVarStorageNode (
  1357. IN EFI_GUID *Guid,
  1358. IN CHAR8 *StoreName,
  1359. IN EFI_VARSTORE_ID VarStoreId,
  1360. IN SVfrDataType *DataType,
  1361. IN BOOLEAN BitsVarstore,
  1362. IN BOOLEAN Flag
  1363. )
  1364. {
  1365. if (Guid != NULL) {
  1366. mGuid = *Guid;
  1367. } else {
  1368. memset (&mGuid, 0, sizeof (EFI_GUID));
  1369. }
  1370. if (StoreName != NULL) {
  1371. mVarStoreName = new CHAR8[strlen(StoreName) + 1];
  1372. strcpy (mVarStoreName, StoreName);
  1373. } else {
  1374. mVarStoreName = NULL;
  1375. }
  1376. mNext = NULL;
  1377. mVarStoreId = VarStoreId;
  1378. if (BitsVarstore) {
  1379. mVarStoreType = EFI_VFR_VARSTORE_BUFFER_BITS;
  1380. } else {
  1381. mVarStoreType = EFI_VFR_VARSTORE_BUFFER;
  1382. }
  1383. mStorageInfo.mDataType = DataType;
  1384. mAssignedFlag = Flag;
  1385. }
  1386. SVfrVarStorageNode::SVfrVarStorageNode (
  1387. IN CHAR8 *StoreName,
  1388. IN EFI_VARSTORE_ID VarStoreId
  1389. )
  1390. {
  1391. memset (&mGuid, 0, sizeof (EFI_GUID));
  1392. if (StoreName != NULL) {
  1393. mVarStoreName = new CHAR8[strlen(StoreName) + 1];
  1394. strcpy (mVarStoreName, StoreName);
  1395. } else {
  1396. mVarStoreName = NULL;
  1397. }
  1398. mNext = NULL;
  1399. mVarStoreId = VarStoreId;
  1400. mVarStoreType = EFI_VFR_VARSTORE_NAME;
  1401. mStorageInfo.mNameSpace.mNameTable = new EFI_VARSTORE_ID[DEFAULT_NAME_TABLE_ITEMS];
  1402. mStorageInfo.mNameSpace.mTableSize = 0;
  1403. mAssignedFlag = FALSE;
  1404. }
  1405. SVfrVarStorageNode::~SVfrVarStorageNode (
  1406. VOID
  1407. )
  1408. {
  1409. if (mVarStoreName != NULL) {
  1410. delete[] mVarStoreName;
  1411. }
  1412. if (mVarStoreType == EFI_VFR_VARSTORE_NAME) {
  1413. delete[] mStorageInfo.mNameSpace.mNameTable;
  1414. }
  1415. }
  1416. CVfrDataStorage::CVfrDataStorage (
  1417. VOID
  1418. )
  1419. {
  1420. UINT32 Index;
  1421. for (Index = 0; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
  1422. mFreeVarStoreIdBitMap[Index] = 0;
  1423. }
  1424. // Question ID 0 is reserved.
  1425. mFreeVarStoreIdBitMap[0] = 0x80000000;
  1426. mBufferVarStoreList = NULL;
  1427. mEfiVarStoreList = NULL;
  1428. mNameVarStoreList = NULL;
  1429. mCurrVarStorageNode = NULL;
  1430. mNewVarStorageNode = NULL;
  1431. mBufferFieldInfoListHead = NULL;
  1432. mBufferFieldInfoListTail = NULL;
  1433. }
  1434. CVfrDataStorage::~CVfrDataStorage (
  1435. VOID
  1436. )
  1437. {
  1438. SVfrVarStorageNode *pNode;
  1439. while (mBufferVarStoreList != NULL) {
  1440. pNode = mBufferVarStoreList;
  1441. mBufferVarStoreList = mBufferVarStoreList->mNext;
  1442. delete pNode;
  1443. }
  1444. while (mEfiVarStoreList != NULL) {
  1445. pNode = mEfiVarStoreList;
  1446. mEfiVarStoreList = mEfiVarStoreList->mNext;
  1447. delete pNode;
  1448. }
  1449. while (mNameVarStoreList != NULL) {
  1450. pNode = mNameVarStoreList;
  1451. mNameVarStoreList = mNameVarStoreList->mNext;
  1452. delete pNode;
  1453. }
  1454. if (mNewVarStorageNode != NULL) {
  1455. delete mNewVarStorageNode;
  1456. }
  1457. }
  1458. EFI_VARSTORE_ID
  1459. CVfrDataStorage::GetFreeVarStoreId (
  1460. EFI_VFR_VARSTORE_TYPE VarType
  1461. )
  1462. {
  1463. UINT32 Index, Mask, Offset;
  1464. //
  1465. // Assign the different ID range for the different type VarStore to support Framework Vfr
  1466. //
  1467. Index = 0;
  1468. if ((!VfrCompatibleMode) || (VarType == EFI_VFR_VARSTORE_BUFFER)) {
  1469. Index = 0;
  1470. } else if (VarType == EFI_VFR_VARSTORE_EFI) {
  1471. Index = 1;
  1472. } else if (VarType == EFI_VFR_VARSTORE_NAME) {
  1473. Index = 2;
  1474. }
  1475. for (; Index < EFI_FREE_VARSTORE_ID_BITMAP_SIZE; Index++) {
  1476. if (mFreeVarStoreIdBitMap[Index] != 0xFFFFFFFF) {
  1477. break;
  1478. }
  1479. }
  1480. if (Index == EFI_FREE_VARSTORE_ID_BITMAP_SIZE) {
  1481. return EFI_VARSTORE_ID_INVALID;
  1482. }
  1483. for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
  1484. if ((mFreeVarStoreIdBitMap[Index] & Mask) == 0) {
  1485. mFreeVarStoreIdBitMap[Index] |= Mask;
  1486. return (EFI_VARSTORE_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
  1487. }
  1488. }
  1489. return EFI_VARSTORE_ID_INVALID;
  1490. }
  1491. BOOLEAN
  1492. CVfrDataStorage::ChekVarStoreIdFree (
  1493. IN EFI_VARSTORE_ID VarStoreId
  1494. )
  1495. {
  1496. UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
  1497. UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
  1498. return (mFreeVarStoreIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
  1499. }
  1500. VOID
  1501. CVfrDataStorage::MarkVarStoreIdUsed (
  1502. IN EFI_VARSTORE_ID VarStoreId
  1503. )
  1504. {
  1505. UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
  1506. UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
  1507. mFreeVarStoreIdBitMap[Index] |= (0x80000000 >> Offset);
  1508. }
  1509. VOID
  1510. CVfrDataStorage::MarkVarStoreIdUnused (
  1511. IN EFI_VARSTORE_ID VarStoreId
  1512. )
  1513. {
  1514. UINT32 Index = (VarStoreId / EFI_BITS_PER_UINT32);
  1515. UINT32 Offset = (VarStoreId % EFI_BITS_PER_UINT32);
  1516. mFreeVarStoreIdBitMap[Index] &= ~(0x80000000 >> Offset);
  1517. }
  1518. EFI_VFR_RETURN_CODE
  1519. CVfrDataStorage::DeclareNameVarStoreBegin (
  1520. IN CHAR8 *StoreName,
  1521. IN EFI_VARSTORE_ID VarStoreId
  1522. )
  1523. {
  1524. SVfrVarStorageNode *pNode = NULL;
  1525. EFI_VARSTORE_ID TmpVarStoreId;
  1526. if (StoreName == NULL) {
  1527. return VFR_RETURN_FATAL_ERROR;
  1528. }
  1529. if (GetVarStoreId (StoreName, &TmpVarStoreId) == VFR_RETURN_SUCCESS) {
  1530. return VFR_RETURN_REDEFINED;
  1531. }
  1532. if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
  1533. VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_NAME);
  1534. } else {
  1535. if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
  1536. return VFR_RETURN_VARSTOREID_REDEFINED;
  1537. }
  1538. MarkVarStoreIdUsed (VarStoreId);
  1539. }
  1540. if ((pNode = new SVfrVarStorageNode (StoreName, VarStoreId)) == NULL) {
  1541. return VFR_RETURN_UNDEFINED;
  1542. }
  1543. mNewVarStorageNode = pNode;
  1544. return VFR_RETURN_SUCCESS;
  1545. }
  1546. EFI_VFR_RETURN_CODE
  1547. CVfrDataStorage::NameTableAddItem (
  1548. IN EFI_STRING_ID Item
  1549. )
  1550. {
  1551. EFI_VARSTORE_ID *NewTable, *OldTable;
  1552. UINT32 TableSize;
  1553. OldTable = mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable;
  1554. TableSize = mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize;
  1555. if ((TableSize != 0) && ((TableSize % DEFAULT_NAME_TABLE_ITEMS) == 0)) {
  1556. if ((NewTable = new EFI_VARSTORE_ID[TableSize + DEFAULT_NAME_TABLE_ITEMS]) == NULL) {
  1557. return VFR_RETURN_OUT_FOR_RESOURCES;
  1558. }
  1559. memcpy (NewTable, OldTable, TableSize);
  1560. mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable = NewTable;
  1561. }
  1562. mNewVarStorageNode->mStorageInfo.mNameSpace.mNameTable[TableSize++] = Item;
  1563. mNewVarStorageNode->mStorageInfo.mNameSpace.mTableSize = TableSize;
  1564. return VFR_RETURN_SUCCESS;
  1565. }
  1566. EFI_VFR_RETURN_CODE
  1567. CVfrDataStorage::DeclareNameVarStoreEnd (
  1568. IN EFI_GUID *Guid
  1569. )
  1570. {
  1571. mNewVarStorageNode->mGuid = *Guid;
  1572. mNewVarStorageNode->mNext = mNameVarStoreList;
  1573. mNameVarStoreList = mNewVarStorageNode;
  1574. mNewVarStorageNode = NULL;
  1575. return VFR_RETURN_SUCCESS;
  1576. }
  1577. EFI_VFR_RETURN_CODE
  1578. CVfrDataStorage::DeclareEfiVarStore (
  1579. IN CHAR8 *StoreName,
  1580. IN EFI_GUID *Guid,
  1581. IN EFI_STRING_ID NameStrId,
  1582. IN UINT32 VarSize,
  1583. IN BOOLEAN Flag
  1584. )
  1585. {
  1586. SVfrVarStorageNode *pNode;
  1587. EFI_VARSTORE_ID VarStoreId;
  1588. if ((StoreName == NULL) || (Guid == NULL)) {
  1589. return VFR_RETURN_FATAL_ERROR;
  1590. }
  1591. if (VarSize > sizeof (UINT64)) {
  1592. return VFR_RETURN_EFIVARSTORE_SIZE_ERROR;
  1593. }
  1594. if (GetVarStoreId (StoreName, &VarStoreId, Guid) == VFR_RETURN_SUCCESS) {
  1595. return VFR_RETURN_REDEFINED;
  1596. }
  1597. VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_EFI);
  1598. if ((pNode = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, NameStrId, VarSize, Flag)) == NULL) {
  1599. return VFR_RETURN_OUT_FOR_RESOURCES;
  1600. }
  1601. pNode->mNext = mEfiVarStoreList;
  1602. mEfiVarStoreList = pNode;
  1603. return VFR_RETURN_SUCCESS;
  1604. }
  1605. EFI_VFR_RETURN_CODE
  1606. CVfrDataStorage::DeclareBufferVarStore (
  1607. IN CHAR8 *StoreName,
  1608. IN EFI_GUID *Guid,
  1609. IN CVfrVarDataTypeDB *DataTypeDB,
  1610. IN CHAR8 *TypeName,
  1611. IN EFI_VARSTORE_ID VarStoreId,
  1612. IN BOOLEAN IsBitVarStore,
  1613. IN BOOLEAN Flag
  1614. )
  1615. {
  1616. SVfrVarStorageNode *pNew = NULL;
  1617. SVfrDataType *pDataType = NULL;
  1618. EFI_VARSTORE_ID TempVarStoreId;
  1619. if ((StoreName == NULL) || (Guid == NULL) || (DataTypeDB == NULL)) {
  1620. return VFR_RETURN_FATAL_ERROR;
  1621. }
  1622. if (GetVarStoreId (StoreName, &TempVarStoreId, Guid) == VFR_RETURN_SUCCESS) {
  1623. return VFR_RETURN_REDEFINED;
  1624. }
  1625. CHECK_ERROR_RETURN(DataTypeDB->GetDataType (TypeName, &pDataType), VFR_RETURN_SUCCESS);
  1626. if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
  1627. VarStoreId = GetFreeVarStoreId (EFI_VFR_VARSTORE_BUFFER);
  1628. } else {
  1629. if (ChekVarStoreIdFree (VarStoreId) == FALSE) {
  1630. return VFR_RETURN_VARSTOREID_REDEFINED;
  1631. }
  1632. MarkVarStoreIdUsed (VarStoreId);
  1633. }
  1634. if ((pNew = new SVfrVarStorageNode (Guid, StoreName, VarStoreId, pDataType, IsBitVarStore, Flag)) == NULL) {
  1635. return VFR_RETURN_OUT_FOR_RESOURCES;
  1636. }
  1637. pNew->mNext = mBufferVarStoreList;
  1638. mBufferVarStoreList = pNew;
  1639. if (gCVfrBufferConfig.Register(StoreName, Guid) != 0) {
  1640. return VFR_RETURN_FATAL_ERROR;
  1641. }
  1642. return VFR_RETURN_SUCCESS;
  1643. }
  1644. EFI_VFR_RETURN_CODE
  1645. CVfrDataStorage::GetVarStoreByDataType (
  1646. IN CHAR8 *DataTypeName,
  1647. OUT SVfrVarStorageNode **VarNode,
  1648. IN EFI_GUID *VarGuid
  1649. )
  1650. {
  1651. SVfrVarStorageNode *pNode;
  1652. SVfrVarStorageNode *MatchNode;
  1653. //
  1654. // Framework VFR uses Data type name as varstore name, so don't need check again.
  1655. //
  1656. if (VfrCompatibleMode) {
  1657. return VFR_RETURN_UNDEFINED;
  1658. }
  1659. MatchNode = NULL;
  1660. for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1661. if (strcmp (pNode->mStorageInfo.mDataType->mTypeName, DataTypeName) != 0) {
  1662. continue;
  1663. }
  1664. if ((VarGuid != NULL)) {
  1665. if (memcmp (VarGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
  1666. *VarNode = pNode;
  1667. return VFR_RETURN_SUCCESS;
  1668. }
  1669. } else {
  1670. if (MatchNode == NULL) {
  1671. MatchNode = pNode;
  1672. } else {
  1673. //
  1674. // More than one varstores referred the same data structures.
  1675. //
  1676. return VFR_RETURN_VARSTORE_DATATYPE_REDEFINED_ERROR;
  1677. }
  1678. }
  1679. }
  1680. if (MatchNode == NULL) {
  1681. return VFR_RETURN_UNDEFINED;
  1682. }
  1683. *VarNode = MatchNode;
  1684. return VFR_RETURN_SUCCESS;
  1685. }
  1686. EFI_VARSTORE_ID
  1687. CVfrDataStorage::CheckGuidField (
  1688. IN SVfrVarStorageNode *pNode,
  1689. IN EFI_GUID *StoreGuid,
  1690. IN BOOLEAN *HasFoundOne,
  1691. OUT EFI_VFR_RETURN_CODE *ReturnCode
  1692. )
  1693. {
  1694. if (StoreGuid != NULL) {
  1695. //
  1696. // If has guid info, compare the guid filed.
  1697. //
  1698. if (memcmp (StoreGuid, &pNode->mGuid, sizeof (EFI_GUID)) == 0) {
  1699. //
  1700. // Both name and guid are same, this this varstore.
  1701. //
  1702. mCurrVarStorageNode = pNode;
  1703. *ReturnCode = VFR_RETURN_SUCCESS;
  1704. return TRUE;
  1705. }
  1706. } else {
  1707. //
  1708. // Not has Guid field, check whether this name is the only one.
  1709. //
  1710. if (*HasFoundOne) {
  1711. //
  1712. // The name has conflict, return name redefined.
  1713. //
  1714. *ReturnCode = VFR_RETURN_VARSTORE_NAME_REDEFINED_ERROR;
  1715. return TRUE;
  1716. }
  1717. *HasFoundOne = TRUE;
  1718. mCurrVarStorageNode = pNode;
  1719. }
  1720. return FALSE;
  1721. }
  1722. /**
  1723. Base on the input store name and guid to find the varstore id.
  1724. If both name and guid are inputed, base on the name and guid to
  1725. found the varstore. If only name inputed, base on the name to
  1726. found the varstore and go on to check whether more than one varstore
  1727. has the same name. If only has found one varstore, return this
  1728. varstore; if more than one varstore has same name, return varstore
  1729. name redefined error. If no varstore found by varstore name, call
  1730. function GetVarStoreByDataType and use inputed varstore name as
  1731. data type name to search.
  1732. **/
  1733. EFI_VFR_RETURN_CODE
  1734. CVfrDataStorage::GetVarStoreId (
  1735. IN CHAR8 *StoreName,
  1736. OUT EFI_VARSTORE_ID *VarStoreId,
  1737. IN EFI_GUID *StoreGuid
  1738. )
  1739. {
  1740. EFI_VFR_RETURN_CODE ReturnCode;
  1741. SVfrVarStorageNode *pNode;
  1742. BOOLEAN HasFoundOne = FALSE;
  1743. mCurrVarStorageNode = NULL;
  1744. for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1745. if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
  1746. if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
  1747. *VarStoreId = mCurrVarStorageNode->mVarStoreId;
  1748. return ReturnCode;
  1749. }
  1750. }
  1751. }
  1752. for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1753. if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
  1754. if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
  1755. *VarStoreId = mCurrVarStorageNode->mVarStoreId;
  1756. return ReturnCode;
  1757. }
  1758. }
  1759. }
  1760. for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1761. if (strcmp (pNode->mVarStoreName, StoreName) == 0) {
  1762. if (CheckGuidField(pNode, StoreGuid, &HasFoundOne, &ReturnCode)) {
  1763. *VarStoreId = mCurrVarStorageNode->mVarStoreId;
  1764. return ReturnCode;
  1765. }
  1766. }
  1767. }
  1768. if (HasFoundOne) {
  1769. *VarStoreId = mCurrVarStorageNode->mVarStoreId;
  1770. return VFR_RETURN_SUCCESS;
  1771. }
  1772. *VarStoreId = EFI_VARSTORE_ID_INVALID;
  1773. //
  1774. // Assume that Data structure name is used as StoreName, and check again.
  1775. //
  1776. ReturnCode = GetVarStoreByDataType (StoreName, &pNode, StoreGuid);
  1777. if (pNode != NULL) {
  1778. mCurrVarStorageNode = pNode;
  1779. *VarStoreId = pNode->mVarStoreId;
  1780. }
  1781. return ReturnCode;
  1782. }
  1783. EFI_VFR_RETURN_CODE
  1784. CVfrDataStorage::GetBufferVarStoreDataTypeName (
  1785. IN EFI_VARSTORE_ID VarStoreId,
  1786. OUT CHAR8 **DataTypeName
  1787. )
  1788. {
  1789. SVfrVarStorageNode *pNode;
  1790. if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
  1791. return VFR_RETURN_FATAL_ERROR;
  1792. }
  1793. for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1794. if (pNode->mVarStoreId == VarStoreId) {
  1795. *DataTypeName = pNode->mStorageInfo.mDataType->mTypeName;
  1796. return VFR_RETURN_SUCCESS;
  1797. }
  1798. }
  1799. return VFR_RETURN_UNDEFINED;
  1800. }
  1801. EFI_VFR_VARSTORE_TYPE
  1802. CVfrDataStorage::GetVarStoreType (
  1803. IN EFI_VARSTORE_ID VarStoreId
  1804. )
  1805. {
  1806. SVfrVarStorageNode *pNode;
  1807. EFI_VFR_VARSTORE_TYPE VarStoreType;
  1808. VarStoreType = EFI_VFR_VARSTORE_INVALID;
  1809. if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
  1810. return VarStoreType;
  1811. }
  1812. for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1813. if (pNode->mVarStoreId == VarStoreId) {
  1814. VarStoreType = pNode->mVarStoreType;
  1815. return VarStoreType;
  1816. }
  1817. }
  1818. for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1819. if (pNode->mVarStoreId == VarStoreId) {
  1820. VarStoreType = pNode->mVarStoreType;
  1821. return VarStoreType;
  1822. }
  1823. }
  1824. for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1825. if (pNode->mVarStoreId == VarStoreId) {
  1826. VarStoreType = pNode->mVarStoreType;
  1827. return VarStoreType;
  1828. }
  1829. }
  1830. return VarStoreType;
  1831. }
  1832. EFI_GUID *
  1833. CVfrDataStorage::GetVarStoreGuid (
  1834. IN EFI_VARSTORE_ID VarStoreId
  1835. )
  1836. {
  1837. SVfrVarStorageNode *pNode;
  1838. EFI_GUID *VarGuid;
  1839. VarGuid = NULL;
  1840. if (VarStoreId == EFI_VARSTORE_ID_INVALID) {
  1841. return VarGuid;
  1842. }
  1843. for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1844. if (pNode->mVarStoreId == VarStoreId) {
  1845. VarGuid = &pNode->mGuid;
  1846. return VarGuid;
  1847. }
  1848. }
  1849. for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1850. if (pNode->mVarStoreId == VarStoreId) {
  1851. VarGuid = &pNode->mGuid;
  1852. return VarGuid;
  1853. }
  1854. }
  1855. for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1856. if (pNode->mVarStoreId == VarStoreId) {
  1857. VarGuid = &pNode->mGuid;
  1858. return VarGuid;
  1859. }
  1860. }
  1861. return VarGuid;
  1862. }
  1863. EFI_VFR_RETURN_CODE
  1864. CVfrDataStorage::GetVarStoreName (
  1865. IN EFI_VARSTORE_ID VarStoreId,
  1866. OUT CHAR8 **VarStoreName
  1867. )
  1868. {
  1869. SVfrVarStorageNode *pNode;
  1870. if (VarStoreName == NULL) {
  1871. return VFR_RETURN_FATAL_ERROR;
  1872. }
  1873. for (pNode = mBufferVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1874. if (pNode->mVarStoreId == VarStoreId) {
  1875. *VarStoreName = pNode->mVarStoreName;
  1876. return VFR_RETURN_SUCCESS;
  1877. }
  1878. }
  1879. for (pNode = mEfiVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1880. if (pNode->mVarStoreId == VarStoreId) {
  1881. *VarStoreName = pNode->mVarStoreName;
  1882. return VFR_RETURN_SUCCESS;
  1883. }
  1884. }
  1885. for (pNode = mNameVarStoreList; pNode != NULL; pNode = pNode->mNext) {
  1886. if (pNode->mVarStoreId == VarStoreId) {
  1887. *VarStoreName = pNode->mVarStoreName;
  1888. return VFR_RETURN_SUCCESS;
  1889. }
  1890. }
  1891. *VarStoreName = NULL;
  1892. return VFR_RETURN_UNDEFINED;
  1893. }
  1894. EFI_VFR_RETURN_CODE
  1895. CVfrDataStorage::GetEfiVarStoreInfo (
  1896. IN OUT EFI_VARSTORE_INFO *Info
  1897. )
  1898. {
  1899. if (Info == NULL) {
  1900. return VFR_RETURN_FATAL_ERROR;
  1901. }
  1902. if (mCurrVarStorageNode == NULL) {
  1903. return VFR_RETURN_GET_EFIVARSTORE_ERROR;
  1904. }
  1905. Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarName;
  1906. Info->mVarTotalSize = mCurrVarStorageNode->mStorageInfo.mEfiVar.mEfiVarSize;
  1907. switch (Info->mVarTotalSize) {
  1908. case 1:
  1909. Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_8;
  1910. break;
  1911. case 2:
  1912. Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_16;
  1913. break;
  1914. case 4:
  1915. Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_32;
  1916. break;
  1917. case 8:
  1918. Info->mVarType = EFI_IFR_TYPE_NUM_SIZE_64;
  1919. break;
  1920. default :
  1921. return VFR_RETURN_FATAL_ERROR;
  1922. }
  1923. return VFR_RETURN_SUCCESS;
  1924. }
  1925. EFI_VFR_RETURN_CODE
  1926. CVfrDataStorage::AddBufferVarStoreFieldInfo (
  1927. IN EFI_VARSTORE_INFO *Info
  1928. )
  1929. {
  1930. BufferVarStoreFieldInfoNode *pNew;
  1931. if ((pNew = new BufferVarStoreFieldInfoNode(Info)) == NULL) {
  1932. return VFR_RETURN_FATAL_ERROR;
  1933. }
  1934. if (mBufferFieldInfoListHead == NULL) {
  1935. mBufferFieldInfoListHead = pNew;
  1936. mBufferFieldInfoListTail= pNew;
  1937. } else {
  1938. mBufferFieldInfoListTail->mNext = pNew;
  1939. mBufferFieldInfoListTail = pNew;
  1940. }
  1941. return VFR_RETURN_SUCCESS;
  1942. }
  1943. EFI_VFR_RETURN_CODE
  1944. CVfrDataStorage::GetBufferVarStoreFieldInfo (
  1945. IN OUT EFI_VARSTORE_INFO *Info
  1946. )
  1947. {
  1948. BufferVarStoreFieldInfoNode *pNode;
  1949. pNode = mBufferFieldInfoListHead;
  1950. while (pNode != NULL) {
  1951. if (Info->mVarStoreId == pNode->mVarStoreInfo.mVarStoreId &&
  1952. Info->mInfo.mVarOffset == pNode->mVarStoreInfo.mInfo.mVarOffset) {
  1953. Info->mVarTotalSize = pNode->mVarStoreInfo.mVarTotalSize;
  1954. Info->mVarType = pNode->mVarStoreInfo.mVarType;
  1955. return VFR_RETURN_SUCCESS;
  1956. }
  1957. pNode = pNode->mNext;
  1958. }
  1959. return VFR_RETURN_FATAL_ERROR;
  1960. }
  1961. EFI_VFR_RETURN_CODE
  1962. CVfrDataStorage::GetNameVarStoreInfo (
  1963. OUT EFI_VARSTORE_INFO *Info,
  1964. IN UINT32 Index
  1965. )
  1966. {
  1967. if (Info == NULL) {
  1968. return VFR_RETURN_FATAL_ERROR;
  1969. }
  1970. if (mCurrVarStorageNode == NULL) {
  1971. return VFR_RETURN_GET_NVVARSTORE_ERROR;
  1972. }
  1973. //
  1974. // Framework Vfr file Index is from 1, but Uefi Vfr file Index is from 0.
  1975. //
  1976. if (VfrCompatibleMode) {
  1977. if (Index == 0) {
  1978. return VFR_RETURN_ERROR_ARRARY_NUM;
  1979. }
  1980. Index --;
  1981. }
  1982. Info->mInfo.mVarName = mCurrVarStorageNode->mStorageInfo.mNameSpace.mNameTable[Index];
  1983. return VFR_RETURN_SUCCESS;
  1984. }
  1985. SVfrDefaultStoreNode::SVfrDefaultStoreNode (
  1986. IN EFI_IFR_DEFAULTSTORE *ObjBinAddr,
  1987. IN CHAR8 *RefName,
  1988. IN EFI_STRING_ID DefaultStoreNameId,
  1989. IN UINT16 DefaultId
  1990. )
  1991. {
  1992. mObjBinAddr = ObjBinAddr;
  1993. if (RefName != NULL) {
  1994. mRefName = new CHAR8[strlen (RefName) + 1];
  1995. strcpy (mRefName, RefName);
  1996. } else {
  1997. mRefName = NULL;
  1998. }
  1999. mNext = NULL;
  2000. mDefaultId = DefaultId;
  2001. mDefaultStoreNameId = DefaultStoreNameId;
  2002. }
  2003. SVfrDefaultStoreNode::~SVfrDefaultStoreNode (
  2004. VOID
  2005. )
  2006. {
  2007. if (mRefName != NULL) {
  2008. delete[] mRefName;
  2009. }
  2010. }
  2011. CVfrDefaultStore::CVfrDefaultStore (
  2012. VOID
  2013. )
  2014. {
  2015. mDefaultStoreList = NULL;
  2016. }
  2017. CVfrDefaultStore::~CVfrDefaultStore (
  2018. VOID
  2019. )
  2020. {
  2021. SVfrDefaultStoreNode *pTmp = NULL;
  2022. while (mDefaultStoreList != NULL) {
  2023. pTmp = mDefaultStoreList;
  2024. mDefaultStoreList = mDefaultStoreList->mNext;
  2025. delete pTmp;
  2026. }
  2027. }
  2028. EFI_VFR_RETURN_CODE
  2029. CVfrDefaultStore::RegisterDefaultStore (
  2030. IN CHAR8 *ObjBinAddr,
  2031. IN CHAR8 *RefName,
  2032. IN EFI_STRING_ID DefaultStoreNameId,
  2033. IN UINT16 DefaultId
  2034. )
  2035. {
  2036. SVfrDefaultStoreNode *pNode = NULL;
  2037. if (RefName == NULL) {
  2038. return VFR_RETURN_FATAL_ERROR;
  2039. }
  2040. for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
  2041. if (strcmp (pNode->mRefName, RefName) == 0) {
  2042. return VFR_RETURN_REDEFINED;
  2043. }
  2044. }
  2045. if ((pNode = new SVfrDefaultStoreNode ((EFI_IFR_DEFAULTSTORE *)ObjBinAddr, RefName, DefaultStoreNameId, DefaultId)) == NULL) {
  2046. return VFR_RETURN_OUT_FOR_RESOURCES;
  2047. }
  2048. pNode->mNext = mDefaultStoreList;
  2049. mDefaultStoreList = pNode;
  2050. return VFR_RETURN_SUCCESS;
  2051. }
  2052. /*
  2053. * assign new reference name or new default store name id only if
  2054. * the original is invalid
  2055. */
  2056. EFI_VFR_RETURN_CODE
  2057. CVfrDefaultStore::ReRegisterDefaultStoreById (
  2058. IN UINT16 DefaultId,
  2059. IN CHAR8 *RefName,
  2060. IN EFI_STRING_ID DefaultStoreNameId
  2061. )
  2062. {
  2063. SVfrDefaultStoreNode *pNode = NULL;
  2064. for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
  2065. if (pNode->mDefaultId == DefaultId) {
  2066. break;
  2067. }
  2068. }
  2069. if (pNode == NULL) {
  2070. return VFR_RETURN_UNDEFINED;
  2071. } else {
  2072. if (pNode->mDefaultStoreNameId == EFI_STRING_ID_INVALID) {
  2073. pNode->mDefaultStoreNameId = DefaultStoreNameId;
  2074. if (pNode->mObjBinAddr != NULL) {
  2075. pNode->mObjBinAddr->DefaultName = DefaultStoreNameId;
  2076. }
  2077. } else {
  2078. return VFR_RETURN_REDEFINED;
  2079. }
  2080. if (RefName != NULL) {
  2081. delete pNode->mRefName;
  2082. pNode->mRefName = new CHAR8[strlen (RefName) + 1];
  2083. if (pNode->mRefName != NULL) {
  2084. strcpy (pNode->mRefName, RefName);
  2085. }
  2086. }
  2087. }
  2088. return VFR_RETURN_SUCCESS;
  2089. }
  2090. BOOLEAN
  2091. CVfrDefaultStore::DefaultIdRegistered (
  2092. IN UINT16 DefaultId
  2093. )
  2094. {
  2095. SVfrDefaultStoreNode *pNode = NULL;
  2096. for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
  2097. if (pNode->mDefaultId == DefaultId) {
  2098. return TRUE;
  2099. }
  2100. }
  2101. return FALSE;
  2102. }
  2103. EFI_VFR_RETURN_CODE
  2104. CVfrDefaultStore::GetDefaultId (
  2105. IN CHAR8 *RefName,
  2106. OUT UINT16 *DefaultId
  2107. )
  2108. {
  2109. SVfrDefaultStoreNode *pTmp = NULL;
  2110. if (DefaultId == NULL) {
  2111. return VFR_RETURN_FATAL_ERROR;
  2112. }
  2113. for (pTmp = mDefaultStoreList; pTmp != NULL; pTmp = pTmp->mNext) {
  2114. if (strcmp (pTmp->mRefName, RefName) == 0) {
  2115. *DefaultId = pTmp->mDefaultId;
  2116. return VFR_RETURN_SUCCESS;
  2117. }
  2118. }
  2119. return VFR_RETURN_UNDEFINED;
  2120. }
  2121. EFI_VFR_RETURN_CODE
  2122. CVfrDefaultStore::BufferVarStoreAltConfigAdd (
  2123. IN EFI_VARSTORE_ID DefaultId,
  2124. IN EFI_VARSTORE_INFO &Info,
  2125. IN CHAR8 *VarStoreName,
  2126. IN EFI_GUID *VarStoreGuid,
  2127. IN UINT8 Type,
  2128. IN EFI_IFR_TYPE_VALUE Value
  2129. )
  2130. {
  2131. SVfrDefaultStoreNode *pNode = NULL;
  2132. CHAR8 NewAltCfg[2 * 2 * sizeof (UINT16) + 1] = {0,};
  2133. INTN Returnvalue = 0;
  2134. if (VarStoreName == NULL) {
  2135. return VFR_RETURN_FATAL_ERROR;
  2136. }
  2137. for (pNode = mDefaultStoreList; pNode != NULL; pNode = pNode->mNext) {
  2138. if (pNode->mDefaultId == DefaultId) {
  2139. break;
  2140. }
  2141. }
  2142. if (pNode == NULL) {
  2143. return VFR_RETURN_UNDEFINED;
  2144. }
  2145. gCVfrBufferConfig.Open ();
  2146. sprintf (NewAltCfg, "%04x", pNode->mDefaultId);
  2147. if ((Returnvalue = gCVfrBufferConfig.Select(VarStoreName, VarStoreGuid)) == 0) {
  2148. if ((Returnvalue = gCVfrBufferConfig.Write ('a', VarStoreName, VarStoreGuid, NewAltCfg, Type, Info.mInfo.mVarOffset, Info.mVarTotalSize, Value)) != 0) {
  2149. goto WriteError;
  2150. }
  2151. }
  2152. gCVfrBufferConfig.Close ();
  2153. return VFR_RETURN_SUCCESS;
  2154. WriteError:
  2155. gCVfrBufferConfig.Close ();
  2156. return (EFI_VFR_RETURN_CODE)Returnvalue;
  2157. }
  2158. SVfrRuleNode::SVfrRuleNode (
  2159. IN CHAR8 *RuleName,
  2160. IN UINT8 RuleId
  2161. )
  2162. {
  2163. if (RuleName != NULL) {
  2164. mRuleName = new CHAR8[strlen (RuleName) + 1];
  2165. strcpy (mRuleName, RuleName);
  2166. } else {
  2167. mRuleName = NULL;
  2168. }
  2169. mNext = NULL;
  2170. mRuleId = RuleId;
  2171. }
  2172. SVfrRuleNode::~SVfrRuleNode (
  2173. VOID
  2174. )
  2175. {
  2176. if (mRuleName != NULL) {
  2177. delete[] mRuleName;
  2178. }
  2179. }
  2180. CVfrRulesDB::CVfrRulesDB ()
  2181. {
  2182. mRuleList = NULL;
  2183. mFreeRuleId = EFI_VARSTORE_ID_START;
  2184. }
  2185. CVfrRulesDB::~CVfrRulesDB ()
  2186. {
  2187. SVfrRuleNode *pNode;
  2188. while(mRuleList != NULL) {
  2189. pNode = mRuleList;
  2190. mRuleList = mRuleList->mNext;
  2191. delete pNode;
  2192. }
  2193. }
  2194. VOID
  2195. CVfrRulesDB::RegisterRule (
  2196. IN CHAR8 *RuleName
  2197. )
  2198. {
  2199. SVfrRuleNode *pNew;
  2200. if (RuleName == NULL) {
  2201. return ;
  2202. }
  2203. if ((pNew = new SVfrRuleNode (RuleName, mFreeRuleId)) == NULL) {
  2204. return ;
  2205. }
  2206. mFreeRuleId++;
  2207. pNew->mNext = mRuleList;
  2208. mRuleList = pNew;
  2209. }
  2210. UINT8
  2211. CVfrRulesDB::GetRuleId (
  2212. IN CHAR8 *RuleName
  2213. )
  2214. {
  2215. SVfrRuleNode *pNode;
  2216. if (RuleName == NULL) {
  2217. return EFI_RULE_ID_INVALID;
  2218. }
  2219. for (pNode = mRuleList; pNode != NULL; pNode = pNode->mNext) {
  2220. if (strcmp (pNode->mRuleName, RuleName) == 0) {
  2221. return pNode->mRuleId;
  2222. }
  2223. }
  2224. return EFI_RULE_ID_INVALID;
  2225. }
  2226. CVfrRulesDB gCVfrRulesDB;
  2227. EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
  2228. VOID
  2229. )
  2230. {
  2231. mVarStoreId = EFI_VARSTORE_ID_INVALID;
  2232. mInfo.mVarName = EFI_STRING_ID_INVALID;
  2233. mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
  2234. mVarType = EFI_IFR_TYPE_OTHER;
  2235. mVarTotalSize = 0;
  2236. mIsBitVar = FALSE;
  2237. }
  2238. EFI_VARSTORE_INFO::EFI_VARSTORE_INFO (
  2239. IN EFI_VARSTORE_INFO &Info
  2240. )
  2241. {
  2242. mVarStoreId = Info.mVarStoreId;
  2243. mInfo.mVarName = Info.mInfo.mVarName;
  2244. mInfo.mVarOffset = Info.mInfo.mVarOffset;
  2245. mVarType = Info.mVarType;
  2246. mVarTotalSize = Info.mVarTotalSize;
  2247. mIsBitVar = Info.mIsBitVar;
  2248. }
  2249. EFI_VARSTORE_INFO&
  2250. EFI_VARSTORE_INFO::operator= (
  2251. IN CONST EFI_VARSTORE_INFO &Info
  2252. )
  2253. {
  2254. if (this != &Info) {
  2255. mVarStoreId = Info.mVarStoreId;
  2256. mInfo.mVarName = Info.mInfo.mVarName;
  2257. mInfo.mVarOffset = Info.mInfo.mVarOffset;
  2258. mVarType = Info.mVarType;
  2259. mVarTotalSize = Info.mVarTotalSize;
  2260. mIsBitVar = Info.mIsBitVar;
  2261. }
  2262. return *this;
  2263. }
  2264. BOOLEAN
  2265. EFI_VARSTORE_INFO::operator == (
  2266. IN EFI_VARSTORE_INFO *Info
  2267. )
  2268. {
  2269. if ((mVarStoreId == Info->mVarStoreId) &&
  2270. (mInfo.mVarName == Info->mInfo.mVarName) &&
  2271. (mInfo.mVarOffset == Info->mInfo.mVarOffset) &&
  2272. (mVarType == Info->mVarType) &&
  2273. (mVarTotalSize == Info->mVarTotalSize) &&
  2274. (mIsBitVar == Info->mIsBitVar)) {
  2275. return TRUE;
  2276. }
  2277. return FALSE;
  2278. }
  2279. BufferVarStoreFieldInfoNode::BufferVarStoreFieldInfoNode(
  2280. IN EFI_VARSTORE_INFO *Info
  2281. )
  2282. {
  2283. mVarStoreInfo.mVarType = Info->mVarType;
  2284. mVarStoreInfo.mVarTotalSize = Info->mVarTotalSize;
  2285. mVarStoreInfo.mInfo.mVarOffset = Info->mInfo.mVarOffset;
  2286. mVarStoreInfo.mVarStoreId = Info->mVarStoreId;
  2287. mNext = NULL;
  2288. }
  2289. BufferVarStoreFieldInfoNode::~BufferVarStoreFieldInfoNode ()
  2290. {
  2291. mVarStoreInfo.mVarType = EFI_IFR_TYPE_OTHER;
  2292. mVarStoreInfo.mVarTotalSize = 0;
  2293. mVarStoreInfo.mInfo.mVarOffset = EFI_VAROFFSET_INVALID;
  2294. mVarStoreInfo.mVarStoreId = EFI_VARSTORE_ID_INVALID;
  2295. mNext = NULL;
  2296. }
  2297. static EFI_VARSTORE_INFO gEfiInvalidVarStoreInfo;
  2298. EFI_QUESTION_ID
  2299. CVfrQuestionDB::GetFreeQuestionId (
  2300. VOID
  2301. )
  2302. {
  2303. UINT32 Index, Mask, Offset;
  2304. for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
  2305. if (mFreeQIdBitMap[Index] != 0xFFFFFFFF) {
  2306. break;
  2307. }
  2308. }
  2309. if (Index == EFI_FREE_QUESTION_ID_BITMAP_SIZE) {
  2310. return EFI_QUESTION_ID_INVALID;
  2311. }
  2312. for (Offset = 0, Mask = 0x80000000; Mask != 0; Mask >>= 1, Offset++) {
  2313. if ((mFreeQIdBitMap[Index] & Mask) == 0) {
  2314. mFreeQIdBitMap[Index] |= Mask;
  2315. return (EFI_QUESTION_ID)((Index << EFI_BITS_SHIFT_PER_UINT32) + Offset);
  2316. }
  2317. }
  2318. return EFI_QUESTION_ID_INVALID;
  2319. }
  2320. BOOLEAN
  2321. CVfrQuestionDB::ChekQuestionIdFree (
  2322. IN EFI_QUESTION_ID QId
  2323. )
  2324. {
  2325. UINT32 Index = (QId / EFI_BITS_PER_UINT32);
  2326. UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
  2327. return (mFreeQIdBitMap[Index] & (0x80000000 >> Offset)) == 0;
  2328. }
  2329. VOID
  2330. CVfrQuestionDB::MarkQuestionIdUsed (
  2331. IN EFI_QUESTION_ID QId
  2332. )
  2333. {
  2334. UINT32 Index = (QId / EFI_BITS_PER_UINT32);
  2335. UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
  2336. mFreeQIdBitMap[Index] |= (0x80000000 >> Offset);
  2337. }
  2338. VOID
  2339. CVfrQuestionDB::MarkQuestionIdUnused (
  2340. IN EFI_QUESTION_ID QId
  2341. )
  2342. {
  2343. UINT32 Index = (QId / EFI_BITS_PER_UINT32);
  2344. UINT32 Offset = (QId % EFI_BITS_PER_UINT32);
  2345. mFreeQIdBitMap[Index] &= ~(0x80000000 >> Offset);
  2346. }
  2347. SVfrQuestionNode::SVfrQuestionNode (
  2348. IN CHAR8 *Name,
  2349. IN CHAR8 *VarIdStr,
  2350. IN UINT32 BitMask
  2351. )
  2352. {
  2353. mName = NULL;
  2354. mVarIdStr = NULL;
  2355. mQuestionId = EFI_QUESTION_ID_INVALID;
  2356. mBitMask = BitMask;
  2357. mNext = NULL;
  2358. mQtype = QUESTION_NORMAL;
  2359. if (Name == NULL) {
  2360. mName = new CHAR8[strlen ("$DEFAULT") + 1];
  2361. strcpy (mName, "$DEFAULT");
  2362. } else {
  2363. mName = new CHAR8[strlen (Name) + 1];
  2364. strcpy (mName, Name);
  2365. }
  2366. if (VarIdStr != NULL) {
  2367. mVarIdStr = new CHAR8[strlen (VarIdStr) + 1];
  2368. strcpy (mVarIdStr, VarIdStr);
  2369. } else {
  2370. mVarIdStr = new CHAR8[strlen ("$") + 1];
  2371. strcpy (mVarIdStr, "$");
  2372. }
  2373. }
  2374. SVfrQuestionNode::~SVfrQuestionNode (
  2375. VOID
  2376. )
  2377. {
  2378. if (mName != NULL) {
  2379. delete[] mName;
  2380. }
  2381. if (mVarIdStr != NULL) {
  2382. delete[] mVarIdStr;
  2383. }
  2384. }
  2385. CVfrQuestionDB::CVfrQuestionDB ()
  2386. {
  2387. UINT32 Index;
  2388. for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
  2389. mFreeQIdBitMap[Index] = 0;
  2390. }
  2391. // Question ID 0 is reserved.
  2392. mFreeQIdBitMap[0] = 0x80000000;
  2393. mQuestionList = NULL;
  2394. }
  2395. CVfrQuestionDB::~CVfrQuestionDB ()
  2396. {
  2397. SVfrQuestionNode *pNode;
  2398. while (mQuestionList != NULL) {
  2399. pNode = mQuestionList;
  2400. mQuestionList = mQuestionList->mNext;
  2401. delete pNode;
  2402. }
  2403. }
  2404. //
  2405. // Reset to init state
  2406. //
  2407. VOID
  2408. CVfrQuestionDB::ResetInit(
  2409. IN VOID
  2410. )
  2411. {
  2412. UINT32 Index;
  2413. SVfrQuestionNode *pNode;
  2414. while (mQuestionList != NULL) {
  2415. pNode = mQuestionList;
  2416. mQuestionList = mQuestionList->mNext;
  2417. delete pNode;
  2418. }
  2419. for (Index = 0; Index < EFI_FREE_QUESTION_ID_BITMAP_SIZE; Index++) {
  2420. mFreeQIdBitMap[Index] = 0;
  2421. }
  2422. // Question ID 0 is reserved.
  2423. mFreeQIdBitMap[0] = 0x80000000;
  2424. mQuestionList = NULL;
  2425. }
  2426. VOID
  2427. CVfrQuestionDB::PrintAllQuestion (
  2428. VOID
  2429. )
  2430. {
  2431. SVfrQuestionNode *pNode = NULL;
  2432. for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
  2433. printf ("Question VarId is %s and QuestionId is 0x%x\n", pNode->mVarIdStr, pNode->mQuestionId);
  2434. }
  2435. }
  2436. EFI_VFR_RETURN_CODE
  2437. CVfrQuestionDB::RegisterQuestion (
  2438. IN CHAR8 *Name,
  2439. IN CHAR8 *VarIdStr,
  2440. IN OUT EFI_QUESTION_ID &QuestionId
  2441. )
  2442. {
  2443. SVfrQuestionNode *pNode = NULL;
  2444. if ((Name != NULL) && (FindQuestion(Name) == VFR_RETURN_SUCCESS)) {
  2445. return VFR_RETURN_REDEFINED;
  2446. }
  2447. if ((pNode = new SVfrQuestionNode (Name, VarIdStr)) == NULL) {
  2448. return VFR_RETURN_OUT_FOR_RESOURCES;
  2449. }
  2450. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2451. QuestionId = GetFreeQuestionId ();
  2452. } else {
  2453. //
  2454. // For Framework Vfr, don't check question ID conflict.
  2455. //
  2456. if (!VfrCompatibleMode && ChekQuestionIdFree (QuestionId) == FALSE) {
  2457. delete pNode;
  2458. return VFR_RETURN_QUESTIONID_REDEFINED;
  2459. }
  2460. MarkQuestionIdUsed (QuestionId);
  2461. }
  2462. pNode->mQuestionId = QuestionId;
  2463. pNode->mNext = mQuestionList;
  2464. mQuestionList = pNode;
  2465. gCFormPkg.DoPendingAssign (VarIdStr, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2466. return VFR_RETURN_SUCCESS;
  2467. }
  2468. VOID
  2469. CVfrQuestionDB::RegisterOldDateQuestion (
  2470. IN CHAR8 *YearVarId,
  2471. IN CHAR8 *MonthVarId,
  2472. IN CHAR8 *DayVarId,
  2473. IN OUT EFI_QUESTION_ID &QuestionId
  2474. )
  2475. {
  2476. SVfrQuestionNode *pNode[3] = {NULL, };
  2477. UINT32 Index;
  2478. if ((YearVarId == NULL) || (MonthVarId == NULL) || (DayVarId == NULL)) {
  2479. return;
  2480. }
  2481. if ((pNode[0] = new SVfrQuestionNode (NULL, YearVarId, DATE_YEAR_BITMASK)) == NULL) {
  2482. goto Err;
  2483. }
  2484. if ((pNode[1] = new SVfrQuestionNode (NULL, MonthVarId, DATE_MONTH_BITMASK)) == NULL) {
  2485. goto Err;
  2486. }
  2487. if ((pNode[2] = new SVfrQuestionNode (NULL, DayVarId, DATE_DAY_BITMASK)) == NULL) {
  2488. goto Err;
  2489. }
  2490. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2491. QuestionId = GetFreeQuestionId ();
  2492. } else {
  2493. if (ChekQuestionIdFree (QuestionId) == FALSE) {
  2494. goto Err;
  2495. }
  2496. MarkQuestionIdUsed (QuestionId);
  2497. }
  2498. pNode[0]->mQuestionId = QuestionId;
  2499. pNode[1]->mQuestionId = QuestionId;
  2500. pNode[2]->mQuestionId = QuestionId;
  2501. pNode[0]->mQtype = QUESTION_DATE;
  2502. pNode[1]->mQtype = QUESTION_DATE;
  2503. pNode[2]->mQtype = QUESTION_DATE;
  2504. pNode[0]->mNext = pNode[1];
  2505. pNode[1]->mNext = pNode[2];
  2506. pNode[2]->mNext = mQuestionList;
  2507. mQuestionList = pNode[0];
  2508. gCFormPkg.DoPendingAssign (YearVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2509. gCFormPkg.DoPendingAssign (MonthVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2510. gCFormPkg.DoPendingAssign (DayVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2511. return;
  2512. Err:
  2513. for (Index = 0; Index < 3; Index++) {
  2514. if (pNode[Index] != NULL) {
  2515. delete pNode[Index];
  2516. }
  2517. }
  2518. QuestionId = EFI_QUESTION_ID_INVALID;
  2519. }
  2520. VOID
  2521. CVfrQuestionDB::RegisterNewDateQuestion (
  2522. IN CHAR8 *Name,
  2523. IN CHAR8 *BaseVarId,
  2524. IN OUT EFI_QUESTION_ID &QuestionId
  2525. )
  2526. {
  2527. SVfrQuestionNode *pNode[3] = {NULL, };
  2528. UINT32 Len;
  2529. CHAR8 *VarIdStr[3] = {NULL, };
  2530. CHAR8 Index;
  2531. if (BaseVarId == NULL && Name == NULL) {
  2532. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2533. QuestionId = GetFreeQuestionId ();
  2534. } else {
  2535. if (ChekQuestionIdFree (QuestionId) == FALSE) {
  2536. goto Err;
  2537. }
  2538. MarkQuestionIdUsed (QuestionId);
  2539. }
  2540. return;
  2541. }
  2542. if (BaseVarId != NULL) {
  2543. Len = strlen (BaseVarId);
  2544. VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
  2545. if (VarIdStr[0] != NULL) {
  2546. strcpy (VarIdStr[0], BaseVarId);
  2547. strcat (VarIdStr[0], ".Year");
  2548. }
  2549. VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
  2550. if (VarIdStr[1] != NULL) {
  2551. strcpy (VarIdStr[1], BaseVarId);
  2552. strcat (VarIdStr[1], ".Month");
  2553. }
  2554. VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
  2555. if (VarIdStr[2] != NULL) {
  2556. strcpy (VarIdStr[2], BaseVarId);
  2557. strcat (VarIdStr[2], ".Day");
  2558. }
  2559. } else {
  2560. Len = strlen (Name);
  2561. VarIdStr[0] = new CHAR8[Len + strlen (".Year") + 1];
  2562. if (VarIdStr[0] != NULL) {
  2563. strcpy (VarIdStr[0], Name);
  2564. strcat (VarIdStr[0], ".Year");
  2565. }
  2566. VarIdStr[1] = new CHAR8[Len + strlen (".Month") + 1];
  2567. if (VarIdStr[1] != NULL) {
  2568. strcpy (VarIdStr[1], Name);
  2569. strcat (VarIdStr[1], ".Month");
  2570. }
  2571. VarIdStr[2] = new CHAR8[Len + strlen (".Day") + 1];
  2572. if (VarIdStr[2] != NULL) {
  2573. strcpy (VarIdStr[2], Name);
  2574. strcat (VarIdStr[2], ".Day");
  2575. }
  2576. }
  2577. if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], DATE_YEAR_BITMASK)) == NULL) {
  2578. goto Err;
  2579. }
  2580. if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], DATE_MONTH_BITMASK)) == NULL) {
  2581. goto Err;
  2582. }
  2583. if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], DATE_DAY_BITMASK)) == NULL) {
  2584. goto Err;
  2585. }
  2586. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2587. QuestionId = GetFreeQuestionId ();
  2588. } else {
  2589. if (ChekQuestionIdFree (QuestionId) == FALSE) {
  2590. goto Err;
  2591. }
  2592. MarkQuestionIdUsed (QuestionId);
  2593. }
  2594. pNode[0]->mQuestionId = QuestionId;
  2595. pNode[1]->mQuestionId = QuestionId;
  2596. pNode[2]->mQuestionId = QuestionId;
  2597. pNode[0]->mQtype = QUESTION_DATE;
  2598. pNode[1]->mQtype = QUESTION_DATE;
  2599. pNode[2]->mQtype = QUESTION_DATE;
  2600. pNode[0]->mNext = pNode[1];
  2601. pNode[1]->mNext = pNode[2];
  2602. pNode[2]->mNext = mQuestionList;
  2603. mQuestionList = pNode[0];
  2604. for (Index = 0; Index < 3; Index++) {
  2605. if (VarIdStr[Index] != NULL) {
  2606. delete[] VarIdStr[Index];
  2607. VarIdStr[Index] = NULL;
  2608. }
  2609. }
  2610. gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2611. gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2612. gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2613. return;
  2614. Err:
  2615. for (Index = 0; Index < 3; Index++) {
  2616. if (pNode[Index] != NULL) {
  2617. delete pNode[Index];
  2618. }
  2619. if (VarIdStr[Index] != NULL) {
  2620. delete[] VarIdStr [Index];
  2621. VarIdStr [Index] = NULL;
  2622. }
  2623. }
  2624. }
  2625. VOID
  2626. CVfrQuestionDB::RegisterOldTimeQuestion (
  2627. IN CHAR8 *HourVarId,
  2628. IN CHAR8 *MinuteVarId,
  2629. IN CHAR8 *SecondVarId,
  2630. IN OUT EFI_QUESTION_ID &QuestionId
  2631. )
  2632. {
  2633. SVfrQuestionNode *pNode[3] = {NULL, };
  2634. UINT32 Index;
  2635. if ((HourVarId == NULL) || (MinuteVarId == NULL) || (SecondVarId == NULL)) {
  2636. return;
  2637. }
  2638. if ((pNode[0] = new SVfrQuestionNode (NULL, HourVarId, TIME_HOUR_BITMASK)) == NULL) {
  2639. goto Err;
  2640. }
  2641. if ((pNode[1] = new SVfrQuestionNode (NULL, MinuteVarId, TIME_MINUTE_BITMASK)) == NULL) {
  2642. goto Err;
  2643. }
  2644. if ((pNode[2] = new SVfrQuestionNode (NULL, SecondVarId, TIME_SECOND_BITMASK)) == NULL) {
  2645. goto Err;
  2646. }
  2647. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2648. QuestionId = GetFreeQuestionId ();
  2649. } else {
  2650. if (ChekQuestionIdFree (QuestionId) == FALSE) {
  2651. goto Err;
  2652. }
  2653. MarkQuestionIdUsed (QuestionId);
  2654. }
  2655. pNode[0]->mQuestionId = QuestionId;
  2656. pNode[1]->mQuestionId = QuestionId;
  2657. pNode[2]->mQuestionId = QuestionId;
  2658. pNode[0]->mQtype = QUESTION_TIME;
  2659. pNode[1]->mQtype = QUESTION_TIME;
  2660. pNode[2]->mQtype = QUESTION_TIME;
  2661. pNode[0]->mNext = pNode[1];
  2662. pNode[1]->mNext = pNode[2];
  2663. pNode[2]->mNext = mQuestionList;
  2664. mQuestionList = pNode[0];
  2665. gCFormPkg.DoPendingAssign (HourVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2666. gCFormPkg.DoPendingAssign (MinuteVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2667. gCFormPkg.DoPendingAssign (SecondVarId, (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2668. return;
  2669. Err:
  2670. for (Index = 0; Index < 3; Index++) {
  2671. if (pNode[Index] != NULL) {
  2672. delete pNode[Index];
  2673. }
  2674. }
  2675. QuestionId = EFI_QUESTION_ID_INVALID;
  2676. }
  2677. VOID
  2678. CVfrQuestionDB::RegisterNewTimeQuestion (
  2679. IN CHAR8 *Name,
  2680. IN CHAR8 *BaseVarId,
  2681. IN OUT EFI_QUESTION_ID &QuestionId
  2682. )
  2683. {
  2684. SVfrQuestionNode *pNode[3] = {NULL, };
  2685. UINT32 Len;
  2686. CHAR8 *VarIdStr[3] = {NULL, };
  2687. CHAR8 Index;
  2688. if (BaseVarId == NULL && Name == NULL) {
  2689. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2690. QuestionId = GetFreeQuestionId ();
  2691. } else {
  2692. if (ChekQuestionIdFree (QuestionId) == FALSE) {
  2693. goto Err;
  2694. }
  2695. MarkQuestionIdUsed (QuestionId);
  2696. }
  2697. return;
  2698. }
  2699. if (BaseVarId != NULL) {
  2700. Len = strlen (BaseVarId);
  2701. VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
  2702. if (VarIdStr[0] != NULL) {
  2703. strcpy (VarIdStr[0], BaseVarId);
  2704. strcat (VarIdStr[0], ".Hour");
  2705. }
  2706. VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
  2707. if (VarIdStr[1] != NULL) {
  2708. strcpy (VarIdStr[1], BaseVarId);
  2709. strcat (VarIdStr[1], ".Minute");
  2710. }
  2711. VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
  2712. if (VarIdStr[2] != NULL) {
  2713. strcpy (VarIdStr[2], BaseVarId);
  2714. strcat (VarIdStr[2], ".Second");
  2715. }
  2716. } else {
  2717. Len = strlen (Name);
  2718. VarIdStr[0] = new CHAR8[Len + strlen (".Hour") + 1];
  2719. if (VarIdStr[0] != NULL) {
  2720. strcpy (VarIdStr[0], Name);
  2721. strcat (VarIdStr[0], ".Hour");
  2722. }
  2723. VarIdStr[1] = new CHAR8[Len + strlen (".Minute") + 1];
  2724. if (VarIdStr[1] != NULL) {
  2725. strcpy (VarIdStr[1], Name);
  2726. strcat (VarIdStr[1], ".Minute");
  2727. }
  2728. VarIdStr[2] = new CHAR8[Len + strlen (".Second") + 1];
  2729. if (VarIdStr[2] != NULL) {
  2730. strcpy (VarIdStr[2], Name);
  2731. strcat (VarIdStr[2], ".Second");
  2732. }
  2733. }
  2734. if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0], TIME_HOUR_BITMASK)) == NULL) {
  2735. goto Err;
  2736. }
  2737. if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1], TIME_MINUTE_BITMASK)) == NULL) {
  2738. goto Err;
  2739. }
  2740. if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2], TIME_SECOND_BITMASK)) == NULL) {
  2741. goto Err;
  2742. }
  2743. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2744. QuestionId = GetFreeQuestionId ();
  2745. } else {
  2746. if (ChekQuestionIdFree (QuestionId) == FALSE) {
  2747. goto Err;
  2748. }
  2749. MarkQuestionIdUsed (QuestionId);
  2750. }
  2751. pNode[0]->mQuestionId = QuestionId;
  2752. pNode[1]->mQuestionId = QuestionId;
  2753. pNode[2]->mQuestionId = QuestionId;
  2754. pNode[0]->mQtype = QUESTION_TIME;
  2755. pNode[1]->mQtype = QUESTION_TIME;
  2756. pNode[2]->mQtype = QUESTION_TIME;
  2757. pNode[0]->mNext = pNode[1];
  2758. pNode[1]->mNext = pNode[2];
  2759. pNode[2]->mNext = mQuestionList;
  2760. mQuestionList = pNode[0];
  2761. for (Index = 0; Index < 3; Index++) {
  2762. if (VarIdStr[Index] != NULL) {
  2763. delete[] VarIdStr[Index];
  2764. VarIdStr[Index] = NULL;
  2765. }
  2766. }
  2767. gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2768. gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2769. gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2770. return;
  2771. Err:
  2772. for (Index = 0; Index < 3; Index++) {
  2773. if (pNode[Index] != NULL) {
  2774. delete pNode[Index];
  2775. }
  2776. if (VarIdStr[Index] != NULL) {
  2777. delete[] VarIdStr[Index];
  2778. VarIdStr[Index] = NULL;
  2779. }
  2780. }
  2781. }
  2782. VOID
  2783. CVfrQuestionDB::RegisterRefQuestion (
  2784. IN CHAR8 *Name,
  2785. IN CHAR8 *BaseVarId,
  2786. IN OUT EFI_QUESTION_ID &QuestionId
  2787. )
  2788. {
  2789. SVfrQuestionNode *pNode[4] = {NULL, };
  2790. UINT32 Len;
  2791. CHAR8 *VarIdStr[4] = {NULL, };
  2792. CHAR8 Index;
  2793. if (BaseVarId == NULL && Name == NULL) {
  2794. return;
  2795. }
  2796. if (BaseVarId != NULL) {
  2797. Len = strlen (BaseVarId);
  2798. VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
  2799. if (VarIdStr[0] != NULL) {
  2800. strcpy (VarIdStr[0], BaseVarId);
  2801. strcat (VarIdStr[0], ".QuestionId");
  2802. }
  2803. VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
  2804. if (VarIdStr[1] != NULL) {
  2805. strcpy (VarIdStr[1], BaseVarId);
  2806. strcat (VarIdStr[1], ".FormId");
  2807. }
  2808. VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
  2809. if (VarIdStr[2] != NULL) {
  2810. strcpy (VarIdStr[2], BaseVarId);
  2811. strcat (VarIdStr[2], ".FormSetGuid");
  2812. }
  2813. VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
  2814. if (VarIdStr[3] != NULL) {
  2815. strcpy (VarIdStr[3], BaseVarId);
  2816. strcat (VarIdStr[3], ".DevicePath");
  2817. }
  2818. } else {
  2819. Len = strlen (Name);
  2820. VarIdStr[0] = new CHAR8[Len + strlen (".QuestionId") + 1];
  2821. if (VarIdStr[0] != NULL) {
  2822. strcpy (VarIdStr[0], Name);
  2823. strcat (VarIdStr[0], ".QuestionId");
  2824. }
  2825. VarIdStr[1] = new CHAR8[Len + strlen (".FormId") + 1];
  2826. if (VarIdStr[1] != NULL) {
  2827. strcpy (VarIdStr[1], Name);
  2828. strcat (VarIdStr[1], ".FormId");
  2829. }
  2830. VarIdStr[2] = new CHAR8[Len + strlen (".FormSetGuid") + 1];
  2831. if (VarIdStr[2] != NULL) {
  2832. strcpy (VarIdStr[2], Name);
  2833. strcat (VarIdStr[2], ".FormSetGuid");
  2834. }
  2835. VarIdStr[3] = new CHAR8[Len + strlen (".DevicePath") + 1];
  2836. if (VarIdStr[3] != NULL) {
  2837. strcpy (VarIdStr[3], Name);
  2838. strcat (VarIdStr[3], ".DevicePath");
  2839. }
  2840. }
  2841. if ((pNode[0] = new SVfrQuestionNode (Name, VarIdStr[0])) == NULL) {
  2842. goto Err;
  2843. }
  2844. if ((pNode[1] = new SVfrQuestionNode (Name, VarIdStr[1])) == NULL) {
  2845. goto Err;
  2846. }
  2847. if ((pNode[2] = new SVfrQuestionNode (Name, VarIdStr[2])) == NULL) {
  2848. goto Err;
  2849. }
  2850. if ((pNode[3] = new SVfrQuestionNode (Name, VarIdStr[3])) == NULL) {
  2851. goto Err;
  2852. }
  2853. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2854. QuestionId = GetFreeQuestionId ();
  2855. } else {
  2856. if (ChekQuestionIdFree (QuestionId) == FALSE) {
  2857. goto Err;
  2858. }
  2859. MarkQuestionIdUsed (QuestionId);
  2860. }
  2861. pNode[0]->mQuestionId = QuestionId;
  2862. pNode[1]->mQuestionId = QuestionId;
  2863. pNode[2]->mQuestionId = QuestionId;
  2864. pNode[3]->mQuestionId = QuestionId;
  2865. pNode[0]->mQtype = QUESTION_REF;
  2866. pNode[1]->mQtype = QUESTION_REF;
  2867. pNode[2]->mQtype = QUESTION_REF;
  2868. pNode[3]->mQtype = QUESTION_REF;
  2869. pNode[0]->mNext = pNode[1];
  2870. pNode[1]->mNext = pNode[2];
  2871. pNode[2]->mNext = pNode[3];
  2872. pNode[3]->mNext = mQuestionList;
  2873. mQuestionList = pNode[0];
  2874. gCFormPkg.DoPendingAssign (VarIdStr[0], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2875. gCFormPkg.DoPendingAssign (VarIdStr[1], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2876. gCFormPkg.DoPendingAssign (VarIdStr[2], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2877. gCFormPkg.DoPendingAssign (VarIdStr[3], (VOID *)&QuestionId, sizeof(EFI_QUESTION_ID));
  2878. return;
  2879. Err:
  2880. for (Index = 0; Index < 4; Index++) {
  2881. if (pNode[Index] != NULL) {
  2882. delete pNode[Index];
  2883. }
  2884. if (VarIdStr[Index] != NULL) {
  2885. delete VarIdStr[Index];
  2886. }
  2887. }
  2888. }
  2889. EFI_VFR_RETURN_CODE
  2890. CVfrQuestionDB::UpdateQuestionId (
  2891. IN EFI_QUESTION_ID QId,
  2892. IN EFI_QUESTION_ID NewQId
  2893. )
  2894. {
  2895. SVfrQuestionNode *pNode = NULL;
  2896. if (QId == NewQId) {
  2897. // don't update
  2898. return VFR_RETURN_SUCCESS;
  2899. }
  2900. //
  2901. // For Framework Vfr, don't check question ID conflict.
  2902. //
  2903. if (!VfrCompatibleMode && ChekQuestionIdFree (NewQId) == FALSE) {
  2904. return VFR_RETURN_REDEFINED;
  2905. }
  2906. for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
  2907. if (pNode->mQuestionId == QId) {
  2908. break;
  2909. }
  2910. }
  2911. if (pNode == NULL) {
  2912. return VFR_RETURN_UNDEFINED;
  2913. }
  2914. MarkQuestionIdUnused (QId);
  2915. pNode->mQuestionId = NewQId;
  2916. MarkQuestionIdUsed (NewQId);
  2917. gCFormPkg.DoPendingAssign (pNode->mVarIdStr, (VOID *)&NewQId, sizeof(EFI_QUESTION_ID));
  2918. return VFR_RETURN_SUCCESS;
  2919. }
  2920. VOID
  2921. CVfrQuestionDB::GetQuestionId (
  2922. IN CHAR8 *Name,
  2923. IN CHAR8 *VarIdStr,
  2924. OUT EFI_QUESTION_ID &QuestionId,
  2925. OUT UINT32 &BitMask,
  2926. OUT EFI_QUESION_TYPE *QType
  2927. )
  2928. {
  2929. SVfrQuestionNode *pNode;
  2930. QuestionId = EFI_QUESTION_ID_INVALID;
  2931. BitMask = 0x00000000;
  2932. if (QType != NULL) {
  2933. *QType = QUESTION_NORMAL;
  2934. }
  2935. if ((Name == NULL) && (VarIdStr == NULL)) {
  2936. return ;
  2937. }
  2938. for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
  2939. if (Name != NULL) {
  2940. if (strcmp (pNode->mName, Name) != 0) {
  2941. continue;
  2942. }
  2943. }
  2944. if (VarIdStr != NULL) {
  2945. if (strcmp (pNode->mVarIdStr, VarIdStr) != 0) {
  2946. continue;
  2947. }
  2948. }
  2949. QuestionId = pNode->mQuestionId;
  2950. BitMask = pNode->mBitMask;
  2951. if (QType != NULL) {
  2952. *QType = pNode->mQtype;
  2953. }
  2954. break;
  2955. }
  2956. return ;
  2957. }
  2958. EFI_VFR_RETURN_CODE
  2959. CVfrQuestionDB::FindQuestion (
  2960. IN EFI_QUESTION_ID QuestionId
  2961. )
  2962. {
  2963. SVfrQuestionNode *pNode;
  2964. if (QuestionId == EFI_QUESTION_ID_INVALID) {
  2965. return VFR_RETURN_INVALID_PARAMETER;
  2966. }
  2967. for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
  2968. if (pNode->mQuestionId == QuestionId) {
  2969. return VFR_RETURN_SUCCESS;
  2970. }
  2971. }
  2972. return VFR_RETURN_UNDEFINED;
  2973. }
  2974. EFI_VFR_RETURN_CODE
  2975. CVfrQuestionDB::FindQuestion (
  2976. IN CHAR8 *Name
  2977. )
  2978. {
  2979. SVfrQuestionNode *pNode;
  2980. if (Name == NULL) {
  2981. return VFR_RETURN_FATAL_ERROR;
  2982. }
  2983. for (pNode = mQuestionList; pNode != NULL; pNode = pNode->mNext) {
  2984. if (strcmp (pNode->mName, Name) == 0) {
  2985. return VFR_RETURN_SUCCESS;
  2986. }
  2987. }
  2988. return VFR_RETURN_UNDEFINED;
  2989. }
  2990. CVfrStringDB::CVfrStringDB ()
  2991. {
  2992. mStringFileName = NULL;
  2993. }
  2994. CVfrStringDB::~CVfrStringDB ()
  2995. {
  2996. if (mStringFileName != NULL) {
  2997. delete[] mStringFileName;
  2998. }
  2999. mStringFileName = NULL;
  3000. }
  3001. VOID
  3002. CVfrStringDB::SetStringFileName(IN CHAR8 *StringFileName)
  3003. {
  3004. UINT32 FileLen = 0;
  3005. if (StringFileName == NULL) {
  3006. return;
  3007. }
  3008. if (mStringFileName != NULL) {
  3009. delete[] mStringFileName;
  3010. }
  3011. FileLen = strlen (StringFileName) + 1;
  3012. mStringFileName = new CHAR8[FileLen];
  3013. if (mStringFileName == NULL) {
  3014. return;
  3015. }
  3016. strcpy (mStringFileName, StringFileName);
  3017. mStringFileName[FileLen - 1] = '\0';
  3018. }
  3019. /**
  3020. Returns TRUE or FALSE whether SupportedLanguages contains the best matching language
  3021. from a set of supported languages.
  3022. @param[in] SupportedLanguages A pointer to a Null-terminated ASCII string that
  3023. contains a set of language codes.
  3024. @param[in] Language A variable that contains pointers to Null-terminated
  3025. ASCII strings that contain one language codes.
  3026. @retval FALSE The best matching language could not be found in SupportedLanguages.
  3027. @retval TRUE The best matching language could be found in SupportedLanguages.
  3028. **/
  3029. BOOLEAN
  3030. CVfrStringDB::GetBestLanguage (
  3031. IN CONST CHAR8 *SupportedLanguages,
  3032. IN CHAR8 *Language
  3033. )
  3034. {
  3035. UINTN CompareLength;
  3036. UINTN LanguageLength;
  3037. CONST CHAR8 *Supported;
  3038. if (SupportedLanguages == NULL || Language == NULL){
  3039. return FALSE;
  3040. }
  3041. //
  3042. // Determine the length of the first RFC 4646 language code in Language
  3043. //
  3044. for (LanguageLength = 0; Language[LanguageLength] != 0 && Language[LanguageLength] != ';'; LanguageLength++);
  3045. //
  3046. // Trim back the length of Language used until it is empty
  3047. //
  3048. while (LanguageLength > 0) {
  3049. //
  3050. // Loop through all language codes in SupportedLanguages
  3051. //
  3052. for (Supported = SupportedLanguages; *Supported != '\0'; Supported += CompareLength) {
  3053. //
  3054. // Skip ';' characters in Supported
  3055. //
  3056. for (; *Supported != '\0' && *Supported == ';'; Supported++);
  3057. //
  3058. // Determine the length of the next language code in Supported
  3059. //
  3060. for (CompareLength = 0; Supported[CompareLength] != 0 && Supported[CompareLength] != ';'; CompareLength++);
  3061. //
  3062. // If Language is longer than the Supported, then skip to the next language
  3063. //
  3064. if (LanguageLength > CompareLength) {
  3065. continue;
  3066. }
  3067. //
  3068. // See if the first LanguageLength characters in Supported match Language
  3069. //
  3070. if (strncmp (Supported, Language, LanguageLength) == 0) {
  3071. return TRUE;
  3072. }
  3073. }
  3074. //
  3075. // Trim Language from the right to the next '-' character
  3076. //
  3077. for (LanguageLength--; LanguageLength > 0 && Language[LanguageLength] != '-'; LanguageLength--);
  3078. }
  3079. //
  3080. // No matches were found
  3081. //
  3082. return FALSE;
  3083. }
  3084. CHAR8 *
  3085. CVfrStringDB::GetVarStoreNameFormStringId (
  3086. IN EFI_STRING_ID StringId
  3087. )
  3088. {
  3089. FILE *pInFile = NULL;
  3090. UINT32 NameOffset;
  3091. UINT32 Length;
  3092. UINT8 *StringPtr;
  3093. CHAR8 *StringName;
  3094. CHAR16 *UnicodeString;
  3095. CHAR8 *VarStoreName = NULL;
  3096. CHAR8 *DestTmp;
  3097. UINT8 *Current;
  3098. EFI_STATUS Status;
  3099. CHAR8 LineBuf[EFI_IFR_MAX_LENGTH];
  3100. UINT8 BlockType;
  3101. EFI_HII_STRING_PACKAGE_HDR *PkgHeader;
  3102. if (mStringFileName == NULL) {
  3103. return NULL;
  3104. }
  3105. if ((pInFile = fopen (LongFilePath (mStringFileName), "rb")) == NULL) {
  3106. return NULL;
  3107. }
  3108. //
  3109. // Get file length.
  3110. //
  3111. fseek (pInFile, 0, SEEK_END);
  3112. Length = ftell (pInFile);
  3113. fseek (pInFile, 0, SEEK_SET);
  3114. //
  3115. // Get file data.
  3116. //
  3117. StringPtr = new UINT8[Length];
  3118. if (StringPtr == NULL) {
  3119. fclose (pInFile);
  3120. return NULL;
  3121. }
  3122. fread ((char *)StringPtr, sizeof (UINT8), Length, pInFile);
  3123. fclose (pInFile);
  3124. PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
  3125. //
  3126. // Check the String package.
  3127. //
  3128. if (PkgHeader->Header.Type != EFI_HII_PACKAGE_STRINGS) {
  3129. delete[] StringPtr;
  3130. return NULL;
  3131. }
  3132. //
  3133. // Search the language, get best language base on RFC 4647 matching algorithm.
  3134. //
  3135. Current = StringPtr;
  3136. while (!GetBestLanguage ("en", PkgHeader->Language)) {
  3137. Current += PkgHeader->Header.Length;
  3138. PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) Current;
  3139. //
  3140. // If can't find string package base on language, just return the first string package.
  3141. //
  3142. if (Current - StringPtr >= Length) {
  3143. Current = StringPtr;
  3144. PkgHeader = (EFI_HII_STRING_PACKAGE_HDR *) StringPtr;
  3145. break;
  3146. }
  3147. }
  3148. Current += PkgHeader->HdrSize;
  3149. //
  3150. // Find the string block according the stringId.
  3151. //
  3152. Status = FindStringBlock(Current, StringId, &NameOffset, &BlockType);
  3153. if (Status != EFI_SUCCESS) {
  3154. delete[] StringPtr;
  3155. return NULL;
  3156. }
  3157. //
  3158. // Get varstore name according the string type.
  3159. //
  3160. switch (BlockType) {
  3161. case EFI_HII_SIBT_STRING_SCSU:
  3162. case EFI_HII_SIBT_STRING_SCSU_FONT:
  3163. case EFI_HII_SIBT_STRINGS_SCSU:
  3164. case EFI_HII_SIBT_STRINGS_SCSU_FONT:
  3165. StringName = (CHAR8*)(Current + NameOffset);
  3166. VarStoreName = new CHAR8[strlen(StringName) + 1];
  3167. strcpy (VarStoreName, StringName);
  3168. break;
  3169. case EFI_HII_SIBT_STRING_UCS2:
  3170. case EFI_HII_SIBT_STRING_UCS2_FONT:
  3171. case EFI_HII_SIBT_STRINGS_UCS2:
  3172. case EFI_HII_SIBT_STRINGS_UCS2_FONT:
  3173. UnicodeString = (CHAR16*)(Current + NameOffset);
  3174. Length = GetUnicodeStringTextSize ((UINT8*)UnicodeString) ;
  3175. DestTmp = new CHAR8[Length / 2 + 1];
  3176. VarStoreName = DestTmp;
  3177. while (*UnicodeString != '\0') {
  3178. *(DestTmp++) = (CHAR8) *(UnicodeString++);
  3179. }
  3180. *DestTmp = '\0';
  3181. break;
  3182. default:
  3183. break;
  3184. }
  3185. delete[] StringPtr;
  3186. return VarStoreName;
  3187. }
  3188. EFI_STATUS
  3189. CVfrStringDB::FindStringBlock (
  3190. IN UINT8 *StringData,
  3191. IN EFI_STRING_ID StringId,
  3192. OUT UINT32 *StringTextOffset,
  3193. OUT UINT8 *BlockType
  3194. )
  3195. {
  3196. UINT8 *BlockHdr;
  3197. EFI_STRING_ID CurrentStringId;
  3198. UINT32 BlockSize;
  3199. UINT32 Index;
  3200. UINT8 *StringTextPtr;
  3201. UINT32 Offset;
  3202. UINT16 StringCount;
  3203. UINT16 SkipCount;
  3204. UINT8 Length8;
  3205. EFI_HII_SIBT_EXT2_BLOCK Ext2;
  3206. UINT32 Length32;
  3207. UINT32 StringSize;
  3208. CurrentStringId = 1;
  3209. //
  3210. // Parse the string blocks to get the string text and font.
  3211. //
  3212. BlockHdr = StringData;
  3213. BlockSize = 0;
  3214. Offset = 0;
  3215. while (*BlockHdr != EFI_HII_SIBT_END) {
  3216. switch (*BlockHdr) {
  3217. case EFI_HII_SIBT_STRING_SCSU:
  3218. Offset = sizeof (EFI_HII_STRING_BLOCK);
  3219. StringTextPtr = BlockHdr + Offset;
  3220. BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
  3221. CurrentStringId++;
  3222. break;
  3223. case EFI_HII_SIBT_STRING_SCSU_FONT:
  3224. Offset = sizeof (EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK) - sizeof (UINT8);
  3225. StringTextPtr = BlockHdr + Offset;
  3226. BlockSize += Offset + strlen ((CHAR8 *) StringTextPtr) + 1;
  3227. CurrentStringId++;
  3228. break;
  3229. case EFI_HII_SIBT_STRINGS_SCSU:
  3230. memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
  3231. StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_BLOCK) - sizeof (UINT8);
  3232. BlockSize += StringTextPtr - BlockHdr;
  3233. for (Index = 0; Index < StringCount; Index++) {
  3234. BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
  3235. if (CurrentStringId == StringId) {
  3236. *BlockType = *BlockHdr;
  3237. *StringTextOffset = StringTextPtr - StringData;
  3238. return EFI_SUCCESS;
  3239. }
  3240. StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
  3241. CurrentStringId++;
  3242. }
  3243. break;
  3244. case EFI_HII_SIBT_STRINGS_SCSU_FONT:
  3245. memcpy (
  3246. &StringCount,
  3247. BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
  3248. sizeof (UINT16)
  3249. );
  3250. StringTextPtr = BlockHdr + sizeof (EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK) - sizeof (UINT8);
  3251. BlockSize += StringTextPtr - BlockHdr;
  3252. for (Index = 0; Index < StringCount; Index++) {
  3253. BlockSize += strlen ((CHAR8 *) StringTextPtr) + 1;
  3254. if (CurrentStringId == StringId) {
  3255. *BlockType = *BlockHdr;
  3256. *StringTextOffset = StringTextPtr - StringData;
  3257. return EFI_SUCCESS;
  3258. }
  3259. StringTextPtr = StringTextPtr + strlen ((CHAR8 *) StringTextPtr) + 1;
  3260. CurrentStringId++;
  3261. }
  3262. break;
  3263. case EFI_HII_SIBT_STRING_UCS2:
  3264. Offset = sizeof (EFI_HII_STRING_BLOCK);
  3265. StringTextPtr = BlockHdr + Offset;
  3266. //
  3267. // Use StringSize to store the size of the specified string, including the NULL
  3268. // terminator.
  3269. //
  3270. StringSize = GetUnicodeStringTextSize (StringTextPtr);
  3271. BlockSize += Offset + StringSize;
  3272. CurrentStringId++;
  3273. break;
  3274. case EFI_HII_SIBT_STRING_UCS2_FONT:
  3275. Offset = sizeof (EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK) - sizeof (CHAR16);
  3276. StringTextPtr = BlockHdr + Offset;
  3277. //
  3278. // Use StrSize to store the size of the specified string, including the NULL
  3279. // terminator.
  3280. //
  3281. StringSize = GetUnicodeStringTextSize (StringTextPtr);
  3282. BlockSize += Offset + StringSize;
  3283. CurrentStringId++;
  3284. break;
  3285. case EFI_HII_SIBT_STRINGS_UCS2:
  3286. Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_BLOCK) - sizeof (CHAR16);
  3287. StringTextPtr = BlockHdr + Offset;
  3288. BlockSize += Offset;
  3289. memcpy (&StringCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
  3290. for (Index = 0; Index < StringCount; Index++) {
  3291. StringSize = GetUnicodeStringTextSize (StringTextPtr);
  3292. BlockSize += StringSize;
  3293. if (CurrentStringId == StringId) {
  3294. *BlockType = *BlockHdr;
  3295. *StringTextOffset = StringTextPtr - StringData;
  3296. return EFI_SUCCESS;
  3297. }
  3298. StringTextPtr = StringTextPtr + StringSize;
  3299. CurrentStringId++;
  3300. }
  3301. break;
  3302. case EFI_HII_SIBT_STRINGS_UCS2_FONT:
  3303. Offset = sizeof (EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK) - sizeof (CHAR16);
  3304. StringTextPtr = BlockHdr + Offset;
  3305. BlockSize += Offset;
  3306. memcpy (
  3307. &StringCount,
  3308. BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
  3309. sizeof (UINT16)
  3310. );
  3311. for (Index = 0; Index < StringCount; Index++) {
  3312. StringSize = GetUnicodeStringTextSize (StringTextPtr);
  3313. BlockSize += StringSize;
  3314. if (CurrentStringId == StringId) {
  3315. *BlockType = *BlockHdr;
  3316. *StringTextOffset = StringTextPtr - StringData;
  3317. return EFI_SUCCESS;
  3318. }
  3319. StringTextPtr = StringTextPtr + StringSize;
  3320. CurrentStringId++;
  3321. }
  3322. break;
  3323. case EFI_HII_SIBT_DUPLICATE:
  3324. if (CurrentStringId == StringId) {
  3325. //
  3326. // Incoming StringId is an id of a duplicate string block.
  3327. // Update the StringId to be the previous string block.
  3328. // Go back to the header of string block to search.
  3329. //
  3330. memcpy (
  3331. &StringId,
  3332. BlockHdr + sizeof (EFI_HII_STRING_BLOCK),
  3333. sizeof (EFI_STRING_ID)
  3334. );
  3335. CurrentStringId = 1;
  3336. BlockSize = 0;
  3337. } else {
  3338. BlockSize += sizeof (EFI_HII_SIBT_DUPLICATE_BLOCK);
  3339. CurrentStringId++;
  3340. }
  3341. break;
  3342. case EFI_HII_SIBT_SKIP1:
  3343. SkipCount = (UINT16) (*(BlockHdr + sizeof (EFI_HII_STRING_BLOCK)));
  3344. CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
  3345. BlockSize += sizeof (EFI_HII_SIBT_SKIP1_BLOCK);
  3346. break;
  3347. case EFI_HII_SIBT_SKIP2:
  3348. memcpy (&SkipCount, BlockHdr + sizeof (EFI_HII_STRING_BLOCK), sizeof (UINT16));
  3349. CurrentStringId = (UINT16) (CurrentStringId + SkipCount);
  3350. BlockSize += sizeof (EFI_HII_SIBT_SKIP2_BLOCK);
  3351. break;
  3352. case EFI_HII_SIBT_EXT1:
  3353. memcpy (
  3354. &Length8,
  3355. BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
  3356. sizeof (UINT8)
  3357. );
  3358. BlockSize += Length8;
  3359. break;
  3360. case EFI_HII_SIBT_EXT2:
  3361. memcpy (&Ext2, BlockHdr, sizeof (EFI_HII_SIBT_EXT2_BLOCK));
  3362. BlockSize += Ext2.Length;
  3363. break;
  3364. case EFI_HII_SIBT_EXT4:
  3365. memcpy (
  3366. &Length32,
  3367. BlockHdr + sizeof (EFI_HII_STRING_BLOCK) + sizeof (UINT8),
  3368. sizeof (UINT32)
  3369. );
  3370. BlockSize += Length32;
  3371. break;
  3372. default:
  3373. break;
  3374. }
  3375. if (StringId > 0 && StringId != (EFI_STRING_ID)(-1)) {
  3376. *StringTextOffset = BlockHdr - StringData + Offset;
  3377. *BlockType = *BlockHdr;
  3378. if (StringId == CurrentStringId - 1) {
  3379. //
  3380. // if only one skip item, return EFI_NOT_FOUND.
  3381. //
  3382. if(*BlockType == EFI_HII_SIBT_SKIP2 || *BlockType == EFI_HII_SIBT_SKIP1) {
  3383. return EFI_NOT_FOUND;
  3384. } else {
  3385. return EFI_SUCCESS;
  3386. }
  3387. }
  3388. if (StringId < CurrentStringId - 1) {
  3389. return EFI_NOT_FOUND;
  3390. }
  3391. }
  3392. BlockHdr = StringData + BlockSize;
  3393. }
  3394. return EFI_NOT_FOUND;
  3395. }
  3396. UINT32
  3397. CVfrStringDB::GetUnicodeStringTextSize (
  3398. IN UINT8 *StringSrc
  3399. )
  3400. {
  3401. UINT32 StringSize;
  3402. CHAR16 *StringPtr;
  3403. StringSize = sizeof (CHAR16);
  3404. StringPtr = (UINT16*)StringSrc;
  3405. while (*StringPtr++ != L'\0') {
  3406. StringSize += sizeof (CHAR16);
  3407. }
  3408. return StringSize;
  3409. }
  3410. BOOLEAN VfrCompatibleMode = FALSE;
  3411. CVfrVarDataTypeDB gCVfrVarDataTypeDB;
  3412. CVfrDefaultStore gCVfrDefaultStore;
  3413. CVfrDataStorage gCVfrDataStorage;