]> git.proxmox.com Git - mirror_edk2.git/blame - 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
93e3992d 1/** @file\r
53cf48e0 2This is an example of how a driver might export data to the HII protocol to be\r
3later utilized by the Setup Protocol\r
4\r
8d00a0f1 5Copyright (c) 2004 - 2008, Intel Corporation\r
93e3992d 6All rights reserved. This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
93e3992d 14**/\r
15\r
16\r
17#include "DriverSample.h"\r
18\r
7e3bcccb 19#define DISPLAY_ONLY_MY_ITEM 0x0002\r
93e3992d 20\r
21EFI_GUID mFormSetGuid = FORMSET_GUID;\r
22EFI_GUID mInventoryGuid = INVENTORY_GUID;\r
23\r
24CHAR16 VariableName[] = L"MyIfrNVData";\r
25\r
2f3065c0
LG
26EFI_HANDLE DriverHandle[2] = {NULL, NULL};\r
27DRIVER_SAMPLE_PRIVATE_DATA *PrivateData = NULL;\r
28\r
29HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = {\r
f6f910dd 30 {\r
31 {\r
32 HARDWARE_DEVICE_PATH,\r
33 HW_VENDOR_DP,\r
34 {\r
35 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
36 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
37 }\r
38 },\r
39 //\r
40 // {C153B68D-EBFC-488e-B110-662867745B87}\r
41 //\r
42 { 0xc153b68d, 0xebfc, 0x488e, { 0xb1, 0x10, 0x66, 0x28, 0x67, 0x74, 0x5b, 0x87 } }\r
43 },\r
44 {\r
45 END_DEVICE_PATH_TYPE,\r
46 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
47 { \r
48 (UINT8) (END_DEVICE_PATH_LENGTH),\r
49 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
50 }\r
51 }\r
52};\r
53\r
2f3065c0 54HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = {\r
f6f910dd 55 {\r
56 {\r
57 HARDWARE_DEVICE_PATH,\r
58 HW_VENDOR_DP,\r
59 {\r
60 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
61 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
62 }\r
63 },\r
64 //\r
65 // {06F37F07-0C48-40e9-8436-0A08A0BB76B0}\r
66 //\r
67 { 0x6f37f07, 0xc48, 0x40e9, { 0x84, 0x36, 0xa, 0x8, 0xa0, 0xbb, 0x76, 0xb0 } }\r
68 },\r
69 {\r
70 END_DEVICE_PATH_TYPE,\r
71 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
72 { \r
73 (UINT8) (END_DEVICE_PATH_LENGTH),\r
74 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
75 }\r
76 }\r
77};\r
78\r
7064c0a5 79/**\r
80 Encode the password using a simple algorithm.\r
81 \r
82 @param Password The string to be encoded.\r
83 @param MaxSize The size of the string.\r
84 \r
85**/\r
93e3992d 86VOID\r
87EncodePassword (\r
88 IN CHAR16 *Password,\r
5a829f56 89 IN UINTN MaxSize\r
93e3992d 90 )\r
91{\r
92 UINTN Index;\r
93 UINTN Loop;\r
94 CHAR16 *Buffer;\r
95 CHAR16 *Key;\r
96\r
97 Key = L"MAR10648567";\r
98 Buffer = AllocateZeroPool (MaxSize);\r
99 ASSERT (Buffer != NULL);\r
100\r
101 for (Index = 0; Key[Index] != 0; Index++) {\r
102 for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) {\r
103 Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]);\r
104 }\r
105 }\r
106\r
107 CopyMem (Password, Buffer, MaxSize);\r
108\r
53cf48e0 109 FreePool (Buffer);\r
93e3992d 110 return ;\r
111}\r
112\r
7064c0a5 113/**\r
114 Validate the user's password.\r
115 \r
116 @param PrivateData This driver's private context data.\r
117 @param StringId The user's input.\r
118 \r
119 @retval EFI_SUCCESS The user's input matches the password.\r
120 @retval EFI_NOT_READY The user's input does not match the password.\r
121**/\r
93e3992d 122EFI_STATUS\r
123ValidatePassword (\r
7064c0a5 124 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,\r
125 IN EFI_STRING_ID StringId\r
93e3992d 126 )\r
127{\r
128 EFI_STATUS Status;\r
129 UINTN Index;\r
130 UINTN BufferSize;\r
131 CHAR16 *Password;\r
132 CHAR16 *EncodedPassword;\r
133 BOOLEAN OldPassword;\r
134\r
135 //\r
136 // Get encoded password first\r
137 //\r
138 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
139 Status = gRT->GetVariable (\r
140 VariableName,\r
141 &mFormSetGuid,\r
142 NULL,\r
143 &BufferSize,\r
144 &PrivateData->Configuration\r
145 );\r
146 if (EFI_ERROR (Status)) {\r
147 //\r
148 // Old password not exist, prompt for new password\r
149 //\r
150 return EFI_SUCCESS;\r
151 }\r
152\r
153 OldPassword = FALSE;\r
154 //\r
155 // Check whether we have any old password set\r
156 //\r
157 for (Index = 0; Index < 20; Index++) {\r
158 if (PrivateData->Configuration.WhatIsThePassword2[Index] != 0) {\r
159 OldPassword = TRUE;\r
160 break;\r
161 }\r
162 }\r
163 if (!OldPassword) {\r
164 //\r
165 // Old password not exist, return EFI_SUCCESS to prompt for new password\r
166 //\r
167 return EFI_SUCCESS;\r
168 }\r
169\r
170 //\r
171 // Get user input password\r
172 //\r
cb7d01c0 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
53cf48e0 178 FreePool (Password);\r
cb7d01c0 179 return EFI_NOT_READY;\r
93e3992d 180 }\r
181\r
182 //\r
183 // Validate old password\r
184 //\r
cb7d01c0 185 EncodedPassword = AllocateZeroPool (21 * sizeof (CHAR16));\r
93e3992d 186 ASSERT (EncodedPassword != NULL);\r
cb7d01c0 187 StrnCpy (EncodedPassword, Password, 21);\r
93e3992d 188 EncodePassword (EncodedPassword, 20 * sizeof (CHAR16));\r
189 if (CompareMem (EncodedPassword, PrivateData->Configuration.WhatIsThePassword2, 20 * sizeof (CHAR16)) != 0) {\r
190 //\r
191 // Old password mismatch, return EFI_NOT_READY to prompt for error message\r
192 //\r
193 Status = EFI_NOT_READY;\r
194 } else {\r
195 Status = EFI_SUCCESS;\r
196 }\r
197\r
53cf48e0 198 FreePool (Password);\r
199 FreePool (EncodedPassword);\r
93e3992d 200\r
201 return Status;\r
202}\r
203\r
7064c0a5 204/**\r
205 Encode the password using a simple algorithm.\r
206 \r
207 @param PrivateData This driver's private context data.\r
208 @param StringId The password from User.\r
209 \r
210 @retval EFI_SUCESS The operation is successful.\r
211 @return Other value if gRT->SetVariable () fails.\r
212 \r
213**/\r
93e3992d 214EFI_STATUS\r
215SetPassword (\r
7064c0a5 216 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,\r
217 IN EFI_STRING_ID StringId\r
93e3992d 218 )\r
219{\r
220 EFI_STATUS Status;\r
93e3992d 221 CHAR16 *Password;\r
cb7d01c0 222 CHAR16 *TempPassword;\r
5a829f56 223 UINTN PasswordSize;\r
93e3992d 224 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
7e3bcccb 225 UINTN BufferSize;\r
93e3992d 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
cb7d01c0 246 PasswordSize = sizeof (PrivateData->Configuration.WhatIsThePassword2); \r
5a829f56 247 ZeroMem (Password, PasswordSize);\r
cb7d01c0 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
93e3992d 256 }\r
cb7d01c0 257 StrnCpy (Password, TempPassword, PasswordSize / sizeof (CHAR16));\r
258 FreePool (TempPassword);\r
93e3992d 259\r
260 //\r
261 // Retrive uncommitted data from Browser\r
262 //\r
7e3bcccb
LG
263 Configuration = (DRIVER_SAMPLE_CONFIGURATION *) HiiGetBrowserData (&mFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
264 if (Configuration != NULL) {\r
93e3992d 265 //\r
266 // Update password's clear text in the screen\r
267 //\r
5a829f56 268 CopyMem (Configuration->PasswordClearText, Password, PasswordSize);\r
93e3992d 269\r
270 //\r
271 // Update uncommitted data of Browser\r
272 //\r
7e3bcccb
LG
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
93e3992d 282 }\r
7e3bcccb 283\r
93e3992d 284\r
285 //\r
286 // Set password\r
287 //\r
5a829f56 288 EncodePassword (Password, PasswordSize);\r
93e3992d 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
8d00a0f1 343 //\r
93e3992d 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
8d00a0f1 359 if (Request == NULL) {\r
360 //\r
361 // Request is set to NULL, return all configurable elements together with ALTCFG\r
362 //\r
7e3bcccb
LG
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
8d00a0f1 376 );\r
7e3bcccb
LG
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
8d00a0f1 384\r
7e3bcccb 385 return EFI_SUCCESS;\r
8d00a0f1 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
7e3bcccb 392 if (!HiiIsConfigHdrMatch (Request, &mFormSetGuid, VariableName)) {\r
8d00a0f1 393 *Progress = Request;\r
394 return EFI_NOT_FOUND;\r
395 }\r
396\r
93e3992d 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
8d00a0f1 443 if (Configuration == NULL) {\r
444 return EFI_INVALID_PARAMETER;\r
445 }\r
446\r
93e3992d 447 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
448 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
449\r
8d00a0f1 450 // Check routing data in <ConfigHdr>.\r
451 // Note: if only one Storage is used, then this checking could be skipped.\r
452 //\r
7e3bcccb 453 if (!HiiIsConfigHdrMatch (Configuration, &mFormSetGuid, VariableName)) {\r
8d00a0f1 454 *Progress = Configuration;\r
455 return EFI_NOT_FOUND;\r
456 }\r
457\r
93e3992d 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
8d00a0f1 538 UINT8 MyVar;\r
7e3bcccb
LG
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
93e3992d 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
8d00a0f1 555 // Initialize the container for dynamic opcodes\r
93e3992d 556 //\r
7e3bcccb
LG
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
8d00a0f1 668 \r
7e3bcccb
LG
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
8d00a0f1 695 \r
7e3bcccb
LG
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
93e3992d 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
7064c0a5 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
93e3992d 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
93e3992d 795 EFI_HII_HANDLE HiiHandle[2];\r
93e3992d 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
93e3992d 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
f6f910dd 871 Status = gBS->InstallMultipleProtocolInterfaces (\r
93e3992d 872 &DriverHandle[0],\r
f6f910dd 873 &gEfiDevicePathProtocolGuid,\r
2f3065c0 874 &mHiiVendorDevicePath0,\r
93e3992d 875 &gEfiHiiConfigAccessProtocolGuid,\r
f6f910dd 876 &PrivateData->ConfigAccess,\r
877 NULL\r
93e3992d 878 );\r
879 ASSERT_EFI_ERROR (Status);\r
880\r
f6f910dd 881 PrivateData->DriverHandle[0] = DriverHandle[0];\r
882\r
93e3992d 883 //\r
884 // Publish our HII data\r
885 //\r
cb7d01c0 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
93e3992d 894 return EFI_OUT_OF_RESOURCES;\r
895 }\r
896\r
93e3992d 897 PrivateData->HiiHandle[0] = HiiHandle[0];\r
898\r
899 //\r
900 // Publish another Fromset\r
901 //\r
f6f910dd 902 Status = gBS->InstallMultipleProtocolInterfaces (\r
903 &DriverHandle[1],\r
904 &gEfiDevicePathProtocolGuid,\r
2f3065c0 905 &mHiiVendorDevicePath1,\r
f6f910dd 906 NULL\r
907 );\r
908 ASSERT_EFI_ERROR (Status);\r
909\r
93e3992d 910 PrivateData->DriverHandle[1] = DriverHandle[1];\r
911\r
cb7d01c0 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
93e3992d 920 return EFI_OUT_OF_RESOURCES;\r
921 }\r
922\r
93e3992d 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
cb7d01c0 931 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {\r
932 return EFI_OUT_OF_RESOURCES;\r
93e3992d 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
3c7449e4 957 Status = HiiIfrLibExtractDefault (Configuration, &BufferSize, 1, VfrMyIfrNVDataDefault0000);\r
93e3992d 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
7e3bcccb
LG
971 // Default this driver is built into Flash device image, \r
972 // the following code doesn't run.\r
93e3992d 973 //\r
7e3bcccb 974\r
2f3065c0 975 //\r
7e3bcccb
LG
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
2f3065c0 979 //\r
7e3bcccb
LG
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
7e3bcccb 993 \r
14d59fa1 994 HiiRemovePackages (HiiHandle[0]);\r
7e3bcccb 995 \r
14d59fa1 996 HiiRemovePackages (HiiHandle[1]);\r
2f3065c0
LG
997 }\r
998\r
14d59fa1 999 return Status;\r
2f3065c0
LG
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
14d59fa1
LG
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
2f3065c0
LG
1043 if (PrivateData != NULL) {\r
1044 FreePool (PrivateData);\r
93e3992d 1045 }\r
1046\r
1047 return EFI_SUCCESS;\r
1048}\r