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