EDK2 doxygen online documents - Firmware Encoding Index 1
EDK2 doxygen online documents - Firmware Encoding Index

EdkCompatibilityPkg/Compatibility/FrameworkHiiOnUefiHiiThunk/Forms.c

Go to the documentation of this file.
00001 
00016 #include "HiiDatabase.h"
00017 #include "UefiIfrDefault.h"
00018 
00019 //
00020 // This structure is only intended to be used in this file.
00021 //
00022 #pragma pack(1)
00023 typedef struct {
00024   EFI_HII_PACK_HEADER            PackageHeader;
00025   FRAMEWORK_EFI_IFR_FORM_SET     FormSet;
00026   EFI_IFR_END_FORM_SET           EndFormSet;
00027 } FW_HII_FORMSET_TEMPLATE;
00028 #pragma pack()
00029 
00030 FW_HII_FORMSET_TEMPLATE FormSetTemplate = {
00031   {
00032     sizeof (FW_HII_FORMSET_TEMPLATE),
00033     EFI_HII_IFR
00034   },
00035   {
00036     {
00037       FRAMEWORK_EFI_IFR_FORM_SET_OP,
00038       sizeof (FRAMEWORK_EFI_IFR_FORM_SET)
00039     },
00040     {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}, //Guid
00041     0,
00042     0,
00043     0,
00044     0,
00045     0,
00046     0
00047   },
00048   {
00049     {
00050       EFI_IFR_END_FORM_SET_OP,
00051       sizeof (EFI_IFR_END_FORM_SET)
00052     }
00053   }
00054 };
00055 
00056 
00057 EFI_GUID  mTianoHiiIfrGuid              = EFI_IFR_TIANO_GUID;
00058 
00074 EFI_STATUS
00075 EFIAPI
00076 HiiExportDatabase (
00077   IN     EFI_HII_PROTOCOL *This,
00078   IN     FRAMEWORK_EFI_HII_HANDLE    Handle,
00079   IN OUT UINTN            *BufferSize,
00080   OUT    VOID             *Buffer
00081   )
00082 {
00083   ASSERT (FALSE);
00084   return EFI_UNSUPPORTED;
00085 }
00086 
00087 
00116 EFI_STATUS
00117 EFIAPI
00118 HiiGetForms (
00119   IN     EFI_HII_PROTOCOL             *This,
00120   IN     FRAMEWORK_EFI_HII_HANDLE     Handle,
00121   IN     EFI_FORM_ID                  FormId,
00122   IN OUT UINTN                        *BufferLengthTemp,
00123   OUT    UINT8                        *Buffer
00124   )
00125 {
00126   HII_THUNK_PRIVATE_DATA                *Private;
00127   HII_THUNK_CONTEXT  *ThunkContext;
00128   FW_HII_FORMSET_TEMPLATE            *OutputFormSet;
00129 
00130   if (*BufferLengthTemp < sizeof(FW_HII_FORMSET_TEMPLATE)) {
00131     *BufferLengthTemp = sizeof(FW_HII_FORMSET_TEMPLATE);
00132     return EFI_BUFFER_TOO_SMALL;
00133   }
00134   
00135   Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
00136 
00137   ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
00138 
00139   if (ThunkContext == NULL) {
00140     return EFI_NOT_FOUND;
00141   }
00142 
00143   OutputFormSet = (FW_HII_FORMSET_TEMPLATE *) Buffer;
00144   
00145   CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FW_HII_FORMSET_TEMPLATE));
00146   CopyMem (&OutputFormSet->FormSet.Guid, &ThunkContext->TagGuid, sizeof (EFI_GUID)); 
00147 
00148   if (ThunkContext->FormSet != NULL) {
00149     OutputFormSet->FormSet.Class = ThunkContext->FormSet->Class;
00150     OutputFormSet->FormSet.SubClass = ThunkContext->FormSet->SubClass;
00151     OutputFormSet->FormSet.Help     = ThunkContext->FormSet->Help;
00152     OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSet->FormSetTitle;
00153   }
00154 
00155   return EFI_SUCCESS;
00156 }
00157 
00158 
00178 EFI_STATUS
00179 EFIAPI
00180 HiiGetDefaultImage (
00181   IN     EFI_HII_PROTOCOL            *This,
00182   IN     FRAMEWORK_EFI_HII_HANDLE    Handle,
00183   IN     UINTN                       DefaultMask,
00184   OUT    EFI_HII_VARIABLE_PACK_LIST  **VariablePackList
00185   )
00186 {
00187   LIST_ENTRY        *UefiDefaults;
00188   EFI_STATUS        Status;
00189   HII_THUNK_PRIVATE_DATA *Private;
00190   HII_THUNK_CONTEXT *ThunkContext;
00191 
00192   Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
00193 
00194   ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
00195   if (ThunkContext == NULL) {
00196     ASSERT (FALSE);
00197     return EFI_INVALID_PARAMETER;
00198   }
00199 
00200   UefiDefaults = NULL;
00201   Status = UefiIfrGetBufferTypeDefaults (ThunkContext, &UefiDefaults);
00202   if (EFI_ERROR (Status)) {
00203     goto Done;
00204   }
00205 
00206   Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, ThunkContext->FormSet->DefaultVarStoreId, VariablePackList);
00207 
00208 Done:
00209   FreeDefaultList (UefiDefaults);
00210   
00211   return Status;
00212 }
00213 
00226 EFI_STATUS
00227 UpdateFormCallBack (
00228   IN       EFI_HANDLE                                CallbackHandle,
00229   IN CONST HII_THUNK_CONTEXT                         *ThunkContext
00230   )
00231 {
00232   EFI_STATUS                                Status;
00233   EFI_FORM_CALLBACK_PROTOCOL                *FormCallbackProtocol;
00234   EFI_HII_CONFIG_ACCESS_PROTOCOL            *ConfigAccessProtocol;
00235   EFI_HANDLE                                UefiDriverHandle;
00236   CONFIG_ACCESS_PRIVATE                     *ConfigAccessPrivate;
00237   
00238   Status = gBS->HandleProtocol (
00239                    CallbackHandle,
00240                    &gEfiFormCallbackProtocolGuid,
00241                    (VOID **) &FormCallbackProtocol
00242                    );
00243   if (EFI_ERROR (Status)) {
00244     return EFI_INVALID_PARAMETER;
00245   }
00246   
00247   Status = mHiiDatabase->GetPackageListHandle (
00248                                         mHiiDatabase,
00249                                         ThunkContext->UefiHiiHandle,
00250                                         &UefiDriverHandle
00251                                         );
00252   ASSERT_EFI_ERROR (Status);
00253   Status = gBS->HandleProtocol (
00254                    UefiDriverHandle,
00255                    &gEfiHiiConfigAccessProtocolGuid,
00256                    (VOID **) &ConfigAccessProtocol
00257                    );
00258   ASSERT_EFI_ERROR (Status);
00259   
00260   ConfigAccessPrivate = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccessProtocol);
00261   
00262   ConfigAccessPrivate->FormCallbackProtocol = FormCallbackProtocol;
00263 
00264   return EFI_SUCCESS;
00265 }
00266 
00267 
00280 EFI_STATUS
00281 GetPackageData (
00282   IN  EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
00283   IN  UINT32                      PackageIndex,
00284   OUT UINT32                      *BufferLen,
00285   OUT EFI_HII_PACKAGE_HEADER      **Buffer
00286   )
00287 {
00288   UINT32                        Index;
00289   EFI_HII_PACKAGE_HEADER        *Package;
00290   UINT32                        Offset;
00291   UINT32                        PackageListLength;
00292   EFI_HII_PACKAGE_HEADER        PackageHeader;
00293 
00294   ASSERT(HiiPackageList != NULL);
00295 
00296   if ((BufferLen == NULL) || (Buffer == NULL)) {
00297     return EFI_INVALID_PARAMETER;
00298   }
00299 
00300   ZeroMem (&PackageHeader, sizeof (PackageHeader));
00301   Package = NULL;
00302   Index   = 0;
00303   Offset  = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
00304   CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
00305   while (Offset < PackageListLength) {
00306     Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);
00307     CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
00308     if (Index == PackageIndex) {
00309       break;
00310     }
00311     Offset += PackageHeader.Length;
00312     Index++;
00313   }
00314   if (Offset >= PackageListLength) {
00315     //
00316     // no package found in this Package List
00317     //
00318     return EFI_NOT_FOUND;
00319   }
00320 
00321   *BufferLen = PackageHeader.Length;
00322   *Buffer    = Package;
00323   return EFI_SUCCESS;
00324 }
00325 
00338 EFI_STATUS
00339 LocateLabel (
00340   IN CONST EFI_HII_PACKAGE_HEADER *Package,
00341   IN       EFI_FORM_LABEL          Label,
00342   OUT      EFI_GUID                *FormsetGuid,
00343   OUT      EFI_FORM_ID             *FormId
00344   )
00345 {
00346   UINTN                     Offset;
00347   EFI_IFR_OP_HEADER         *IfrOpHdr;
00348   EFI_GUID                  InternalFormSetGuid;
00349   EFI_FORM_ID               InternalFormId;
00350   BOOLEAN                   GetFormSet;
00351   BOOLEAN                   GetForm;
00352   EFI_IFR_GUID_LABEL        *LabelOpcode;
00353 
00354   IfrOpHdr   = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));
00355   Offset     = sizeof (EFI_HII_PACKAGE_HEADER);
00356 
00357   InternalFormId= 0;
00358   ZeroMem (&InternalFormSetGuid, sizeof (EFI_GUID));
00359   GetFormSet = FALSE;
00360   GetForm    = FALSE;
00361 
00362   while (Offset < Package->Length) {
00363     switch (IfrOpHdr->OpCode) {
00364     case EFI_IFR_FORM_SET_OP :
00365       CopyMem (&InternalFormSetGuid, &((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, sizeof (EFI_GUID));
00366       GetFormSet = TRUE;
00367       break;
00368 
00369     case EFI_IFR_FORM_OP:
00370       CopyMem (&InternalFormId, &((EFI_IFR_FORM *) IfrOpHdr)->FormId, sizeof (EFI_FORM_ID));
00371       GetForm = TRUE;
00372       break;
00373 
00374     case EFI_IFR_GUID_OP :
00375       LabelOpcode = (EFI_IFR_GUID_LABEL *) IfrOpHdr;
00376       //
00377       // If it is an Label opcode.
00378       //
00379       if ((LabelOpcode->ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) && (CompareMem (&LabelOpcode->Guid, &mTianoHiiIfrGuid, sizeof (EFI_GUID)) == 0)) {
00380         if (CompareMem (&Label, &LabelOpcode->Number, sizeof (UINT16)) == 0) {
00381           ASSERT (GetForm && GetFormSet);
00382           CopyGuid (FormsetGuid, &InternalFormSetGuid);
00383           *FormId = InternalFormId;
00384           return EFI_SUCCESS;
00385         }
00386       }
00387       break;
00388     default :
00389       break;
00390     }
00391 
00392     //
00393     // Go to the next Op-Code
00394     //
00395     Offset   += IfrOpHdr->Length;
00396     IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
00397   }
00398 
00399   return EFI_NOT_FOUND;
00400 }
00401 
00421 EFI_STATUS
00422 LocateFormId (
00423   IN  EFI_HII_HANDLE Handle,
00424   IN  EFI_FORM_LABEL Label,
00425   OUT EFI_GUID       *FormsetGuid,
00426   OUT EFI_FORM_ID    *FormId
00427   )
00428 {
00429   EFI_STATUS                   Status;
00430   EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;
00431   UINT32                       Index;
00432   UINTN                        BufferSize;
00433   EFI_HII_PACKAGE_HEADER       PackageHeader;
00434   EFI_HII_PACKAGE_HEADER       *Package;
00435   UINT32                       PackageLength;
00436 
00437   BufferSize = 0;
00438   HiiPackageList   = NULL;
00439   Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
00440   if (Status == EFI_BUFFER_TOO_SMALL) {
00441     HiiPackageList = AllocatePool (BufferSize);
00442     ASSERT (HiiPackageList != NULL);
00443 
00444     Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
00445     if (EFI_ERROR (Status)) {
00446       goto Done;
00447     }
00448   }
00449 
00450   for (Index = 0; ; Index++) {
00451     Status = GetPackageData (HiiPackageList, Index, &PackageLength, &Package);
00452     if (!EFI_ERROR (Status)) {
00453       CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
00454       if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
00455         Status = LocateLabel (Package, Label, FormsetGuid, FormId);
00456         if (!EFI_ERROR(Status)) {
00457           break;
00458         }
00459       }
00460     } else {
00461       break;
00462     }
00463   }
00464 
00465   
00466 Done:
00467   FreePool (HiiPackageList);
00468   
00469   return Status;
00470 }
00471 
00487 EFI_STATUS
00488 EFIAPI
00489 HiiThunkUpdateForm (
00490   IN EFI_HII_PROTOCOL                  *This,
00491   IN FRAMEWORK_EFI_HII_HANDLE          Handle,
00492   IN EFI_FORM_LABEL                    Label,
00493   IN BOOLEAN                           AddData,
00494   IN EFI_HII_UPDATE_DATA               *Data
00495   )
00496 {
00497   EFI_STATUS                                Status;
00498   HII_THUNK_PRIVATE_DATA                    *Private;
00499   HII_THUNK_CONTEXT                         *ThunkContext;
00500   EFI_HII_HANDLE                            UefiHiiHandle;
00501   EFI_GUID                                  FormsetGuid;
00502   EFI_FORM_ID                               FormId;
00503   EFI_TPL                                   OldTpl;
00504   VOID                                      *StartOpCodeHandle;
00505   VOID                                      *EndOpCodeHandle;
00506   EFI_IFR_GUID_LABEL                        *StartLabel;
00507   EFI_IFR_GUID_LABEL                        *EndLabel;
00508 
00509   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
00510   
00511   mInFrameworkUpdatePakcage = TRUE;
00512   Status = EFI_SUCCESS;
00513 
00514   Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
00515 
00516   ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
00517 
00518   if (ThunkContext == NULL) {
00519     Status = EFI_NOT_FOUND;
00520     goto Done;
00521   }
00522   
00523   if (Data->FormSetUpdate) {
00524     Status = UpdateFormCallBack ((EFI_HANDLE) (UINTN) Data->FormCallbackHandle, ThunkContext);
00525     if (EFI_ERROR (Status)) {
00526       goto Done;
00527     }
00528   }
00529 
00530   if (ThunkContext->IfrPackageCount == 0) {
00531     ASSERT (FALSE);
00532     Status = EFI_INVALID_PARAMETER;
00533     goto Done;
00534   } else {
00535     UefiHiiHandle = ThunkContext->UefiHiiHandle;
00536   }
00537 
00538   Status = LocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);
00539   if (EFI_ERROR (Status)) {
00540     //
00541     // Can't find the label.
00542     //
00543     goto Done;
00544   }
00545 
00546   //
00547   // Init OpCode Handle
00548   //
00549   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
00550   ASSERT (StartOpCodeHandle != NULL);
00551 
00552   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
00553   ASSERT (EndOpCodeHandle != NULL);
00554 
00555   //
00556   // Create Hii Extend Label OpCode as the start opcode
00557   //
00558   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
00559   StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
00560   StartLabel->Number       = Label;
00561 
00562   //
00563   // Create Hii Extend Label OpCode as the end opcode
00564   //
00565   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
00566   EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
00567   EndLabel->Number       = 0xffff;
00568 
00569   if (AddData) {
00570     if (Data->DataCount != 0) {
00571 
00572       ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);
00573       ASSERT (ThunkContext != NULL);
00574       Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, StartOpCodeHandle);
00575       ASSERT_EFI_ERROR (Status);
00576 
00577       Status = HiiUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, StartOpCodeHandle, NULL);
00578       ASSERT_EFI_ERROR (Status);
00579     }
00580   } else {
00581     //
00582     // Delete Opcode starting from Labe in FormId found
00583     //
00584     Status = HiiUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, StartOpCodeHandle, EndOpCodeHandle);
00585     ASSERT_EFI_ERROR (Status);
00586   }
00587 
00588   HiiFreeOpCodeHandle (StartOpCodeHandle);
00589   HiiFreeOpCodeHandle (EndOpCodeHandle);
00590 
00591 Done:
00592 
00593   mInFrameworkUpdatePakcage = FALSE; 
00594 
00595   gBS->RestoreTPL (OldTpl);
00596 
00597   return Status;
00598 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Defines