]> 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
7e3bcccb 19#define DISPLAY_ONLY_MY_ITEM 0x0002\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
93e3992d 221 CHAR16 *Password;\r
5a829f56 222 UINTN PasswordSize;\r
93e3992d 223 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
7e3bcccb 224 UINTN BufferSize;\r
93e3992d 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
7e3bcccb
LG
256 Configuration = (DRIVER_SAMPLE_CONFIGURATION *) HiiGetBrowserData (&mFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
257 if (Configuration != NULL) {\r
93e3992d 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
7e3bcccb
LG
266 HiiSetBrowserData (\r
267 &mFormSetGuid,\r
268 VariableName,\r
269 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
270 (UINT8 *) Configuration,\r
271 NULL\r
272 );\r
273 \r
274 FreePool (Configuration);\r
93e3992d 275 }\r
7e3bcccb 276\r
93e3992d 277\r
278 //\r
279 // Set password\r
280 //\r
5a829f56 281 EncodePassword (Password, PasswordSize);\r
93e3992d 282 Status = gRT->SetVariable(\r
283 VariableName,\r
284 &mFormSetGuid,\r
285 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
286 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
287 &PrivateData->Configuration\r
288 );\r
289 return Status;\r
290}\r
291\r
292\r
293/**\r
294 This function allows a caller to extract the current configuration for one\r
295 or more named elements from the target driver.\r
296\r
297 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
298 @param Request A null-terminated Unicode string in\r
299 <ConfigRequest> format.\r
300 @param Progress On return, points to a character in the Request\r
301 string. Points to the string's null terminator if\r
302 request was successful. Points to the most recent\r
303 '&' before the first failing name/value pair (or\r
304 the beginning of the string if the failure is in\r
305 the first name/value pair) if the request was not\r
306 successful.\r
307 @param Results A null-terminated Unicode string in\r
308 <ConfigAltResp> format which has all values filled\r
309 in for the names in the Request string. String to\r
310 be allocated by the called function.\r
311\r
312 @retval EFI_SUCCESS The Results is filled with the requested values.\r
313 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
314 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
315 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
316 driver.\r
317\r
318**/\r
319EFI_STATUS\r
320EFIAPI\r
321ExtractConfig (\r
322 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
323 IN CONST EFI_STRING Request,\r
324 OUT EFI_STRING *Progress,\r
325 OUT EFI_STRING *Results\r
326 )\r
327{\r
328 EFI_STATUS Status;\r
329 UINTN BufferSize;\r
330 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
331 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
332\r
333 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
334 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
335\r
8d00a0f1 336 //\r
93e3992d 337 //\r
338 // Get Buffer Storage data from EFI variable\r
339 //\r
340 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
341 Status = gRT->GetVariable (\r
342 VariableName,\r
343 &mFormSetGuid,\r
344 NULL,\r
345 &BufferSize,\r
346 &PrivateData->Configuration\r
347 );\r
348 if (EFI_ERROR (Status)) {\r
349 return Status;\r
350 }\r
351\r
8d00a0f1 352 if (Request == NULL) {\r
353 //\r
354 // Request is set to NULL, return all configurable elements together with ALTCFG\r
355 //\r
7e3bcccb
LG
356 *Results = HiiConstructConfigAltResp (\r
357 &mFormSetGuid,\r
358 VariableName,\r
359 PrivateData->DriverHandle[0],\r
360 &PrivateData->Configuration,\r
361 BufferSize,\r
362 VfrMyIfrNVDataBlockName,\r
363 STRING_TOKEN (STR_STANDARD_DEFAULT_PROMPT),\r
364 VfrMyIfrNVDataDefault0000,\r
365 STRING_TOKEN (STR_MANUFACTURE_DEFAULT_PROMPT),\r
366 VfrMyIfrNVDataDefault0001,\r
367 0,\r
368 NULL\r
8d00a0f1 369 );\r
7e3bcccb
LG
370 \r
371 //\r
372 // No matched storage is found.\r
373 //\r
374 if (*Results == NULL) {\r
375 return EFI_NOT_FOUND;\r
376 }\r
8d00a0f1 377\r
7e3bcccb 378 return EFI_SUCCESS;\r
8d00a0f1 379 }\r
380\r
381 //\r
382 // Check routing data in <ConfigHdr>.\r
383 // Note: if only one Storage is used, then this checking could be skipped.\r
384 //\r
7e3bcccb 385 if (!HiiIsConfigHdrMatch (Request, &mFormSetGuid, VariableName)) {\r
8d00a0f1 386 *Progress = Request;\r
387 return EFI_NOT_FOUND;\r
388 }\r
389\r
93e3992d 390 //\r
391 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
392 //\r
393 Status = HiiConfigRouting->BlockToConfig (\r
394 HiiConfigRouting,\r
395 Request,\r
396 (UINT8 *) &PrivateData->Configuration,\r
397 BufferSize,\r
398 Results,\r
399 Progress\r
400 );\r
401 return Status;\r
402}\r
403\r
404\r
405/**\r
406 This function processes the results of changes in configuration.\r
407\r
408 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
409 @param Configuration A null-terminated Unicode string in <ConfigResp>\r
410 format.\r
411 @param Progress A pointer to a string filled in with the offset of\r
412 the most recent '&' before the first failing\r
413 name/value pair (or the beginning of the string if\r
414 the failure is in the first name/value pair) or\r
415 the terminating NULL if all was successful.\r
416\r
417 @retval EFI_SUCCESS The Results is processed successfully.\r
418 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
419 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
420 driver.\r
421\r
422**/\r
423EFI_STATUS\r
424EFIAPI\r
425RouteConfig (\r
426 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
427 IN CONST EFI_STRING Configuration,\r
428 OUT EFI_STRING *Progress\r
429 )\r
430{\r
431 EFI_STATUS Status;\r
432 UINTN BufferSize;\r
433 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
434 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
435\r
8d00a0f1 436 if (Configuration == NULL) {\r
437 return EFI_INVALID_PARAMETER;\r
438 }\r
439\r
93e3992d 440 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
441 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
442\r
8d00a0f1 443 // Check routing data in <ConfigHdr>.\r
444 // Note: if only one Storage is used, then this checking could be skipped.\r
445 //\r
7e3bcccb 446 if (!HiiIsConfigHdrMatch (Configuration, &mFormSetGuid, VariableName)) {\r
8d00a0f1 447 *Progress = Configuration;\r
448 return EFI_NOT_FOUND;\r
449 }\r
450\r
93e3992d 451 //\r
452 // Get Buffer Storage data from EFI variable\r
453 //\r
454 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
455 Status = gRT->GetVariable (\r
456 VariableName,\r
457 &mFormSetGuid,\r
458 NULL,\r
459 &BufferSize,\r
460 &PrivateData->Configuration\r
461 );\r
462 if (EFI_ERROR (Status)) {\r
463 return Status;\r
464 }\r
465\r
466 //\r
467 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
468 //\r
469 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
470 Status = HiiConfigRouting->ConfigToBlock (\r
471 HiiConfigRouting,\r
472 Configuration,\r
473 (UINT8 *) &PrivateData->Configuration,\r
474 &BufferSize,\r
475 Progress\r
476 );\r
477 if (EFI_ERROR (Status)) {\r
478 return Status;\r
479 }\r
480\r
481 //\r
482 // Store Buffer Storage back to EFI variable\r
483 //\r
484 Status = gRT->SetVariable(\r
485 VariableName,\r
486 &mFormSetGuid,\r
487 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
488 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
489 &PrivateData->Configuration\r
490 );\r
491\r
492 return Status;\r
493}\r
494\r
495\r
496/**\r
497 This function processes the results of changes in configuration.\r
498\r
499 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
500 @param Action Specifies the type of action taken by the browser.\r
501 @param QuestionId A unique value which is sent to the original\r
502 exporting driver so that it can identify the type\r
503 of data to expect.\r
504 @param Type The type of value for the question.\r
505 @param Value A pointer to the data being sent to the original\r
506 exporting driver.\r
507 @param ActionRequest On return, points to the action requested by the\r
508 callback function.\r
509\r
510 @retval EFI_SUCCESS The callback successfully handled the action.\r
511 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
512 variable and its data.\r
513 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
514 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
515 callback.\r
516\r
517**/\r
518EFI_STATUS\r
519EFIAPI\r
520DriverCallback (\r
521 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
522 IN EFI_BROWSER_ACTION Action,\r
523 IN EFI_QUESTION_ID QuestionId,\r
524 IN UINT8 Type,\r
525 IN EFI_IFR_TYPE_VALUE *Value,\r
526 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
527 )\r
528{\r
529 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
530 EFI_STATUS Status;\r
8d00a0f1 531 UINT8 MyVar;\r
7e3bcccb
LG
532 VOID *StartOpCodeHandle;\r
533 VOID *OptionsOpCodeHandle;\r
534 EFI_IFR_GUID_LABEL *StartLabel;\r
535 VOID *EndOpCodeHandle;\r
536 EFI_IFR_GUID_LABEL *EndLabel;\r
93e3992d 537\r
538 if ((Value == NULL) || (ActionRequest == NULL)) {\r
539 return EFI_INVALID_PARAMETER;\r
540 }\r
541\r
542 Status = EFI_SUCCESS;\r
543 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
544\r
545 switch (QuestionId) {\r
546 case 0x1234:\r
547 //\r
8d00a0f1 548 // Initialize the container for dynamic opcodes\r
93e3992d 549 //\r
7e3bcccb
LG
550 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
551 ASSERT (StartOpCodeHandle != NULL);\r
552\r
553 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
554 ASSERT (EndOpCodeHandle != NULL);\r
555\r
556 //\r
557 // Create Hii Extend Label OpCode as the start opcode\r
558 //\r
559 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
560 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
561 StartLabel->Number = LABEL_UPDATE1;\r
562\r
563 //\r
564 // Create Hii Extend Label OpCode as the end opcode\r
565 //\r
566 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
567 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
568 EndLabel->Number = LABEL_END;\r
569\r
570 HiiCreateActionOpCode (\r
571 StartOpCodeHandle, // Container for dynamic created opcodes\r
572 0x1237, // Question ID\r
573 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
574 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
575 EFI_IFR_FLAG_CALLBACK, // Question flag\r
576 0 // Action String ID\r
577 );\r
578\r
579 //\r
580 // Create Option OpCode\r
581 //\r
582 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
583 ASSERT (OptionsOpCodeHandle != NULL);\r
584\r
585 HiiCreateOneOfOptionOpCode (\r
586 OptionsOpCodeHandle,\r
587 STRING_TOKEN (STR_BOOT_OPTION1),\r
588 0,\r
589 EFI_IFR_NUMERIC_SIZE_1,\r
590 1\r
591 );\r
592\r
593 HiiCreateOneOfOptionOpCode (\r
594 OptionsOpCodeHandle,\r
595 STRING_TOKEN (STR_BOOT_OPTION2),\r
596 0,\r
597 EFI_IFR_NUMERIC_SIZE_1,\r
598 2\r
599 );\r
600\r
601 //\r
602 // Prepare initial value for the dynamic created oneof Question\r
603 //\r
604 PrivateData->Configuration.DynamicOneof = 2;\r
605 Status = gRT->SetVariable(\r
606 VariableName,\r
607 &mFormSetGuid,\r
608 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
609 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
610 &PrivateData->Configuration\r
611 );\r
612\r
613 HiiCreateOneOfOpCode (\r
614 StartOpCodeHandle, // Container for dynamic created opcodes\r
615 0x8001, // Question ID (or call it "key")\r
616 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
617 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage\r
618 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text\r
619 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text\r
620 EFI_IFR_FLAG_CALLBACK, // Question flag\r
621 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value\r
622 OptionsOpCodeHandle, // Option Opcode list\r
623 NULL // Default Opcode is NULl\r
624 );\r
625\r
626 HiiCreateOrderedListOpCode (\r
627 StartOpCodeHandle, // Container for dynamic created opcodes\r
628 0x8002, // Question ID\r
629 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
630 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage\r
631 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text\r
632 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text\r
633 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag\r
634 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET\r
635 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value\r
636 5, // Maximum container\r
637 OptionsOpCodeHandle, // Option Opcode list\r
638 NULL // Default Opcode is NULl\r
639 );\r
640\r
641 HiiCreateGotoOpCode (\r
642 StartOpCodeHandle, // Container for dynamic created opcodes\r
643 1, // Target Form ID\r
644 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text\r
645 STRING_TOKEN (STR_GOTO_HELP), // Help text\r
646 0, // Question flag\r
647 0x8003 // Question ID\r
648 );\r
649\r
650 HiiUpdateForm (\r
651 PrivateData->HiiHandle[0], // HII handle\r
652 &mFormSetGuid, // Formset GUID\r
653 0x1234, // Form ID\r
654 StartOpCodeHandle, // Label for where to insert opcodes\r
655 EndOpCodeHandle // Replace data\r
656 );\r
657\r
658 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
659 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
660 break;\r
8d00a0f1 661 \r
7e3bcccb
LG
662 case 0x5678:\r
663 //\r
664 // We will reach here once the Question is refreshed\r
665 //\r
666\r
667 //\r
668 // Initialize the container for dynamic opcodes\r
669 //\r
670 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
671 ASSERT (StartOpCodeHandle != NULL);\r
672\r
673 //\r
674 // Create Hii Extend Label OpCode as the start opcode\r
675 //\r
676 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
677 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
678 StartLabel->Number = LABEL_UPDATE2;\r
679\r
680 HiiCreateActionOpCode (\r
681 StartOpCodeHandle, // Container for dynamic created opcodes\r
682 0x1237, // Question ID\r
683 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
684 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
685 EFI_IFR_FLAG_CALLBACK, // Question flag\r
686 0 // Action String ID\r
687 );\r
8d00a0f1 688 \r
7e3bcccb
LG
689 HiiUpdateForm (\r
690 PrivateData->HiiHandle[0], // HII handle\r
691 &mFormSetGuid, // Formset GUID\r
692 0x3, // Form ID\r
693 StartOpCodeHandle, // Label for where to insert opcodes\r
694 NULL // Insert data\r
695 );\r
696\r
697 HiiFreeOpCodeHandle (StartOpCodeHandle); \r
698 \r
699 //\r
700 // Refresh the Question value\r
701 //\r
702 PrivateData->Configuration.DynamicRefresh++;\r
703 Status = gRT->SetVariable(\r
704 VariableName,\r
705 &mFormSetGuid,\r
706 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
707 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
708 &PrivateData->Configuration\r
709 );\r
710 \r
711 //\r
712 // Change an EFI Variable storage (MyEfiVar) asynchronous, this will cause\r
713 // the first statement in Form 3 be suppressed\r
714 //\r
715 MyVar = 111;\r
716 Status = gRT->SetVariable(\r
717 L"MyVar",\r
718 &mFormSetGuid,\r
719 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
720 1,\r
721 &MyVar\r
722 );\r
93e3992d 723 break;\r
724\r
725 case 0x1237:\r
726 //\r
727 // User press "Exit now", request Browser to exit\r
728 //\r
729 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
730 break;\r
731\r
732 case 0x1238:\r
733 //\r
734 // User press "Save now", request Browser to save the uncommitted data.\r
735 //\r
736 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
737 break;\r
738\r
739 case 0x2000:\r
740 //\r
741 // When try to set a new password, user will be chanlleged with old password.\r
742 // The Callback is responsible for validating old password input by user,\r
743 // If Callback return EFI_SUCCESS, it indicates validation pass.\r
744 //\r
745 switch (PrivateData->PasswordState) {\r
746 case BROWSER_STATE_VALIDATE_PASSWORD:\r
747 Status = ValidatePassword (PrivateData, Value->string);\r
748 if (Status == EFI_SUCCESS) {\r
749 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;\r
750 }\r
751 break;\r
752\r
753 case BROWSER_STATE_SET_PASSWORD:\r
754 Status = SetPassword (PrivateData, Value->string);\r
755 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
756 break;\r
757\r
758 default:\r
759 break;\r
760 }\r
761\r
762 break;\r
763\r
764 default:\r
765 break;\r
766 }\r
767\r
768 return Status;\r
769}\r
770\r
7064c0a5 771/**\r
772 Main entry for this driver.\r
773 \r
774 @param ImageHandle Image handle this driver.\r
775 @param SystemTable Pointer to SystemTable.\r
776\r
777 @retval EFI_SUCESS This function always complete successfully.\r
778\r
779**/\r
93e3992d 780EFI_STATUS\r
781EFIAPI\r
782DriverSampleInit (\r
783 IN EFI_HANDLE ImageHandle,\r
784 IN EFI_SYSTEM_TABLE *SystemTable\r
785 )\r
786{\r
787 EFI_STATUS Status;\r
788 EFI_STATUS SavedStatus;\r
789 EFI_HII_PACKAGE_LIST_HEADER *PackageList;\r
790 EFI_HII_HANDLE HiiHandle[2];\r
93e3992d 791 EFI_SCREEN_DESCRIPTOR Screen;\r
792 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
793 EFI_HII_STRING_PROTOCOL *HiiString;\r
794 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
795 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
796 CHAR16 *NewString;\r
797 UINTN BufferSize;\r
798 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
799 BOOLEAN ExtractIfrDefault;\r
800\r
801 //\r
802 // Initialize the library and our protocol.\r
803 //\r
93e3992d 804\r
805 //\r
806 // Initialize screen dimensions for SendForm().\r
807 // Remove 3 characters from top and bottom\r
808 //\r
809 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
810 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);\r
811\r
812 Screen.TopRow = 3;\r
813 Screen.BottomRow = Screen.BottomRow - 3;\r
814\r
815 //\r
816 // Initialize driver private data\r
817 //\r
818 PrivateData = AllocatePool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));\r
819 if (PrivateData == NULL) {\r
820 return EFI_OUT_OF_RESOURCES;\r
821 }\r
822\r
823 PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;\r
824\r
825 PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;\r
826 PrivateData->ConfigAccess.RouteConfig = RouteConfig;\r
827 PrivateData->ConfigAccess.Callback = DriverCallback;\r
828 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
829\r
830 //\r
831 // Locate Hii Database protocol\r
832 //\r
833 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
834 if (EFI_ERROR (Status)) {\r
835 return Status;\r
836 }\r
837 PrivateData->HiiDatabase = HiiDatabase;\r
838\r
839 //\r
840 // Locate HiiString protocol\r
841 //\r
842 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
843 if (EFI_ERROR (Status)) {\r
844 return Status;\r
845 }\r
846 PrivateData->HiiString = HiiString;\r
847\r
848 //\r
849 // Locate Formbrowser2 protocol\r
850 //\r
851 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
852 if (EFI_ERROR (Status)) {\r
853 return Status;\r
854 }\r
855 PrivateData->FormBrowser2 = FormBrowser2;\r
856\r
857 //\r
858 // Locate ConfigRouting protocol\r
859 //\r
860 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);\r
861 if (EFI_ERROR (Status)) {\r
862 return Status;\r
863 }\r
864 PrivateData->HiiConfigRouting = HiiConfigRouting;\r
865\r
f6f910dd 866 Status = gBS->InstallMultipleProtocolInterfaces (\r
93e3992d 867 &DriverHandle[0],\r
f6f910dd 868 &gEfiDevicePathProtocolGuid,\r
2f3065c0 869 &mHiiVendorDevicePath0,\r
93e3992d 870 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 871 &PrivateData->ConfigAccess,\r
872 NULL\r
93e3992d 873 );\r
874 ASSERT_EFI_ERROR (Status);\r
875\r
f6f910dd 876 PrivateData->DriverHandle[0] = DriverHandle[0];\r
877\r
93e3992d 878 //\r
879 // Publish our HII data\r
880 //\r
9226efe5 881 PackageList = HiiLibPreparePackageList (\r
93e3992d 882 2,\r
883 &mFormSetGuid,\r
884 DriverSampleStrings,\r
885 VfrBin\r
886 );\r
887 if (PackageList == NULL) {\r
888 return EFI_OUT_OF_RESOURCES;\r
889 }\r
890\r
891 Status = HiiDatabase->NewPackageList (\r
892 HiiDatabase,\r
893 PackageList,\r
894 DriverHandle[0],\r
895 &HiiHandle[0]\r
896 );\r
53cf48e0 897 FreePool (PackageList);\r
93e3992d 898 if (EFI_ERROR (Status)) {\r
899 return Status;\r
900 }\r
901 PrivateData->HiiHandle[0] = HiiHandle[0];\r
902\r
903 //\r
904 // Publish another Fromset\r
905 //\r
f6f910dd 906 Status = gBS->InstallMultipleProtocolInterfaces (\r
907 &DriverHandle[1],\r
908 &gEfiDevicePathProtocolGuid,\r
2f3065c0 909 &mHiiVendorDevicePath1,\r
f6f910dd 910 NULL\r
911 );\r
912 ASSERT_EFI_ERROR (Status);\r
913\r
93e3992d 914 PrivateData->DriverHandle[1] = DriverHandle[1];\r
915\r
9226efe5 916 PackageList = HiiLibPreparePackageList (\r
93e3992d 917 2,\r
918 &mInventoryGuid,\r
919 DriverSampleStrings,\r
920 InventoryBin\r
921 );\r
922 if (PackageList == NULL) {\r
923 return EFI_OUT_OF_RESOURCES;\r
924 }\r
925\r
926 Status = HiiDatabase->NewPackageList (\r
927 HiiDatabase,\r
928 PackageList,\r
929 DriverHandle[1],\r
930 &HiiHandle[1]\r
931 );\r
53cf48e0 932 FreePool (PackageList);\r
93e3992d 933 if (EFI_ERROR (Status)) {\r
934 return Status;\r
935 }\r
936 PrivateData->HiiHandle[1] = HiiHandle[1];\r
937\r
938 //\r
939 // Very simple example of how one would update a string that is already\r
940 // in the HII database\r
941 //\r
942 NewString = L"700 Mhz";\r
943\r
9226efe5 944 Status = HiiLibSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString);\r
93e3992d 945 if (EFI_ERROR (Status)) {\r
946 return Status;\r
947 }\r
948\r
949 //\r
950 // Initialize configuration data\r
951 //\r
952 Configuration = &PrivateData->Configuration;\r
953 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
954\r
955 //\r
956 // Try to read NV config EFI variable first\r
957 //\r
958 ExtractIfrDefault = TRUE;\r
959 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
960 Status = gRT->GetVariable (VariableName, &mFormSetGuid, NULL, &BufferSize, Configuration);\r
961 if (!EFI_ERROR (Status) && (BufferSize == sizeof (DRIVER_SAMPLE_CONFIGURATION))) {\r
962 ExtractIfrDefault = FALSE;\r
963 }\r
964\r
965 if (ExtractIfrDefault) {\r
966 //\r
967 // EFI variable for NV config doesn't exit, we should build this variable\r
968 // based on default values stored in IFR\r
969 //\r
970 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
9226efe5 971 Status = IfrLibExtractDefault (Configuration, &BufferSize, 1, VfrMyIfrNVDataDefault0000);\r
93e3992d 972\r
973 if (!EFI_ERROR (Status)) {\r
974 gRT->SetVariable(\r
975 VariableName,\r
976 &mFormSetGuid,\r
977 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
978 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
979 Configuration\r
980 );\r
981 }\r
982 }\r
7e3bcccb
LG
983 \r
984 SavedStatus = EFI_SUCCESS;\r
93e3992d 985\r
986 //\r
7e3bcccb
LG
987 // Default this driver is built into Flash device image, \r
988 // the following code doesn't run.\r
93e3992d 989 //\r
7e3bcccb 990\r
2f3065c0 991 //\r
7e3bcccb
LG
992 // Example of how to display only the item we sent to HII\r
993 // When this driver is not built into Flash device image, \r
994 // it need to call SendForm to show front page by itself.\r
2f3065c0 995 //\r
7e3bcccb
LG
996 if (DISPLAY_ONLY_MY_ITEM <= 1) {\r
997 //\r
998 // Have the browser pull out our copy of the data, and only display our data\r
999 //\r
1000 Status = FormBrowser2->SendForm (\r
1001 FormBrowser2,\r
1002 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),\r
1003 1,\r
1004 NULL,\r
1005 0,\r
1006 NULL,\r
1007 NULL\r
1008 );\r
1009 SavedStatus = Status;\r
1010 \r
1011 Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[0]);\r
1012 if (EFI_ERROR (Status)) {\r
1013 return Status;\r
1014 }\r
1015 \r
1016 Status = HiiDatabase->RemovePackageList (HiiDatabase, HiiHandle[1]);\r
1017 if (EFI_ERROR (Status)) {\r
1018 return Status;\r
1019 }\r
2f3065c0
LG
1020 }\r
1021\r
1022 return SavedStatus;\r
1023}\r
1024\r
1025/**\r
1026 Unloads the application and its installed protocol.\r
1027\r
1028 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
1029\r
1030 @retval EFI_SUCCESS The image has been unloaded.\r
1031**/\r
1032EFI_STATUS\r
1033EFIAPI\r
1034DriverSampleUnload (\r
1035 IN EFI_HANDLE ImageHandle\r
1036 )\r
1037{\r
1038 if (DriverHandle[0] != NULL) {\r
1039 gBS->UninstallMultipleProtocolInterfaces (\r
1040 DriverHandle[0],\r
1041 &gEfiDevicePathProtocolGuid,\r
1042 &mHiiVendorDevicePath0,\r
1043 &gEfiHiiConfigAccessProtocolGuid,\r
1044 &PrivateData->ConfigAccess,\r
1045 NULL\r
1046 );\r
1047 }\r
1048\r
1049 if (DriverHandle[1] != NULL) {\r
1050 gBS->UninstallMultipleProtocolInterfaces (\r
1051 DriverHandle[1],\r
1052 &gEfiDevicePathProtocolGuid,\r
1053 &mHiiVendorDevicePath1,\r
1054 NULL\r
1055 );\r
1056 }\r
1057\r
1058 if (PrivateData != NULL) {\r
1059 FreePool (PrivateData);\r
93e3992d 1060 }\r
1061\r
1062 return EFI_SUCCESS;\r
1063}\r