Add Example for EFI_BROWSER_ACTION_RETRIEVE callback
[efi/edk2/.git] / edk2 / MdeModulePkg / Universal / DriverSampleDxe / DriverSample.c
1 /** @file\r
2 This is an example of how a driver might export data to the HII protocol to be\r
3 later utilized by the Setup Protocol\r
4 \r
5 Copyright (c) 2004 - 2009, Intel Corporation\r
6 All rights reserved. This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution.  The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10 \r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13 \r
14 **/\r
15 \r
16 \r
17 #include "DriverSample.h"\r
18 \r
19 #define DISPLAY_ONLY_MY_ITEM  0x0002\r
20 \r
21 EFI_GUID   mFormSetGuid = FORMSET_GUID;\r
22 EFI_GUID   mInventoryGuid = INVENTORY_GUID;\r
23 \r
24 CHAR16     VariableName[] = L"MyIfrNVData";\r
25 EFI_HANDLE                      DriverHandle[2] = {NULL, NULL};\r
26 DRIVER_SAMPLE_PRIVATE_DATA      *PrivateData = NULL;\r
27 \r
28 HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath0 = {\r
29   {\r
30     {\r
31       HARDWARE_DEVICE_PATH,\r
32       HW_VENDOR_DP,\r
33       {\r
34         (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
35         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
36       }\r
37     },\r
38     //\r
39     // {C153B68D-EBFC-488e-B110-662867745B87}\r
40     //\r
41     { 0xc153b68d, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0x87 } }\r
42   },\r
43   {\r
44     END_DEVICE_PATH_TYPE,\r
45     END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
46     {\r
47       (UINT8) (END_DEVICE_PATH_LENGTH),\r
48       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
49     }\r
50   }\r
51 };\r
52 \r
53 HII_VENDOR_DEVICE_PATH  mHiiVendorDevicePath1 = {\r
54   {\r
55     {\r
56       HARDWARE_DEVICE_PATH,\r
57       HW_VENDOR_DP,\r
58       {\r
59         (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
60         (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
61       }\r
62     },\r
63     //\r
64     // {06F37F07-0C48-40e9-8436-0A08A0BB76B0}\r
65     //\r
66     { 0x6f37f07, 0xc48, 0x40e9, { 0x84, 0x36, 0xa, 0x8, 0xa0, 0xbb, 0x76, 0xb0 } }\r
67   },\r
68   {\r
69     END_DEVICE_PATH_TYPE,\r
70     END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
71     {\r
72       (UINT8) (END_DEVICE_PATH_LENGTH),\r
73       (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
74     }\r
75   }\r
76 };\r
77 \r
78 /**\r
79   Encode the password using a simple algorithm.\r
80 \r
81   @param Password The string to be encoded.\r
82   @param MaxSize  The size of the string.\r
83 \r
84 **/\r
85 VOID\r
86 EncodePassword (\r
87   IN  CHAR16                      *Password,\r
88   IN  UINTN                       MaxSize\r
89   )\r
90 {\r
91   UINTN   Index;\r
92   UINTN   Loop;\r
93   CHAR16  *Buffer;\r
94   CHAR16  *Key;\r
95 \r
96   Key     = L"MAR10648567";\r
97   Buffer  = AllocateZeroPool (MaxSize);\r
98   ASSERT (Buffer != NULL);\r
99 \r
100   for (Index = 0; Key[Index] != 0; Index++) {\r
101     for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) {\r
102       Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]);\r
103     }\r
104   }\r
105 \r
106   CopyMem (Password, Buffer, MaxSize);\r
107 \r
108   FreePool (Buffer);\r
109   return ;\r
110 }\r
111 \r
112 /**\r
113   Validate the user's password.\r
114 \r
115   @param PrivateData This driver's private context data.\r
116   @param StringId    The user's input.\r
117 \r
118   @retval EFI_SUCCESS   The user's input matches the password.\r
119   @retval EFI_NOT_READY The user's input does not match the password.\r
120 **/\r
121 EFI_STATUS\r
122 ValidatePassword (\r
123   IN       DRIVER_SAMPLE_PRIVATE_DATA      *PrivateData,\r
124   IN       EFI_STRING_ID                   StringId\r
125   )\r
126 {\r
127   EFI_STATUS                      Status;\r
128   UINTN                           Index;\r
129   UINTN                           BufferSize;\r
130   UINTN                           PasswordMaxSize;\r
131   CHAR16                          *Password;\r
132   CHAR16                          *EncodedPassword;\r
133   BOOLEAN                         OldPassword;\r
134 \r
135   //\r
136   // Get encoded password first\r
137   //\r
138   BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
139   Status = gRT->GetVariable (\r
140                   VariableName,\r
141                   &mFormSetGuid,\r
142                   NULL,\r
143                   &BufferSize,\r
144                   &PrivateData->Configuration\r
145                   );\r
146   if (EFI_ERROR (Status)) {\r
147     //\r
148     // Old password not exist, prompt for new password\r
149     //\r
150     return EFI_SUCCESS;\r
151   }\r
152 \r
153   OldPassword = FALSE;\r
154   PasswordMaxSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);\r
155   //\r
156   // Check whether we have any old password set\r
157   //\r
158   for (Index = 0; Index < PasswordMaxSize / sizeof (UINT16); Index++) {\r
159     if (PrivateData->Configuration.WhatIsThePassword2[Index] != 0) {\r
160       OldPassword = TRUE;\r
161       break;\r
162     }\r
163   }\r
164   if (!OldPassword) {\r
165     //\r
166     // Old password not exist, return EFI_SUCCESS to prompt for new password\r
167     //\r
168     return EFI_SUCCESS;\r
169   }\r
170 \r
171   //\r
172   // Get user input password\r
173   //\r
174   Password = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL);\r
175   if (Password == NULL) {\r
176     return EFI_NOT_READY;\r
177   }\r
178   if (StrSize (Password) > PasswordMaxSize) {\r
179     FreePool (Password);\r
180     return EFI_NOT_READY;\r
181   }\r
182 \r
183   //\r
184   // Validate old password\r
185   //\r
186   EncodedPassword = AllocateZeroPool (PasswordMaxSize);\r
187   ASSERT (EncodedPassword != NULL);\r
188   StrnCpy (EncodedPassword, Password, StrLen (Password));\r
189   EncodePassword (EncodedPassword, StrLen (EncodedPassword) * sizeof (CHAR16));\r
190   if (CompareMem (EncodedPassword, PrivateData->Configuration.WhatIsThePassword2, StrLen (EncodedPassword) * sizeof (CHAR16)) != 0) {\r
191     //\r
192     // Old password mismatch, return EFI_NOT_READY to prompt for error message\r
193     //\r
194     Status = EFI_NOT_READY;\r
195   } else {\r
196     Status = EFI_SUCCESS;\r
197   }\r
198 \r
199   FreePool (Password);\r
200   FreePool (EncodedPassword);\r
201 \r
202   return Status;\r
203 }\r
204 \r
205 /**\r
206   Encode the password using a simple algorithm.\r
207 \r
208   @param PrivateData This driver's private context data.\r
209   @param StringId    The password from User.\r
210 \r
211   @retval  EFI_SUCESS The operation is successful.\r
212   @return  Other value if gRT->SetVariable () fails.\r
213 \r
214 **/\r
215 EFI_STATUS\r
216 SetPassword (\r
217   IN DRIVER_SAMPLE_PRIVATE_DATA      *PrivateData,\r
218   IN EFI_STRING_ID                   StringId\r
219   )\r
220 {\r
221   EFI_STATUS                      Status;\r
222   CHAR16                          *Password;\r
223   CHAR16                          *TempPassword;\r
224   UINTN                           PasswordSize;\r
225   DRIVER_SAMPLE_CONFIGURATION     *Configuration;\r
226   UINTN                           BufferSize;\r
227 \r
228   //\r
229   // Get Buffer Storage data from EFI variable\r
230   //\r
231   BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
232   Status = gRT->GetVariable (\r
233                   VariableName,\r
234                   &mFormSetGuid,\r
235                   NULL,\r
236                   &BufferSize,\r
237                   &PrivateData->Configuration\r
238                   );\r
239   if (EFI_ERROR (Status)) {\r
240     return Status;\r
241   }\r
242 \r
243   //\r
244   // Get user input password\r
245   //\r
246   Password = &PrivateData->Configuration.WhatIsThePassword2[0];\r
247   PasswordSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);\r
248   ZeroMem (Password, PasswordSize);\r
249 \r
250   TempPassword = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL);\r
251   if (TempPassword == NULL) {\r
252     return EFI_NOT_READY;\r
253   }\r
254   if (StrSize (TempPassword) > PasswordSize) {\r
255     FreePool (TempPassword);\r
256     return EFI_NOT_READY;\r
257   }\r
258   StrnCpy (Password, TempPassword, StrLen (TempPassword));\r
259   FreePool (TempPassword);\r
260 \r
261   //\r
262   // Retrive uncommitted data from Browser\r
263   //\r
264   Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
265   ASSERT (Configuration != NULL);\r
266   if (HiiGetBrowserData (&mFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) {\r
267     //\r
268     // Update password's clear text in the screen\r
269     //\r
270     CopyMem (Configuration->PasswordClearText, Password, StrSize (Password));\r
271 \r
272     //\r
273     // Update uncommitted data of Browser\r
274     //\r
275     HiiSetBrowserData (\r
276        &mFormSetGuid,\r
277        VariableName,\r
278        sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
279        (UINT8 *) Configuration,\r
280        NULL\r
281        );\r
282   }\r
283 \r
284   //\r
285   // Free Configuration Buffer\r
286   //\r
287   FreePool (Configuration);\r
288 \r
289 \r
290   //\r
291   // Set password\r
292   //\r
293   EncodePassword (Password, StrLen (Password) * 2);\r
294   Status = gRT->SetVariable(\r
295                   VariableName,\r
296                   &mFormSetGuid,\r
297                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
298                   sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
299                   &PrivateData->Configuration\r
300                   );\r
301   return Status;\r
302 }\r
303 \r
304 \r
305 /**\r
306   This function allows a caller to extract the current configuration for one\r
307   or more named elements from the target driver.\r
308 \r
309   @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
310   @param  Request                A null-terminated Unicode string in\r
311                                  <ConfigRequest> format.\r
312   @param  Progress               On return, points to a character in the Request\r
313                                  string. Points to the string's null terminator if\r
314                                  request was successful. Points to the most recent\r
315                                  '&' before the first failing name/value pair (or\r
316                                  the beginning of the string if the failure is in\r
317                                  the first name/value pair) if the request was not\r
318                                  successful.\r
319   @param  Results                A null-terminated Unicode string in\r
320                                  <ConfigAltResp> format which has all values filled\r
321                                  in for the names in the Request string. String to\r
322                                  be allocated by the called function.\r
323 \r
324   @retval EFI_SUCCESS            The Results is filled with the requested values.\r
325   @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
326   @retval EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.\r
327   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
328                                  driver.\r
329 \r
330 **/\r
331 EFI_STATUS\r
332 EFIAPI\r
333 ExtractConfig (\r
334   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
335   IN  CONST EFI_STRING                       Request,\r
336   OUT EFI_STRING                             *Progress,\r
337   OUT EFI_STRING                             *Results\r
338   )\r
339 {\r
340   EFI_STATUS                       Status;\r
341   UINTN                            BufferSize;\r
342   DRIVER_SAMPLE_PRIVATE_DATA       *PrivateData;\r
343   EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;\r
344   EFI_STRING                       ConfigRequest;\r
345   EFI_STRING                       ConfigRequestHdr;\r
346   UINTN                            Size;\r
347 \r
348   if (Progress == NULL || Results == NULL || Request == NULL) {\r
349     return EFI_INVALID_PARAMETER;\r
350   }\r
351   //\r
352   // Initialize the local variables.\r
353   //\r
354   ConfigRequestHdr  = NULL;\r
355   ConfigRequest     = NULL;\r
356   Size              = 0;\r
357   *Progress         = Request;\r
358 \r
359   PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
360   HiiConfigRouting = PrivateData->HiiConfigRouting;\r
361 \r
362   //\r
363   // Get Buffer Storage data from EFI variable.\r
364   // Try to get the current setting from variable.\r
365   //\r
366   BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
367   Status = gRT->GetVariable (\r
368             VariableName,\r
369             &mFormSetGuid,\r
370             NULL,\r
371             &BufferSize,\r
372             &PrivateData->Configuration\r
373             );\r
374   if (EFI_ERROR (Status)) {\r
375     return EFI_NOT_FOUND;\r
376   }\r
377 \r
378   if (Request == NULL) {\r
379     //\r
380     // Request is set to NULL, construct full request string.\r
381     //\r
382 \r
383     //\r
384     // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
385     // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
386     //\r
387     ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
388     Size = (StrLen (ConfigRequest) + 32 + 1) * sizeof (CHAR16);\r
389     ConfigRequest = AllocateZeroPool (Size);\r
390     UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
391     FreePool (ConfigRequestHdr);\r
392   } else {\r
393     //\r
394     // Check routing data in <ConfigHdr>.\r
395     // Note: if only one Storage is used, then this checking could be skipped.\r
396     //\r
397     if (!HiiIsConfigHdrMatch (Request, &mFormSetGuid, VariableName)) {\r
398       return EFI_NOT_FOUND;\r
399     }\r
400     ConfigRequest = Request;\r
401   }\r
402 \r
403   //\r
404   // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
405   //\r
406   Status = HiiConfigRouting->BlockToConfig (\r
407                                 HiiConfigRouting,\r
408                                 ConfigRequest,\r
409                                 (UINT8 *) &PrivateData->Configuration,\r
410                                 BufferSize,\r
411                                 Results,\r
412                                 Progress\r
413                                 );\r
414 \r
415   if (Request == NULL) {\r
416     FreePool (ConfigRequest);\r
417     *Progress = NULL;\r
418   }\r
419 \r
420   return Status;\r
421 }\r
422 \r
423 \r
424 /**\r
425   This function processes the results of changes in configuration.\r
426 \r
427   @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
428   @param  Configuration          A null-terminated Unicode string in <ConfigResp>\r
429                                  format.\r
430   @param  Progress               A pointer to a string filled in with the offset of\r
431                                  the most recent '&' before the first failing\r
432                                  name/value pair (or the beginning of the string if\r
433                                  the failure is in the first name/value pair) or\r
434                                  the terminating NULL if all was successful.\r
435 \r
436   @retval EFI_SUCCESS            The Results is processed successfully.\r
437   @retval EFI_INVALID_PARAMETER  Configuration is NULL.\r
438   @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this\r
439                                  driver.\r
440 \r
441 **/\r
442 EFI_STATUS\r
443 EFIAPI\r
444 RouteConfig (\r
445   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
446   IN  CONST EFI_STRING                       Configuration,\r
447   OUT EFI_STRING                             *Progress\r
448   )\r
449 {\r
450   EFI_STATUS                       Status;\r
451   UINTN                            BufferSize;\r
452   DRIVER_SAMPLE_PRIVATE_DATA       *PrivateData;\r
453   EFI_HII_CONFIG_ROUTING_PROTOCOL  *HiiConfigRouting;\r
454 \r
455   if (Configuration == NULL || Progress == NULL) {\r
456     return EFI_INVALID_PARAMETER;\r
457   }\r
458 \r
459   PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
460   HiiConfigRouting = PrivateData->HiiConfigRouting;\r
461   *Progress = Configuration;\r
462 \r
463   //\r
464   // Check routing data in <ConfigHdr>.\r
465   // Note: if only one Storage is used, then this checking could be skipped.\r
466   //\r
467   if (!HiiIsConfigHdrMatch (Configuration, &mFormSetGuid, VariableName)) {\r
468     return EFI_NOT_FOUND;\r
469   }\r
470 \r
471   //\r
472   // Get Buffer Storage data from EFI variable\r
473   //\r
474   BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
475   Status = gRT->GetVariable (\r
476             VariableName,\r
477             &mFormSetGuid,\r
478             NULL,\r
479             &BufferSize,\r
480             &PrivateData->Configuration\r
481             );\r
482   if (EFI_ERROR (Status)) {\r
483     return Status;\r
484   }\r
485 \r
486   //\r
487   // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
488   //\r
489   BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
490   Status = HiiConfigRouting->ConfigToBlock (\r
491                                HiiConfigRouting,\r
492                                Configuration,\r
493                                (UINT8 *) &PrivateData->Configuration,\r
494                                &BufferSize,\r
495                                Progress\r
496                                );\r
497   if (EFI_ERROR (Status)) {\r
498     return Status;\r
499   }\r
500 \r
501   //\r
502   // Store Buffer Storage back to EFI variable\r
503   //\r
504   Status = gRT->SetVariable(\r
505                   VariableName,\r
506                   &mFormSetGuid,\r
507                   EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
508                   sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
509                   &PrivateData->Configuration\r
510                   );\r
511 \r
512   return Status;\r
513 }\r
514 \r
515 \r
516 /**\r
517   This function processes the results of changes in configuration.\r
518 \r
519   @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
520   @param  Action                 Specifies the type of action taken by the browser.\r
521   @param  QuestionId             A unique value which is sent to the original\r
522                                  exporting driver so that it can identify the type\r
523                                  of data to expect.\r
524   @param  Type                   The type of value for the question.\r
525   @param  Value                  A pointer to the data being sent to the original\r
526                                  exporting driver.\r
527   @param  ActionRequest          On return, points to the action requested by the\r
528                                  callback function.\r
529 \r
530   @retval EFI_SUCCESS            The callback successfully handled the action.\r
531   @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the\r
532                                  variable and its data.\r
533   @retval EFI_DEVICE_ERROR       The variable could not be saved.\r
534   @retval EFI_UNSUPPORTED        The specified Action is not supported by the\r
535                                  callback.\r
536 \r
537 **/\r
538 EFI_STATUS\r
539 EFIAPI\r
540 DriverCallback (\r
541   IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
542   IN  EFI_BROWSER_ACTION                     Action,\r
543   IN  EFI_QUESTION_ID                        QuestionId,\r
544   IN  UINT8                                  Type,\r
545   IN  EFI_IFR_TYPE_VALUE                     *Value,\r
546   OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
547   )\r
548 {\r
549   DRIVER_SAMPLE_PRIVATE_DATA      *PrivateData;\r
550   EFI_STATUS                      Status;\r
551   UINT8                           MyVar;\r
552   VOID                            *StartOpCodeHandle;\r
553   VOID                            *OptionsOpCodeHandle;\r
554   EFI_IFR_GUID_LABEL              *StartLabel;\r
555   VOID                            *EndOpCodeHandle;\r
556   EFI_IFR_GUID_LABEL              *EndLabel;\r
557   EFI_INPUT_KEY                   Key;\r
558   DRIVER_SAMPLE_CONFIGURATION     *Configuration;\r
559   UINTN                           MyVarSize;\r
560 \r
561   if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
562     //\r
563     // On FORM_OPEN event, update the form on-the-fly\r
564     //\r
565     PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
566 \r
567     //\r
568     // Initialize the container for dynamic opcodes\r
569     //\r
570     StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
571     ASSERT (StartOpCodeHandle != NULL);\r
572 \r
573     //\r
574     // Create Hii Extend Label OpCode as the start opcode\r
575     //\r
576     StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
577     StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
578     StartLabel->Number       = LABEL_UPDATE2;\r
579 \r
580     HiiCreateActionOpCode (\r
581       StartOpCodeHandle,                // Container for dynamic created opcodes\r
582       0x1238,                           // Question ID\r
583       STRING_TOKEN(STR_SAVE_TEXT),      // Prompt text\r
584       STRING_TOKEN(STR_SAVE_TEXT),      // Help text\r
585       EFI_IFR_FLAG_CALLBACK,            // Question flag\r
586       0                                 // Action String ID\r
587     );\r
588 \r
589     HiiUpdateForm (\r
590       PrivateData->HiiHandle[0],  // HII handle\r
591       &mFormSetGuid,              // Formset GUID\r
592       0x3,                        // Form ID\r
593       StartOpCodeHandle,          // Label for where to insert opcodes\r
594       NULL                        // Insert data\r
595       );\r
596 \r
597     HiiFreeOpCodeHandle (StartOpCodeHandle);\r
598     return EFI_SUCCESS;\r
599   }\r
600 \r
601   if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {\r
602     //\r
603     // On FORM_CLOSE event, show up a pop-up\r
604     //\r
605     do {\r
606       CreatePopUp (\r
607         EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
608         &Key,\r
609         L"",\r
610         L"You are going to leave the Form!",\r
611         L"Press ESC or ENTER to continue ...",\r
612         L"",\r
613         NULL\r
614         );\r
615     } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
616 \r
617     return EFI_SUCCESS;\r
618   }\r
619 \r
620   if ((Value == NULL) || (ActionRequest == NULL)) {\r
621     return EFI_INVALID_PARAMETER;\r
622   }\r
623 \r
624   if ((Type == EFI_IFR_TYPE_STRING) && (Value->string == 0)) {\r
625     return EFI_INVALID_PARAMETER;\r
626   }\r
627 \r
628   Status = EFI_SUCCESS;\r
629   PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
630 \r
631   switch (QuestionId) {\r
632   case 0x1234:\r
633     //\r
634     // Initialize the container for dynamic opcodes\r
635     //\r
636     StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
637     ASSERT (StartOpCodeHandle != NULL);\r
638 \r
639     EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
640     ASSERT (EndOpCodeHandle != NULL);\r
641 \r
642     //\r
643     // Create Hii Extend Label OpCode as the start opcode\r
644     //\r
645     StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
646     StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
647     StartLabel->Number       = LABEL_UPDATE1;\r
648 \r
649     //\r
650     // Create Hii Extend Label OpCode as the end opcode\r
651     //\r
652     EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
653     EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
654     EndLabel->Number       = LABEL_END;\r
655 \r
656     HiiCreateActionOpCode (\r
657       StartOpCodeHandle,                // Container for dynamic created opcodes\r
658       0x1237,                           // Question ID\r
659       STRING_TOKEN(STR_EXIT_TEXT),      // Prompt text\r
660       STRING_TOKEN(STR_EXIT_TEXT),      // Help text\r
661       EFI_IFR_FLAG_CALLBACK,            // Question flag\r
662       0                                 // Action String ID\r
663     );\r
664 \r
665     //\r
666     // Create Option OpCode\r
667     //\r
668     OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
669     ASSERT (OptionsOpCodeHandle != NULL);\r
670 \r
671     HiiCreateOneOfOptionOpCode (\r
672       OptionsOpCodeHandle,\r
673       STRING_TOKEN (STR_BOOT_OPTION1),\r
674       0,\r
675       EFI_IFR_NUMERIC_SIZE_1,\r
676       1\r
677       );\r
678 \r
679     HiiCreateOneOfOptionOpCode (\r
680       OptionsOpCodeHandle,\r
681       STRING_TOKEN (STR_BOOT_OPTION2),\r
682       0,\r
683       EFI_IFR_NUMERIC_SIZE_1,\r
684       2\r
685       );\r
686 \r
687     //\r
688     // Prepare initial value for the dynamic created oneof Question\r
689     //\r
690     PrivateData->Configuration.DynamicOneof = 2;\r
691     Status = gRT->SetVariable(\r
692                     VariableName,\r
693                     &mFormSetGuid,\r
694                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
695                     sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
696                     &PrivateData->Configuration\r
697                     );\r
698 \r
699     //\r
700     // Set initial vlaue of dynamic created oneof Question in Form Browser\r
701     //\r
702     Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
703     ASSERT (Configuration != NULL);\r
704     Status = HiiGetBrowserData (&mFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration);\r
705     if (!EFI_ERROR (Status)) {\r
706       Configuration->DynamicOneof = 2;\r
707 \r
708       //\r
709       // Update uncommitted data of Browser\r
710       //\r
711       HiiSetBrowserData (\r
712         &mFormSetGuid,\r
713         VariableName,\r
714         sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
715         (UINT8 *) Configuration,\r
716         NULL\r
717         );\r
718     }\r
719     FreePool (Configuration);\r
720 \r
721     HiiCreateOneOfOpCode (\r
722       StartOpCodeHandle,                         // Container for dynamic created opcodes\r
723       0x8001,                                    // Question ID (or call it "key")\r
724       CONFIGURATION_VARSTORE_ID,                 // VarStore ID\r
725       (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET,        // Offset in Buffer Storage\r
726       STRING_TOKEN (STR_ONE_OF_PROMPT),          // Question prompt text\r
727       STRING_TOKEN (STR_ONE_OF_HELP),            // Question help text\r
728       EFI_IFR_FLAG_CALLBACK,                     // Question flag\r
729       EFI_IFR_NUMERIC_SIZE_1,                    // Data type of Question Value\r
730       OptionsOpCodeHandle,                       // Option Opcode list\r
731       NULL                                       // Default Opcode is NULl\r
732       );\r
733 \r
734     HiiCreateOrderedListOpCode (\r
735       StartOpCodeHandle,                         // Container for dynamic created opcodes\r
736       0x8002,                                    // Question ID\r
737       CONFIGURATION_VARSTORE_ID,                 // VarStore ID\r
738       (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET,  // Offset in Buffer Storage\r
739       STRING_TOKEN (STR_BOOT_OPTIONS),           // Question prompt text\r
740       STRING_TOKEN (STR_BOOT_OPTIONS),           // Question help text\r
741       EFI_IFR_FLAG_RESET_REQUIRED,               // Question flag\r
742       0,                                         // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET\r
743       EFI_IFR_NUMERIC_SIZE_1,                    // Data type of Question value\r
744       5,                                         // Maximum container\r
745       OptionsOpCodeHandle,                       // Option Opcode list\r
746       NULL                                       // Default Opcode is NULl\r
747       );\r
748 \r
749     HiiCreateGotoOpCode (\r
750       StartOpCodeHandle,                // Container for dynamic created opcodes\r
751       1,                                // Target Form ID\r
752       STRING_TOKEN (STR_GOTO_FORM1),    // Prompt text\r
753       STRING_TOKEN (STR_GOTO_HELP),     // Help text\r
754       0,                                // Question flag\r
755       0x8003                            // Question ID\r
756       );\r
757 \r
758     HiiUpdateForm (\r
759       PrivateData->HiiHandle[0],  // HII handle\r
760       &mFormSetGuid,              // Formset GUID\r
761       0x1234,                     // Form ID\r
762       StartOpCodeHandle,          // Label for where to insert opcodes\r
763       EndOpCodeHandle             // Replace data\r
764       );\r
765 \r
766     HiiFreeOpCodeHandle (StartOpCodeHandle);\r
767     HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
768     HiiFreeOpCodeHandle (EndOpCodeHandle);\r
769     break;\r
770 \r
771   case 0x5678:\r
772     //\r
773     // We will reach here once the Question is refreshed\r
774     //\r
775 \r
776     //\r
777     // Initialize the container for dynamic opcodes\r
778     //\r
779     StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
780     ASSERT (StartOpCodeHandle != NULL);\r
781 \r
782     //\r
783     // Create Hii Extend Label OpCode as the start opcode\r
784     //\r
785     StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
786     StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
787     StartLabel->Number       = LABEL_UPDATE2;\r
788 \r
789     HiiCreateActionOpCode (\r
790       StartOpCodeHandle,                // Container for dynamic created opcodes\r
791       0x1237,                           // Question ID\r
792       STRING_TOKEN(STR_EXIT_TEXT),      // Prompt text\r
793       STRING_TOKEN(STR_EXIT_TEXT),      // Help text\r
794       EFI_IFR_FLAG_CALLBACK,            // Question flag\r
795       0                                 // Action String ID\r
796     );\r
797 \r
798     HiiUpdateForm (\r
799       PrivateData->HiiHandle[0],  // HII handle\r
800       &mFormSetGuid,              // Formset GUID\r
801       0x3,                        // Form ID\r
802       StartOpCodeHandle,          // Label for where to insert opcodes\r
803       NULL                        // Insert data\r
804       );\r
805 \r
806     HiiFreeOpCodeHandle (StartOpCodeHandle);\r
807 \r
808     //\r
809     // Refresh the Question value\r
810     //\r
811     PrivateData->Configuration.DynamicRefresh++;\r
812     Status = gRT->SetVariable(\r
813                     VariableName,\r
814                     &mFormSetGuid,\r
815                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
816                     sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
817                     &PrivateData->Configuration\r
818                     );\r
819 \r
820     //\r
821     // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause\r
822     // the first statement in Form 3 be suppressed\r
823     //\r
824     MyVarSize = 1;\r
825     MyVar = 111;\r
826     Status = gRT->SetVariable(\r
827                     L"MyVar",\r
828                     &mFormSetGuid,\r
829                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
830                     MyVarSize,\r
831                     &MyVar\r
832                     );\r
833     break;\r
834 \r
835   case 0x1237:\r
836     //\r
837     // User press "Exit now", request Browser to exit\r
838     //\r
839     *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
840     break;\r
841 \r
842   case 0x1238:\r
843     //\r
844     // User press "Save now", request Browser to save the uncommitted data.\r
845     //\r
846     *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
847     break;\r
848 \r
849   case 0x2000:\r
850     //\r
851     // When try to set a new password, user will be chanlleged with old password.\r
852     // The Callback is responsible for validating old password input by user,\r
853     // If Callback return EFI_SUCCESS, it indicates validation pass.\r
854     //\r
855     switch (PrivateData->PasswordState) {\r
856     case BROWSER_STATE_VALIDATE_PASSWORD:\r
857       Status = ValidatePassword (PrivateData, Value->string);\r
858       if (Status == EFI_SUCCESS) {\r
859         PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;\r
860       }\r
861       break;\r
862 \r
863     case BROWSER_STATE_SET_PASSWORD:\r
864       Status = SetPassword (PrivateData, Value->string);\r
865       PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
866       break;\r
867 \r
868     default:\r
869       break;\r
870     }\r
871 \r
872     break;\r
873 \r
874   case 0x1111:\r
875     //\r
876     // EfiVarstore question takes sample action (print value as debug information) \r
877     // after read/write question.\r
878     //\r
879     MyVarSize = 1;\r
880     Status = gRT->GetVariable(\r
881                     L"MyVar",\r
882                     &mFormSetGuid,\r
883                     NULL,\r
884                     &MyVarSize,\r
885                     &MyVar\r
886                     );\r
887     ASSERT_EFI_ERROR (Status);\r
888     DEBUG ((DEBUG_INFO, "EfiVarstore question: Tall value is %d with value width %d\n", MyVar, MyVarSize));\r
889   default:\r
890     break;\r
891   }\r
892 \r
893   return Status;\r
894 }\r
895 \r
896 /**\r
897   Main entry for this driver.\r
898 \r
899   @param ImageHandle     Image handle this driver.\r
900   @param SystemTable     Pointer to SystemTable.\r
901 \r
902   @retval EFI_SUCESS     This function always complete successfully.\r
903 \r
904 **/\r
905 EFI_STATUS\r
906 EFIAPI\r
907 DriverSampleInit (\r
908   IN EFI_HANDLE                   ImageHandle,\r
909   IN EFI_SYSTEM_TABLE             *SystemTable\r
910   )\r
911 {\r
912   EFI_STATUS                      Status;\r
913   EFI_HII_HANDLE                  HiiHandle[2];\r
914   EFI_SCREEN_DESCRIPTOR           Screen;\r
915   EFI_HII_DATABASE_PROTOCOL       *HiiDatabase;\r
916   EFI_HII_STRING_PROTOCOL         *HiiString;\r
917   EFI_FORM_BROWSER2_PROTOCOL      *FormBrowser2;\r
918   EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
919   CHAR16                          *NewString;\r
920   UINTN                           BufferSize;\r
921   DRIVER_SAMPLE_CONFIGURATION     *Configuration;\r
922   BOOLEAN                         ActionFlag;\r
923   EFI_STRING                      ConfigRequestHdr;\r
924 \r
925   //\r
926   // Initialize the local variables.\r
927   //\r
928   ConfigRequestHdr = NULL;\r
929   //\r
930   // Initialize screen dimensions for SendForm().\r
931   // Remove 3 characters from top and bottom\r
932   //\r
933   ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
934   gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);\r
935 \r
936   Screen.TopRow     = 3;\r
937   Screen.BottomRow  = Screen.BottomRow - 3;\r
938 \r
939   //\r
940   // Initialize driver private data\r
941   //\r
942   PrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));\r
943   if (PrivateData == NULL) {\r
944     return EFI_OUT_OF_RESOURCES;\r
945   }\r
946 \r
947   PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;\r
948 \r
949   PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;\r
950   PrivateData->ConfigAccess.RouteConfig = RouteConfig;\r
951   PrivateData->ConfigAccess.Callback = DriverCallback;\r
952   PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
953 \r
954   //\r
955   // Locate Hii Database protocol\r
956   //\r
957   Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
958   if (EFI_ERROR (Status)) {\r
959     return Status;\r
960   }\r
961   PrivateData->HiiDatabase = HiiDatabase;\r
962 \r
963   //\r
964   // Locate HiiString protocol\r
965   //\r
966   Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
967   if (EFI_ERROR (Status)) {\r
968     return Status;\r
969   }\r
970   PrivateData->HiiString = HiiString;\r
971 \r
972   //\r
973   // Locate Formbrowser2 protocol\r
974   //\r
975   Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
976   if (EFI_ERROR (Status)) {\r
977     return Status;\r
978   }\r
979   PrivateData->FormBrowser2 = FormBrowser2;\r
980 \r
981   //\r
982   // Locate ConfigRouting protocol\r
983   //\r
984   Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);\r
985   if (EFI_ERROR (Status)) {\r
986     return Status;\r
987   }\r
988   PrivateData->HiiConfigRouting = HiiConfigRouting;\r
989 \r
990   Status = gBS->InstallMultipleProtocolInterfaces (\r
991                   &DriverHandle[0],\r
992                   &gEfiDevicePathProtocolGuid,\r
993                   &mHiiVendorDevicePath0,\r
994                   &gEfiHiiConfigAccessProtocolGuid,\r
995                   &PrivateData->ConfigAccess,\r
996                   NULL\r
997                   );\r
998   ASSERT_EFI_ERROR (Status);\r
999 \r
1000   PrivateData->DriverHandle[0] = DriverHandle[0];\r
1001 \r
1002   //\r
1003   // Publish our HII data\r
1004   //\r
1005   HiiHandle[0] = HiiAddPackages (\r
1006                    &mFormSetGuid,\r
1007                    DriverHandle[0],\r
1008                    DriverSampleStrings,\r
1009                    VfrBin,\r
1010                    NULL\r
1011                    );\r
1012   if (HiiHandle[0] == NULL) {\r
1013     return EFI_OUT_OF_RESOURCES;\r
1014   }\r
1015 \r
1016   PrivateData->HiiHandle[0] = HiiHandle[0];\r
1017 \r
1018   //\r
1019   // Publish another Fromset\r
1020   //\r
1021   Status = gBS->InstallMultipleProtocolInterfaces (\r
1022                   &DriverHandle[1],\r
1023                   &gEfiDevicePathProtocolGuid,\r
1024                   &mHiiVendorDevicePath1,\r
1025                   NULL\r
1026                   );\r
1027   ASSERT_EFI_ERROR (Status);\r
1028 \r
1029   PrivateData->DriverHandle[1] = DriverHandle[1];\r
1030 \r
1031   HiiHandle[1] = HiiAddPackages (\r
1032                    &mInventoryGuid,\r
1033                    DriverHandle[1],\r
1034                    DriverSampleStrings,\r
1035                    InventoryBin,\r
1036                    NULL\r
1037                    );\r
1038   if (HiiHandle[1] == NULL) {\r
1039     return EFI_OUT_OF_RESOURCES;\r
1040   }\r
1041 \r
1042   PrivateData->HiiHandle[1] = HiiHandle[1];\r
1043 \r
1044   //\r
1045   // Very simple example of how one would update a string that is already\r
1046   // in the HII database\r
1047   //\r
1048   NewString = L"700 Mhz";\r
1049 \r
1050   if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {\r
1051     return EFI_OUT_OF_RESOURCES;\r
1052   }\r
1053 \r
1054   //\r
1055   // Initialize configuration data\r
1056   //\r
1057   Configuration = &PrivateData->Configuration;\r
1058   ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
1059 \r
1060   //\r
1061   // Try to read NV config EFI variable first\r
1062   //\r
1063   ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, DriverHandle[0]);\r
1064   ASSERT (ConfigRequestHdr != NULL);\r
1065 \r
1066   BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
1067   Status = gRT->GetVariable (VariableName, &mFormSetGuid, NULL, &BufferSize, Configuration);\r
1068   if (EFI_ERROR (Status)) {\r
1069     //\r
1070     // Store zero data Buffer Storage to EFI variable\r
1071     //\r
1072     Status = gRT->SetVariable(\r
1073                     VariableName,\r
1074                     &mFormSetGuid,\r
1075                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1076                     sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1077                     Configuration\r
1078                     );\r
1079     ASSERT (Status == EFI_SUCCESS);\r
1080     //\r
1081     // EFI variable for NV config doesn't exit, we should build this variable\r
1082     // based on default values stored in IFR\r
1083     //\r
1084     ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
1085     ASSERT (ActionFlag);\r
1086   } else {\r
1087     //\r
1088     // EFI variable does exist and Validate Current Setting\r
1089     //\r
1090     ActionFlag = HiiValidateSettings (ConfigRequestHdr);\r
1091     ASSERT (ActionFlag);\r
1092   }\r
1093 \r
1094   FreePool (ConfigRequestHdr);\r
1095 \r
1096 \r
1097   //\r
1098   // In default, this driver is built into Flash device image,\r
1099   // the following code doesn't run.\r
1100   //\r
1101 \r
1102   //\r
1103   // Example of how to display only the item we sent to HII\r
1104   // When this driver is not built into Flash device image,\r
1105   // it need to call SendForm to show front page by itself.\r
1106   //\r
1107   if (DISPLAY_ONLY_MY_ITEM <= 1) {\r
1108     //\r
1109     // Have the browser pull out our copy of the data, and only display our data\r
1110     //\r
1111     Status = FormBrowser2->SendForm (\r
1112                              FormBrowser2,\r
1113                              &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),\r
1114                              1,\r
1115                              NULL,\r
1116                              0,\r
1117                              NULL,\r
1118                              NULL\r
1119                              );\r
1120 \r
1121     HiiRemovePackages (HiiHandle[0]);\r
1122 \r
1123     HiiRemovePackages (HiiHandle[1]);\r
1124   }\r
1125 \r
1126   return EFI_SUCCESS;\r
1127 }\r
1128 \r
1129 /**\r
1130   Unloads the application and its installed protocol.\r
1131 \r
1132   @param[in]  ImageHandle       Handle that identifies the image to be unloaded.\r
1133 \r
1134   @retval EFI_SUCCESS           The image has been unloaded.\r
1135 **/\r
1136 EFI_STATUS\r
1137 EFIAPI\r
1138 DriverSampleUnload (\r
1139   IN EFI_HANDLE  ImageHandle\r
1140   )\r
1141 {\r
1142   if (DriverHandle[0] != NULL) {\r
1143     gBS->UninstallMultipleProtocolInterfaces (\r
1144             DriverHandle[0],\r
1145             &gEfiDevicePathProtocolGuid,\r
1146             &mHiiVendorDevicePath0,\r
1147             &gEfiHiiConfigAccessProtocolGuid,\r
1148             &PrivateData->ConfigAccess,\r
1149             NULL\r
1150            );\r
1151     DriverHandle[0] = NULL;\r
1152   }\r
1153 \r
1154   if (DriverHandle[1] != NULL) {\r
1155     gBS->UninstallMultipleProtocolInterfaces (\r
1156             DriverHandle[1],\r
1157             &gEfiDevicePathProtocolGuid,\r
1158             &mHiiVendorDevicePath1,\r
1159             NULL\r
1160            );\r
1161     DriverHandle[1] = NULL;\r
1162   }\r
1163 \r
1164   if (PrivateData->HiiHandle[0] != NULL) {\r
1165     HiiRemovePackages (PrivateData->HiiHandle[0]);\r
1166   }\r
1167 \r
1168   if (PrivateData->HiiHandle[1] != NULL) {\r
1169     HiiRemovePackages (PrivateData->HiiHandle[1]);\r
1170   }\r
1171 \r
1172   if (PrivateData != NULL) {\r
1173     FreePool (PrivateData);\r
1174     PrivateData = NULL;\r
1175   }\r
1176 \r
1177   return EFI_SUCCESS;\r
1178 }\r