]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
Add UefiHiiServicesLib library instance in every one DSC
[mirror_edk2.git] / MdeModulePkg / Universal / DriverSampleDxe / DriverSample.c
CommitLineData
93e3992d 1/** @file\r
53cf48e0 2This is an example of how a driver might export data to the HII protocol to be\r
3later utilized by the Setup Protocol\r
4\r
8d00a0f1 5Copyright (c) 2004 - 2008, Intel Corporation\r
93e3992d 6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
93e3992d 14**/\r
15\r
16\r
17#include "DriverSample.h"\r
18\r
2f3065c0 19#define DISPLAY_ONLY_MY_ITEM 0x0000\r
93e3992d 20\r
21EFI_GUID mFormSetGuid = FORMSET_GUID;\r
22EFI_GUID mInventoryGuid = INVENTORY_GUID;\r
23\r
24CHAR16 VariableName[] = L"MyIfrNVData";\r
25\r
2f3065c0
LG
26EFI_HANDLE DriverHandle[2] = {NULL, NULL};\r
27DRIVER_SAMPLE_PRIVATE_DATA *PrivateData = NULL;\r
28\r
29HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = {\r
f6f910dd 30 {\r
31 {\r
32 HARDWARE_DEVICE_PATH,\r
33 HW_VENDOR_DP,\r
34 {\r
35 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
36 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
37 }\r
38 },\r
39 //\r
40 // {C153B68D-EBFC-488e-B110-662867745B87}\r
41 //\r
42 { 0xc153b68d, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0x87 } }\r
43 },\r
44 {\r
45 END_DEVICE_PATH_TYPE,\r
46 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
47 { \r
48 (UINT8) (END_DEVICE_PATH_LENGTH),\r
49 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
50 }\r
51 }\r
52};\r
53\r
2f3065c0 54HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = {\r
f6f910dd 55 {\r
56 {\r
57 HARDWARE_DEVICE_PATH,\r
58 HW_VENDOR_DP,\r
59 {\r
60 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
61 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
62 }\r
63 },\r
64 //\r
65 // {06F37F07-0C48-40e9-8436-0A08A0BB76B0}\r
66 //\r
67 { 0x6f37f07, 0xc48, 0x40e9, { 0x84, 0x36, 0xa, 0x8, 0xa0, 0xbb, 0x76, 0xb0 } }\r
68 },\r
69 {\r
70 END_DEVICE_PATH_TYPE,\r
71 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
72 { \r
73 (UINT8) (END_DEVICE_PATH_LENGTH),\r
74 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
75 }\r
76 }\r
77};\r
78\r
7064c0a5 79/**\r
80 Encode the password using a simple algorithm.\r
81 \r
82 @param Password The string to be encoded.\r
83 @param MaxSize The size of the string.\r
84 \r
85**/\r
93e3992d 86VOID\r
87EncodePassword (\r
88 IN CHAR16 *Password,\r
5a829f56 89 IN UINTN MaxSize\r
93e3992d 90 )\r
91{\r
92 UINTN Index;\r
93 UINTN Loop;\r
94 CHAR16 *Buffer;\r
95 CHAR16 *Key;\r
96\r
97 Key = L"MAR10648567";\r
98 Buffer = AllocateZeroPool (MaxSize);\r
99 ASSERT (Buffer != NULL);\r
100\r
101 for (Index = 0; Key[Index] != 0; Index++) {\r
102 for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) {\r
103 Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]);\r
104 }\r
105 }\r
106\r
107 CopyMem (Password, Buffer, MaxSize);\r
108\r
53cf48e0 109 FreePool (Buffer);\r
93e3992d 110 return ;\r
111}\r
112\r
7064c0a5 113/**\r
114 Validate the user's password.\r
115 \r
116 @param PrivateData This driver's private context data.\r
117 @param StringId The user's input.\r
118 \r
119 @retval EFI_SUCCESS The user's input matches the password.\r
120 @retval EFI_NOT_READY The user's input does not match the password.\r
121**/\r
93e3992d 122EFI_STATUS\r
123ValidatePassword (\r
7064c0a5 124 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,\r
125 IN EFI_STRING_ID StringId\r
93e3992d 126 )\r
127{\r
128 EFI_STATUS Status;\r
129 UINTN Index;\r
130 UINTN BufferSize;\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 //\r
155 // Check whether we have any old password set\r
156 //\r
157 for (Index = 0; Index < 20; Index++) {\r
158 if (PrivateData->Configuration.WhatIsThePassword2[Index] != 0) {\r
159 OldPassword = TRUE;\r
160 break;\r
161 }\r
162 }\r
163 if (!OldPassword) {\r
164 //\r
165 // Old password not exist, return EFI_SUCCESS to prompt for new password\r
166 //\r
167 return EFI_SUCCESS;\r
168 }\r
169\r
170 //\r
171 // Get user input password\r
172 //\r
173 BufferSize = 21 * sizeof (CHAR16);\r
174 Password = AllocateZeroPool (BufferSize);\r
175 ASSERT (Password != NULL);\r
176\r
9226efe5 177 Status = HiiLibGetString (PrivateData->HiiHandle[0], StringId, Password, &BufferSize);\r
93e3992d 178 if (EFI_ERROR (Status)) {\r
53cf48e0 179 FreePool (Password);\r
93e3992d 180 return Status;\r
181 }\r
182\r
183 //\r
184 // Validate old password\r
185 //\r
186 EncodedPassword = AllocateCopyPool (21 * sizeof (CHAR16), Password);\r
187 ASSERT (EncodedPassword != NULL);\r
188 EncodePassword (EncodedPassword, 20 * sizeof (CHAR16));\r
189 if (CompareMem (EncodedPassword, PrivateData->Configuration.WhatIsThePassword2, 20 * sizeof (CHAR16)) != 0) {\r
190 //\r
191 // Old password mismatch, return EFI_NOT_READY to prompt for error message\r
192 //\r
193 Status = EFI_NOT_READY;\r
194 } else {\r
195 Status = EFI_SUCCESS;\r
196 }\r
197\r
53cf48e0 198 FreePool (Password);\r
199 FreePool (EncodedPassword);\r
93e3992d 200\r
201 return Status;\r
202}\r
203\r
7064c0a5 204/**\r
205 Encode the password using a simple algorithm.\r
206 \r
207 @param PrivateData This driver's private context data.\r
208 @param StringId The password from User.\r
209 \r
210 @retval EFI_SUCESS The operation is successful.\r
211 @return Other value if gRT->SetVariable () fails.\r
212 \r
213**/\r
93e3992d 214EFI_STATUS\r
215SetPassword (\r
7064c0a5 216 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,\r
217 IN EFI_STRING_ID StringId\r
93e3992d 218 )\r
219{\r
220 EFI_STATUS Status;\r
221 UINTN BufferSize;\r
222 CHAR16 *Password;\r
5a829f56 223 UINTN PasswordSize;\r
93e3992d 224 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
225\r
226 //\r
227 // Get Buffer Storage data from EFI variable\r
228 //\r
229 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
230 Status = gRT->GetVariable (\r
231 VariableName,\r
232 &mFormSetGuid,\r
233 NULL,\r
234 &BufferSize,\r
235 &PrivateData->Configuration\r
236 );\r
237 if (EFI_ERROR (Status)) {\r
238 return Status;\r
239 }\r
240\r
241 //\r
242 // Get user input password\r
243 //\r
244 Password = &PrivateData->Configuration.WhatIsThePassword2[0];\r
5a829f56 245 PasswordSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);\r
246 \r
247 ZeroMem (Password, PasswordSize);\r
9226efe5 248 Status = HiiLibGetString (PrivateData->HiiHandle[0], StringId, Password, &BufferSize);\r
93e3992d 249 if (EFI_ERROR (Status)) {\r
250 return Status;\r
251 }\r
252\r
253 //\r
254 // Retrive uncommitted data from Browser\r
255 //\r
256 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
257 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));\r
258 ASSERT (Configuration != NULL);\r
259 Status = GetBrowserData (&mFormSetGuid, VariableName, &BufferSize, (UINT8 *) Configuration);\r
260 if (!EFI_ERROR (Status)) {\r
261 //\r
262 // Update password's clear text in the screen\r
263 //\r
5a829f56 264 CopyMem (Configuration->PasswordClearText, Password, PasswordSize);\r
93e3992d 265\r
266 //\r
267 // Update uncommitted data of Browser\r
268 //\r
269 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
270 Status = SetBrowserData (\r
271 &mFormSetGuid,\r
272 VariableName,\r
273 BufferSize,\r
274 (UINT8 *) Configuration,\r
275 NULL\r
276 );\r
277 }\r
53cf48e0 278 FreePool (Configuration);\r
93e3992d 279\r
280 //\r
281 // Set password\r
282 //\r
5a829f56 283 EncodePassword (Password, PasswordSize);\r
93e3992d 284 Status = gRT->SetVariable(\r
285 VariableName,\r
286 &mFormSetGuid,\r
287 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
288 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
289 &PrivateData->Configuration\r
290 );\r
291 return Status;\r
292}\r
293\r
294\r
295/**\r
296 This function allows a caller to extract the current configuration for one\r
297 or more named elements from the target driver.\r
298\r
299 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
300 @param Request A null-terminated Unicode string in\r
301 <ConfigRequest> format.\r
302 @param Progress On return, points to a character in the Request\r
303 string. Points to the string's null terminator if\r
304 request was successful. Points to the most recent\r
305 '&' before the first failing name/value pair (or\r
306 the beginning of the string if the failure is in\r
307 the first name/value pair) if the request was not\r
308 successful.\r
309 @param Results A null-terminated Unicode string in\r
310 <ConfigAltResp> format which has all values filled\r
311 in for the names in the Request string. String to\r
312 be allocated by the called function.\r
313\r
314 @retval EFI_SUCCESS The Results is filled with the requested values.\r
315 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
316 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
317 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
318 driver.\r
319\r
320**/\r
321EFI_STATUS\r
322EFIAPI\r
323ExtractConfig (\r
324 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
325 IN CONST EFI_STRING Request,\r
326 OUT EFI_STRING *Progress,\r
327 OUT EFI_STRING *Results\r
328 )\r
329{\r
330 EFI_STATUS Status;\r
331 UINTN BufferSize;\r
332 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
333 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
334\r
335 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
336 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
337\r
8d00a0f1 338 //\r
93e3992d 339 //\r
340 // Get Buffer Storage data from EFI variable\r
341 //\r
342 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
343 Status = gRT->GetVariable (\r
344 VariableName,\r
345 &mFormSetGuid,\r
346 NULL,\r
347 &BufferSize,\r
348 &PrivateData->Configuration\r
349 );\r
350 if (EFI_ERROR (Status)) {\r
351 return Status;\r
352 }\r
353\r
8d00a0f1 354 if (Request == NULL) {\r
355 //\r
356 // Request is set to NULL, return all configurable elements together with ALTCFG\r
357 //\r
358 Status = ConstructConfigAltResp (\r
359 NULL,\r
360 NULL,\r
361 Results,\r
362 &mFormSetGuid,\r
363 VariableName,\r
364 PrivateData->DriverHandle[0],\r
365 &PrivateData->Configuration,\r
366 BufferSize,\r
367 VfrMyIfrNVDataBlockName,\r
368 2,\r
369 STRING_TOKEN (STR_STANDARD_DEFAULT_PROMPT),\r
370 VfrMyIfrNVDataDefault0000,\r
371 STRING_TOKEN (STR_MANUFACTURE_DEFAULT_PROMPT),\r
372 VfrMyIfrNVDataDefault0001\r
373 );\r
374\r
375 return Status;\r
376 }\r
377\r
378 //\r
379 // Check routing data in <ConfigHdr>.\r
380 // Note: if only one Storage is used, then this checking could be skipped.\r
381 //\r
382 if (!IsConfigHdrMatch (Request, &mFormSetGuid, VariableName)) {\r
383 *Progress = Request;\r
384 return EFI_NOT_FOUND;\r
385 }\r
386\r
93e3992d 387 //\r
388 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
389 //\r
390 Status = HiiConfigRouting->BlockToConfig (\r
391 HiiConfigRouting,\r
392 Request,\r
393 (UINT8 *) &PrivateData->Configuration,\r
394 BufferSize,\r
395 Results,\r
396 Progress\r
397 );\r
398 return Status;\r
399}\r
400\r
401\r
402/**\r
403 This function processes the results of changes in configuration.\r
404\r
405 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
406 @param Configuration A null-terminated Unicode string in <ConfigResp>\r
407 format.\r
408 @param Progress A pointer to a string filled in with the offset of\r
409 the most recent '&' before the first failing\r
410 name/value pair (or the beginning of the string if\r
411 the failure is in the first name/value pair) or\r
412 the terminating NULL if all was successful.\r
413\r
414 @retval EFI_SUCCESS The Results is processed successfully.\r
415 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
416 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
417 driver.\r
418\r
419**/\r
420EFI_STATUS\r
421EFIAPI\r
422RouteConfig (\r
423 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
424 IN CONST EFI_STRING Configuration,\r
425 OUT EFI_STRING *Progress\r
426 )\r
427{\r
428 EFI_STATUS Status;\r
429 UINTN BufferSize;\r
430 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
431 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
432\r
8d00a0f1 433 if (Configuration == NULL) {\r
434 return EFI_INVALID_PARAMETER;\r
435 }\r
436\r
93e3992d 437 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
438 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
439\r
8d00a0f1 440 // Check routing data in <ConfigHdr>.\r
441 // Note: if only one Storage is used, then this checking could be skipped.\r
442 //\r
443 if (!IsConfigHdrMatch (Configuration, &mFormSetGuid, VariableName)) {\r
444 *Progress = Configuration;\r
445 return EFI_NOT_FOUND;\r
446 }\r
447\r
93e3992d 448 //\r
449 // Get Buffer Storage data from EFI variable\r
450 //\r
451 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
452 Status = gRT->GetVariable (\r
453 VariableName,\r
454 &mFormSetGuid,\r
455 NULL,\r
456 &BufferSize,\r
457 &PrivateData->Configuration\r
458 );\r
459 if (EFI_ERROR (Status)) {\r
460 return Status;\r
461 }\r
462\r
463 //\r
464 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
465 //\r
466 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
467 Status = HiiConfigRouting->ConfigToBlock (\r
468 HiiConfigRouting,\r
469 Configuration,\r
470 (UINT8 *) &PrivateData->Configuration,\r
471 &BufferSize,\r
472 Progress\r
473 );\r
474 if (EFI_ERROR (Status)) {\r
475 return Status;\r
476 }\r
477\r
478 //\r
479 // Store Buffer Storage back to EFI variable\r
480 //\r
481 Status = gRT->SetVariable(\r
482 VariableName,\r
483 &mFormSetGuid,\r
484 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
485 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
486 &PrivateData->Configuration\r
487 );\r
488\r
489 return Status;\r
490}\r
491\r
492\r
493/**\r
494 This function processes the results of changes in configuration.\r
495\r
496 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
497 @param Action Specifies the type of action taken by the browser.\r
498 @param QuestionId A unique value which is sent to the original\r
499 exporting driver so that it can identify the type\r
500 of data to expect.\r
501 @param Type The type of value for the question.\r
502 @param Value A pointer to the data being sent to the original\r
503 exporting driver.\r
504 @param ActionRequest On return, points to the action requested by the\r
505 callback function.\r
506\r
507 @retval EFI_SUCCESS The callback successfully handled the action.\r
508 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
509 variable and its data.\r
510 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
511 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
512 callback.\r
513\r
514**/\r
515EFI_STATUS\r
516EFIAPI\r
517DriverCallback (\r
518 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
519 IN EFI_BROWSER_ACTION Action,\r
520 IN EFI_QUESTION_ID QuestionId,\r
521 IN UINT8 Type,\r
522 IN EFI_IFR_TYPE_VALUE *Value,\r
523 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
524 )\r
525{\r
526 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
527 EFI_STATUS Status;\r
528 EFI_HII_UPDATE_DATA UpdateData;\r
529 IFR_OPTION *IfrOptionList;\r
8d00a0f1 530 UINT8 MyVar;\r
93e3992d 531\r
532 if ((Value == NULL) || (ActionRequest == NULL)) {\r
533 return EFI_INVALID_PARAMETER;\r
534 }\r
535\r
536 Status = EFI_SUCCESS;\r
537 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
538\r
539 switch (QuestionId) {\r
540 case 0x1234:\r
541 //\r
8d00a0f1 542 // Initialize the container for dynamic opcodes\r
93e3992d 543 //\r
8d00a0f1 544 IfrLibInitUpdateData (&UpdateData, 0x1000);\r
93e3992d 545\r
546 IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION));\r
547 ASSERT (IfrOptionList != NULL);\r
548\r
549 IfrOptionList[0].Flags = 0;\r
550 IfrOptionList[0].StringToken = STRING_TOKEN (STR_BOOT_OPTION1);\r
551 IfrOptionList[0].Value.u8 = 1;\r
552 IfrOptionList[1].Flags = EFI_IFR_OPTION_DEFAULT;\r
553 IfrOptionList[1].StringToken = STRING_TOKEN (STR_BOOT_OPTION2);\r
554 IfrOptionList[1].Value.u8 = 2;\r
555\r
8d00a0f1 556 CreateActionOpCode (\r
557 0x1237, // Question ID\r
558 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
559 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
560 EFI_IFR_FLAG_CALLBACK, // Question flag\r
561 0, // Action String ID\r
562 &UpdateData // Container for dynamic created opcodes\r
563 );\r
564 \r
565 //\r
566 // Prepare initial value for the dynamic created oneof Question\r
567 //\r
568 PrivateData->Configuration.DynamicOneof = 2;\r
569 Status = gRT->SetVariable(\r
570 VariableName,\r
571 &mFormSetGuid,\r
572 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
573 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
574 &PrivateData->Configuration\r
575 );\r
576 CreateOneOfOpCode (\r
999acf5a 577 0x8001, // Question ID (or call it "key")\r
578 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
579 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage\r
580 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text\r
581 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text\r
582 EFI_IFR_FLAG_CALLBACK, // Question flag\r
583 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value\r
584 IfrOptionList, // Option list\r
585 2, // Number of options in Option list\r
586 &UpdateData // Container for dynamic created opcodes\r
8d00a0f1 587 );\r
588 \r
589 CreateOrderedListOpCode (\r
999acf5a 590 0x8002, // Question ID\r
591 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
592 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage\r
593 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text\r
594 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text\r
595 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag\r
596 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET\r
597 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value\r
598 5, // Maximum container\r
599 IfrOptionList, // Option list\r
600 2, // Number of options in Option list\r
601 &UpdateData // Container for dynamic created opcodes\r
8d00a0f1 602 );\r
603 \r
604 CreateGotoOpCode (\r
605 1, // Target Form ID\r
606 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text\r
607 STRING_TOKEN (STR_GOTO_HELP), // Help text\r
608 0, // Question flag\r
609 0x8003, // Question ID\r
610 &UpdateData // Container for dynamic created opcodes\r
611 );\r
612 \r
613 Status = IfrLibUpdateForm (\r
614 PrivateData->HiiHandle[0], // HII handle\r
615 &mFormSetGuid, // Formset GUID\r
616 0x1234, // Form ID\r
617 0x1234, // Label for where to insert opcodes\r
618 TRUE, // Append or replace\r
619 &UpdateData // Dynamic created opcodes\r
620 );\r
53cf48e0 621 FreePool (IfrOptionList);\r
8d00a0f1 622 IfrLibFreeUpdateData (&UpdateData);\r
623 break;\r
624 \r
625 case 0x5678:\r
626 //\r
627 // We will reach here once the Question is refreshed\r
628 //\r
629 IfrLibInitUpdateData (&UpdateData, 0x1000);\r
630 \r
631 IfrOptionList = AllocatePool (2 * sizeof (IFR_OPTION));\r
632 ASSERT (IfrOptionList != NULL);\r
633 \r
634 CreateActionOpCode (\r
635 0x1237, // Question ID\r
636 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
637 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
638 EFI_IFR_FLAG_CALLBACK, // Question flag\r
639 0, // Action String ID\r
640 &UpdateData // Container for dynamic created opcodes\r
641 );\r
642 \r
643 Status = IfrLibUpdateForm (\r
644 PrivateData->HiiHandle[0], // HII handle\r
645 &mFormSetGuid, // Formset GUID\r
646 3, // Form ID\r
647 0x2234, // Label for where to insert opcodes\r
648 TRUE, // Append or replace\r
649 &UpdateData // Dynamic created opcodes\r
650 );\r
651 IfrLibFreeUpdateData (&UpdateData);\r
652 \r
653 //\r
654 // Refresh the Question value\r
655 //\r
656 PrivateData->Configuration.DynamicRefresh++;\r
657 Status = gRT->SetVariable(\r
658 VariableName,\r
659 &mFormSetGuid,\r
660 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
661 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
662 &PrivateData->Configuration\r
663 );\r
664 \r
665 //\r
666 // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause\r
667 // the first statement in Form 3 be suppressed\r
668 //\r
669 MyVar = 111;\r
670 Status = gRT->SetVariable(\r
671 L"MyVar",\r
672 &mFormSetGuid,\r
673 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
674 1,\r
675 &MyVar\r
676 );\r
93e3992d 677 break;\r
678\r
679 case 0x1237:\r
680 //\r
681 // User press "Exit now", request Browser to exit\r
682 //\r
683 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
684 break;\r
685\r
686 case 0x1238:\r
687 //\r
688 // User press "Save now", request Browser to save the uncommitted data.\r
689 //\r
690 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
691 break;\r
692\r
693 case 0x2000:\r
694 //\r
695 // When try to set a new password, user will be chanlleged with old password.\r
696 // The Callback is responsible for validating old password input by user,\r
697 // If Callback return EFI_SUCCESS, it indicates validation pass.\r
698 //\r
699 switch (PrivateData->PasswordState) {\r
700 case BROWSER_STATE_VALIDATE_PASSWORD:\r
701 Status = ValidatePassword (PrivateData, Value->string);\r
702 if (Status == EFI_SUCCESS) {\r
703 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;\r
704 }\r
705 break;\r
706\r
707 case BROWSER_STATE_SET_PASSWORD:\r
708 Status = SetPassword (PrivateData, Value->string);\r
709 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
710 break;\r
711\r
712 default:\r
713 break;\r
714 }\r
715\r
716 break;\r
717\r
718 default:\r
719 break;\r
720 }\r
721\r
722 return Status;\r
723}\r
724\r
7064c0a5 725/**\r
726 Main entry for this driver.\r
727 \r
728 @param ImageHandle Image handle this driver.\r
729 @param SystemTable Pointer to SystemTable.\r
730\r
731 @retval EFI_SUCESS This function always complete successfully.\r
732\r
733**/\r
93e3992d 734EFI_STATUS\r
735EFIAPI\r
736DriverSampleInit (\r
737 IN EFI_HANDLE ImageHandle,\r
738 IN EFI_SYSTEM_TABLE *SystemTable\r
739 )\r
740{\r
741 EFI_STATUS Status;\r
742 EFI_STATUS SavedStatus;\r
743 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
744 EFI_HII_HANDLE HiiHandle[2];\r
93e3992d 745 EFI_SCREEN_DESCRIPTOR Screen;\r
746 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
747 EFI_HII_STRING_PROTOCOL *HiiString;\r
748 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
749 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
750 CHAR16 *NewString;\r
751 UINTN BufferSize;\r
752 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
753 BOOLEAN ExtractIfrDefault;\r
754\r
755 //\r
756 // Initialize the library and our protocol.\r
757 //\r
93e3992d 758\r
759 //\r
760 // Initialize screen dimensions for SendForm().\r
761 // Remove 3 characters from top and bottom\r
762 //\r
763 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
764 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);\r
765\r
766 Screen.TopRow = 3;\r
767 Screen.BottomRow = Screen.BottomRow - 3;\r
768\r
769 //\r
770 // Initialize driver private data\r
771 //\r
772 PrivateData = AllocatePool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));\r
773 if (PrivateData == NULL) {\r
774 return EFI_OUT_OF_RESOURCES;\r
775 }\r
776\r
777 PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;\r
778\r
779 PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;\r
780 PrivateData->ConfigAccess.RouteConfig = RouteConfig;\r
781 PrivateData->ConfigAccess.Callback = DriverCallback;\r
782 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
783\r
784 //\r
785 // Locate Hii Database protocol\r
786 //\r
787 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
788 if (EFI_ERROR (Status)) {\r
789 return Status;\r
790 }\r
791 PrivateData->HiiDatabase = HiiDatabase;\r
792\r
793 //\r
794 // Locate HiiString protocol\r
795 //\r
796 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
797 if (EFI_ERROR (Status)) {\r
798 return Status;\r
799 }\r
800 PrivateData->HiiString = HiiString;\r
801\r
802 //\r
803 // Locate Formbrowser2 protocol\r
804 //\r
805 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
806 if (EFI_ERROR (Status)) {\r
807 return Status;\r
808 }\r
809 PrivateData->FormBrowser2 = FormBrowser2;\r
810\r
811 //\r
812 // Locate ConfigRouting protocol\r
813 //\r
814 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);\r
815 if (EFI_ERROR (Status)) {\r
816 return Status;\r
817 }\r
818 PrivateData->HiiConfigRouting = HiiConfigRouting;\r
819\r
f6f910dd 820 Status = gBS->InstallMultipleProtocolInterfaces (\r
93e3992d 821 &DriverHandle[0],\r
f6f910dd 822 &gEfiDevicePathProtocolGuid,\r
2f3065c0 823 &mHiiVendorDevicePath0,\r
93e3992d 824 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 825 &PrivateData->ConfigAccess,\r
826 NULL\r
93e3992d 827 );\r
828 ASSERT_EFI_ERROR (Status);\r
829\r
f6f910dd 830 PrivateData->DriverHandle[0] = DriverHandle[0];\r
831\r
93e3992d 832 //\r
833 // Publish our HII data\r
834 //\r
9226efe5 835 PackageList = HiiLibPreparePackageList (\r
93e3992d 836 2,\r
837 &mFormSetGuid,\r
838 DriverSampleStrings,\r
839 VfrBin\r
840 );\r
841 if (PackageList == NULL) {\r
842 return EFI_OUT_OF_RESOURCES;\r
843 }\r
844\r
845 Status = HiiDatabase->NewPackageList (\r
846 HiiDatabase,\r
847 PackageList,\r
848 DriverHandle[0],\r
849 &HiiHandle[0]\r
850 );\r
53cf48e0 851 FreePool (PackageList);\r
93e3992d 852 if (EFI_ERROR (Status)) {\r
853 return Status;\r
854 }\r
855 PrivateData->HiiHandle[0] = HiiHandle[0];\r
856\r
857 //\r
858 // Publish another Fromset\r
859 //\r
f6f910dd 860 Status = gBS->InstallMultipleProtocolInterfaces (\r
861 &DriverHandle[1],\r
862 &gEfiDevicePathProtocolGuid,\r
2f3065c0 863 &mHiiVendorDevicePath1,\r
f6f910dd 864 NULL\r
865 );\r
866 ASSERT_EFI_ERROR (Status);\r
867\r
93e3992d 868 PrivateData->DriverHandle[1] = DriverHandle[1];\r
869\r
9226efe5 870 PackageList = HiiLibPreparePackageList (\r
93e3992d 871 2,\r
872 &mInventoryGuid,\r
873 DriverSampleStrings,\r
874 InventoryBin\r
875 );\r
876 if (PackageList == NULL) {\r
877 return EFI_OUT_OF_RESOURCES;\r
878 }\r
879\r
880 Status = HiiDatabase->NewPackageList (\r
881 HiiDatabase,\r
882 PackageList,\r
883 DriverHandle[1],\r
884 &HiiHandle[1]\r
885 );\r
53cf48e0 886 FreePool (PackageList);\r
93e3992d 887 if (EFI_ERROR (Status)) {\r
888 return Status;\r
889 }\r
890 PrivateData->HiiHandle[1] = HiiHandle[1];\r
891\r
892 //\r
893 // Very simple example of how one would update a string that is already\r
894 // in the HII database\r
895 //\r
896 NewString = L"700 Mhz";\r
897\r
9226efe5 898 Status = HiiLibSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString);\r
93e3992d 899 if (EFI_ERROR (Status)) {\r
900 return Status;\r
901 }\r
902\r
903 //\r
904 // Initialize configuration data\r
905 //\r
906 Configuration = &PrivateData->Configuration;\r
907 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
908\r
909 //\r
910 // Try to read NV config EFI variable first\r
911 //\r
912 ExtractIfrDefault = TRUE;\r
913 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
914 Status = gRT->GetVariable (VariableName, &mFormSetGuid, NULL, &BufferSize, Configuration);\r
915 if (!EFI_ERROR (Status) && (BufferSize == sizeof (DRIVER_SAMPLE_CONFIGURATION))) {\r
916 ExtractIfrDefault = FALSE;\r
917 }\r
918\r
919 if (ExtractIfrDefault) {\r
920 //\r
921 // EFI variable for NV config doesn't exit, we should build this variable\r
922 // based on default values stored in IFR\r
923 //\r
924 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
9226efe5 925 Status = IfrLibExtractDefault (Configuration, &BufferSize, 1, VfrMyIfrNVDataDefault0000);\r
93e3992d 926\r
927 if (!EFI_ERROR (Status)) {\r
928 gRT->SetVariable(\r
929 VariableName,\r
930 &mFormSetGuid,\r
931 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
932 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
933 Configuration\r
934 );\r
935 }\r
936 }\r
937\r
938 //\r
939 // Example of how to display only the item we sent to HII\r
940 //\r
2f3065c0
LG
941 //\r
942 // Have the browser pull out our copy of the data, and only display our data\r
943 //\r
944 Status = FormBrowser2->SendForm (\r
945 FormBrowser2,\r
946 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),\r
947 1,\r
948 NULL,\r
949 0,\r
950 NULL,\r
951 NULL\r
952 );\r
953 SavedStatus = Status;\r
93e3992d 954\r
2f3065c0
LG
955 Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[0]);\r
956 if (EFI_ERROR (Status)) {\r
957 return Status;\r
958 }\r
93e3992d 959\r
2f3065c0
LG
960 Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[1]);\r
961 if (EFI_ERROR (Status)) {\r
962 return Status;\r
963 }\r
964\r
965 return SavedStatus;\r
966}\r
967\r
968/**\r
969 Unloads the application and its installed protocol.\r
970\r
971 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
972\r
973 @retval EFI_SUCCESS The image has been unloaded.\r
974**/\r
975EFI_STATUS\r
976EFIAPI\r
977DriverSampleUnload (\r
978 IN EFI_HANDLE ImageHandle\r
979 )\r
980{\r
981 if (DriverHandle[0] != NULL) {\r
982 gBS->UninstallMultipleProtocolInterfaces (\r
983 DriverHandle[0],\r
984 &gEfiDevicePathProtocolGuid,\r
985 &mHiiVendorDevicePath0,\r
986 &gEfiHiiConfigAccessProtocolGuid,\r
987 &PrivateData->ConfigAccess,\r
988 NULL\r
989 );\r
990 }\r
991\r
992 if (DriverHandle[1] != NULL) {\r
993 gBS->UninstallMultipleProtocolInterfaces (\r
994 DriverHandle[1],\r
995 &gEfiDevicePathProtocolGuid,\r
996 &mHiiVendorDevicePath1,\r
997 NULL\r
998 );\r
999 }\r
1000\r
1001 if (PrivateData != NULL) {\r
1002 FreePool (PrivateData);\r
93e3992d 1003 }\r
1004\r
1005 return EFI_SUCCESS;\r
1006}\r