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