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