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