1 /** @file
2   This file contains the form processing code to the HII database.
3 
4 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution.  The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9 
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 
16 #include "HiiDatabase.h"
17 #include "UefiIfrDefault.h"
18 
19 //
20 // This structure is only intended to be used in this file.
21 //
22 #pragma pack(1)
23 typedef struct {
24   EFI_HII_PACK_HEADER            PackageHeader;
25   FRAMEWORK_EFI_IFR_FORM_SET     FormSet;
26   EFI_IFR_END_FORM_SET           EndFormSet;
27 } FW_HII_FORMSET_TEMPLATE;
28 #pragma pack()
29 
30 FW_HII_FORMSET_TEMPLATE FormSetTemplate = {
31   {
32     sizeof (FW_HII_FORMSET_TEMPLATE),
33     EFI_HII_IFR
34   },
35   {
36     {
37       FRAMEWORK_EFI_IFR_FORM_SET_OP,
38       sizeof (FRAMEWORK_EFI_IFR_FORM_SET)
39     },
40     {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}, //Guid
41     0,
42     0,
43     0,
44     0,
45     0,
46     0
47   },
48   {
49     {
50       EFI_IFR_END_FORM_SET_OP,
51       sizeof (EFI_IFR_END_FORM_SET)
52     }
53   }
54 };
55 
56 
57 EFI_GUID  mTianoHiiIfrGuid              = EFI_IFR_TIANO_GUID;
58 
59 /**
60 
61   This thunk module only handles UEFI HII packages. The caller of this function
62   won't be able to parse the content. Therefore, it is not supported.
63 
64   This function will ASSERT and return EFI_UNSUPPORTED.
65 
66   @param This            N.A.
67   @param Handle          N.A.
68   @param BufferSize      N.A.
69   @param Buffer          N.A.
70 
71   @retval EFI_UNSUPPORTED
72 
73 **/
74 EFI_STATUS
75 EFIAPI
HiiExportDatabase(IN EFI_HII_PROTOCOL * This,IN FRAMEWORK_EFI_HII_HANDLE Handle,IN OUT UINTN * BufferSize,OUT VOID * Buffer)76 HiiExportDatabase (
77   IN     EFI_HII_PROTOCOL *This,
78   IN     FRAMEWORK_EFI_HII_HANDLE    Handle,
79   IN OUT UINTN            *BufferSize,
80   OUT    VOID             *Buffer
81   )
82 {
83   ASSERT (FALSE);
84   return EFI_UNSUPPORTED;
85 }
86 
87 
88 /**
89   This function allows a program to extract a form or form package that has
90   previously been registered with the EFI HII database.
91 
92   In this thunk module, this function will create a IFR Package with only
93   one Formset. Effectively, only the GUID of the Formset is updated and return
94   in this IFR package to caller. This is enable the Framework modules which call
95   a API named GetStringFromToken. GetStringFromToken retieves a String based on
96   a String Token from a Package List known only by the Formset GUID.
97 
98 
99 
100   @param This             A pointer to the EFI_HII_PROTOCOL instance.
101   @param Handle           Handle on which the form resides. Type FRAMEWORK_EFI_HII_HANDLE  is defined in
102                           EFI_HII_PROTOCOL.NewPack() in the Packages section.
103   @param FormId           Ignored by this implementation.
104   @param BufferLengthTemp On input, the size of input buffer. On output, it
105                           is the size of FW_HII_FORMSET_TEMPLATE.
106   @param Buffer           The buffer designed to receive the form(s).
107 
108   @retval  EFI_SUCCESS            Buffer filled with the requested forms. BufferLength
109                                   was updated.
110   @retval  EFI_INVALID_PARAMETER  The handle is unknown.
111   @retval  EFI_NOT_FOUND          A form on the requested handle cannot be found with the
112                                   requested FormId.
113   @retval  EFI_BUFFER_TOO_SMALL   The buffer provided was not large enough to allow the form to be stored.
114 
115 **/
116 EFI_STATUS
117 EFIAPI
HiiGetForms(IN EFI_HII_PROTOCOL * This,IN FRAMEWORK_EFI_HII_HANDLE Handle,IN EFI_FORM_ID FormId,IN OUT UINTN * BufferLengthTemp,OUT UINT8 * Buffer)118 HiiGetForms (
119   IN     EFI_HII_PROTOCOL             *This,
120   IN     FRAMEWORK_EFI_HII_HANDLE     Handle,
121   IN     EFI_FORM_ID                  FormId,
122   IN OUT UINTN                        *BufferLengthTemp,
123   OUT    UINT8                        *Buffer
124   )
125 {
126   HII_THUNK_PRIVATE_DATA                *Private;
127   HII_THUNK_CONTEXT  *ThunkContext;
128   FW_HII_FORMSET_TEMPLATE            *OutputFormSet;
129 
130   if (*BufferLengthTemp < sizeof(FW_HII_FORMSET_TEMPLATE)) {
131     *BufferLengthTemp = sizeof(FW_HII_FORMSET_TEMPLATE);
132     return EFI_BUFFER_TOO_SMALL;
133   }
134 
135   Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
136 
137   ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
138 
139   if (ThunkContext == NULL) {
140     return EFI_NOT_FOUND;
141   }
142 
143   OutputFormSet = (FW_HII_FORMSET_TEMPLATE *) Buffer;
144 
145   CopyMem (OutputFormSet, &FormSetTemplate, sizeof (FW_HII_FORMSET_TEMPLATE));
146   CopyMem (&OutputFormSet->FormSet.Guid, &ThunkContext->TagGuid, sizeof (EFI_GUID));
147 
148   if (ThunkContext->FormSet != NULL) {
149     OutputFormSet->FormSet.Class = ThunkContext->FormSet->Class;
150     OutputFormSet->FormSet.SubClass = ThunkContext->FormSet->SubClass;
151     OutputFormSet->FormSet.Help     = ThunkContext->FormSet->Help;
152     OutputFormSet->FormSet.FormSetTitle = ThunkContext->FormSet->FormSetTitle;
153   }
154 
155   return EFI_SUCCESS;
156 }
157 
158 
159 /**
160 
161   This function allows a program to extract the NV Image
162   that represents the default storage image
163 
164 
165   @param This            A pointer to the EFI_HII_PROTOCOL instance.
166   @param Handle          The HII handle from which will have default data retrieved.
167                          UINTN            - Mask used to retrieve the default image.
168   @param DefaultMask     EDES_TODO: Add parameter description
169   @param VariablePackList Callee allocated, tightly-packed, link list data
170                          structure that contain all default varaible packs
171                          from the Hii Database.
172 
173   @retval  EFI_NOT_FOUND          If Hii database does not contain any default images.
174   @retval  EFI_INVALID_PARAMETER  Invalid input parameter.
175   @retval  EFI_SUCCESS            Operation successful.
176 
177 **/
178 EFI_STATUS
179 EFIAPI
HiiGetDefaultImage(IN EFI_HII_PROTOCOL * This,IN FRAMEWORK_EFI_HII_HANDLE Handle,IN UINTN DefaultMask,OUT EFI_HII_VARIABLE_PACK_LIST ** VariablePackList)180 HiiGetDefaultImage (
181   IN     EFI_HII_PROTOCOL            *This,
182   IN     FRAMEWORK_EFI_HII_HANDLE    Handle,
183   IN     UINTN                       DefaultMask,
184   OUT    EFI_HII_VARIABLE_PACK_LIST  **VariablePackList
185   )
186 {
187   LIST_ENTRY        *UefiDefaults;
188   EFI_STATUS        Status;
189   HII_THUNK_PRIVATE_DATA *Private;
190   HII_THUNK_CONTEXT *ThunkContext;
191 
192   Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
193 
194   ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
195   if (ThunkContext == NULL) {
196     ASSERT (FALSE);
197     return EFI_INVALID_PARAMETER;
198   }
199 
200   UefiDefaults = NULL;
201   Status = UefiIfrGetBufferTypeDefaults (ThunkContext, &UefiDefaults);
202   if (EFI_ERROR (Status)) {
203     goto Done;
204   }
205 
206   Status = UefiDefaultsToFwDefaults (UefiDefaults, DefaultMask, ThunkContext->FormSet->DefaultVarStoreId, VariablePackList);
207 
208 Done:
209   FreeDefaultList (UefiDefaults);
210 
211   return Status;
212 }
213 
214 /**
215   This function update the FormCallbackProtocol cached in Config Access
216   private context data.
217 
218   @param CallbackHandle  The EFI Handle on which the Framework FormCallbackProtocol is
219                          installed.
220   @param ThunkContext    The Thunk Context.
221 
222   @retval EFI_SUCCESS             The update is successful.
223   @retval EFI_INVALID_PARAMETER   If no Framework FormCallbackProtocol is located on CallbackHandle.
224 
225 **/
226 EFI_STATUS
UpdateFormCallBack(IN EFI_HANDLE CallbackHandle,IN CONST HII_THUNK_CONTEXT * ThunkContext)227 UpdateFormCallBack (
228   IN       EFI_HANDLE                                CallbackHandle,
229   IN CONST HII_THUNK_CONTEXT                         *ThunkContext
230   )
231 {
232   EFI_STATUS                                Status;
233   EFI_FORM_CALLBACK_PROTOCOL                *FormCallbackProtocol;
234   EFI_HII_CONFIG_ACCESS_PROTOCOL            *ConfigAccessProtocol;
235   EFI_HANDLE                                UefiDriverHandle;
236   CONFIG_ACCESS_PRIVATE                     *ConfigAccessPrivate;
237 
238   Status = gBS->HandleProtocol (
239                    CallbackHandle,
240                    &gEfiFormCallbackProtocolGuid,
241                    (VOID **) &FormCallbackProtocol
242                    );
243   if (EFI_ERROR (Status)) {
244     return EFI_INVALID_PARAMETER;
245   }
246 
247   Status = mHiiDatabase->GetPackageListHandle (
248                                         mHiiDatabase,
249                                         ThunkContext->UefiHiiHandle,
250                                         &UefiDriverHandle
251                                         );
252   ASSERT_EFI_ERROR (Status);
253   Status = gBS->HandleProtocol (
254                    UefiDriverHandle,
255                    &gEfiHiiConfigAccessProtocolGuid,
256                    (VOID **) &ConfigAccessProtocol
257                    );
258   ASSERT_EFI_ERROR (Status);
259 
260   ConfigAccessPrivate = CONFIG_ACCESS_PRIVATE_FROM_PROTOCOL (ConfigAccessProtocol);
261 
262   ConfigAccessPrivate->FormCallbackProtocol = FormCallbackProtocol;
263 
264   return EFI_SUCCESS;
265 }
266 
267 
268 /**
269   Get the package data from the Package List.
270 
271   @param HiiPackageList  Package List.
272   @param PackageIndex    The index of the Package in the Package List.
273   @param BufferLen       The Length of the Pacage data.
274   @param Buffer          On output, the Package data.
275 
276   @return EFI_NOT_FOUND  No Package is found for PackageIndex.
277   @return EFI_SUCCESS    The package data is returned.
278 
279 **/
280 EFI_STATUS
GetPackageData(IN EFI_HII_PACKAGE_LIST_HEADER * HiiPackageList,IN UINT32 PackageIndex,OUT UINT32 * BufferLen,OUT EFI_HII_PACKAGE_HEADER ** Buffer)281 GetPackageData (
282   IN  EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList,
283   IN  UINT32                      PackageIndex,
284   OUT UINT32                      *BufferLen,
285   OUT EFI_HII_PACKAGE_HEADER      **Buffer
286   )
287 {
288   UINT32                        Index;
289   EFI_HII_PACKAGE_HEADER        *Package;
290   UINT32                        Offset;
291   UINT32                        PackageListLength;
292   EFI_HII_PACKAGE_HEADER        PackageHeader;
293 
294   ASSERT(HiiPackageList != NULL);
295 
296   if ((BufferLen == NULL) || (Buffer == NULL)) {
297     return EFI_INVALID_PARAMETER;
298   }
299 
300   ZeroMem (&PackageHeader, sizeof (PackageHeader));
301   Package = NULL;
302   Index   = 0;
303   Offset  = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
304   CopyMem (&PackageListLength, &HiiPackageList->PackageLength, sizeof (UINT32));
305   while (Offset < PackageListLength) {
306     Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);
307     CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
308     if (Index == PackageIndex) {
309       break;
310     }
311     Offset += PackageHeader.Length;
312     Index++;
313   }
314   if (Offset >= PackageListLength) {
315     //
316     // no package found in this Package List
317     //
318     return EFI_NOT_FOUND;
319   }
320 
321   *BufferLen = PackageHeader.Length;
322   *Buffer    = Package;
323   return EFI_SUCCESS;
324 }
325 
326 /**
327   Check if Label exist in the IFR form package and return the FormSet GUID
328   and Form ID.
329 
330   @param Package      The Package Header.
331   @param Label        The Label ID.
332   @param FormsetGuid  Returns the FormSet GUID.
333   @param FormId       Returns the Form ID.
334 
335   @retval EFI_SUCCESS     The FORM ID is found.
336   @retval EFI_NOT_FOUND   The FORM ID is not found.
337 **/
338 EFI_STATUS
LocateLabel(IN CONST EFI_HII_PACKAGE_HEADER * Package,IN EFI_FORM_LABEL Label,OUT EFI_GUID * FormsetGuid,OUT EFI_FORM_ID * FormId)339 LocateLabel (
340   IN CONST EFI_HII_PACKAGE_HEADER *Package,
341   IN       EFI_FORM_LABEL          Label,
342   OUT      EFI_GUID                *FormsetGuid,
343   OUT      EFI_FORM_ID             *FormId
344   )
345 {
346   UINTN                     Offset;
347   EFI_IFR_OP_HEADER         *IfrOpHdr;
348   EFI_GUID                  InternalFormSetGuid;
349   EFI_FORM_ID               InternalFormId;
350   BOOLEAN                   GetFormSet;
351   BOOLEAN                   GetForm;
352   EFI_IFR_GUID_LABEL        *LabelOpcode;
353 
354   IfrOpHdr   = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));
355   Offset     = sizeof (EFI_HII_PACKAGE_HEADER);
356 
357   InternalFormId= 0;
358   ZeroMem (&InternalFormSetGuid, sizeof (EFI_GUID));
359   GetFormSet = FALSE;
360   GetForm    = FALSE;
361 
362   while (Offset < Package->Length) {
363     switch (IfrOpHdr->OpCode) {
364     case EFI_IFR_FORM_SET_OP :
365       CopyMem (&InternalFormSetGuid, &((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, sizeof (EFI_GUID));
366       GetFormSet = TRUE;
367       break;
368 
369     case EFI_IFR_FORM_OP:
370       CopyMem (&InternalFormId, &((EFI_IFR_FORM *) IfrOpHdr)->FormId, sizeof (EFI_FORM_ID));
371       GetForm = TRUE;
372       break;
373 
374     case EFI_IFR_GUID_OP :
375       LabelOpcode = (EFI_IFR_GUID_LABEL *) IfrOpHdr;
376       //
377       // If it is an Label opcode.
378       //
379       if ((LabelOpcode->ExtendOpCode == EFI_IFR_EXTEND_OP_LABEL) && (CompareMem (&LabelOpcode->Guid, &mTianoHiiIfrGuid, sizeof (EFI_GUID)) == 0)) {
380         if (CompareMem (&Label, &LabelOpcode->Number, sizeof (UINT16)) == 0) {
381           ASSERT (GetForm && GetFormSet);
382           CopyGuid (FormsetGuid, &InternalFormSetGuid);
383           *FormId = InternalFormId;
384           return EFI_SUCCESS;
385         }
386       }
387       break;
388     default :
389       break;
390     }
391 
392     //
393     // Go to the next Op-Code
394     //
395     Offset   += IfrOpHdr->Length;
396     IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
397   }
398 
399   return EFI_NOT_FOUND;
400 }
401 
402 /**
403   Find the first EFI_FORM_LABEL in FormSets for a given EFI_HII_HANLDE defined.
404 
405   EFI_FORM_LABEL is a specific to Tiano implementation. The current implementation
406   does not restrict labels with same label value to be duplicated in either FormSet
407   scope or Form scope. This function will only locate the FIRST EFI_FORM_LABEL
408   with value as the same as the input Label in the Formset registered with UefiHiiHandle. The FormSet GUID
409   and Form ID is returned if such Label is found.
410 
411   @param Handle       Uefi Hii Handle to be searched.
412   @param Label        The first Label ID to be found.
413   @param FormsetGuid  The matched FormSet GUID.
414   @param FormId       The matched Form ID.
415 
416   @retval EFI_INVALID_PARAMETER If UefiHiiHandle is not a valid handle.
417   @retval EFI_NOT_FOUND         The package list identified by UefiHiiHandle deos not contain FormSet or
418                                 Form ID with value Label found in all Form Sets in the pacakge list.
419   @retval EFI_SUCCESS           The first found Form ID is returned in FormId.
420 **/
421 EFI_STATUS
LocateFormId(IN EFI_HII_HANDLE Handle,IN EFI_FORM_LABEL Label,OUT EFI_GUID * FormsetGuid,OUT EFI_FORM_ID * FormId)422 LocateFormId (
423   IN  EFI_HII_HANDLE Handle,
424   IN  EFI_FORM_LABEL Label,
425   OUT EFI_GUID       *FormsetGuid,
426   OUT EFI_FORM_ID    *FormId
427   )
428 {
429   EFI_STATUS                   Status;
430   EFI_HII_PACKAGE_LIST_HEADER  *HiiPackageList;
431   UINT32                       Index;
432   UINTN                        BufferSize;
433   EFI_HII_PACKAGE_HEADER       PackageHeader;
434   EFI_HII_PACKAGE_HEADER       *Package;
435   UINT32                       PackageLength;
436 
437   BufferSize = 0;
438   HiiPackageList   = NULL;
439   Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
440   if (Status == EFI_BUFFER_TOO_SMALL) {
441     HiiPackageList = AllocatePool (BufferSize);
442     ASSERT (HiiPackageList != NULL);
443 
444     Status = mHiiDatabase->ExportPackageLists (mHiiDatabase, Handle, &BufferSize, HiiPackageList);
445     if (EFI_ERROR (Status)) {
446       goto Done;
447     }
448   }
449 
450   for (Index = 0; ; Index++) {
451     Status = GetPackageData (HiiPackageList, Index, &PackageLength, &Package);
452     if (!EFI_ERROR (Status)) {
453       CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
454       if (PackageHeader.Type == EFI_HII_PACKAGE_FORMS) {
455         Status = LocateLabel (Package, Label, FormsetGuid, FormId);
456         if (!EFI_ERROR(Status)) {
457           break;
458         }
459       }
460     } else {
461       break;
462     }
463   }
464 
465 
466 Done:
467   FreePool (HiiPackageList);
468 
469   return Status;
470 }
471 
472 /**
473   This function allows the caller to update a form that has
474   previously been registered with the EFI HII database.
475 
476 
477   @param This            EDES_TODO: Add parameter description
478   @param Handle          Hii Handle associated with the Formset to modify
479   @param Label           Update information starting immediately after this label in the IFR
480   @param AddData         If TRUE, add data.  If FALSE, remove data
481   @param Data            If adding data, this is the pointer to the data to add
482 
483   @retval  EFI_SUCCESS  Update success.
484   @retval  Other        Update fail.
485 
486 **/
487 EFI_STATUS
488 EFIAPI
HiiThunkUpdateForm(IN EFI_HII_PROTOCOL * This,IN FRAMEWORK_EFI_HII_HANDLE Handle,IN EFI_FORM_LABEL Label,IN BOOLEAN AddData,IN EFI_HII_UPDATE_DATA * Data)489 HiiThunkUpdateForm (
490   IN EFI_HII_PROTOCOL                  *This,
491   IN FRAMEWORK_EFI_HII_HANDLE          Handle,
492   IN EFI_FORM_LABEL                    Label,
493   IN BOOLEAN                           AddData,
494   IN EFI_HII_UPDATE_DATA               *Data
495   )
496 {
497   EFI_STATUS                                Status;
498   HII_THUNK_PRIVATE_DATA                    *Private;
499   HII_THUNK_CONTEXT                         *ThunkContext;
500   EFI_HII_HANDLE                            UefiHiiHandle;
501   EFI_GUID                                  FormsetGuid;
502   EFI_FORM_ID                               FormId;
503   EFI_TPL                                   OldTpl;
504   VOID                                      *StartOpCodeHandle;
505   VOID                                      *EndOpCodeHandle;
506   EFI_IFR_GUID_LABEL                        *StartLabel;
507   EFI_IFR_GUID_LABEL                        *EndLabel;
508 
509   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
510 
511   mInFrameworkUpdatePakcage = TRUE;
512   Status = EFI_SUCCESS;
513 
514   Private = HII_THUNK_PRIVATE_DATA_FROM_THIS(This);
515 
516   ThunkContext = FwHiiHandleToThunkContext (Private, Handle);
517 
518   if (ThunkContext == NULL) {
519     Status = EFI_NOT_FOUND;
520     goto Done;
521   }
522 
523   if (Data->FormSetUpdate) {
524     Status = UpdateFormCallBack ((EFI_HANDLE) (UINTN) Data->FormCallbackHandle, ThunkContext);
525     if (EFI_ERROR (Status)) {
526       goto Done;
527     }
528   }
529 
530   if (ThunkContext->IfrPackageCount == 0) {
531     ASSERT (FALSE);
532     Status = EFI_INVALID_PARAMETER;
533     goto Done;
534   } else {
535     UefiHiiHandle = ThunkContext->UefiHiiHandle;
536   }
537 
538   Status = LocateFormId (UefiHiiHandle, Label, &FormsetGuid, &FormId);
539   if (EFI_ERROR (Status)) {
540     //
541     // Can't find the label.
542     //
543     goto Done;
544   }
545 
546   //
547   // Init OpCode Handle
548   //
549   StartOpCodeHandle = HiiAllocateOpCodeHandle ();
550   ASSERT (StartOpCodeHandle != NULL);
551 
552   EndOpCodeHandle = HiiAllocateOpCodeHandle ();
553   ASSERT (EndOpCodeHandle != NULL);
554 
555   //
556   // Create Hii Extend Label OpCode as the start opcode
557   //
558   StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
559   StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
560   StartLabel->Number       = Label;
561 
562   //
563   // Create Hii Extend Label OpCode as the end opcode
564   //
565   EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
566   EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
567   EndLabel->Number       = 0xffff;
568 
569   if (AddData) {
570     if (Data->DataCount != 0) {
571 
572       ThunkContext = UefiHiiHandleToThunkContext (Private, UefiHiiHandle);
573       ASSERT (ThunkContext != NULL);
574       Status = FwUpdateDataToUefiUpdateData (ThunkContext, Data, StartOpCodeHandle);
575       ASSERT_EFI_ERROR (Status);
576 
577       Status = HiiUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, StartOpCodeHandle, NULL);
578       ASSERT_EFI_ERROR (Status);
579     }
580   } else {
581     //
582     // Delete Opcode starting from Labe in FormId found
583     //
584     Status = HiiUpdateForm (UefiHiiHandle, &FormsetGuid, FormId, StartOpCodeHandle, EndOpCodeHandle);
585     ASSERT_EFI_ERROR (Status);
586   }
587 
588   HiiFreeOpCodeHandle (StartOpCodeHandle);
589   HiiFreeOpCodeHandle (EndOpCodeHandle);
590 
591 Done:
592 
593   mInFrameworkUpdatePakcage = FALSE;
594 
595   gBS->RestoreTPL (OldTpl);
596 
597   return Status;
598 }
599