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