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