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