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