//********************************************************************** //********************************************************************** //** ** //** (C)Copyright 1985-2005, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** //** ** //** Phone: (770)-246-8600 ** //** ** //********************************************************************** //********************************************************************** //********************************************************************** // $Header: /Alaska/SOURCE/Core/CORE_DXE/FrameworkHii/HIIDB.c 5 2/10/10 5:08p Felixp $ // // $Revision: 5 $ // // $Date: 2/10/10 5:08p $ //********************************************************************** // Revision History // ---------------- // $Log: /Alaska/SOURCE/Core/CORE_DXE/FrameworkHii/HIIDB.c $ // // 5 2/10/10 5:08p Felixp // Bug fix in HiiExtGetFormInfo function. // // 4 2/10/10 3:43p Felixp // x64 compiler warnings are fixed. // // 3 12/29/09 2:38p Yakovlevs // Fixed issue with hanging in TSE big number of setup questions. // Changed size of Length fields in some HII internal structures from // UIN16 to UINTN. // Code clenup (removed not used variables changes to compile with W4) // // 2 12/04/09 2:16p Yakovlevs // 1.Fixed potential NULL pointer use in function NewFontPack() // 2.Fixed inconsistancy in VarStore management (requires updated HiiDb.h) // // 1 10/09/09 6:10p Felixp // // 45 6/03/09 10:58a Yakovlevs // if Hii->RemovePack is called reset global pointers to NULL since they // might pointing at data that was freed. // // 44 10/01/08 1:01p Yakovlevs // fixed bug in HiiExtGetFormLabels() function. // // 43 1/09/08 10:49a Yakovlevs // // 42 9/05/07 9:18p Felixp // // 41 9/05/07 5:59p Yakovlevs // Bug fixes in UpdateForm and RemovePack routines. // // 2 6/28/07 5:16p Yakovlevs // Fixed FormUpdate Protocol Function, and some other minor bug fixes. // // 39 5/23/07 4:32p Pavell // Reindexing formsets // // 38 3/18/07 3:10p Felixp // GetSecondaryLanguages fix: return EFI_NOT_FOUND when no languages found // // 37 3/12/07 6:06p Yakovlevs // Fixed NewKbPack function. // // 36 3/12/07 1:46p Yakovlevs // Handled a situation when there are no Keyboard Layout data in HII // Database. // // 35 3/07/07 8:21p Yakovlevs // Added GetKeyboardLayout function implamentation. // // 34 1/23/07 12:23p Yakovlevs // // 33 12/21/06 1:57p Felixp // // 32 12/20/06 10:37a Felixp // // 31 12/18/06 5:42p Pavell // Added a fix for variable size determination // 30 11/15/06 5:55p Yakovlevs // // 29 11/02/06 6:45p Yakovlevs // Fixed HiiTestString NON_SPACING attribute handling // // 27 10/31/06 11:15a Yakovlevs // HiiTestString fixed to skip none spacing characters. // // 25 10/30/06 6:09p Yakovlevs // HII Spec v 0.92 updates // // 24 9/27/06 7:44p Felixp // Improvement in GetHiiString: // If string is not found for the current system language language, try // with the package primary language. // // 23 9/26/06 9:03a Felixp // Multilanguage Support. Do not use hard-coded glyphs. Load font file // instead. // // 22 9/18/06 6:23p Felixp // Bug fix in HiiGetString: buffer overrun when Raw is FALSE // // 21 8/24/06 10:11a Felixp // x64 support: warning/error fixes // // 20 8/04/06 5:18p Felixp // Bug fix in NewFontPack function (wide glyph handling). // // 19 7/24/06 11:46a Yakovlevs // Hii->ExportDatabase support added. // // 18 3/13/06 5:30p Felixp // // 17 10/03/05 2:47p Markw // Fixed uninitialized variables. // // 16 7/20/05 6:43p Felixp // GlyphToBlt modifed to support wide characters // // 15 7/19/05 8:17p Felixp // NewString modified to support update for all languages when three // spaces Language provided // // 13 7/13/05 9:46p Felixp // // 12 6/24/05 2:03p Yakovlevs // // 11 6/23/05 5:43p Yakovlevs // Fixed "Missing String" message // // 10 5/27/05 12:16p Felixp // bug fix in HiiGetString // // 9 2/28/05 6:21p Yakovlevs // Fixed DateTime and Object Conditions issue; // // 8 3/17/05 1:57p Felixp // implementation of HiiNewPackNew updated // // 7 3/04/05 12:52p Felixp // // 6 3/04/05 9:23a Mandal // //********************************************************************** // // // Name: // // Description: // // //********************************************************************** // // Module Name: HIIDB.C // // Abstract: This file contains implementation of HII Database Protocol. // #include #include #include extern UINT8 *UsStdNarrowGlyphData; extern HII_UTILITIES_PROTOCOL HiiUtilitiesProtocol; //================================================================================== // Some globals we need //================================================================================== //------------------------------------------ //Prototypes EFI_STATUS InitPrivateData(EFI_HANDLE MyImgHandle); EFI_STATUS CreateLabelObjects(HII_LABEL *Label); //EFI_STATUS HiiNewPack (IN EFI_HII_PROTOCOL *This, // IN EFI_HII_PACK_LIST *Package, // OUT EFI_HII_HANDLE *Handle); //------------------------------------------ //GUIDs EFI_GUID gEfiHiiProtocolGuidOld = EFI_HII_OLD_PROTOCOL_GUID; EFI_GUID gEfiHiiProtocolGuidNew = EFI_HII_NEW_PROTOCOL_GUID; static EFI_GUID gEfiExtHiiProtocolGuid = EFI_HII_EXT_PROTOCOL_GUID; //------------------------------------------ //Data Vars //Define String Database Key fields #define STR_KEY 0 #define STR_KEY_CNT 1 //it is going to be combined key //Token->size16;LangIdx->size32;Handle->size16; total = 8 byte->UINT64 //Token->Least Segnificant Field Handle Most Significant Field //the resulting Index for StringToken->23, LangIndex->2, Hii Handle=1 will be // Handle|LangIdx |Token // 0x0001|00000002|0023 -> easy to sort easy to find static DBE_OFFSET_KEY_CONTEXT gStrOffsetInfo = {EFI_FIELD_OFFSET(HII_STR ,Token), 8 }; static DBE_KEY_FIELD gStrKey=OFFSET_KEY(gStrOffsetInfo); //Any Language Printable string static UINT16 gAnyLang[]=L"Any Language"; //HII DATABASE global var static HII_DB gHiiDb; /////////////////////////////////////////////////////////////////// //in order to save some time when LocateHandle routine been called //I have decide to save Current HandleInfo structure pionter //here rather than locate it every time static HII_HANDLE *mCurHnd=NULL; static HII_LANG *mCurLang=NULL; static UINTN mCurHid=0, mCurLid=0; /////////////////////////////////////////////////////////////////// //in order to save some time when HiiGetLine routine been called //I have decide to save Current StringInfo structure pionter //here rather than locate it every time HiiGetLine been called static HII_STR *mCurStr=NULL; /////////////////////////////////////////////////////////////////// // save the varstore context based on the formset static UINT16 CurrentVarId = 0; //================================================================================== // Entry Point //================================================================================== //********************************************************************** // // // Procedure: HiiDbEntryPoint() // // Description: Initialize HII Database (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) // // Input: EFI_HANDLE ImageHandle This Driver Image Handle. // EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI System Table // // Output: EFI_STATUS EFI_SUCCESS - Driver Loadded. // Other - Driver Error // // //********************************************************************** EFI_STATUS HiiDbEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable){ EFI_STATUS Status=0; UINTN hCnt; EFI_HANDLE *hBuf; //----------------------------------- InitAmiLib(ImageHandle, SystemTable); //Only one HII Driver has to be in the system Status=pBS->LocateHandleBuffer(ByProtocol, &gEfiHiiProtocolGuidOld, NULL, &hCnt, &hBuf); //If there was no error, report that we has been already started if (!EFI_ERROR(Status)) { if (!hBuf)pBS->FreePool(hBuf); //Don't forget to free the memory return EFI_ALREADY_STARTED; } Status=InitPrivateData(ImageHandle); if(EFI_ERROR(Status)) return Status; Status = pBS->InstallMultipleProtocolInterfaces(&gHiiDb.HiiHandle, &gEfiHiiProtocolGuidOld,&gHiiDb.HiiProtocolOld, &gEfiHiiProtocolGuidNew,&gHiiDb.HiiProtocolNew, &gEfiExtHiiProtocolGuid,&gHiiDb.HiiExtProtocol, &gHiiUtilitiesProtocolGuid, &HiiUtilitiesProtocol, NULL); return Status; } /////////////////////////////////////////////////////////////////// // Common Worker Functions /////////////////////////////////////////////////////////////////// //************************************************************************* // // // Name: GetDefaultLang // // Description: // EFI_STATUS GetDefaultLang(OUT CHAR16 *DefaultLang) returns the default // system language in the string specified by DefaultLang. // // Input: // OUT CHAR16 *DefaultLang // Pointer to the null-terminated Unicode string. // // Output: // EFI_NOT_FOUND, if the default language could not be found. // Otherwise, EFI_SUCCESS. // // Modified: // // Referrals: // // Notes: // // //************************************************************************* //Get System Default Language EFI_STATUS GetDefaultLang(CHAR16 *DefaultLang){ EFI_GUID EfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE; EFI_STATUS Status=0; UINT8 al[3]; UINTN i=sizeof(al); //----------------------- Status=pRS->GetVariable(L"Lang",&EfiGlobalVariableGuid,NULL,&i,al); if (EFI_ERROR(Status)) return Status; for(i=0; iItemCount; i++){ if(!MemCmp(ItemLst->Items[i],Item,Size)) { if(Index)*Index=i; return EFI_SUCCESS; } } return EFI_NOT_FOUND; } /////////////////////////////////////////////////////////////////// //Will return Lenth of the screen representation of Str with respect //of wide narrow and non spacing glyphs it using //Len excluding '0' char (\n) UINT16 GetScrLen(CHAR16 *Str, UINT16 Len){ UINTN i; UINT16 u,sl=0; HII_N_FONT *fnt; //-------------------------------------- for(i=0;i=0xfff0)continue; fnt=gHiiDb.FontDb[u]; if(fnt){ if(fnt->Attr & GLYPH_NON_SPACING) continue; if(fnt->Attr & GLYPH_WIDE) sl+=2; else sl++; } else sl++; //we will print empty rect for non existent glyph } return sl; } /////////////////////////////////////////////////////////////////// //Will allocate Mem for the length of the string and Copy "Str" there UINT16* StrAlloc(UINT16 *Str,UINT16 *StrLen OPTIONAL, UINT16 *ScrLen OPTIONAL){ UINT16 len; UINT16 *str; //------------------------------------- len=(UINT16)Wcslen(Str);//terminator not included str=(UINT16*)Malloc((len+1)*sizeof(UINT16)); if(!str)return NULL; Wcscpy(str,Str); if(StrLen)*StrLen=len+1; if(ScrLen)*ScrLen=GetScrLen(Str,len); return str; } /////////////////////////////////////////////////////////////////// //This will Change Language Attributes //VOID SetLangAttr(UINTN Index, UINT32 Attr){ // HII_LANG *lang; //-------------------- // lang=(HII_LANG*)gHiiDb.LangDb.ResDsc[Index]; // lang->Attr=Attr; //} /////////////////////////////////////////////////////////////////// //this will find and return HII_LANG "Index", //if "Language" is stored In Hii Handle Database HII_LANG* LocateLang(UINT16 *Language, UINTN *Index){ EFI_STATUS Status; UINTN idx; //------------------------ if( !mCurLang || MemCmp(&mCurLang->sName[0],Language,sizeof(mCurLang->sName)) ) { Status=LocateItem(&gHiiDb.LangDb,Language,sizeof(UINT16)*4,&idx); if(EFI_ERROR(Status)){ mCurLang=NULL; //flush Language Cache mCurLid=0; //make index to generate exception if used } else { mCurLang=gHiiDb.LangDb.Items[idx]; mCurLid=idx; } } if(mCurLang && Index)*Index=mCurLid; return mCurLang; } HII_HANDLE *LocateHandleGuid(EFI_GUID *Guid, UINTN *Index){ HII_HANDLE *phnd=NULL; UINTN i; //------------------------------- for(i=0; iGuid,Guid,sizeof(EFI_GUID)))break; else phnd=NULL; } if(phnd && Index)*Index=i; return phnd; } /////////////////////////////////////////////////////////////////// //This function will Locate another Handle with the same Guid as //passed Handle. //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //This function is Obsolete but I need it for compliance with Intel's //Setup because they using same guid more than once per Ifr and Strings pare. //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO VOID LocateSameGuidHandle(UINTN CurIdx, UINTN *IdxBuffer, UINTN *IdxCount){ HII_HANDLE *phnd=NULL,*chnd=gHiiDb.HandleDb.Items[CurIdx]; UINTN i, c=0; //---------------------------- for(i=0; iGuid,&chnd->Guid,sizeof(EFI_GUID))){ IdxBuffer[c]=i; c++; }else phnd=NULL; } *IdxCount=c; } /////////////////////////////////////////////////////////////////// //if on passed handle in any string function there are no //strings associated with we need to find another handle with //the same guid having strings on it HII_HANDLE *LocateStrHandleGuid(UINTN CurIdx, UINTN *Index){ HII_HANDLE *phnd=NULL,*chnd=gHiiDb.HandleDb.Items[CurIdx]; UINTN i; //---------------------------- for(i=0; iGuid,&chnd->Guid,sizeof(EFI_GUID)) && phnd->HasStr){ if(Index)*Index=i; break; }else phnd=NULL; } return phnd; } /////////////////////////////////////////////////////////////////// //this will find and return HII_HANDLE "Index", //if "Handle" is stored In Hii Handle Database static HII_HANDLE* LocateHandle(EFI_HII_HANDLE Handle, UINTN *Index){ EFI_STATUS Status; UINTN idx; //------------------------ if((!mCurHnd) || (mCurHnd->Handle!=Handle)){ Status=LocateItem(&gHiiDb.HandleDb,&Handle,sizeof(EFI_HII_HANDLE),&idx); if(EFI_ERROR(Status)){ mCurHnd=NULL; //flush Handle Cache mCurHid=-1; //make index to generate exception if used } else { mCurHnd=gHiiDb.HandleDb.Items[idx]; mCurHid=idx; } } if(mCurHnd && Index)*Index=mCurHid; return mCurHnd; } /////////////////////////////////////////////////////////////////// //this will find and return HII_HANDLE "Index", //if "Handle" is stored in Handle Database //or Append Handle Database with this Handle if not and return a new "Index" EFI_STATUS LocateHandleAdd(EFI_HII_HANDLE Handle, EFI_GUID *GuidId, UINTN *Index){ EFI_STATUS Status=0; HII_HANDLE *phnd; //---------------- phnd=LocateHandle(Handle,Index); if(!phnd){ phnd=MallocZ(sizeof(HII_HANDLE)); if(!phnd)return EFI_OUT_OF_RESOURCES; pBS->CopyMem(&phnd->Guid,GuidId,sizeof(EFI_GUID)); phnd->Handle=Handle; Status=AppendItemLst(&gHiiDb.HandleDb,phnd); if(EFI_ERROR(Status)) return Status; *Index=gHiiDb.HandleDb.ItemCount-1; } return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// //this will find and return HII_LANG "Index", //if "Language" is stored in Handle Database //or Append Handle Database with this Handle if not and return a new "Index" EFI_STATUS LocateLangAdd(UINT16 *Language, UINT16 *PrintLanguage, UINTN *Index){ EFI_STATUS Status; HII_LANG *lang; //------------------ //Check if we have the Language installed already lang=LocateLang(Language,Index); if(!lang){ lang=MallocZ(sizeof(HII_LANG)); if(!lang)return EFI_OUT_OF_RESOURCES; pBS->CopyMem(&lang->sName,Language,sizeof(UINT16)*4); if(PrintLanguage){ lang->lName=StrAlloc(PrintLanguage,NULL,NULL); if(!lang->lName) return EFI_OUT_OF_RESOURCES; } Status=AppendItemLst(&gHiiDb.LangDb,lang); if(EFI_ERROR(Status)) return Status; if(Index)*Index=gHiiDb.LangDb.ItemCount-1; } return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// //This will check if Lang Index is present in Secondary Lang List //on this Handle /////////////////////////////////////////////////////////////////// EFI_STATUS LocateSecLangAdd(HII_HANDLE *Hnd, UINTN *SecLangIdx, BOOLEAN AddIt){ UINTN i; //------------------------------ for(i=0; iSecLang.ItemCount; i++){ if(*SecLangIdx==(UINTN)(Hnd->SecLang.Items[i])) return EFI_SUCCESS; } if(AddIt)return AppendItemLst(&Hnd->SecLang,(VOID*)(*SecLangIdx)); else return EFI_NOT_FOUND; } /////////////////////////////////////////////////////////////////// //================================================================= //HII Database Protocol Functions //================================================================= /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// // Font related /////////////////////////////////////////////////////////////////// EFI_STATUS NewFontPack(IN EFI_HII_FONT_PACK *Package) { UINTN i; UINT16 u; EFI_NARROW_GLYPH *ng; EFI_WIDE_GLYPH *wg; //-------------------------- //Set Pointer to the beginning of Package Data. ng=(EFI_NARROW_GLYPH*)(Package+1); if(Package->NumberOfNarrowGlyphs){ HII_N_FONT *fnt; //--------------------------- //Allocate Space for Number of Narrow Glyphs fnt=(HII_N_FONT*)Malloc(sizeof(HII_N_FONT)*Package->NumberOfNarrowGlyphs); if(!fnt)return EFI_OUT_OF_RESOURCES; for(i=0; iNumberOfNarrowGlyphs; i++){ u=ng[i].UnicodeWeight; //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //we will populate only empty spots in FontD or oposite //made SDL token for that if(!gHiiDb.FontDb[u]){ //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //fnt=(HII_FONT*)Malloc(sizeof(HII_FONT)); pBS->CopyMem((VOID*)&fnt[i], &ng[i].Attributes,sizeof(HII_N_FONT)); gHiiDb.FontDb[u]=&fnt[i]; } } } if(Package->NumberOfWideGlyphs){ UINTN j,k; HII_W_FONT *fnt; //--------------- //Allocate Space for Number of Wide Glyphs wg=(EFI_WIDE_GLYPH*)(ng+Package->NumberOfNarrowGlyphs); fnt=(HII_W_FONT*)Malloc((sizeof(HII_W_FONT))*Package->NumberOfWideGlyphs); if(!fnt)return EFI_OUT_OF_RESOURCES; for(i=0; iNumberOfWideGlyphs; i++){ u=wg[i].UnicodeWeight; if(!gHiiDb.FontDb[u]){ fnt[i].Attr=wg[i].Attributes; for(j=0,k=0; jAttr& GLYPH_NON_SPACING ){ i++; continue; } if(fnt->Attr&GLYPH_WIDE) bs+=WG_SIZE; else bs+=NG_SIZE; i++; } else { Status=EFI_NOT_FOUND; break; } } *FirstMissing=i; *GlyphBufferSize=bs; return Status; } static UINT8 gGE[NG_SIZE]= {0x00,0x00,0x00,0x7E,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x7E,0x00,0x00,0x00};// \ // 0x00,0x00,0x00,0x7E,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x7E,0x00,0x00,0x00}; static EFI_WIDE_GLYPH gGB; /////////////////////////////////////////////////////////////////// EFI_STATUS HiiGetGlyph(IN EFI_HII_PROTOCOL *This, IN CHAR16 *Source, IN OUT UINT16 *Index, OUT UINT8 **GlyphBuffer, OUT UINT16 *BitWidth, IN OUT UINT32 *InternalStatus) { UINTN i, bs=NG_SIZE; HII_N_FONT *fnt;//=gHiiDb.FontDb[Source[j]]; // HII_GL_COL *gc1=NULL, *gc2=NULL; // BOOLEAN w=FALSE; //------------------------------------------ if(!This) return EFI_INVALID_PARAMETER; if((!GlyphBuffer)||(!Index)||(!Source)||(!BitWidth)) return EFI_INVALID_PARAMETER; fnt=gHiiDb.FontDb[Source[*Index]]; if(!fnt) { if(InternalStatus)*InternalStatus=(UINT32)-1; //If after calling TestString somebody will call us with invalid Unicode Char pBS->CopyMem(&gGB.GlyphCol1[0],&gGE, NG_SIZE); *BitWidth=GLYPH_W; *GlyphBuffer=(UINT8*)&gGB; (*Index)++; return EFI_NOT_FOUND; } //first char must not be the non-spacing character if(fnt->Attr&GLYPH_NON_SPACING) return EFI_INVALID_PARAMETER; if(fnt->Attr&GLYPH_WIDE){ *BitWidth=GLYPH_W*2; bs=WG_SIZE; } else *BitWidth=GLYPH_W; pBS->SetMem(&gGB,sizeof(EFI_WIDE_GLYPH),0); do{ fnt=gHiiDb.FontDb[Source[*Index]]; for(i=0;iGlData[i]; (*Index)++; } while(fnt->Attr&GLYPH_NON_SPACING); *GlyphBuffer=(UINT8*)&gGB; if(InternalStatus)*InternalStatus=0; return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// //!!!! this function suppose to take care of thing with mixed size gpyphs EFI_STATUS HiiGlyphToBlt(IN EFI_HII_PROTOCOL *This, IN UINT8 *GlyphBuffer, IN EFI_UGA_PIXEL Foreground, IN EFI_UGA_PIXEL Background, IN UINTN Count,//Number of NARROW Glyps left in BltBuffer //or count from the end of the buffer in terms of NARROW glyphs IN UINTN Width, IN UINTN Height, IN OUT EFI_UGA_PIXEL *BltBuffer) { // UINTN x,y;//,i,o; // UINT8 k = Width > GLYPH_W ? 2 : 1; //------------------------------------ // if(!This) return EFI_INVALID_PARAMETER; // if( !(Width==GLYPH_W || Width==(GLYPH_W*2)) || Height!=GLYPH_H )return EFI_INVALID_PARAMETER; /* for (y=0,o=0; y> x)) BltBuffer[y*GLYPH_W*Count+x+o]=Foreground; else BltBuffer[y*GLYPH_W*Count+x+o]=Background; } o=GLYPH_W; } } return EFI_SUCCESS; UINTN X; UINTN Y; */ UINT8 Mask; UINTN Index, Line, Part; UINTN TotalParts = Width/GLYPH_W; EFI_NARROW_GLYPH *Glyph = (EFI_NARROW_GLYPH *)GlyphBuffer; if(!This) return EFI_INVALID_PARAMETER; if( !(Width==GLYPH_W || Width==GLYPH_W*2) || Height!=GLYPH_H || Count 0; Mask>>=1, Index++) { if (Glyph->GlyphCol1[Line*TotalParts+Part] & Mask) BltBuffer[Index] = Foreground; else BltBuffer[Index] = Background; } } } /*/// BltBuffer[Index] = (Glyph->GlyphCol1[y] & (1 << x)) ? Foreground : Background; if (Width > GLYPH_W) BltBuffer[Index+GLYPH_W] = (Glyph->GlyphCol1[GLYPH_H+y] & (1 << x)) ? Foreground : Background; /// EFI_NARROW_GLYPH *Glyph = (EFI_NARROW_GLYPH *)GlyphBuffer; for (y = 0; y < Height; y++) { for (x = 0; x < GLYPH_W; x++) { UINTN Index = y * GLYPH_W * Count + (GLYPH_W - x - 1); for(i=0; iGlyphCol1[i*GLYPH_H+y] & (1 << x)) != 0) BltBuffer[Index+GLYPH_W*i] = Foreground; else BltBuffer[Index+GLYPH_W*i] = Background; } }*/ return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// // String related /////////////////////////////////////////////////////////////////// HII_STR *LocateString(HII_HANDLE *PHnd, UINTN LangIdx, STRING_REF Token/*, UINTN HandleIdx OPTIONAL*/){ UINTN li=LangIdx, j; HII_STR sd = {0,0,0,0,NULL}; INT8 v; VOID **cs; //----------------- //if CurrentString must be refreshed if(!mCurStr || mCurStr->LangIdx!=LangIdx || mCurStr->Token!=Token || mCurStr->Handle!=PHnd->Handle) { //--------------------- do { sd.Handle=PHnd->Handle; sd.LangIdx=(UINT32)li; sd.Token=Token; DbeLocateKey(&gHiiDb.StringDb,STR_KEY,(VOID*)&sd,(VOID**)&cs,&v,&j); if(v)mCurStr=NULL; else { mCurStr=(HII_STR*)(*cs); break; } //if we were looking for any language and failed //just get Primary Package Language if(!li)li=PHnd->PriLang; else break; } while(v); //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //this patch was made to keep compatibility with Intel's implemntation //of BDS - DevicerManagerVfrBin and FrontPageVfrBin uses the same Guid //and Same String Pack expecting valid strings on from one StringPack //when passing different GUIDs????????? /* if(!mCurStr){ HII_HANDLE *phnd; UINTN i,sgib[10]={0,0,0,0,0,0,0,0,0,0};//same GUID index Buffer //---------------------------------- LocateSameGuidHandle(HandleIdx,&sgib[0],&c); for(i=0; iHandle; sd.LangIdx=(UINT32)li; sd.Token=Token; DbeLocateKey(&gHiiDb.StringDb,STR_KEY,(VOID*)&sd,(VOID**)&cs,&v,&j); if(v)mCurStr=NULL; else { mCurStr=(HII_STR*)(*cs); break; } //if we were looking for any language and faild //just get Primary Package Language if(!li)li=PHnd->PriLang; else break; } while(v); if(mCurStr)break; } } */ //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO } return mCurStr; } /////////////////////////////////////////////////////////////////// EFI_STATUS ReplaceString(HII_STR *StrData, UINT16 *Replacement) { UINT16 *str; UINT16 len,slen; //----------------------------- str=StrAlloc(Replacement, &len, &slen); if(!str)return EFI_OUT_OF_RESOURCES; if(StrData->NewStr.StrPtr)pBS->FreePool(StrData->NewStr.StrPtr); StrData->NewStr.StrLen=len; StrData->NewStr.ScrLen=slen; StrData->NewStr.StrPtr=str; return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// EFI_STATUS AddString(UINTN LangIdx, HII_HANDLE *PHandle, UINT16 *String, BOOLEAN Initial, STRING_REF *Token) { HII_STR *str; //------------------------------------- str=MallocZ(sizeof(HII_STR)); if(!str) return EFI_OUT_OF_RESOURCES; if(Initial){ str->String.StrPtr=StrAlloc(String,&str->String.StrLen,&str->String.ScrLen); if(!(str->String.StrPtr))return EFI_OUT_OF_RESOURCES; } else { str->NewStr.StrPtr=StrAlloc(String,&str->NewStr.StrLen, &str->NewStr.ScrLen); if(!(str->NewStr.StrPtr))return EFI_OUT_OF_RESOURCES; } str->LangIdx=(UINT32)LangIdx; //if Token is provided, use it. Otherwise assign new one. if (Token && *Token) str->Token=*Token; else { str->Token=PHandle->NextStrToken; PHandle->NextStrToken++; if (Token) *Token = str->Token; } str->Handle=PHandle->Handle; return DbeInsert(&gHiiDb.StringDb,(VOID*)str); } EFI_STATUS UpdateString(IN UINTN li, IN HII_HANDLE *phnd, IN STRING_REF *Reference, IN CHAR16 *NewString) { EFI_STATUS Status; //Check if String with this Token# already present in String Db if((*Reference)==0){ Status=AddString(li,phnd,NewString,FALSE,Reference); if(EFI_ERROR(Status)) return Status; } else { HII_STR *str; if (*Reference >= phnd->NextStrToken) return EFI_INVALID_PARAMETER; str=LocateString(phnd,li,*Reference); //if str is NULL, it means that string with this token has been created //for a different language Status= (str) ? ReplaceString(str,NewString) : AddString(li,phnd,NewString,FALSE,Reference); } return Status; } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiNewString(IN EFI_HII_PROTOCOL *This, IN CHAR16 *Language, IN EFI_HII_HANDLE Handle, IN STRING_REF *Reference, IN CHAR16 *NewString) { UINTN li=0, hi=0; HII_LANG *lang; HII_HANDLE *phnd; EFI_STATUS Status=0; UINT16 dl[4]={0x20,0x20,0x20,0}, *pdl;//Any Lang //------------------------------- if(!This || !Reference || !NewString) return EFI_INVALID_PARAMETER; //first Check if the Handle is valid. phnd=LocateHandle(Handle,&hi); if(!phnd) return EFI_INVALID_PARAMETER; if(!phnd->HasStr){ phnd=LocateStrHandleGuid(hi,&hi); if(!phnd) return EFI_INVALID_PARAMETER; } if(!Language){ pdl=&dl[0]; if(EFI_ERROR( GetDefaultLang(pdl))){ pdl=(UINT16*)gHiiDb.LangDb.Items[phnd->PriLang]; } } else pdl=Language; //dl has a language string "xxx" lang=LocateLang(pdl,&li); if (!li) {//language index 0 referes to language " ", which means we have to update //string for all languages //update string for primary language Status = UpdateString(phnd->PriLang,phnd,Reference,NewString); //update string for all secondary languages for(li=0; !EFI_ERROR(Status) && liSecLang.ItemCount; li++) Status = UpdateString((UINTN)phnd->SecLang.Items[li],phnd,Reference,NewString); return Status; } if(!lang) return EFI_INVALID_PARAMETER; //If language is valid but not mutch Pack PriLang if(phnd->PriLang!=li){ Status=LocateSecLangAdd(phnd,&li,FALSE); if(EFI_ERROR(Status))li=phnd->PriLang; //lang=(HII_LANG*)gHiiDb.LangDb.Items[li]; } return UpdateString(li,phnd,Reference,NewString); } /////////////////////////////////////////////////////////////////// EFI_STATUS GetLanguageFromPack(EFI_HII_STRING_PACK *Pack, UINTN *LangIndex){ UINT16 *sn, *ln; UINT8 *ofs=(UINT8*)Pack;//(Pack+1); //------------------------- sn=(UINT16*)(ofs+Pack->LanguageNameString); ln=(UINT16*)(ofs+Pack->PrintableLanguageName); return LocateLangAdd(sn,ln,LangIndex); } /////////////////////////////////////////////////////////////////// BOOLEAN IsLastStrPack(EFI_HII_STRING_PACK *Pack){ if(Pack->Header.Type==EFI_HII_STRING && Pack->Header.Length == 0 && Pack->Attributes == 0 && Pack->LanguageNameString == 0 && Pack->NumStringPointers == 0 && Pack->PrintableLanguageName == 0 ) return TRUE; return FALSE; } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiGetPrimaryLanguage(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, OUT EFI_STRING *LanguageString) { HII_HANDLE *phnd; HII_LANG *lang; UINTN hi; UINT16 *ls,*bp; //---------------------- if(!This || !LanguageString) return EFI_INVALID_PARAMETER; phnd=LocateHandle(Handle,&hi); if(!phnd) return EFI_INVALID_PARAMETER; if(!phnd->HasStr){ phnd=LocateStrHandleGuid(hi,&hi); if(!phnd) return EFI_INVALID_PARAMETER; } //TODO//TODO//TODO//TODO//TODO//TODO//TODO//??????????????????????????????????????? //if for some reson Somebody submit just IFR vith no Strings //there are no way to determine language so I just put there 0 -Any Language //but Intel's code expect me to return something like "eng" //so I will return Default System Lang. //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO ls=Malloc(sizeof(UINT16)*3*(phnd->SecLang.ItemCount+1)+1); //4 characters if(!ls) return EFI_OUT_OF_RESOURCES; bp=ls; lang=gHiiDb.LangDb.Items[phnd->PriLang]; pBS->CopyMem(ls,&lang->sName,sizeof(UINT16)*3); bp+=3; for(hi=0;hiSecLang.ItemCount; hi++){ lang=gHiiDb.LangDb.Items[(UINTN)phnd->SecLang.Items[hi]]; pBS->CopyMem(bp,&lang->sName,sizeof(UINT16)*3); bp+=3; } *bp=0; *LanguageString=ls; return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// // EFI_STATUS HiiGetSecondaryLanguages(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN CHAR16 *PrimaryLanguage, OUT EFI_STRING *LanguageString) { UINTN id,i; HII_HANDLE *phnd; HII_LANG *lang; UINT16 *ls; //---------------------- if(!This) return EFI_INVALID_PARAMETER; phnd=LocateHandle(Handle,NULL); if(!phnd) return EFI_INVALID_PARAMETER; //Some how caller managed to scrue up with parameters. lang=LocateLang(PrimaryLanguage,&id);//Lang provided does not mutch with what we've recorded if( !lang || phnd->PriLang!=id ) return EFI_INVALID_PARAMETER; if(phnd->SecLang.ItemCount>0){ UINT16 *l; //---------------- ls=Malloc(sizeof(UINT16)*3*phnd->SecLang.ItemCount+1); if(!ls) return EFI_OUT_OF_RESOURCES; l=ls; for(i=0; iSecLang.ItemCount; i++){ //we are not returning Any Language str " " //And Any Lang String has index 0 upon initialization if((UINTN)(phnd->SecLang.Items[i])){ lang=(HII_LANG*)gHiiDb.LangDb.Items[(UINTN)(phnd->SecLang.Items[i])]; pBS->CopyMem(l,&lang->sName[0],sizeof(UINT16)*3);//4 unicode chars; l+=3; } }//resulting string will be consist of N*3xUINT16+TERMINATOR *l=0x0000; //put terminator at the end of set of sec lang *LanguageString=ls; }else { *LanguageString=NULL; return EFI_NOT_FOUND;} return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// //This is a worker function to avoid dubliceted code in HiiGetString, //HiiGetLine and ExtHiiGetStrInfo HII_STR *GetHiiString(EFI_HII_HANDLE Handle, UINT16 *Lang, STRING_REF Token){ UINTN li,hi; UINT16 dl[4]={0x20,0x20,0x20,0}, *pdl; HII_HANDLE *phnd; HII_STR *str; //------------------------------ phnd=LocateHandle(Handle,&hi); if(!phnd) return NULL; if(!phnd->HasStr){ phnd=LocateStrHandleGuid(hi,&hi); if(!phnd) return NULL; } if(!Lang){ pdl=&dl[0]; if(EFI_ERROR(GetDefaultLang(pdl)))pdl=(UINT16*)gHiiDb.LangDb.Items[phnd->PriLang]; } else pdl=Lang; //dl has a language string it " " or "xxx" //lang=LocateLang(pdl,&li); if(!LocateLang(pdl,&li)) return NULL; str=LocateString(phnd,li,Token); // If String is not found and language is not specified, // let's try with the primary package language. if (!str && !Lang) str=LocateString(phnd,0,Token); return str; } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiGetStringNew(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN STRING_REF Token, IN BOOLEAN Raw, IN CHAR16 *LanguageString, IN OUT UINTN *BufferLength, //in units of UINT16 OUT EFI_STRING StringBuffer) { HII_STR *str; UINTN j,i; UINT16 *ps, sl; //-------------------------- if( !This || !BufferLength || *BufferLength && !StringBuffer ) return EFI_INVALID_PARAMETER; str=GetHiiString(Handle,LanguageString,Token); if(!str) return EFI_INVALID_PARAMETER; if(str->NewStr.StrPtr){ ps=str->NewStr.StrPtr; sl=str->NewStr.StrLen; } else { ps=str->String.StrPtr; sl=str->String.StrLen; } //str->StrLen in UINT16 units if(*BufferLengthCopyMem(&StringBuffer[0],ps,sl*sizeof(UINT16)); *BufferLength=sl*sizeof(UINT16); } else { for(i=0,j=0;i<(UINTN)(sl-1);i++){ //replace with //if(ps[i]==0x0013) // StringBuffer[j]=0x0020; //else { //skip all Special and Control Characters. if((ps[i]>=0xFFF0 && ps[i]<=0xFFFF)) //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //It is amazing how Intel's engineers not in compliance with //their own Specs. //"If (Raw) TRUE, the string is returned unedited in the internal storage format described //above. If FALSE, the string returned is edited by replacing !!!! with and by //removing special characters such as the ???? prefix." // ||(ps[i]>=0x0000 && ps[i]<=0x001F)) //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO continue; //Copy the rest of chars else StringBuffer[j]=ps[i]; //} j++; } StringBuffer[j]=0;//Terminate String!! *BufferLength=(UINT16)((j+1)*sizeof(UINT16)); } return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiGetStringOld(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN STRING_REF Token, IN BOOLEAN Raw, IN CHAR16 *LanguageString, IN OUT UINT16 *BufferLength, //in units of UINT16 OUT EFI_STRING StringBuffer) { EFI_STATUS Status; UINTN bl; //----------------- if(BufferLength==NULL) return EFI_INVALID_PARAMETER; bl=(UINTN)(*BufferLength); Status=HiiGetStringNew(This,Handle,Token,Raw,LanguageString,&bl,StringBuffer); (*BufferLength)=(UINT16)bl; if((Status==EFI_BUFFER_TOO_SMALL) && (bl > 0xFFFF)) Status=EFI_INVALID_PARAMETER; return Status; } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiGetLine(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN STRING_REF Token, IN OUT UINT16 *Index, IN UINT16 LineWidth, IN CHAR16 *LanguageString, IN OUT UINT16 *BufferLength, OUT EFI_STRING StringBuffer) { HII_STR *str; UINTN j,i; UINT16 *ps, sl; BOOLEAN cr=FALSE; //-------------------------- if( !This || !BufferLength || !StringBuffer ) return EFI_INVALID_PARAMETER; str=GetHiiString(Handle,LanguageString,Token); if(!str) return EFI_INVALID_PARAMETER; if(str->NewStr.StrPtr){ ps=str->NewStr.StrPtr; sl=str->NewStr.StrLen; } else { ps=str->String.StrPtr; sl=str->String.StrLen; } //I don't know should I remove a special chars or not // So I will for now for(j=0,i=*Index; (i with if(ps[i]==0x0013){ if(cr) { //if hit second time in a row - terminate string StringBuffer[j]=0x0000; *Index=(UINT16)i; break; } else { //else replece it with space an set "cr" flag StringBuffer[j]=0x0020; cr=TRUE; } }else{ cr=FALSE; //if we here - reset "cr" flarg //skip all Special and Control Characters. if((ps[i]>=0xFFF0 && ps[i]<=0xFFFF)||(ps[i]<=0x001F)) continue; //will not increase "j" the buffer index //Copy the rest of chars into the Buffer else StringBuffer[j]=ps[i]; } j++; } StringBuffer[j]=0;//Terminate String!! *BufferLength=(UINT16)((j+1)*sizeof(UINT16)); return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiResetStrings(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle) { HII_STR *str; UINTN i,hi;//,j,gbi[10],gc=0; HII_HANDLE *phnd; //------------------------ if(!This) return EFI_INVALID_PARAMETER; phnd=LocateHandle(Handle,&hi); if(!phnd) return EFI_INVALID_PARAMETER; if(!phnd->HasStr){ phnd=LocateStrHandleGuid(hi,&hi); if(!phnd) return EFI_INVALID_PARAMETER; } //LocateSameGuidHandle(hi, &gbi[0], &gc); //for(j=0; j<=gc; j++){ for(i=0; iHasStr) break; DbeGoToIndex(&gHiiDb.StringDb,STR_KEY,i,&str); if(str->Handle==phnd->Handle){ if(str->NewStr.StrPtr){ pBS->FreePool(str->NewStr.StrPtr); str->NewStr.StrPtr=NULL; str->NewStr.StrLen=0; str->NewStr.ScrLen=0; //Cleanup Dtabase from RECORDS which was addes //after initial Package if(!str->String.StrPtr){ DbeDelete(&gHiiDb.StringDb, str, TRUE); i--;//we ned to step on the same data index continue; //since we have delited current one //phnd->NextStrToken--; } } } if(str->Handle>phnd->Handle) break; } phnd->NextStrToken=phnd->StrCount; // if(jPriLang=(UINT32)lid; f=FALSE; } else { //All other languages if any will be Secondary languages Status=LocateSecLangAdd(phnd,&lid,TRUE); if(EFI_ERROR(Status)) return Status; } for(i=0; iNumStringPointers; i++){ phnd->NextStrToken=(STRING_REF)i; if(!ps[i]) continue; str=(UINT16*)(ofs+ps[i]); Status=AddString(lid,phnd,str,TRUE,NULL); if(EFI_ERROR(Status)) return Status; } cp=(EFI_HII_STRING_PACK*)((UINT8*)cp+cp->Header.Length); } phnd->StrCount=(STRING_REF)Package->NumStringPointers; phnd->HasStr=TRUE; return Status; } /////////////////////////////////////////////////////////////////// // IFR Releated Functions /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// //this one will calculate length in bytes for the buffer designed //to receive a copy of form instance //UINT16 GetFormLen(HII_FORM *Form){ // HII_LABEL *lbl; // UINTN i; // UINT16 len=Form->BufferLength; //------------------------ // for(i=0; iLabels.ItemCount; i++){ // lbl=Form->Labels.Items[i]; // if(lbl->Erased) len-=lbl->OrgDataLength; // len+=lbl->UpdDataLength; // } // return len; //} /////////////////////////////////////////////////////////////////// //this one will calculate length in bytes for the buffer designed //to receive a copy of FormSet instance //UINT16 GetFormSetLen(HII_FORMSET *FormSet){ // UINT16 len=0; // UINTN i; // HII_FORM *frm; //------------------ // for(i=0; iForms.ItemCount; i++){ // frm=FormSet->Forms.Items[i]; // len+=GetFormLen(frm); // } // return len+FormSet->FormSetData->Header.Length+FormSet->EndFormSet->Header.Length; //} UINTN GetDataLen( UINT8 *OpCode, UINTN *Count, BOOLEAN Remove){ UINTN i; UINTN len=0; UINT8 *p=OpCode; //------------------------ for(i=0; i<*Count; i++){ // if( !Remove && // ( (*p)==EFI_IFR_END_FORM_OP || (*p)==EFI_IFR_LABEL_OP ) // ){ // i=i; // } if( ( Remove && ( (*p)==EFI_IFR_END_FORM_OP || (*p)==EFI_IFR_LABEL_OP ) //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //when adding data I expect that caller knows what he is doing and //passes me correct Data Count. Guess what? This is not TRUE in Intel's Setup. //Intel uses Zeroed buffer to fill with desired Opcodes, set Data count to 0xFF and here we go. //In this case if in buffer we will found junk which satisfy conditions below //we can seriousely scrue up!!!!! //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO || ((*p)==0 || (*p)>EFI_IFR_VARSTORE_SELECT_PAIR_OP ))){ *Count=i; break; } len = len + ((EFI_IFR_OP_HEADER*)p)->Length; p=OpCode+len; } return len; } /////////////////////////////////////////////////////////////////// //this will copy form from HII DB private storage to decignated Buffer VOID CopyForm(UINT8* Buffer, HII_FORM *Form, UINTN *BytesCnt){ UINTN i,cnt=0; HII_LABEL *lbl=NULL; UINT8 *bp=Buffer; //---------------- //Now First Label has data starting from opcode next to FORM_OP //and lbl->Label of very first label in the list actualy FORM_OP //so don't need following code //if(Form->Labels.ItemCount)lbl=(HII_LABEL*)Form->Labels.Items[0]; //1. copy form till first label (including LABEL OPCODE) //if(lbl)//Total Bufferlength including EOF opcode // cnt=(UINT8*)(lbl->Label)-(UINT8*)Form->FormData; //else // cnt=Form->BufferLength-Form->EndForm->Header.Length; //pBS->CopyMem(bp,Form->FormData,For); //bp+=cnt; //Advance buffer pointer; //(*BytesCnt)=cnt; (*BytesCnt)=0; //Keep circling trough Labels copying corresponded data for(i=0;iLabels.ItemCount;i++){ lbl=(HII_LABEL*)Form->Labels.Items[i]; //copy Label OpCode pBS->CopyMem(bp,lbl->Label,lbl->Label->Header.Length); bp+=lbl->Label->Header.Length; (*BytesCnt)+=lbl->Label->Header.Length; //if Label was updated copy Update data first... if(lbl->LabelData){ pBS->CopyMem(bp,lbl->LabelData,lbl->DataLength); bp+=lbl->DataLength; (*BytesCnt)+=lbl->DataLength; } } //Copy EOF opcode cnt=Form->EndForm->Header.Length; pBS->CopyMem(bp,Form->EndForm,cnt); (*BytesCnt)+=cnt; return; } /////////////////////////////////////////////////////////////////// //will copy entire formset data excluding Pcakage Header VOID CopyFormSet(UINT8* Buffer, HII_FORMSET *FormSet, UINTN *BytesCnt){ UINTN i; UINT8 *bp=Buffer,*pp; UINTN cnt; HII_FORM *frm; //---------------- bp=Buffer; //Copy Formset OpCode... pBS->CopyMem(bp,FormSet->FormSetData,FormSet->FormSetData->Header.Length); bp+=FormSet->FormSetData->Header.Length; *BytesCnt=FormSet->FormSetData->Header.Length; //Copy any information that we might have from end of FormSet Opcode //to the befinning of FOrm OpCode VARSTORE for example. if(FormSet->Forms.ItemCount){ pp=(UINT8*)FormSet->FormSetData+FormSet->FormSetData->Header.Length; frm=FormSet->Forms.Items[0]; cnt=(UINTN)((UINT8*)frm->FormData-pp); pBS->CopyMem(bp,pp,cnt); bp+=cnt; *BytesCnt+=cnt; } for(i=0; iForms.ItemCount; i++){ frm=FormSet->Forms.Items[i]; CopyForm(bp,frm,&cnt); bp+=cnt; *BytesCnt+=cnt; } //copy END_OF_FORM_SET OP here cnt=FormSet->EndFormSet->Header.Length; pBS->CopyMem(bp,&FormSet->EndFormSet->Header.OpCode,cnt); *BytesCnt+=cnt; return; } /////////////////////////////////////////////////////////////////// //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO // Cache Form and Formset HII_FORM *LocateForm(HII_FORMSET *FormSet, EFI_FORM_ID FormId){ EFI_STATUS Status=0; UINTN fid; //---------------------------------------------- Status=LocateItem(&FormSet->Forms,&FormId,sizeof(EFI_FORM_ID),&fid); if(EFI_ERROR(Status)) return NULL; return (HII_FORM*)FormSet->Forms.Items[fid]; } /////////////////////////////////////////////////////////////////// //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO // Cache Form and Formset HII_FORMSET *LocateFormSet(UINTN HandleIdx, UINTN* FormSetIdx){ EFI_STATUS Status=0; UINTN fsid; //-------------------------- Status=LocateItem(&gHiiDb.IfrDb,&((UINT32)HandleIdx),sizeof(UINT32),&fsid); if(EFI_ERROR(Status)) return NULL; if(FormSetIdx!=NULL)*FormSetIdx=fsid; return (HII_FORMSET*)gHiiDb.IfrDb.Items[fsid]; } HII_LABEL *LocateFormLabel(HII_FORM *Form, EFI_FORM_LABEL LabelId, UINTN *LabelIdx){ EFI_STATUS Status=0; UINTN lid; //---------------------------------------------- Status=LocateItem(&Form->Labels,&LabelId, sizeof(EFI_FORM_LABEL),&lid); if(EFI_ERROR(Status)) return NULL; *LabelIdx=lid; return (HII_LABEL*)Form->Labels.Items[lid]; } HII_LABEL *LocateFormSetLabel(HII_FORMSET *FormSet, EFI_FORM_LABEL LabelId, UINTN *LabelIdx){ EFI_STATUS Status=0; UINTN lid; //---------------------------------------------- Status=LocateItem(&FormSet->Labels,&LabelId, sizeof(EFI_FORM_LABEL),&lid); if(EFI_ERROR(Status)) return NULL; if(LabelIdx)*LabelIdx=lid; return (HII_LABEL*)FormSet->Labels.Items[lid]; } /////////////////////////////////////////////////////////////////// //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //This MUST be here to make Shell working static UINT8 gDummyVfr[] = { //Header 0x2c, 0x00, 0x00, 0x00, //Actual Length of Data Buffer 0x03, 0x00, //Type; // start of IFR data /*O*/ 0x0E, //Opcode=EFI_IFR_FORM_SET_OP /*L*/ 0x24, //Length //Offset=8 /*G*/ 0xBC, 0x30, 0x0C, 0x9E, 0x06, 0x3F, 0xA6, 0x4B, 0x82, 0x88, 0x09, 0x17, 0x9B, 0x85, 0x5D, 0xBE, //GUID /*S*/ 0x02, 0x00, //FormSet Title /*S*/ 0x00, 0x00, //Help 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//Callback 0x00, 0x00, //Class 0x00, 0x00, //SubClass 0x00, 0x00, //NvDataSize /*O*/ 0x0D, //OpCOde=EFI_IFR_END_FORM_SET_OP /*L*/ 0x02, }; //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// EFI_STATUS HiiGetFormsNew(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN EFI_FORM_ID FormId, IN OUT UINTN *BufferLength, OUT UINT8 *Buffer) { UINTN hid; HII_FORMSET *fs; HII_FORM *frm; HII_HANDLE *phnd; UINTN len; //-------------------------------------- if(This==NULL && BufferLength==NULL) return EFI_INVALID_PARAMETER; //phnd=LocateHandle(Handle, &hid); //TODO: Felix: by the HII Spec. we should return EFI_INVALID_PARAMETER //However, Intel Device Manager expects EFI_NOT_FOUND //(it hangs if it is something else) phnd=LocateHandle(Handle, &hid); if(!phnd) return EFI_NOT_FOUND; fs=LocateFormSet(hid, NULL); if(!fs){ if(!FormId){ //Technically I must Return NOT_FOUND ERROR but... //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //this patch was made to keep Shell working. Shell and HII coexistance is //based on assumption that "It must be some IFR pack associated with String pack" //If this statement FALSE Shell will hang in INFINITE LOOP!!!! //////////////////////////////////////////////////////////////////////// //this comments I took from Intel's HII Database Driver // "If someone is passing in a string only, create a dummy IfrPack with a Guid // to enable future searching of this data." //////////////////////////////////////////////////////////////////////// if(*BufferLength< sizeof(gDummyVfr)) { *BufferLength=sizeof(gDummyVfr); return EFI_BUFFER_TOO_SMALL; } *BufferLength=sizeof(gDummyVfr); pBS->CopyMem(Buffer,&gDummyVfr[0],sizeof(gDummyVfr)); //copy handle guid here Shell expect it to mutch with some standart guids pBS->CopyMem((VOID*)(Buffer+8),(VOID*)&(phnd->Guid),sizeof(EFI_GUID)); return EFI_SUCCESS; } else return EFI_NOT_FOUND; //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO } if(!FormId){//we must return whole FormSet //STUPID SHELL expect me to return formset with EFI_HII_PACK_HEADER // why? I don't know! len=fs->BufferLength+sizeof(EFI_HII_PACK_HEADER); } else { frm=LocateForm(fs,FormId); if(!frm) return EFI_NOT_FOUND; len=frm->BufferLength; } if(*BufferLength 0xFFFF)) Status=EFI_INVALID_PARAMETER; return Status; } /////////////////////////////////////////////////////////////////// //Will free all memory blocks associated with Label->Objects structures VOID DeleteLabelObjects(HII_LABEL *Label){ UINTN i; HII_OBJECT *obj; //------------------ for(i=0;iObjects.ItemCount; i++){ obj=Label->Objects.Items[i]; ClearItemLst(&obj->Conditions,FALSE); ClearItemLst(&obj->Options,FALSE); } ClearItemLst(&Label->Objects,TRUE); } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiUpdateForm(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN EFI_FORM_LABEL Label, IN BOOLEAN AddData, IN EFI_HII_UPDATE_DATA *Data) { EFI_STATUS Status=0; UINTN hid,lid; HII_FORMSET *fs; HII_FORM *frm; HII_LABEL *lbl; UINTN len,cnt; UINT8 *ub; EFI_IFR_OP_HEADER *op; //------------------------- if(!This || !Data ) return EFI_INVALID_PARAMETER; if(!LocateHandle(Handle, &hid)) return EFI_INVALID_PARAMETER; //Find Formset fs=LocateFormSet(hid, NULL); if(!fs) return EFI_INVALID_PARAMETER; //Find Label //FormUpdate= TRUE means just change Form Title!!! if(Data->FormUpdate){ //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //In Intel's HII implementation Data->FormValue field is missing //Find Form using UPDATE Data // frm=LocateForm(fs,Data->FormValue); // if(!frm) return EFI_NOT_FOUND; //Update Form Title // frm->FormData->FormTitle=Data->FormTitle; //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO } // if(Data->DataCount){ //Find Label lbl=LocateFormSetLabel(fs, Label, &lid); if(!lbl) return EFI_NOT_FOUND; frm=lbl->OwnerForm; cnt=Data->DataCount; if(AddData){ op=(EFI_IFR_OP_HEADER*)&Data->Data; if(!op->OpCode || !op->Length) return EFI_INVALID_PARAMETER; //Calculate size of UPDATE data len=GetDataLen((UINT8*)op,&cnt,FALSE); ub=Malloc(len+lbl->DataLength); if(!ub) return EFI_OUT_OF_RESOURCES; //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //Copy Update Data in Private Buffer pBS->CopyMem(ub,op,len); //Copy Old Data in same Private Buffer if(lbl->LabelData)pBS->CopyMem((VOID*)(ub+len),lbl->LabelData,lbl->DataLength); //for coimpatibility with Intel's setup I've change order in which the chanks of opcodes // been copied in a new label buffer - New data will be added after the old data //if(lbl->LabelData)pBS->CopyMem(ub,lbl->LabelData,lbl->DataLength); //pBS->CopyMem((VOID*)(ub+lbl->DataLength),op,len); //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //Update Buffer parameters in every structure affected by update lbl->DataLength = lbl->DataLength + len; lbl->DataCount = lbl->DataCount + Data->DataCount; if(lbl->Updated && lbl->LabelData)pBS->FreePool(lbl->LabelData); lbl->LabelData=(EFI_IFR_OP_HEADER*)ub; fs->BufferLength = fs->BufferLength + len; frm->BufferLength = frm->BufferLength + len; //Delete Old Data DeleteLabelObjects(lbl); }else{ //we will not erase an empty Label! if(lbl->LabelData){ op=lbl->LabelData; if(Data->DataCount>=lbl->DataCount){ cnt=lbl->DataCount; len=lbl->DataLength; } else len=GetDataLen((UINT8*)op,&cnt,TRUE); //if after erasing no data has left, no need to allocate new buffer if((INTN)(lbl->DataLength-len)>0){ ub=Malloc(lbl->DataLength-len); if(!ub) return EFI_OUT_OF_RESOURCES; //Copy rest of Old Data in Private Buffer pBS->CopyMem(ub,(UINT8*)lbl->LabelData+len,lbl->DataLength-len); } else ub=NULL; //Update Buffer parameters in every structure affected by update lbl->DataLength = lbl->DataLength - len; lbl->DataCount = lbl->DataCount - cnt; if(lbl->Updated && lbl->LabelData)pBS->FreePool(lbl->LabelData); lbl->LabelData=(EFI_IFR_OP_HEADER*)ub; fs->BufferLength = fs->BufferLength - len; frm->BufferLength = frm->BufferLength - len; DeleteLabelObjects(lbl); } } //Populate pointers on Label Objects from Label Dtat Buffer if(lbl->LabelData!=NULL)Status=CreateLabelObjects(lbl); if(EFI_ERROR(Status))return Status; lbl->Updated=TRUE; if(lbl->UpdateCallBack) lbl->UpdateCallBack(Label, Handle,AddData); } if(Data->FormSetUpdate){ fs->FormSetData->CallbackHandle=Data->FormCallbackHandle; } return EFI_SUCCESS; } EFI_STATUS InitDefStorage(HII_FORMSET *FormSet){ EFI_STATUS Status; HII_STORE *st; static CHAR8 *ss="Setup";//{'S','e','t','u','p',0}; CHAR8 *pn;//pointer to var name; //------------------------------------------------ st=MallocZ(sizeof(HII_STORE)); if(!st)return EFI_OUT_OF_RESOURCES; Status=AppendItemLst(&FormSet->Storages,st); st->VarStore=MallocZ(sizeof(EFI_IFR_VARSTORE)+6); if(!st->VarStore)return EFI_OUT_OF_RESOURCES; //Init Default VarStore Structure VarId is Always 0x0000 st->VarStore->Header.Length=sizeof(EFI_IFR_VARSTORE)+6; st->VarStore->Header.OpCode=EFI_IFR_VARSTORE_OP; st->VarStore->Size=FormSet->FormSetData->NvDataSize; //Copy formset GUID here pBS->CopyMem(&st->VarStore->Guid,&FormSet->FormSetData->Guid,sizeof(EFI_GUID)); pn=(CHAR8*)st->VarStore; pn+=sizeof(EFI_IFR_VARSTORE); pBS->CopyMem(pn,ss,6); return EFI_SUCCESS; } //Selects Var Store Object HII_STORE *LocateStorage(HII_FORMSET *FormSet, UINT16 VarId, UINTN *StoreId OPTIONAL){ UINTN i; HII_STORE *st; //--------------------- for(i=0; iStorages.ItemCount; i++){ st=(HII_STORE*)FormSet->Storages.Items[i]; if(st->VarStore->VarId==VarId) { if(StoreId)*StoreId=i; return st; } } return NULL; } EFI_STATUS CreateLabelObjects(HII_LABEL *Label) { EFI_IFR_OP_HEADER *op; UINTN i,j=0, k; HII_OBJECT *obj=NULL; HII_STORE *st1=NULL, *st2=NULL; static T_ITEM_LIST clst={0,0,NULL},olst={0,0,NULL}; //temp conditions and objects list list static T_ITEM_LIST supprstores = {0, 0, NULL}; EFI_STATUS Status; BOOLEAN cf=FALSE; //conditions flag BOOLEAN Suppress = FALSE; //------------------------------------------- op=Label->LabelData; obj=NULL; //st1=(HII_STORE*)Label->OwnerForm->Owner->Storages.Items[0]; st1 = LocateStorage(Label->OwnerForm->Owner, CurrentVarId, NULL); if(!st1) { st1=(HII_STORE*)Label->OwnerForm->Owner->Storages.Items[0]; CurrentVarId = 0; } st2=NULL; for(i=0;iDataCount;i++){ //Select Default Storage so Store1 switch(op->OpCode){ //Storage Select Opcodes case EFI_IFR_VARSTORE_SELECT_OP: { EFI_IFR_VARSTORE_SELECT *vs=(EFI_IFR_VARSTORE_SELECT*)op; HII_STORE *st=LocateStorage(Label->OwnerForm->Owner,vs->VarId,NULL); // preserve the varstore selection - to be reset only by the next varstore select // or a new formset //------------------------ if(st) { st1=st; CurrentVarId = vs->VarId; } } break; case EFI_IFR_VARSTORE_SELECT_PAIR_OP: { EFI_IFR_VARSTORE_SELECT_PAIR *v2=(EFI_IFR_VARSTORE_SELECT_PAIR*)op; HII_STORE *s1=LocateStorage(Label->OwnerForm->Owner,v2->VarId,NULL); HII_STORE *s2=LocateStorage(Label->OwnerForm->Owner,v2->SecondaryVarId,NULL); //------------------------ if(s1) { st1=s1; CurrentVarId = v2->VarId; } if(s2) st2=s2; } break; //Condition OpCodes case EFI_IFR_GRAYOUT_IF_OP: case EFI_IFR_SUPPRESS_IF_OP: case EFI_IFR_INCONSISTENT_IF_OP: //if we found some logical expression and local ovject list(olst) has some objects //we must add this objects with no conditions to the Label->Objects list //and clear local object list to start fill it with objects who has conditions. if(!cf){ for(j=0;jObjects,obj); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status; } ClearItemLst(&olst,FALSE); obj=NULL; } cf=TRUE; if( op->OpCode == EFI_IFR_SUPPRESS_IF_OP) Suppress = TRUE; else Suppress = FALSE; /////////////////////////////////////////////////////////////////////// //Do not add break instruction here it is not present for a reason!!!! /////////////////////////////////////////////////////////////////////// case EFI_IFR_AND_OP: case EFI_IFR_OR_OP: case EFI_IFR_NOT_OP: case EFI_IFR_EQ_ID_VAL_OP: case EFI_IFR_EQ_ID_ID_OP: case EFI_IFR_EQ_ID_LIST_OP: case EFI_IFR_EQ_VAR_VAL_OP: //Add Opcode to the temp Condition list; Status=AppendItemLst(&clst,op); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status;//out of resources if(op->OpCode == EFI_IFR_EQ_ID_VAL_OP && Suppress) { Status = AppendItemLst(&supprstores, st1); ASSERT(!EFI_ERROR(Status)); } break; //end of conditions OpCode case EFI_IFR_END_IF_OP: //this is definetely end of object presentation, //but some times it might be no object to add conditions info to if(!olst.ItemCount){ for(j=0; jConditions,clst.Items[j]); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status; } } for(j=0;j0, then next call to //Append ItemLst function will allocate this number of entries for ItemList.Items[] Array. obj->Conditions.InitialCount=clst.ItemCount; Status=AppendItemLst(&obj->Conditions,clst.Items[0]); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status; pBS->CopyMem(&obj->Conditions.Items[1],&clst.Items[1],sizeof(VOID*)*(clst.ItemCount-1)); obj->Conditions.ItemCount=clst.ItemCount; for(k = 0; k < supprstores.ItemCount; k++) { Status=AppendItemLst(&obj->SuppressStores,supprstores.Items[k]); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status; } Status=AppendItemLst(&Label->Objects,obj); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status; } ClearItemLst(&clst,FALSE); //don't need to free data - it's VFR pointers! ClearItemLst(&olst,FALSE); ClearItemLst(&supprstores,FALSE); obj=NULL; cf=FALSE; Suppress = FALSE; break; //visual opcodes case EFI_IFR_SUBTITLE_OP: case EFI_IFR_TEXT_OP: case EFI_IFR_INVENTORY_OP: case EFI_IFR_GRAPHIC_OP: case EFI_IFR_CHECKBOX_OP: case EFI_IFR_NUMERIC_OP: case EFI_IFR_PASSWORD_OP: case EFI_IFR_REF_OP: case EFI_IFR_DATE_OP: case EFI_IFR_TIME_OP: case EFI_IFR_STRING_OP: case EFI_IFR_SAVE_DEFAULTS_OP: case EFI_IFR_RESTORE_DEFAULTS_OP: case EFI_IFR_HIDDEN_OP: //continiouse case EFI_IFR_ONE_OF_OP: case EFI_IFR_ORDERED_LIST_OP: ASSERT(!obj); //obj pointer must be cleared when we enter there if(obj)return EFI_INVALID_PARAMETER; obj=MallocZ(sizeof(HII_OBJECT)); ASSERT(obj);//Allocation Problems! if(!obj) return EFI_OUT_OF_RESOURCES; obj->ObjectCode=op; obj->Store1=st1; obj->Store2=st2; Status=AppendItemLst(&olst,obj); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status; //in case of DATE or Time opcode advance by 2 opcodes if(op->OpCode==EFI_IFR_TIME_OP || op->OpCode==EFI_IFR_DATE_OP){ op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length); op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length); i+=2; } obj=NULL; break; case EFI_IFR_ONE_OF_OPTION_OP: ASSERT(olst.ItemCount); if(!olst.ItemCount) return EFI_INVALID_PARAMETER; obj=(HII_OBJECT*)olst.Items[olst.ItemCount-1]; if(!obj) return EFI_INVALID_PARAMETER; //obj must be allocated! Status=AppendItemLst(&obj->Options,op); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status;//out of resources break; case EFI_IFR_END_ONE_OF_OP: obj=NULL; break; }//end switch; //Advance to next opcode op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length); } //If there were no any Condition Opcodes contents of the ObjectList(olst) was not copied to the Label.Objects for(j=0;jObjects,obj); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status)) return Status; } ClearItemLst(&olst,FALSE); return EFI_SUCCESS; } //This Routine is called to parse FormVfr and Create Objects which must be shown on the screen; EFI_STATUS CreateFormObjects(HII_FORM *Form){ UINTN i; EFI_STATUS Status = EFI_SUCCESS; //--------------------------------- for(i=0; iLabels.ItemCount; i++){ Status=CreateLabelObjects((HII_LABEL*)Form->Labels.Items[i]); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status))return Status; } return Status; } EFI_STATUS NewKbdPack(EFI_HII_KEYBOARD_PACK *Package, UINTN HandleId) { EFI_STATUS Status; HII_KB_LAYOUT_DATA *kbld; //-------------------- //Get Some Memory to accomodate Kb Layout Buffer kbld=Malloc(sizeof(EFI_KEY_DESCRIPTOR)*Package->DescriptorCount+sizeof(HII_KB_LAYOUT_DATA)); ASSERT(kbld); if(kbld==NULL) return EFI_OUT_OF_RESOURCES; kbld->HandleIndex=HandleId; //just in case to find HII_HANDLE structure assotiated with this PACK kbld->KeyDscCount=Package->DescriptorCount; //We will store KB Layout Data right after the HII_KB_LAYOUT_DATA structure itself kbld->KeyDsc=(EFI_KEY_DESCRIPTOR*)(kbld+1); MemCpy((VOID*)kbld->KeyDsc, (VOID*)Package->Descriptor, sizeof(EFI_KEY_DESCRIPTOR)*kbld->KeyDscCount); //Add saved KB Layout Data to the HII DB Status=AppendItemLst((T_ITEM_LIST*)&gHiiDb.KeybdDb.KblInitCount,(VOID*)kbld); ASSERT_EFI_ERROR(Status); //Set recently submitted KB Layout as the current one gHiiDb.KeybdDb.ActiveLayout=gHiiDb.KeybdDb.KblCount-1; return Status; } EFI_STATUS NewIfrPack(EFI_HII_IFR_PACK *Package, UINTN HandleId) { EFI_STATUS Status; EFI_IFR_OP_HEADER *op; // INT32 id=0; HII_FORM *cf=NULL; HII_FORMSET *cfs=NULL; HII_LABEL *cl=NULL; HII_STORE *st=NULL; HII_HANDLE *phnd=(HII_HANDLE*)gHiiDb.HandleDb.Items[HandleId]; UINT8 *p; BOOLEAN la=FALSE;//label active flag - helps count OPCODES and Label.dLength //--------------------------------------------- //Copy Data to a new Storage =(EFI_IFR_OP_HEADER*)(Package+1); p=Malloc(Package->Header.Length); if(!p) return EFI_OUT_OF_RESOURCES; pBS->CopyMem(p,Package,Package->Header.Length); op=(EFI_IFR_OP_HEADER*)(p+sizeof(EFI_HII_PACK_HEADER)); //Parse IFR and crete Working set of data //Every IFR Pack must start from FORM_SET_OP while(/*(op->OpCode!=EFI_IFR_END_FORM_SET_OP)||*/((UINTN)op<((UINTN)p)+Package->Header.Length)){ switch (op->OpCode){ //Take care of Forms Sets case EFI_IFR_FORM_SET_OP: CurrentVarId = 0; cfs=MallocZ(sizeof(HII_FORMSET)); if(!cfs) return EFI_OUT_OF_RESOURCES; //cfs->BufferLength=0; it is 0 cfs->FormSetData=(EFI_IFR_FORM_SET*)op; cfs->HandleId=(UINT32)HandleId; cfs->Handle=phnd->Handle; //Setup Initial Storage var Status=InitDefStorage(cfs); if(EFI_ERROR(Status)) return Status; break; case EFI_IFR_VARSTORE_OP: if(!cfs) return EFI_INVALID_PARAMETER; st=MallocZ(sizeof(HII_STORE)); if(!st) return EFI_OUT_OF_RESOURCES; Status=AppendItemLst(&cfs->Storages,st); st->VarStore=(EFI_IFR_VARSTORE*)op; break; case EFI_IFR_END_FORM_SET_OP: if(!cfs)return EFI_INVALID_PARAMETER; //found EFI_IFR_END_FORM_SET_OP without EFI_IFR_FORM_SET_OP //cfs->BufferLength=(UINT16)((UINT8*)op+op->Length-(UINT8*)cfs->FormSetData); CurrentVarId = 0; cfs->EndFormSet=(EFI_IFR_END_FORM_SET*)op; cfs->HandleId=(UINT32)HandleId; cfs->BufferLength = cfs->BufferLength + op->Length; Status=AppendItemLst(&gHiiDb.IfrDb,(VOID*)cfs); if(EFI_ERROR(Status)) return Status; cfs=NULL; break; //Take care of Forms and Labels case EFI_IFR_FORM_OP: case EFI_IFR_LABEL_OP: { EFI_IFR_OP_HEADER *nxt; //---------------------------- if(op->OpCode==EFI_IFR_FORM_OP){ //it must be some FORM_SET OpCode before we met FORM OpCode if(!cfs) return EFI_INVALID_PARAMETER; cf=MallocZ(sizeof(HII_FORM)); if(!cf) return EFI_OUT_OF_RESOURCES; //cf->BufferLength=0; cf->FormData=(EFI_IFR_FORM*)op; cf->FormId=cf->FormData->FormId; cf->Owner=cfs; } if(!cf && !cfs )return EFI_INVALID_PARAMETER; //Form mus be present cl=MallocZ(sizeof(HII_LABEL)); if(!cl) return EFI_OUT_OF_RESOURCES; cl->OwnerForm=cf; cl->Label=(EFI_IFR_LABEL*)op; //it must be a valid opcode next... nxt=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length); if(nxt->OpCode!=EFI_IFR_END_FORM_OP && nxt->OpCode!=EFI_IFR_LABEL_OP)cl->LabelData=nxt; if(op->OpCode==EFI_IFR_FORM_OP){ cl->LabelId=0xFACE; //Fake LabelID } else { cl->LabelId=cl->Label->LabelId; Status=AppendItemLst(&cfs->Labels,cl); if(EFI_ERROR(Status)) return Status; } Status=AppendItemLst(&cf->Labels,cl); if(EFI_ERROR(Status)) return Status; la=TRUE; } break; case EFI_IFR_END_FORM_OP: if(!cf)return EFI_INVALID_PARAMETER; //found EFI_IFR_END_FORM_OP without EFI_IFR_FORM_OP //cf->BufferLength=(UINT16)((UINT8*)op+op->Length-(UINT8*)cf->FormData); cf->EndForm=(EFI_IFR_END_FORM*)op; cf->BufferLength = cf->BufferLength + op->Length; Status=AppendItemLst(&cfs->Forms,cf); if(EFI_ERROR(Status)) return Status; Status=CreateFormObjects(cf); cf=NULL; la=FALSE; break; //Labels Has Left /*case EFI_IFR_LABEL_OP:{ EFI_IFR_OP_HEADER *nxt; //--------------------------- if(!cf && !cfs )return EFI_INVALID_PARAMETER; //Form mus be present cl=MallocZ(sizeof(HII_LABEL)); if(!cl) return EFI_OUT_OF_RESOURCES; cl->Label=(EFI_IFR_LABEL*)op; cl->LabelId=cl->Label->LabelId; cl->OwnerForm=cf; nxt=(EFI_IFR_OP_HEADER*)(cl->Label+1); //it must be a valid opcode next... if(nxt->OpCode!=EFI_IFR_END_FORM_OP && nxt->OpCode!=EFI_IFR_LABEL_OP)cl->LabelData=nxt; Status=AppendItemLst(&cf->Labels,cl); if(EFI_ERROR(Status)) return Status; Status=AppendItemLst(&cfs->Labels,cl); if(EFI_ERROR(Status)) return Status; la=TRUE; break; } */ default : if(la){ cl->DataCount++; cl->DataLength = cl->DataLength + op->Length; } } //Switch if(cfs)cfs->BufferLength = cfs->BufferLength + op->Length; if(cf)cf->BufferLength = cf->BufferLength + op->Length; op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length); } phnd->Ifr=p; return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// // Common Interface functions /////////////////////////////////////////////////////////////////// EFI_STATUS HiiNewPackNew(IN EFI_HII_PROTOCOL *This, IN EFI_HII_PACKAGES *Packages, OUT EFI_HII_HANDLE *Handle) { UINTN i; EFI_HII_PACK_HEADER *hdr, **hdrptr; EFI_STATUS Status=0; UINTN c=0,hid=0; HII_HANDLE *phnd=NULL; BOOLEAN sp=0,vp=0,hp=0; //----------------------------------------- if(!This) return EFI_INVALID_PARAMETER; hdrptr=(EFI_HII_PACK_HEADER**)(Packages+1); for(i=0; iNumberOfPackages; i++){ hdr=hdrptr[i]; switch(hdr->Type){ case EFI_HII_FONT: Status=NewFontPack((EFI_HII_FONT_PACK*)hdr); if(EFI_ERROR(Status)) return Status; break; case EFI_HII_STRING: if(sp)return EFI_INVALID_PARAMETER; phnd=LocateHandleGuid(Packages->GuidId,&hid); //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //this is wrong !!! //here we are trying to check if somebody using passed GuidId registered Ifr with us //it should not be like this but Intel's Setup Browser uses same GuidId sor 2 different //Ifr instances. To maintain compatibility I'll try to patch code... if(!phnd || phnd->HasStr){ //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO Status=LocateHandleAdd(gHiiDb.NextHiiHandle,Packages->GuidId,&hid); if(Status) return Status; else c++; phnd=gHiiDb.HandleDb.Items[hid]; } Status=NewStringPack((EFI_HII_STRING_PACK*)hdr, hid); if(EFI_ERROR(Status)) return Status; sp=TRUE; break; case EFI_HII_IFR: if(vp)return EFI_INVALID_PARAMETER; phnd=LocateHandleGuid(Packages->GuidId,&hid); //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //this is wrong !!!//same goes gor IFR if(!phnd || phnd->Ifr){ //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO Status=LocateHandleAdd(gHiiDb.NextHiiHandle,Packages->GuidId,&hid); if(Status) return Status; else c++; phnd=gHiiDb.HandleDb.Items[hid]; } Status=NewIfrPack((EFI_HII_IFR_PACK*)hdr, hid); if(EFI_ERROR(Status)) return Status; vp=TRUE; break; case EFI_HII_KEYBOARD: Status=NewKbdPack((EFI_HII_KEYBOARD_PACK*)hdr, hid); break; case EFI_HII_HANDLES: if(hp)return EFI_INVALID_PARAMETER; //TODO hp=TRUE; break; case EFI_HII_VARIABLE: //TODO break; case EFI_HII_DEVICE_PATH: //TODO break; default: return EFI_INVALID_PARAMETER; }//switch } if(c)gHiiDb.NextHiiHandle++; if(phnd)*Handle=phnd->Handle; else *Handle=0; return Status; } EFI_STATUS HiiNewPackOld (IN EFI_HII_PROTOCOL *This, IN EFI_HII_PACK_LIST *Package, OUT EFI_HII_HANDLE *Handle) { EFI_STATUS Status=0; UINTN c=0,hid; HII_HANDLE *phnd=NULL; //---------------------------------- if(!This) return EFI_INVALID_PARAMETER; //Check if we have this GUID ib GuidDb already //For Font and Keyboadr Data HAndle is allways = 0 if(Package->FontPack) Status=NewFontPack(Package->FontPack); if(EFI_ERROR(Status)) return Status; if(Package->StringPack){ phnd=LocateHandleGuid(Package->GuidId,&hid); //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //this is wrong !!! //here we are trying to check if somebody using passed GuidId registered Ifr with us //it should not be like this but Intel's Setup Browser uses same GuidId sor 2 different //Ifr instances. To maintain compatibility I'll try to patch code... if(!phnd || phnd->HasStr){ //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO // if(!phnd){ Status=LocateHandleAdd(gHiiDb.NextHiiHandle,Package->GuidId,&hid); if(Status) return Status; else c++; phnd=gHiiDb.HandleDb.Items[hid]; } //if(phnd->HasStr) return EFI_INVALID_PARAMETER; Status=NewStringPack(Package->StringPack, hid); if(EFI_ERROR(Status)) return Status; } if(Package->IfrPack){ phnd=LocateHandleGuid(Package->GuidId,&hid); //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //this is wrong !!! //here we are trying to check if somebody using passed GuidId registered Ifr with us //it should not be like this but Intel's Setup Browser uses same GuidId sor 2 different //Ifr instances. To maintain compatibility I'll try to patch code... if(!phnd || phnd->Ifr){ //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO // if(!phnd){ Status=LocateHandleAdd(gHiiDb.NextHiiHandle,Package->GuidId,&hid); if(Status) return Status; else c++; phnd=gHiiDb.HandleDb.Items[hid]; } //if(phnd->HasIfr) return EFI_INVALID_PARAMETER; Status=NewIfrPack(Package->IfrPack, hid); if(EFI_ERROR(Status)) return Status; } //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //nothing is done for keyboard layout functions //this is empty spot in spec! //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO if(c)gHiiDb.NextHiiHandle++; if(phnd)*Handle=phnd->Handle; else *Handle=0; return Status; } /////////////////////////////////////////////////////////////////// //TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO //this function even not in spec yet so UNSUPPORT it!!! // here is an explanation I've got from Initial's Source // "This function allows to extract the NV Image // that represents the default storage image" //Still Unclear what to do with it EFI_STATUS HiiGetDefaultImageOld(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN UINTN DefaultMask, IN OUT UINT16 *BufferLength, IN OUT UINT8 *Buffer) { HII_HANDLE *phnd; HII_FORMSET *fs; EFI_IFR_OP_HEADER *op; UINTN hi,fsi,i,t=0,cv=0; UINT8 *fsb;//formset buffer BOOLEAN ol=FALSE; EFI_STATUS Status; //--------------------------------- if(!This) return EFI_INVALID_PARAMETER; phnd=LocateHandle(Handle,&hi); if(!phnd || !phnd->Ifr) return EFI_INVALID_PARAMETER; fs=LocateFormSet(hi,&fsi); if(!fs) return EFI_INVALID_PARAMETER; if(*BufferLengthFormSetData->NvDataSize){ *BufferLength=fs->FormSetData->NvDataSize; return EFI_BUFFER_TOO_SMALL; } *BufferLength=fs->FormSetData->NvDataSize; i=*BufferLength; if (DefaultMask & EFI_IFR_FLAG_DEFAULT) Status=pRS->GetVariable(L"SetupDefaultOverride",&phnd->Guid,NULL,&i,Buffer); else { if (DefaultMask & EFI_IFR_FLAG_MANUFACTURING) Status=pRS->GetVariable(L"SetupManufacturingOverride",&phnd->Guid,NULL,&i,Buffer); else { DefaultMask = DefaultMask | EFI_IFR_FLAG_DEFAULT; Status=pRS->GetVariable(L"Setup",&phnd->Guid,NULL,&i,Buffer); } } fsb=Malloc(fs->BufferLength); if(!fsb) return EFI_OUT_OF_RESOURCES; CopyFormSet(fsb,fs,&i); op=(EFI_IFR_OP_HEADER*)fsb; while(op->OpCode!=EFI_IFR_END_FORM_SET_OP){ switch(op->OpCode){ case EFI_IFR_ORDERED_LIST_OP: ol=TRUE; i=((EFI_IFR_ONE_OF*)op)->QuestionId; t=((EFI_IFR_ONE_OF*)op)->Width; break; case EFI_IFR_ONE_OF_OP: ol=FALSE; i=((EFI_IFR_ONE_OF*)op)->QuestionId; t=((EFI_IFR_ONE_OF*)op)->Width; break; case EFI_IFR_ONE_OF_OPTION_OP:{ EFI_IFR_ONE_OF_OPTION *ifro=(EFI_IFR_ONE_OF_OPTION*)op; //----------------- if(!cv){ if(ol){ //pBS->CopyMem(&Buffer[i],&((EFI_IFR_ONE_OF_OPTION*)op)->Value, 1); pBS->CopyMem(&Buffer[i],&ifro->Value, 1); i++; } else { //if (((EFI_IFR_ONE_OF_OPTION*)op)->Flags & DefaultMask) // pBS->CopyMem(&Buffer[i],&((EFI_IFR_ONE_OF_OPTION*)op)->Value,t); if (ifro->Flags & DefaultMask) pBS->CopyMem(&Buffer[i],&ifro->Value,t); } } } break; case EFI_IFR_END_OP: t=0; break; case EFI_IFR_CHECKBOX_OP:{ EFI_IFR_CHECK_BOX *ifrc=(EFI_IFR_CHECK_BOX*)op; //-------------------- if(!cv){ //if(((EFI_IFR_CHECK_BOX*)op)->Flags & DefaultMask) // Buffer[((EFI_IFR_CHECK_BOX*)op)->QuestionId] = 1; //else // Buffer[((EFI_IFR_CHECK_BOX*)op)->QuestionId] = 0; if(ifrc->Flags & DefaultMask) Buffer[ifrc->QuestionId] = 1; else Buffer[ifrc->QuestionId] = 0; } } break; case EFI_IFR_NUMERIC_OP:{ EFI_IFR_NUMERIC *ifrn=(EFI_IFR_NUMERIC*)op; //-------------------------- //if (!cv)pBS->CopyMem(&Buffer[((EFI_IFR_NUMERIC*)op)->QuestionId], // &((EFI_IFR_NUMERIC*)op)->Default,((EFI_IFR_NUMERIC*)op)->Width); if (!cv){ pBS->CopyMem(&Buffer[ifrn->QuestionId], &ifrn->Default,ifrn->Width); } } break; case EFI_IFR_VARSTORE_SELECT_OP: case EFI_IFR_VARSTORE_SELECT_PAIR_OP: cv=((EFI_IFR_VARSTORE_SELECT*)op)->VarId; break; } op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length); } pBS->FreePool(fsb); return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiFindHandles(IN EFI_HII_PROTOCOL *This, //spec not says in what units assume, for now, it is in EFI_HII_HANDLE IN OUT UINT16 *HandleBufferLength, OUT EFI_HII_HANDLE *Handle) { UINTN i; HII_HANDLE *hnd; //------------------------------- if(!This) return EFI_INVALID_PARAMETER; if(*HandleBufferLengthHandle; } return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// // Will remove all stuff associated with form set on particular handle // including all Update Data and Free all memory used to store private data // This function assumes "HandleIdx" is valid. VOID RemoveFormSet(UINTN HandleIdx){ HII_FORMSET *fst; HII_FORM *frm; HII_LABEL *lbl; UINTN i,j,fsi; //-------------------------------- while(TRUE) { //it might be more then one formset with the same Handle fst=LocateFormSet(HandleIdx, &fsi); if(!fst) return; //Not a single form set was registred with this Handle for(i=0;iForms.ItemCount;i++){ frm=(HII_FORM*)fst->Forms.Items[i]; for(j=0;jLabels.ItemCount;j++){ lbl=frm->Labels.Items[j]; DeleteLabelObjects(lbl); if(lbl->LabelData && lbl->Updated) pBS->FreePool(lbl->LabelData); } ClearItemLst(&frm->Labels,TRUE); } ClearItemLst(&fst->Labels,FALSE); ClearItemLst(&fst->Forms,TRUE); DeleteItemLst(&gHiiDb.IfrDb,fsi,TRUE); } } /////////////////////////////////////////////////////////////////// // Will remove all String records associated with "HandleIdx" for // all languages. This function assumes "HandleIdx" is valid. VOID RemoveStrings(UINTN HandleIdx){ HII_HANDLE *hnd=(HII_HANDLE*)gHiiDb.HandleDb.Items[HandleIdx]; HII_STR *str; INTN i; //----------------------- for(i=0; (UINTN)iHandle==hnd->Handle){ if(str->String.StrPtr)pBS->FreePool(str->String.StrPtr); if(str->NewStr.StrPtr)pBS->FreePool(str->NewStr.StrPtr); DbeDelete(&gHiiDb.StringDb,str,TRUE); i--; continue; } if(str->Handle>hnd->Handle) break; } } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiRemovePack(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle) { UINTN hid; HII_HANDLE *phnd; HII_FORMSET *fs; UINTN i; //-------------------- if(!This) return EFI_INVALID_PARAMETER; //Here we will try to remove Pack from DB phnd=LocateHandle(Handle,&hid); if(!phnd) return EFI_INVALID_PARAMETER; //So we found requested Handle, now remove all stuff associated with it. //Remove IFRs if(phnd->Ifr){ RemoveFormSet(hid); pBS->FreePool(phnd->Ifr); } //Remove Strings if(phnd->HasStr)RemoveStrings(hid); //Free Items[] buffer if it was allocated //if no Secondary Languages installed for this HII_HANDLE nothing has to be done if(phnd->SecLang.ItemCount)ClearItemLst(&phnd->SecLang,FALSE); //reindexing remaining formsets to take care of //removed HII_HANDLE record from HiiDB.HandleDb[] for(i=0; iHandleId>hid) fs->HandleId--; } DeleteItemLst(&gHiiDb.HandleDb, hid, TRUE); //The current saved handle might be pointing on the one been removed. //so reset them to initial values. mCurHnd=NULL; mCurLang=NULL; mCurHid=0; mCurLid=0; mCurStr=NULL; return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// //HelperFunction to calculate size needed to dump the database //excluding EFI_HII_DATA_TABLE header UINTN GetHandleExpBuffSize(HII_HANDLE *HiiHandle, UINTN HndIndex){ UINTN sz=0, i, li=(UINTN)-1; HII_FORMSET *fs=NULL; HII_STR *str=NULL; HII_STORE *st=NULL; //------------------------------------- //This is an order of data structures as provided in Intel's implementation //DevPath Data stuff Dummy so far just reserve space for DP_PACK and END_OF_DP sz+=sizeof(EFI_HII_DEVICE_PATH_PACK)+sizeof(EFI_DEVICE_PATH_PROTOCOL); //Find Formset we are working with fs=LocateFormSet(HndIndex, NULL); if(!fs) sz+= sizeof(gDummyVfr); //no formset no VAR data just Dummy Formset else { //Variable data for(i=0; iStorages.ItemCount; i++){ //-------------------- st=fs->Storages.Items[i]; if(st->VarStore->Size){ UINT8 *p; UINTN ind = 0, vsize = 0; UINT16 VarName[256] = {0}; //--------------------- sz+=sizeof(EFI_HII_VARIABLE_PACK); //sz+=st->VarStore->Size; p=(UINT8*)(st->VarStore+1); while(*p){ p++; vsize+=sizeof(UINT16); } vsize+=sizeof(UINT16);//NULL terminator sz+=vsize; p=(UINT8*)(st->VarStore+1); while(*p && ind < sizeof(VarName)){ VarName[ind] = (CHAR16)*p; p++; ind++; } vsize=0; pRS->GetVariable(VarName,&st->VarStore->Guid,NULL,&vsize,NULL); if(vsize) sz+=vsize; else sz += st->VarStore->Size; } } if(fs->Storages.ItemCount > 0) sz+=sizeof(EFI_HII_VARIABLE_PACK); // !! added dummy VARIABLE PACK //formset data size sz+=fs->BufferLength+sizeof(EFI_HII_PACK_HEADER);// !! changed to += } //string data size if(HiiHandle->HasStr){ for(i=0; iHandle==HiiHandle->Handle){ if((li==-1)||(li!=str->LangIdx)){ li=str->LangIdx; sz+=sizeof(EFI_HII_STRING_PACK); //new pack for new language } //the StrLen stored in UNICODECHAR units if(str->NewStr.StrPtr)sz+=str->NewStr.StrLen*sizeof(CHAR16)+sizeof(RELOFST); else sz+=str->String.StrLen*sizeof(CHAR16)+sizeof(RELOFST); } if((str->Handle>HiiHandle->Handle)||(i==gHiiDb.StringDb.RecordCount-1)){ sz+=sizeof(EFI_HII_STRING_PACK);//terminator pack break; } } } return sz; } UINT32 CountStrOfLang(HII_HANDLE *HiiHandle, UINTN StartIdx, UINTN LangIdx ){ UINTN i; UINT32 cnt=0; HII_STR *str; //---------------------- for (i=StartIdx; iHandle==HiiHandle->Handle){ if(str->LangIdx==LangIdx)cnt++; else break; } else break; } return cnt; } VOID ExportHandleData(IN HII_HANDLE *HiiHandle, IN UINTN HndIndex, IN EFI_HII_DATA_TABLE *DataTbl, IN OUT UINT8 **BufferPointer) { UINTN sz=0, i; HII_FORMSET *fs; HII_STR *str; HII_STORE *st; UINT8 *p1=*BufferPointer, *p2; EFI_STATUS Status; //------------------------------------- //This is an order of data structures as provided in Intel's implementation //DevPath Data stuff Dummy so far END_OF_DP DataTbl->DevicePathOffset=(UINT32)(p1-(UINT8*)DataTbl); ((EFI_HII_DEVICE_PATH_PACK*)p1)->Header.Type=EFI_HII_DEVICE_PATH; //points to the space after EFI_HII_DEVICE_PATH_PACK structure p2=(p1+sizeof(EFI_HII_DEVICE_PATH_PACK)); ((EFI_DEVICE_PATH_PROTOCOL*)p2)->Type=0xFF; ((EFI_DEVICE_PATH_PROTOCOL*)p2)->SubType=0xFF; // ((EFI_DEVICE_PATH_PROTOCOL*)p2)->Length=0; ((EFI_DEVICE_PATH_PROTOCOL*)p2)->Length[0]=0; ((EFI_DEVICE_PATH_PROTOCOL*)p2)->Length[1]=0; ((EFI_HII_DEVICE_PATH_PACK*)p1)->Header.Length=(UINT32)(p2-p1+sizeof(EFI_DEVICE_PATH_PROTOCOL)); p1=p2+sizeof(EFI_DEVICE_PATH_PROTOCOL); //Find Formset we are working with fs=LocateFormSet(HndIndex, NULL); if(!fs) { //No formset no VAR data DataTbl->VariableDataOffset=0; //Copy a Dummy formset to be compatible with Intel DataTbl->IfrDataOffset=(UINT32)(p1-(UINT8*)DataTbl); pBS->CopyMem(p1,&gDummyVfr[0],sizeof(gDummyVfr)); //copy handle guid here Shell expect it to mutch with some standart guids pBS->CopyMem((VOID*)(p1+8),(VOID*)&HiiHandle->Guid,sizeof(EFI_GUID)); //Adjust the pointer p1+=sizeof(gDummyVfr); } else { //Variable data DataTbl->VariableDataOffset=(UINT32)(p1-(UINT8*)DataTbl); for(i=0; iStorages.ItemCount; i++){ //-------------------- st=fs->Storages.Items[i]; if(st->VarStore->Size){ UINT8 *p; //--------------------- p2=p1+sizeof(EFI_HII_VARIABLE_PACK); ((EFI_HII_VARIABLE_PACK*)p1)->Header.Type=EFI_HII_VARIABLE; //pBS->CopyMem((VOID*)&(((EFI_HII_VARIABLE_PACK*)p1)->VariableGuid), // &st->VarStore.Guid, sizeof(EFI_GUID)); ((EFI_HII_VARIABLE_PACK*)p1)->VariableGuid=st->VarStore->Guid; ((EFI_HII_VARIABLE_PACK*)p1)->VariableId=st->VarStore->VarId; p=(UINT8*)(st->VarStore+1); while(*p){ *p2=*p; p++; p2+=sizeof(UINT16); //per spec VariableLength goes in Bytes ((EFI_HII_VARIABLE_PACK*)p1)->VariableNameLength+=sizeof(UINT16); } p2+=sizeof(UINT16); //Null terminaterd ((EFI_HII_VARIABLE_PACK*)p1)->VariableNameLength+=sizeof(UINT16); //Copy contents of the variable at present p2 p=p1+sizeof(EFI_HII_VARIABLE_PACK); sz=st->VarStore->Size; Status=pRS->GetVariable((UINT16*)p,&st->VarStore->Guid,NULL,&sz,p2); DataTbl->NumberOfVariableData++; //don't forget to update size of Var Data in Pack Header ((EFI_HII_VARIABLE_PACK*)p1)->Header.Length=(UINT32)(p2+sz-p1); p1=p2+sz; } } if(!DataTbl->NumberOfVariableData)DataTbl->VariableDataOffset=0; else { // !! Add zero-terminating EFI HII variable ((EFI_HII_VARIABLE_PACK*)p1)->Header.Type=EFI_HII_VARIABLE; ((EFI_HII_VARIABLE_PACK*)p1)->Header.Length = sizeof(EFI_HII_VARIABLE_PACK); p1 += sizeof(EFI_HII_VARIABLE_PACK); } //Formset goes data here DataTbl->IfrDataOffset=(UINT32)(p1-(UINT8*)DataTbl); p2=p1+sizeof(EFI_HII_PACK_HEADER); ((EFI_HII_PACK_HEADER*)p1)->Length=(UINT32)fs->BufferLength+sizeof(EFI_HII_PACK_HEADER); ((EFI_HII_PACK_HEADER*)p1)->Type=EFI_HII_IFR; i=0; CopyFormSet(p2,fs,&i); p1=p2+i; } //If HIIHandle Data don't have Strings make p2==p1 since we are returning p2 value p2=p1; //string data goes here if(HiiHandle->HasStr){ UINT8 *p=p1; UINT32 li=(UINTN)-1; //----------------- DataTbl->StringDataOffset=(UINT32)(p1-(UINT8*)DataTbl); for(i=0; iHandle==HiiHandle->Handle){ if((li==-1)||(li!=str->LangIdx)){ //p1 points on the EFI_HII_STRING_PACK p1=p; ((EFI_HII_STRING_PACK*)p1)->Header.Type=EFI_HII_STRING; DataTbl->NumberOfLanguages++; //p2 points on the RELOFS array p2=p1+sizeof(EFI_HII_STRING_PACK); li=str->LangIdx; ((EFI_HII_STRING_PACK*)p1)->NumStringPointers=CountStrOfLang(HiiHandle,i,li); //p points on the UnicodeString; p=p2+((EFI_HII_STRING_PACK*)p1)->NumStringPointers*sizeof(UINT32); ((EFI_HII_STRING_PACK*)p1)->LanguageNameString=(UINT32)((UINTN)p-(UINTN)p1); ((EFI_HII_STRING_PACK*)p1)->PrintableLanguageName=((EFI_HII_STRING_PACK*)p1)->LanguageNameString +4*sizeof(CHAR16); ((EFI_HII_STRING_PACK*)p1)->Header.Length=sizeof(EFI_HII_STRING_PACK)+ ((EFI_HII_STRING_PACK*)p1)->NumStringPointers*sizeof(UINT32); } //update offset table *((UINT32*)p2)=(UINT32)((UINTN)p-(UINTN)p1); //the StrLen stored in UNICODECHAR units including NULL CHAR16 if(str->NewStr.StrPtr){ pBS->CopyMem(p, str->NewStr.StrPtr, str->NewStr.StrLen*sizeof(CHAR16)); p+=str->NewStr.StrLen*sizeof(CHAR16); ((EFI_HII_STRING_PACK*)p1)->Header.Length+=str->NewStr.StrLen*sizeof(CHAR16); } else { pBS->CopyMem(p, str->String.StrPtr, str->String.StrLen*sizeof(CHAR16)); p+=str->String.StrLen*sizeof(CHAR16); ((EFI_HII_STRING_PACK*)p1)->Header.Length+=str->String.StrLen*sizeof(CHAR16); } p2+=sizeof(UINT32); } //don't forget to put terminator pack at the very end of the string data if((str->Handle > HiiHandle->Handle) || (i==gHiiDb.StringDb.RecordCount-1)){ //Create a terminator pack p1=p; ((EFI_HII_STRING_PACK*)p1)->Header.Type=EFI_HII_STRING; p2=p1+sizeof(EFI_HII_STRING_PACK); break; } } } *BufferPointer=p2; } /////////////////////////////////////////////////////////////////// EFI_STATUS HiiExport(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN OUT UINTN *BufferSize, OUT VOID *Buffer ) { UINTN sz, i; HII_HANDLE *phnd=NULL; EFI_HII_EXPORT_TABLE *expt=NULL; EFI_HII_DATA_TABLE *cdt=NULL; UINT8 *bp=NULL; //---------------- if(!This) return EFI_INVALID_PARAMETER; sz=sizeof(EFI_HII_EXPORT_TABLE); //Calculate buffer Size for(i=0; iHandle) continue; sz+=GetHandleExpBuffSize(phnd,i) + sizeof(EFI_HII_DATA_TABLE); } //Check the buffer size provided if(sz > *BufferSize){ *BufferSize=sz; return EFI_BUFFER_TOO_SMALL; } pBS->SetMem(Buffer, sz, 0); //Export Table expt=(EFI_HII_EXPORT_TABLE*)Buffer; if((UINTN)This == (UINTN)&gHiiDb.HiiProtocolOld) expt->Revision=gEfiHiiProtocolGuidOld; else expt->Revision=gEfiHiiProtocolGuidNew; bp=(UINT8*)(expt+1); //Start dumping the data for(i=0 ; iHandle) continue; //CurrentDataTable cdt=(EFI_HII_DATA_TABLE*)bp; bp+=sizeof(EFI_HII_DATA_TABLE); sz=GetHandleExpBuffSize(phnd,i); cdt->HiiHandle=phnd->Handle; cdt->PackageGuid=phnd->Guid; cdt->DataTableSize=(UINT32)(sz+sizeof(EFI_HII_DATA_TABLE)); ExportHandleData(phnd, i, cdt, &bp); //debug+ just to test how bp gets incremented ASSERT((UINTN)cdt+sizeof(EFI_HII_DATA_TABLE)+sz==(UINTN)bp); //debug- expt->NumberOfHiiDataTables++; } return EFI_SUCCESS; } EFI_STATUS GetVarStoreData(HII_FORMSET *FormSet, HII_STORE *VarData, UINT8* Buffer, UINTN DefaultMask){ HII_LABEL *lbl; HII_OBJECT *obj; HII_FORM *frm; EFI_IFR_OP_HEADER *op; UINTN i,x,j,k,offs,len; //------------------ for(i=0; iForms.ItemCount; i++){ frm=FormSet->Forms.Items[i]; for(x=0; x< frm->Labels.ItemCount; x++){ //iterate trough the Labels to get each HII_OBJECT lbl=frm->Labels.Items[x]; for(j=0; jObjects.ItemCount; j++){ //iterate trough the Objects to see if obj=lbl->Objects.Items[j]; if( VarData->VarStore->VarId!=obj->Store1->VarStore->VarId || MemCmp(&VarData->VarStore->Guid, &obj->Store1->VarStore->Guid, sizeof(EFI_GUID)) ) continue; //we focused at the Object which has the same VarStore Properies as passed "VarData" //So parse the object to see if it has any default flags set op=obj->ObjectCode; switch(op->OpCode){ //ONE_OF and ORDERED_LIST has almost the same encoding case EFI_IFR_ORDERED_LIST_OP: case EFI_IFR_ONE_OF_OP: { EFI_IFR_ONE_OF_OPTION *opt; //----------------------- offs=((EFI_IFR_ONE_OF*)op)->QuestionId; len=((EFI_IFR_ONE_OF*)op)->Width; //DEBUG CODE to check if update runs out of bound if(offs>=VarData->VarStore->Size) { ASSERT_EFI_ERROR(EFI_BUFFER_TOO_SMALL); return EFI_BUFFER_TOO_SMALL; } //DEBUG CODE to check if update runs out of bound for(k=0; kOptions.ItemCount; k++){ opt=(EFI_IFR_ONE_OF_OPTION*)obj->Options.Items[k]; //for ORDERED_LIST it would not be any Defaults if(op->OpCode==EFI_IFR_ORDERED_LIST_OP){ pBS->CopyMem(&Buffer[offs],&opt->Value, 1); offs++; //DEBUG CODE to check if update runs out of bound if(offs>=VarData->VarStore->Size) return EFI_BUFFER_TOO_SMALL; //DEBUG CODE to check if update runs out of bound } else { UINTN f=(UINTN)opt->Flags; //------------------ if (f & DefaultMask) { pBS->CopyMem(&Buffer[offs],&opt->Value,len); break; } } } }break; case EFI_IFR_CHECKBOX_OP: { EFI_IFR_CHECK_BOX *cb=(EFI_IFR_CHECK_BOX*)obj->ObjectCode; UINTN f=(UINTN)cb->Flags; //-------------------- offs=cb->QuestionId; //DEBUG CODE to check if update runs out of bound if(offs>=VarData->VarStore->Size) return EFI_BUFFER_TOO_SMALL; //DEBUG CODE to check if update runs out of bound if(f & DefaultMask) Buffer[offs] = 1; else Buffer[offs] = 0; } break; case EFI_IFR_NUMERIC_OP: { EFI_IFR_NUMERIC *num =(EFI_IFR_NUMERIC*)obj->ObjectCode; //-------------------------- offs=num->QuestionId; len=num->Width; //DEBUG CODE to check if update runs out of bound if(offs>=VarData->VarStore->Size) return EFI_BUFFER_TOO_SMALL; //DEBUG CODE to check if update runs out of bound pBS->CopyMem(&Buffer[offs],&num->Default,len); } break; } //switch(obj->ObjectCode->Opcode) } //for(j) loop }//for(x) loop } //for(i) loop return EFI_SUCCESS; } EFI_STATUS HiiGetDefaultImageNew(IN EFI_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN UINTN DefaultMask, OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList) { EFI_STATUS Status=EFI_NOT_FOUND; UINTN i, j, k, hidx, vnl=0, tbsz=0; HII_HANDLE *phnd; EFI_HII_VARIABLE_PACK_LIST *vpl, *fvpl=NULL, *pvpl=NULL; HII_FORMSET *fs; HII_STORE *st; UINT8 *pdb, *pnb; //---------------------------------- //Check Parameters if(This==NULL || VariablePackList==NULL || !Handle ) return EFI_INVALID_PARAMETER; //Find the handle phnd=LocateHandle(Handle, &hidx); if(phnd==NULL) return EFI_NOT_FOUND; //If no VarStores associated with passed Handle will return NULL *VariablePackList=NULL; //If Handle Exists then find a FormSet associated with this Handle fs=LocateFormSet(hidx, NULL); //No formset found => no IFR data if(fs==NULL) return EFI_NOT_FOUND; //Collect the Variable data for(i=0, hidx=0; iStorages.ItemCount; i++){ st=fs->Storages.Items[i]; if(!st->VarStore->Size) continue; Status=EFI_SUCCESS; hidx++; //get the variable name length in bytes(ASCII) vnl=st->VarStore->Header.Length-sizeof(EFI_IFR_VARSTORE); //determine how much memory we need to accomodate //EFI_VARIABLE_PACK_LIST + EFI_VARIABLE_PACK + VarName + VarData vpl=MallocZ(sizeof(EFI_HII_VARIABLE_PACK_LIST)+ //EFI_VARIABLE_PACK_LIST sizeof(EFI_HII_VARIABLE_PACK)+ //EFI_VARIABLE_PACK (vnl*sizeof(UINT16))+ //EFI_VARIABLE_PACK has VarName in UINT16 st->VarStore->Size); //Size of actual NV Var Data tbsz+=(sizeof(EFI_HII_VARIABLE_PACK_LIST)+ //EFI_VARIABLE_PACK_LIST sizeof(EFI_HII_VARIABLE_PACK)+ //EFI_VARIABLE_PACK (vnl*sizeof(UINT16))+ //EFI_VARIABLE_PACK has VarName in UINT16 st->VarStore->Size); //Size of actual NV Var Data if(!vpl) return EFI_OUT_OF_RESOURCES; //determine where in VPL buffer Actual VAriable data suppose to start pdb=(UINT8*)vpl+sizeof(EFI_HII_VARIABLE_PACK_LIST)+sizeof(EFI_HII_VARIABLE_PACK)+(vnl*sizeof(UINT16)); GetVarStoreData(fs,st,pdb,DefaultMask); //if this is the first structure in the list remember it we must return it's address if(fvpl==NULL)fvpl=vpl; //if PreviouseVariablePackList ptr was initialized update pointer to next VPL with current VPL if(pvpl!=NULL)pvpl->NextVariablePack=vpl; //reinitialize PreviouseVariablePackList ptr with current VPL pointer pvpl=vpl; //Update context of the VariablePack pointer to the next data byte afer itself(per .92 spec) vpl->VariablePack = (EFI_HII_VARIABLE_PACK*)(vpl+1); //Now fill out fields of HII_VARIABLE_PACK structure vpl->VariablePack->Header.Type=EFI_HII_VARIABLE; vpl->VariablePack->Header.Length=(UINT32)(sizeof(EFI_HII_VARIABLE_PACK)+(vnl*sizeof(UINT16))+st->VarStore->Size); vpl->VariablePack->VariableId=st->VarStore->VarId; vpl->VariablePack->VariableNameLength=(UINT32)(vnl*sizeof(UINT16)); // per spec length in bytes. pBS->CopyMem(&vpl->VariablePack->VariableGuid, &st->VarStore->Guid, sizeof(EFI_GUID)); //now copy Variable name "pdb" points at the befinning of VarName buffer pdb=(UINT8*)vpl+sizeof(EFI_HII_VARIABLE_PACK_LIST)+sizeof(EFI_HII_VARIABLE_PACK); pnb=(UINT8*)(st->VarStore+1); //since in VARIABLE_PACKAGE VAR NAME is UNICODE simple MemCpy wouldn't do. for(j=0,k=0; jCopyMem(pdb,vpl,sizeof(EFI_HII_VARIABLE_PACK_LIST)+vpl->VariablePack->Header.Length); pvpl=(EFI_HII_VARIABLE_PACK_LIST*)pdb; pvpl->VariablePack=(EFI_HII_VARIABLE_PACK*)(pdb+sizeof(EFI_HII_VARIABLE_PACK_LIST)); pdb+=(sizeof(EFI_HII_VARIABLE_PACK_LIST)+vpl->VariablePack->Header.Length); if(vpl->NextVariablePack!=NULL)pvpl->NextVariablePack=(EFI_HII_VARIABLE_PACK_LIST*)pdb; pvpl=vpl; vpl=vpl->NextVariablePack; pBS->FreePool(pvpl); } return Status; } /////////////////////////////////////////////////////////////////// //Keyboard EFI_STATUS HiiGetKeyboardLayout(IN EFI_HII_PROTOCOL *This, OUT UINT16 *DescriptorCount, OUT EFI_KEY_DESCRIPTOR *Descriptor) { HII_KB_LAYOUT_DATA *kbld; //------------------------------- if(!This) return EFI_INVALID_PARAMETER; if(!gHiiDb.KeybdDb.KblCount) return EFI_NOT_FOUND; kbld=gHiiDb.KeybdDb.KbLayout[gHiiDb.KeybdDb.ActiveLayout]; //we got small buffer if(*DescriptorCountKeyDscCount) { *DescriptorCount=kbld->KeyDscCount; return EFI_BUFFER_TOO_SMALL; } MemCpy((VOID*)Descriptor, (VOID*)kbld->KeyDsc, sizeof(EFI_KEY_DESCRIPTOR)*kbld->KeyDscCount); return EFI_SUCCESS; } //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //EXTENDED HII INTERFACE //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// EFI_STATUS HiiExtGetStringInfo( IN EXT_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN STRING_REF Token, IN CHAR16 *Lang, OUT EXT_STR_INFO **ExtStrInfo) { HII_STR *str; //----------------------------------------- if(!This || !ExtStrInfo ) return EFI_INVALID_PARAMETER; str=GetHiiString(Handle,Lang,Token); if(!str) return EFI_NOT_FOUND; if(str->NewStr.StrPtr)*ExtStrInfo=&str->NewStr; else *ExtStrInfo=&str->String; return EFI_SUCCESS; } EFI_STATUS HiiExtGetFormInfo(IN EXT_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN EFI_FORM_ID FormId, OUT HII_FORM **ExtFormInfo) { HII_FORM *frm; UINTN hi; HII_HANDLE *phnd; HII_FORMSET *fs; //----------------------------------------- if(!This || !ExtFormInfo ) return EFI_INVALID_PARAMETER; phnd=LocateHandle(Handle,&hi); ASSERT(phnd); if(!phnd)return EFI_NOT_FOUND; fs=LocateFormSet(hi,NULL); ASSERT(fs); if(!fs)return EFI_NOT_FOUND; frm=LocateForm(fs,FormId); ASSERT(frm); if(!frm)return EFI_NOT_FOUND; *ExtFormInfo=frm; return EFI_SUCCESS; } EFI_STATUS HiiExtRegisterLabelUpdateCallback(IN EXT_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN EFI_FORM_LABEL LabelId, IN HII_LABEL_UPDATE_CALLBACK CallBack) { UINTN hi; HII_LABEL *lbl; HII_FORMSET *fs; //---------------------------------- if(!This || !CallBack ) return EFI_INVALID_PARAMETER; if(!LocateHandle(Handle, &hi)) return EFI_INVALID_PARAMETER; //Find Formset fs=LocateFormSet(hi, NULL); if(!fs) return EFI_INVALID_PARAMETER; lbl=LocateFormSetLabel(fs,LabelId,NULL); if(!lbl) return EFI_NOT_FOUND; lbl->UpdateCallBack=CallBack; return EFI_SUCCESS; } EFI_STATUS HiiExtUnregisterLabelUpdateCallback(IN EXT_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN EFI_FORM_LABEL LabelId) { UINTN hi; HII_LABEL *lbl; HII_FORMSET *fs; //---------------------------------- if(!This) return EFI_INVALID_PARAMETER; if(!LocateHandle(Handle, &hi)) return EFI_INVALID_PARAMETER; //Find Formset fs=LocateFormSet(hi, NULL); if(!fs) return EFI_INVALID_PARAMETER; lbl=LocateFormSetLabel(fs,LabelId,NULL); if(!lbl) return EFI_NOT_FOUND; lbl->UpdateCallBack=NULL; return EFI_SUCCESS; } EFI_STATUS HiiExtGetFormSetInfo(IN EXT_HII_PROTOCOL *This, IN UINT16 ClassMask, //if ==0xFFFF all Classes IN UINT16 SubClass, //if ==0xFFFF all SubClasses OUT T_ITEM_LIST *FormSetList) { UINTN i; HII_FORMSET *fs; //------------------------------ if(!This || !FormSetList) return EFI_INVALID_PARAMETER; //Make sure the list is empty ClearItemLst(FormSetList,FALSE); for(i=0; iFormSetData->SubClass) continue; if((fs->FormSetData->Class & ClassMask)==fs->FormSetData->Class) AppendItemLst(FormSetList,fs); } return EFI_SUCCESS; } EFI_STATUS HiiExtGetFormLabels(IN EXT_HII_PROTOCOL *This, IN EFI_HII_HANDLE Handle, IN EFI_FORM_ID FormID, OUT T_ITEM_LIST *LabelList) { UINTN i; HII_FORMSET *fs; HII_FORM *frm; HII_LABEL *lbl; EFI_STATUS Status; //----------------------------------------- if(!This || !LabelList ) return EFI_INVALID_PARAMETER; if(!LocateHandle(Handle,&i)) return EFI_INVALID_PARAMETER;; fs=LocateFormSet(i,NULL); ASSERT(fs); if(!fs)return EFI_NOT_FOUND; frm=LocateForm(fs,FormID); ASSERT(frm); if(!frm)return EFI_NOT_FOUND; ClearItemLst(LabelList,FALSE); for(i=1;iLabels.ItemCount;i++){ lbl=frm->Labels.Items[i]; Status=AppendItemLst(LabelList,lbl); ASSERT(!EFI_ERROR(Status)); if(EFI_ERROR(Status))return Status; } return EFI_SUCCESS; } /////////////////////////////////////////////////////////////////// //Init All Private Data EFI_STATUS InitPrivateData(EFI_HANDLE MyImgHandle){ EFI_STATUS Status=0; //HII_LANG *al;//any lang //TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST EFI_HII_PACK_LIST *pl=Malloc(sizeof(EFI_HII_PACK_LIST)); // {BB2F3C9D-C7A1-4283-8AE2-4F4362990E2E} static EFI_GUID pguid={ 0xbb2f3c9d, 0xc7a1, 0x4283, 0x8a, 0xe2, 0x4f, 0x43, 0x62, 0x99, 0x0e, 0x2e }; EFI_HII_HANDLE fph;//,sth; // UINT16 bl; // UINT8 *fsb; //TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST //----------------------------- pBS->SetMem(&gHiiDb, sizeof(HII_DB),0 ); gHiiDb.ImageHandle=MyImgHandle; gHiiDb.NextHiiHandle=1; //Zero Handle is Invalid it must be 1 based //Create Any Langguage Entry - empty string L" " Status=LocateLangAdd(L" ",L"Any Language",NULL); if(EFI_ERROR(Status)) return Status; //Create and Initialize String Database gHiiDb.StringDb.KeyCount=STR_KEY_CNT; gHiiDb.StringDb.InitialCount=STRING_DB_MAX_COUNT; gHiiDb.StringDb.KeyField=&gStrKey; gHiiDb.StringDb.MemoryType=EfiBootServicesData; gHiiDb.StringDb.RecordCount=0; gHiiDb.StringDb.IndexArray=MallocZ(sizeof(VOID*)*gHiiDb.StringDb.InitialCount*gHiiDb.StringDb.KeyCount); if(!gHiiDb.StringDb.IndexArray) return EFI_OUT_OF_RESOURCES; //Init Protocol Instance here gHiiDb.HiiProtocolOld.NewPack=HiiNewPackOld; gHiiDb.HiiProtocolNew.NewPack=HiiNewPackNew; gHiiDb.HiiProtocolOld.RemovePack=HiiRemovePack; gHiiDb.HiiProtocolNew.RemovePack=HiiRemovePack; gHiiDb.HiiProtocolOld.FindHandles=HiiFindHandles; gHiiDb.HiiProtocolNew.FindHandles=HiiFindHandles; gHiiDb.HiiProtocolOld.GetDefaultImage=HiiGetDefaultImageOld; gHiiDb.HiiProtocolNew.GetDefaultImage=HiiGetDefaultImageNew; gHiiDb.HiiProtocolOld.TestString=HiiTestString; gHiiDb.HiiProtocolNew.TestString=HiiTestString; gHiiDb.HiiProtocolOld.GetGlyph=HiiGetGlyph; gHiiDb.HiiProtocolNew.GetGlyph=HiiGetGlyph; gHiiDb.HiiProtocolOld.GlyphToBlt=HiiGlyphToBlt; gHiiDb.HiiProtocolNew.GlyphToBlt=HiiGlyphToBlt; gHiiDb.HiiProtocolOld.NewString=HiiNewString; gHiiDb.HiiProtocolNew.NewString=HiiNewString; gHiiDb.HiiProtocolOld.GetPrimaryLanguages=HiiGetPrimaryLanguage; gHiiDb.HiiProtocolNew.GetPrimaryLanguages=HiiGetPrimaryLanguage; gHiiDb.HiiProtocolOld.GetSecondaryLanguages=HiiGetSecondaryLanguages; gHiiDb.HiiProtocolNew.GetSecondaryLanguages=HiiGetSecondaryLanguages; gHiiDb.HiiProtocolOld.GetString=HiiGetStringOld; gHiiDb.HiiProtocolNew.GetString=HiiGetStringNew; gHiiDb.HiiProtocolOld.GetLine=HiiGetLine; gHiiDb.HiiProtocolNew.GetLine=HiiGetLine; gHiiDb.HiiProtocolOld.GetForms=HiiGetFormsOld; gHiiDb.HiiProtocolNew.GetForms=HiiGetFormsNew; gHiiDb.HiiProtocolOld.UpdateForm=HiiUpdateForm; gHiiDb.HiiProtocolNew.UpdateForm=HiiUpdateForm; gHiiDb.HiiProtocolOld.GetKeyboardLayout=HiiGetKeyboardLayout; gHiiDb.HiiProtocolNew.GetKeyboardLayout=HiiGetKeyboardLayout; gHiiDb.HiiProtocolOld.ResetStrings=HiiResetStrings; gHiiDb.HiiProtocolNew.ResetStrings=HiiResetStrings; gHiiDb.HiiProtocolOld.ExportDatabase=HiiExport; gHiiDb.HiiProtocolNew.ExportDatabase=HiiExport; //Now do Extended Hii Interface gHiiDb.HiiExtProtocol.ExtGetStringInfo=HiiExtGetStringInfo; gHiiDb.HiiExtProtocol.ExtGetFormInfo=HiiExtGetFormInfo; gHiiDb.HiiExtProtocol.ExtGetFormsetInfo=HiiExtGetFormSetInfo; gHiiDb.HiiExtProtocol.ExtRegLblCallBack=HiiExtRegisterLabelUpdateCallback; gHiiDb.HiiExtProtocol.ExtUnregLblCallBack=HiiExtUnregisterLabelUpdateCallback; gHiiDb.HiiExtProtocol.ExtGetFormLabels=HiiExtGetFormLabels; //------------------------------------ //init Font Data pl->FontPack=(EFI_HII_FONT_PACK*)&UsStdNarrowGlyphData; pl->GuidId=&pguid; pl->IfrPack=NULL;//(EFI_HII_IFR_PACK*)&FrontPageVfrBin; pl->KeyboardPack=NULL; pl->StringPack=NULL;//(EFI_HII_STRING_PACK*)&FrontPageStrings; ///// Load Font Pack { #define FONT_FFS_FILE_GUID { 0xdac2b117, 0xb5fb, 0x4964, { 0xa3, 0x12, 0xd, 0xcc, 0x77, 0x6, 0x1b, 0x9b } } static EFI_GUID guidFontFile = FONT_FFS_FILE_GUID; EFI_STATUS Status; EFI_FIRMWARE_VOLUME_PROTOCOL *pFV; UINTN DataSize; EFI_GUID *pSectionGuid = NULL; UINT32 Authentication; EFI_HANDLE *pHandle; UINTN Number,i; Status = pBS->LocateHandleBuffer(ByProtocol,&guidFV, NULL, &Number, &pHandle); for(i=0;iHandleProtocol(pHandle[i], &guidFV, &pFV); if (EFI_ERROR(Status)) continue; pSectionGuid=NULL; DataSize=0; Status=pFV->ReadSection ( pFV,&guidFontFile, EFI_SECTION_FREEFORM_SUBTYPE_GUID,0, &pSectionGuid, &DataSize, &Authentication ); if (!EFI_ERROR(Status)) { pl->FontPack=(EFI_HII_FONT_PACK*)((UINT32*)(pSectionGuid+1)+1); break; } } Status=HiiNewPackOld((EFI_HII_PROTOCOL*)&gHiiDb.HiiProtocolOld,pl,&fph); pBS->FreePool(pSectionGuid); } //////////////////// if(EFI_ERROR(Status)) return Status; //TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST /* pl->FontPack=NULL; pl->IfrPack=NULL; pl->KeyboardPack=NULL; pl->StringPack=(EFI_HII_STRING_PACK*)&SetupStrings; Status=HiiNewPack(&gHiiDb.HiiProtocol,pl,&sth); if(EFI_ERROR(Status)) return Status; fsb=NULL; bl=0; Status=HiiGetForms(&gHiiDb.HiiProtocol,fph,0,&bl,fsb); if(Status==EFI_BUFFER_TOO_SMALL); else if(EFI_ERROR(Status)) return Status; fsb=Malloc(bl); if(!fsb) return EFI_OUT_OF_RESOURCES; Status=HiiGetForms(&gHiiDb.HiiProtocol,fph,0,&bl,fsb); //Now, I'll try to ges some strings from FrontPageDb { UINT16 mystr[81]; EFI_STRING plan, slan; EFI_IFR_FORM_SET *fs=(EFI_IFR_FORM_SET*)fsb; UINT32 gb,i=0; //----------------------------------- Status=HiiGetPrimaryLanguage(&gHiiDb.HiiProtocol,fph,&plan); //it might be more than 1 Sec Lang. Status=HiiGetSecondaryLanguages(&gHiiDb.HiiProtocol,fph,plan,&slan); bl=80; Status=HiiGetString(&gHiiDb.HiiProtocol,fph,fs->FormSetTitle,TRUE,slan,&bl,&mystr[0]); Status=HiiGetString(&gHiiDb.HiiProtocol,fph,fs->FormSetTitle,TRUE,plan,&bl,&mystr[0]); Status=HiiGetString(&gHiiDb.HiiProtocol,fph,fs->Help,TRUE,slan,&bl,&mystr[0]); Status=HiiGetString(&gHiiDb.HiiProtocol,fph,fs->Help,TRUE,plan,&bl,&mystr[0]); Status=HiiTestString(&gHiiDb.HiiProtocol,&mystr[0],&i,&gb); } */ //TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST pBS->FreePool(pl); // // return pBS->InstallMultipleProtocolInterfaces( gHiiDb.ImageHandle, // &gEfiHiiProtocolGuid,&gHiiDb.HiiProtocol,NULL,NULL); return EFI_SUCCESS; } //********************************************************************** //********************************************************************** //** ** //** (C)Copyright 1985-2005, American Megatrends, Inc. ** //** ** //** All Rights Reserved. ** //** ** //** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** //** ** //** Phone: (770)-246-8600 ** //** ** //********************************************************************** //**********************************************************************