VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c@ 48674

Last change on this file since 48674 was 48674, checked in by vboxsync, 11 years ago

EFI: Export newly imported tinaocore UEFI sources to OSE.

  • Property svn:eol-style set to native
File size: 62.6 KB
Line 
1/** @file
2This is an example of how a driver might export data to the HII protocol to be
3later utilized by the Setup Protocol
4
5Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
6This program and the accompanying materials
7are licensed and made available under the terms and conditions of the BSD License
8which accompanies this distribution. The full text of the license may be found at
9http://opensource.org/licenses/bsd-license.php
10
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14**/
15
16
17#include "DriverSample.h"
18
19#define DISPLAY_ONLY_MY_ITEM 0x0002
20
21CHAR16 VariableName[] = L"MyIfrNVData";
22CHAR16 MyEfiVar[] = L"MyEfiVar";
23EFI_HANDLE DriverHandle[2] = {NULL, NULL};
24DRIVER_SAMPLE_PRIVATE_DATA *PrivateData = NULL;
25EFI_EVENT mEvent;
26
27HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = {
28 {
29 {
30 HARDWARE_DEVICE_PATH,
31 HW_VENDOR_DP,
32 {
33 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
34 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
35 }
36 },
37 DRIVER_SAMPLE_FORMSET_GUID
38 },
39 {
40 END_DEVICE_PATH_TYPE,
41 END_ENTIRE_DEVICE_PATH_SUBTYPE,
42 {
43 (UINT8) (END_DEVICE_PATH_LENGTH),
44 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
45 }
46 }
47};
48
49HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = {
50 {
51 {
52 HARDWARE_DEVICE_PATH,
53 HW_VENDOR_DP,
54 {
55 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
56 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
57 }
58 },
59 DRIVER_SAMPLE_INVENTORY_GUID
60 },
61 {
62 END_DEVICE_PATH_TYPE,
63 END_ENTIRE_DEVICE_PATH_SUBTYPE,
64 {
65 (UINT8) (END_DEVICE_PATH_LENGTH),
66 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
67 }
68 }
69};
70
71/**
72 Add empty function for event process function.
73
74 @param Event The Event need to be process
75 @param Context The context of the event.
76
77**/
78VOID
79EFIAPI
80DriverSampleInternalEmptyFunction (
81 IN EFI_EVENT Event,
82 IN VOID *Context
83 )
84{
85}
86
87/**
88 Notification function for keystrokes.
89
90 @param[in] KeyData The key that was pressed.
91
92 @retval EFI_SUCCESS The operation was successful.
93**/
94EFI_STATUS
95EFIAPI
96NotificationFunction(
97 IN EFI_KEY_DATA *KeyData
98 )
99{
100 gBS->SignalEvent (mEvent);
101
102 return EFI_SUCCESS;
103}
104
105/**
106 Function to start monitoring for CTRL-C using SimpleTextInputEx.
107
108 @retval EFI_SUCCESS The feature is enabled.
109 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
110**/
111EFI_STATUS
112EFIAPI
113InternalStartMonitor(
114 VOID
115 )
116{
117 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;
118 EFI_KEY_DATA KeyData;
119 EFI_STATUS Status;
120 EFI_HANDLE *Handles;
121 UINTN HandleCount;
122 UINTN HandleIndex;
123 EFI_HANDLE NotifyHandle;
124
125 Status = gBS->LocateHandleBuffer (
126 ByProtocol,
127 &gEfiSimpleTextInputExProtocolGuid,
128 NULL,
129 &HandleCount,
130 &Handles
131 );
132 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
133 Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleEx);
134 ASSERT_EFI_ERROR (Status);
135
136 KeyData.KeyState.KeyToggleState = 0;
137 KeyData.Key.ScanCode = 0;
138 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
139 KeyData.Key.UnicodeChar = L'c';
140
141 Status = SimpleEx->RegisterKeyNotify(
142 SimpleEx,
143 &KeyData,
144 NotificationFunction,
145 &NotifyHandle);
146 if (EFI_ERROR (Status)) {
147 break;
148 }
149
150 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
151 Status = SimpleEx->RegisterKeyNotify(
152 SimpleEx,
153 &KeyData,
154 NotificationFunction,
155 &NotifyHandle);
156 if (EFI_ERROR (Status)) {
157 break;
158 }
159 }
160
161 return EFI_SUCCESS;
162}
163
164/**
165 Function to stop monitoring for CTRL-C using SimpleTextInputEx.
166
167 @retval EFI_SUCCESS The feature is enabled.
168 @retval EFI_OUT_OF_RESOURCES There is not enough mnemory available.
169**/
170EFI_STATUS
171EFIAPI
172InternalStopMonitor(
173 VOID
174 )
175{
176 EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleEx;
177 EFI_STATUS Status;
178 EFI_HANDLE *Handles;
179 EFI_KEY_DATA KeyData;
180 UINTN HandleCount;
181 UINTN HandleIndex;
182 EFI_HANDLE NotifyHandle;
183
184 Status = gBS->LocateHandleBuffer (
185 ByProtocol,
186 &gEfiSimpleTextInputExProtocolGuid,
187 NULL,
188 &HandleCount,
189 &Handles
190 );
191 for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
192 Status = gBS->HandleProtocol (Handles[HandleIndex], &gEfiSimpleTextInputExProtocolGuid, (VOID **) &SimpleEx);
193 ASSERT_EFI_ERROR (Status);
194
195 KeyData.KeyState.KeyToggleState = 0;
196 KeyData.Key.ScanCode = 0;
197 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_LEFT_CONTROL_PRESSED;
198 KeyData.Key.UnicodeChar = L'c';
199
200 Status = SimpleEx->RegisterKeyNotify(
201 SimpleEx,
202 &KeyData,
203 NotificationFunction,
204 &NotifyHandle);
205 if (!EFI_ERROR (Status)) {
206 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle);
207 }
208
209 KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID|EFI_RIGHT_CONTROL_PRESSED;
210 Status = SimpleEx->RegisterKeyNotify(
211 SimpleEx,
212 &KeyData,
213 NotificationFunction,
214 &NotifyHandle);
215 if (!EFI_ERROR (Status)) {
216 Status = SimpleEx->UnregisterKeyNotify (SimpleEx, NotifyHandle);
217 }
218 }
219 return EFI_SUCCESS;
220}
221
222
223/**
224 Encode the password using a simple algorithm.
225
226 @param Password The string to be encoded.
227 @param MaxSize The size of the string.
228
229**/
230VOID
231EncodePassword (
232 IN CHAR16 *Password,
233 IN UINTN MaxSize
234 )
235{
236 UINTN Index;
237 UINTN Loop;
238 CHAR16 *Buffer;
239 CHAR16 *Key;
240
241 Key = L"MAR10648567";
242 Buffer = AllocateZeroPool (MaxSize);
243 ASSERT (Buffer != NULL);
244
245 for (Index = 0; Key[Index] != 0; Index++) {
246 for (Loop = 0; Loop < (UINT8) (MaxSize / 2); Loop++) {
247 Buffer[Loop] = (CHAR16) (Password[Loop] ^ Key[Index]);
248 }
249 }
250
251 CopyMem (Password, Buffer, MaxSize);
252
253 FreePool (Buffer);
254 return ;
255}
256
257/**
258 Validate the user's password.
259
260 @param PrivateData This driver's private context data.
261 @param StringId The user's input.
262
263 @retval EFI_SUCCESS The user's input matches the password.
264 @retval EFI_NOT_READY The user's input does not match the password.
265**/
266EFI_STATUS
267ValidatePassword (
268 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,
269 IN EFI_STRING_ID StringId
270 )
271{
272 EFI_STATUS Status;
273 UINTN Index;
274 UINTN BufferSize;
275 UINTN PasswordMaxSize;
276 CHAR16 *Password;
277 CHAR16 *EncodedPassword;
278 BOOLEAN OldPassword;
279
280 //
281 // Get encoded password first
282 //
283 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
284 Status = gRT->GetVariable (
285 VariableName,
286 &gDriverSampleFormSetGuid,
287 NULL,
288 &BufferSize,
289 &PrivateData->Configuration
290 );
291 if (EFI_ERROR (Status)) {
292 //
293 // Old password not exist, prompt for new password
294 //
295 return EFI_SUCCESS;
296 }
297
298 OldPassword = FALSE;
299 PasswordMaxSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);
300 //
301 // Check whether we have any old password set
302 //
303 for (Index = 0; Index < PasswordMaxSize / sizeof (UINT16); Index++) {
304 if (PrivateData->Configuration.WhatIsThePassword2[Index] != 0) {
305 OldPassword = TRUE;
306 break;
307 }
308 }
309 if (!OldPassword) {
310 //
311 // Old password not exist, return EFI_SUCCESS to prompt for new password
312 //
313 return EFI_SUCCESS;
314 }
315
316 //
317 // Get user input password
318 //
319 Password = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL);
320 if (Password == NULL) {
321 return EFI_NOT_READY;
322 }
323 if (StrSize (Password) > PasswordMaxSize) {
324 FreePool (Password);
325 return EFI_NOT_READY;
326 }
327
328 //
329 // Validate old password
330 //
331 EncodedPassword = AllocateZeroPool (PasswordMaxSize);
332 ASSERT (EncodedPassword != NULL);
333 StrnCpy (EncodedPassword, Password, StrLen (Password));
334 EncodePassword (EncodedPassword, StrLen (EncodedPassword) * sizeof (CHAR16));
335 if (CompareMem (EncodedPassword, PrivateData->Configuration.WhatIsThePassword2, PasswordMaxSize) != 0) {
336 //
337 // Old password mismatch, return EFI_NOT_READY to prompt for error message
338 //
339 Status = EFI_NOT_READY;
340 } else {
341 Status = EFI_SUCCESS;
342 }
343
344 FreePool (Password);
345 FreePool (EncodedPassword);
346
347 return Status;
348}
349
350/**
351 Encode the password using a simple algorithm.
352
353 @param PrivateData This driver's private context data.
354 @param StringId The password from User.
355
356 @retval EFI_SUCESS The operation is successful.
357 @return Other value if gRT->SetVariable () fails.
358
359**/
360EFI_STATUS
361SetPassword (
362 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,
363 IN EFI_STRING_ID StringId
364 )
365{
366 EFI_STATUS Status;
367 CHAR16 *Password;
368 CHAR16 *TempPassword;
369 UINTN PasswordSize;
370 DRIVER_SAMPLE_CONFIGURATION *Configuration;
371 UINTN BufferSize;
372
373 //
374 // Get Buffer Storage data from EFI variable
375 //
376 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
377 Status = gRT->GetVariable (
378 VariableName,
379 &gDriverSampleFormSetGuid,
380 NULL,
381 &BufferSize,
382 &PrivateData->Configuration
383 );
384 if (EFI_ERROR (Status)) {
385 return Status;
386 }
387
388 //
389 // Get user input password
390 //
391 Password = &PrivateData->Configuration.WhatIsThePassword2[0];
392 PasswordSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);
393 ZeroMem (Password, PasswordSize);
394
395 TempPassword = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL);
396 if (TempPassword == NULL) {
397 return EFI_NOT_READY;
398 }
399 if (StrSize (TempPassword) > PasswordSize) {
400 FreePool (TempPassword);
401 return EFI_NOT_READY;
402 }
403 StrnCpy (Password, TempPassword, StrLen (TempPassword));
404 FreePool (TempPassword);
405
406 //
407 // Retrive uncommitted data from Browser
408 //
409 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));
410 ASSERT (Configuration != NULL);
411 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) {
412 //
413 // Update password's clear text in the screen
414 //
415 CopyMem (Configuration->PasswordClearText, Password, StrSize (Password));
416
417 //
418 // Update uncommitted data of Browser
419 //
420 HiiSetBrowserData (
421 &gDriverSampleFormSetGuid,
422 VariableName,
423 sizeof (DRIVER_SAMPLE_CONFIGURATION),
424 (UINT8 *) Configuration,
425 NULL
426 );
427 }
428
429 //
430 // Free Configuration Buffer
431 //
432 FreePool (Configuration);
433
434
435 //
436 // Set password
437 //
438 EncodePassword (Password, StrLen (Password) * 2);
439 Status = gRT->SetVariable(
440 VariableName,
441 &gDriverSampleFormSetGuid,
442 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
443 sizeof (DRIVER_SAMPLE_CONFIGURATION),
444 &PrivateData->Configuration
445 );
446 return Status;
447}
448
449/**
450 Update names of Name/Value storage to current language.
451
452 @param PrivateData Points to the driver private data.
453
454 @retval EFI_SUCCESS All names are successfully updated.
455 @retval EFI_NOT_FOUND Failed to get Name from HII database.
456
457**/
458EFI_STATUS
459LoadNameValueNames (
460 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData
461 )
462{
463 UINTN Index;
464
465 //
466 // Get Name/Value name string of current language
467 //
468 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {
469 PrivateData->NameValueName[Index] = HiiGetString (
470 PrivateData->HiiHandle[0],
471 PrivateData->NameStringId[Index],
472 NULL
473 );
474 if (PrivateData->NameValueName[Index] == NULL) {
475 return EFI_NOT_FOUND;
476 }
477 }
478
479 return EFI_SUCCESS;
480}
481
482
483/**
484 Get the value of <Number> in <BlockConfig> format, i.e. the value of OFFSET
485 or WIDTH or VALUE.
486 <BlockConfig> ::= 'OFFSET='<Number>&'WIDTH='<Number>&'VALUE'=<Number>
487
488 This is a internal function.
489
490 @param StringPtr String in <BlockConfig> format and points to the
491 first character of <Number>.
492 @param Number The output value. Caller takes the responsibility
493 to free memory.
494 @param Len Length of the <Number>, in characters.
495
496 @retval EFI_OUT_OF_RESOURCES Insufficient resources to store neccessary
497 structures.
498 @retval EFI_SUCCESS Value of <Number> is outputted in Number
499 successfully.
500
501**/
502EFI_STATUS
503GetValueOfNumber (
504 IN EFI_STRING StringPtr,
505 OUT UINT8 **Number,
506 OUT UINTN *Len
507 )
508{
509 EFI_STRING TmpPtr;
510 UINTN Length;
511 EFI_STRING Str;
512 UINT8 *Buf;
513 EFI_STATUS Status;
514 UINT8 DigitUint8;
515 UINTN Index;
516 CHAR16 TemStr[2];
517
518 if (StringPtr == NULL || *StringPtr == L'\0' || Number == NULL || Len == NULL) {
519 return EFI_INVALID_PARAMETER;
520 }
521
522 Buf = NULL;
523
524 TmpPtr = StringPtr;
525 while (*StringPtr != L'\0' && *StringPtr != L'&') {
526 StringPtr++;
527 }
528 *Len = StringPtr - TmpPtr;
529 Length = *Len + 1;
530
531 Str = (EFI_STRING) AllocateZeroPool (Length * sizeof (CHAR16));
532 if (Str == NULL) {
533 Status = EFI_OUT_OF_RESOURCES;
534 goto Exit;
535 }
536 CopyMem (Str, TmpPtr, *Len * sizeof (CHAR16));
537 *(Str + *Len) = L'\0';
538
539 Length = (Length + 1) / 2;
540 Buf = (UINT8 *) AllocateZeroPool (Length);
541 if (Buf == NULL) {
542 Status = EFI_OUT_OF_RESOURCES;
543 goto Exit;
544 }
545
546 Length = *Len;
547 ZeroMem (TemStr, sizeof (TemStr));
548 for (Index = 0; Index < Length; Index ++) {
549 TemStr[0] = Str[Length - Index - 1];
550 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
551 if ((Index & 1) == 0) {
552 Buf [Index/2] = DigitUint8;
553 } else {
554 Buf [Index/2] = (UINT8) ((DigitUint8 << 4) + Buf [Index/2]);
555 }
556 }
557
558 *Number = Buf;
559 Status = EFI_SUCCESS;
560
561Exit:
562 if (Str != NULL) {
563 FreePool (Str);
564 }
565
566 return Status;
567}
568
569/**
570 Create altcfg string.
571
572 @param Result The request result string.
573 @param ConfigHdr The request head info. <ConfigHdr> format.
574 @param Offset The offset of the parameter int he structure.
575 @param Width The width of the parameter.
576
577
578 @retval The string with altcfg info append at the end.
579**/
580EFI_STRING
581CreateAltCfgString (
582 IN EFI_STRING Result,
583 IN EFI_STRING ConfigHdr,
584 IN UINTN Offset,
585 IN UINTN Width
586 )
587{
588 EFI_STRING StringPtr;
589 EFI_STRING TmpStr;
590 UINTN NewLen;
591
592 NewLen = StrLen (Result);
593 //
594 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")
595 //
596 NewLen = (NewLen + ((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16);
597 StringPtr = AllocateZeroPool (NewLen);
598 if (StringPtr == NULL) {
599 return NULL;
600 }
601
602 TmpStr = StringPtr;
603 if (Result != NULL) {
604 StrCpy (StringPtr, Result);
605 StringPtr += StrLen (Result);
606 FreePool (Result);
607 }
608
609 UnicodeSPrint (
610 StringPtr,
611 (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16),
612 L"&%s&ALTCFG=%04x",
613 ConfigHdr,
614 EFI_HII_DEFAULT_CLASS_STANDARD
615 );
616 StringPtr += StrLen (StringPtr);
617
618 UnicodeSPrint (
619 StringPtr,
620 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),
621 L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
622 Offset,
623 Width,
624 DEFAULT_CLASS_STANDARD_VALUE
625 );
626 StringPtr += StrLen (StringPtr);
627
628 UnicodeSPrint (
629 StringPtr,
630 (1 + StrLen (ConfigHdr) + 8 + 4 + 1) * sizeof (CHAR16),
631 L"&%s&ALTCFG=%04x",
632 ConfigHdr,
633 EFI_HII_DEFAULT_CLASS_MANUFACTURING
634 );
635 StringPtr += StrLen (StringPtr);
636
637 UnicodeSPrint (
638 StringPtr,
639 (8 + 4 + 7 + 4 + 7 + 4 + 1) * sizeof (CHAR16),
640 L"&OFFSET=%04x&WIDTH=%04x&VALUE=%04x",
641 Offset,
642 Width,
643 DEFAULT_CLASS_MANUFACTURING_VALUE
644 );
645 StringPtr += StrLen (StringPtr);
646
647 return TmpStr;
648}
649
650/**
651 Check whether need to add the altcfg string. if need to add, add the altcfg
652 string.
653
654 @param RequestResult The request result string.
655 @param ConfigRequestHdr The request head info. <ConfigHdr> format.
656
657**/
658VOID
659AppendAltCfgString (
660 IN OUT EFI_STRING *RequestResult,
661 IN EFI_STRING ConfigRequestHdr
662 )
663{
664 EFI_STRING StringPtr;
665 UINTN Length;
666 UINT8 *TmpBuffer;
667 UINTN Offset;
668 UINTN Width;
669 UINTN BlockSize;
670 UINTN ValueOffset;
671 UINTN ValueWidth;
672 EFI_STATUS Status;
673
674 StringPtr = *RequestResult;
675 StringPtr = StrStr (StringPtr, L"OFFSET");
676 BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
677 ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess);
678 ValueWidth = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess);
679
680 if (StringPtr == NULL) {
681 return;
682 }
683
684 while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {
685 StringPtr += StrLen (L"OFFSET=");
686 //
687 // Get Offset
688 //
689 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
690 if (EFI_ERROR (Status)) {
691 return;
692 }
693 Offset = 0;
694 CopyMem (
695 &Offset,
696 TmpBuffer,
697 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
698 );
699 FreePool (TmpBuffer);
700
701 StringPtr += Length;
702 if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
703 return;
704 }
705 StringPtr += StrLen (L"&WIDTH=");
706
707 //
708 // Get Width
709 //
710 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
711 if (EFI_ERROR (Status)) {
712 return;
713 }
714 Width = 0;
715 CopyMem (
716 &Width,
717 TmpBuffer,
718 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
719 );
720 FreePool (TmpBuffer);
721
722 StringPtr += Length;
723 if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {
724 return;
725 }
726 StringPtr += StrLen (L"&VALUE=");
727
728 //
729 // Get Value
730 //
731 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
732 if (EFI_ERROR (Status)) {
733 return;
734 }
735 StringPtr += Length;
736
737 //
738 // Calculate Value and convert it to hex string.
739 //
740 if (Offset + Width > BlockSize) {
741 return;
742 }
743
744 if (Offset <= ValueOffset && Offset + Width >= ValueOffset + ValueWidth) {
745 *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth);
746 return;
747 }
748 }
749}
750
751/**
752 This function allows a caller to extract the current configuration for one
753 or more named elements from the target driver.
754
755 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
756 @param Request A null-terminated Unicode string in
757 <ConfigRequest> format.
758 @param Progress On return, points to a character in the Request
759 string. Points to the string's null terminator if
760 request was successful. Points to the most recent
761 '&' before the first failing name/value pair (or
762 the beginning of the string if the failure is in
763 the first name/value pair) if the request was not
764 successful.
765 @param Results A null-terminated Unicode string in
766 <ConfigAltResp> format which has all values filled
767 in for the names in the Request string. String to
768 be allocated by the called function.
769
770 @retval EFI_SUCCESS The Results is filled with the requested values.
771 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
772 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
773 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
774 driver.
775
776**/
777EFI_STATUS
778EFIAPI
779ExtractConfig (
780 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
781 IN CONST EFI_STRING Request,
782 OUT EFI_STRING *Progress,
783 OUT EFI_STRING *Results
784 )
785{
786 EFI_STATUS Status;
787 UINTN BufferSize;
788 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
789 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
790 EFI_STRING ConfigRequest;
791 EFI_STRING ConfigRequestHdr;
792 UINTN Size;
793 EFI_STRING Value;
794 UINTN ValueStrLen;
795 CHAR16 BackupChar;
796 CHAR16 *StrPointer;
797 BOOLEAN AllocatedRequest;
798
799 if (Progress == NULL || Results == NULL) {
800 return EFI_INVALID_PARAMETER;
801 }
802 //
803 // Initialize the local variables.
804 //
805 ConfigRequestHdr = NULL;
806 ConfigRequest = NULL;
807 Size = 0;
808 *Progress = Request;
809 AllocatedRequest = FALSE;
810
811 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
812 HiiConfigRouting = PrivateData->HiiConfigRouting;
813
814 //
815 // Get Buffer Storage data from EFI variable.
816 // Try to get the current setting from variable.
817 //
818 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
819 Status = gRT->GetVariable (
820 VariableName,
821 &gDriverSampleFormSetGuid,
822 NULL,
823 &BufferSize,
824 &PrivateData->Configuration
825 );
826 if (EFI_ERROR (Status)) {
827 return EFI_NOT_FOUND;
828 }
829
830 if (Request == NULL) {
831 //
832 // Request is set to NULL, construct full request string.
833 //
834
835 //
836 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
837 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
838 //
839 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);
840 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
841 ConfigRequest = AllocateZeroPool (Size);
842 ASSERT (ConfigRequest != NULL);
843 AllocatedRequest = TRUE;
844 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
845 FreePool (ConfigRequestHdr);
846 ConfigRequestHdr = NULL;
847 } else {
848 //
849 // Check routing data in <ConfigHdr>.
850 // Note: if only one Storage is used, then this checking could be skipped.
851 //
852 if (!HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, NULL)) {
853 return EFI_NOT_FOUND;
854 }
855 //
856 // Check whether request for EFI Varstore. EFI varstore get data
857 // through hii database, not support in this path.
858 //
859 if (HiiIsConfigHdrMatch(Request, &gDriverSampleFormSetGuid, MyEfiVar)) {
860 return EFI_UNSUPPORTED;
861 }
862 //
863 // Set Request to the unified request string.
864 //
865 ConfigRequest = Request;
866 //
867 // Check whether Request includes Request Element.
868 //
869 if (StrStr (Request, L"OFFSET") == NULL) {
870 //
871 // Check Request Element does exist in Reques String
872 //
873 StrPointer = StrStr (Request, L"PATH");
874 if (StrPointer == NULL) {
875 return EFI_INVALID_PARAMETER;
876 }
877 if (StrStr (StrPointer, L"&") == NULL) {
878 Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
879 ConfigRequest = AllocateZeroPool (Size);
880 ASSERT (ConfigRequest != NULL);
881 AllocatedRequest = TRUE;
882 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);
883 }
884 }
885 }
886
887 //
888 // Check if requesting Name/Value storage
889 //
890 if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
891 //
892 // Update Name/Value storage Names
893 //
894 Status = LoadNameValueNames (PrivateData);
895 if (EFI_ERROR (Status)) {
896 return Status;
897 }
898
899 //
900 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
901 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
902 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
903 //
904 BufferSize = (StrLen (ConfigRequest) +
905 1 + sizeof (PrivateData->Configuration.NameValueVar0) * 2 +
906 1 + sizeof (PrivateData->Configuration.NameValueVar1) * 2 +
907 1 + sizeof (PrivateData->Configuration.NameValueVar2) * 2 + 1) * sizeof (CHAR16);
908 *Results = AllocateZeroPool (BufferSize);
909 ASSERT (*Results != NULL);
910 StrCpy (*Results, ConfigRequest);
911 Value = *Results;
912
913 //
914 // Append value of NameValueVar0, type is UINT8
915 //
916 if ((Value = StrStr (*Results, PrivateData->NameValueName[0])) != NULL) {
917 Value += StrLen (PrivateData->NameValueName[0]);
918 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar0) * 2) + 1);
919 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
920
921 BackupChar = Value[ValueStrLen];
922 *Value++ = L'=';
923 Value += UnicodeValueToString (
924 Value,
925 PREFIX_ZERO | RADIX_HEX,
926 PrivateData->Configuration.NameValueVar0,
927 sizeof (PrivateData->Configuration.NameValueVar0) * 2
928 );
929 *Value = BackupChar;
930 }
931
932 //
933 // Append value of NameValueVar1, type is UINT16
934 //
935 if ((Value = StrStr (*Results, PrivateData->NameValueName[1])) != NULL) {
936 Value += StrLen (PrivateData->NameValueName[1]);
937 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar1) * 2) + 1);
938 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
939
940 BackupChar = Value[ValueStrLen];
941 *Value++ = L'=';
942 Value += UnicodeValueToString (
943 Value,
944 PREFIX_ZERO | RADIX_HEX,
945 PrivateData->Configuration.NameValueVar1,
946 sizeof (PrivateData->Configuration.NameValueVar1) * 2
947 );
948 *Value = BackupChar;
949 }
950
951 //
952 // Append value of NameValueVar2, type is CHAR16 *
953 //
954 if ((Value = StrStr (*Results, PrivateData->NameValueName[2])) != NULL) {
955 Value += StrLen (PrivateData->NameValueName[2]);
956 ValueStrLen = StrLen (PrivateData->Configuration.NameValueVar2) * 4 + 1;
957 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
958
959 *Value++ = L'=';
960 //
961 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
962 //
963 StrPointer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;
964 for (; *StrPointer != L'\0'; StrPointer++) {
965 Value += UnicodeValueToString (Value, PREFIX_ZERO | RADIX_HEX, *StrPointer, 4);
966 }
967 }
968
969 Status = EFI_SUCCESS;
970 } else {
971 //
972 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
973 //
974 Status = HiiConfigRouting->BlockToConfig (
975 HiiConfigRouting,
976 ConfigRequest,
977 (UINT8 *) &PrivateData->Configuration,
978 BufferSize,
979 Results,
980 Progress
981 );
982 if (!EFI_ERROR (Status)) {
983 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);
984 AppendAltCfgString(Results, ConfigRequestHdr);
985 }
986 }
987
988 //
989 // Free the allocated config request string.
990 //
991 if (AllocatedRequest) {
992 FreePool (ConfigRequest);
993 }
994
995 if (ConfigRequestHdr != NULL) {
996 FreePool (ConfigRequestHdr);
997 }
998 //
999 // Set Progress string to the original request string.
1000 //
1001 if (Request == NULL) {
1002 *Progress = NULL;
1003 } else if (StrStr (Request, L"OFFSET") == NULL) {
1004 *Progress = Request + StrLen (Request);
1005 }
1006
1007 return Status;
1008}
1009
1010
1011/**
1012 This function processes the results of changes in configuration.
1013
1014 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1015 @param Configuration A null-terminated Unicode string in <ConfigResp>
1016 format.
1017 @param Progress A pointer to a string filled in with the offset of
1018 the most recent '&' before the first failing
1019 name/value pair (or the beginning of the string if
1020 the failure is in the first name/value pair) or
1021 the terminating NULL if all was successful.
1022
1023 @retval EFI_SUCCESS The Results is processed successfully.
1024 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1025 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1026 driver.
1027
1028**/
1029EFI_STATUS
1030EFIAPI
1031RouteConfig (
1032 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1033 IN CONST EFI_STRING Configuration,
1034 OUT EFI_STRING *Progress
1035 )
1036{
1037 EFI_STATUS Status;
1038 UINTN BufferSize;
1039 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
1040 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1041 CHAR16 *Value;
1042 CHAR16 *StrPtr;
1043 CHAR16 TemStr[5];
1044 UINT8 *DataBuffer;
1045 UINT8 DigitUint8;
1046 UINTN Index;
1047 CHAR16 *StrBuffer;
1048
1049 if (Configuration == NULL || Progress == NULL) {
1050 return EFI_INVALID_PARAMETER;
1051 }
1052
1053 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1054 HiiConfigRouting = PrivateData->HiiConfigRouting;
1055 *Progress = Configuration;
1056
1057 //
1058 // Check routing data in <ConfigHdr>.
1059 // Note: if only one Storage is used, then this checking could be skipped.
1060 //
1061 if (!HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, NULL)) {
1062 return EFI_NOT_FOUND;
1063 }
1064
1065 //
1066 // Check whether request for EFI Varstore. EFI varstore get data
1067 // through hii database, not support in this path.
1068 //
1069 if (HiiIsConfigHdrMatch(Configuration, &gDriverSampleFormSetGuid, MyEfiVar)) {
1070 return EFI_UNSUPPORTED;
1071 }
1072
1073 //
1074 // Get Buffer Storage data from EFI variable
1075 //
1076 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1077 Status = gRT->GetVariable (
1078 VariableName,
1079 &gDriverSampleFormSetGuid,
1080 NULL,
1081 &BufferSize,
1082 &PrivateData->Configuration
1083 );
1084 if (EFI_ERROR (Status)) {
1085 return Status;
1086 }
1087
1088 //
1089 // Check if configuring Name/Value storage
1090 //
1091 if (StrStr (Configuration, L"OFFSET") == NULL) {
1092 //
1093 // Update Name/Value storage Names
1094 //
1095 Status = LoadNameValueNames (PrivateData);
1096 if (EFI_ERROR (Status)) {
1097 return Status;
1098 }
1099
1100 //
1101 // Convert value for NameValueVar0
1102 //
1103 if ((Value = StrStr (Configuration, PrivateData->NameValueName[0])) != NULL) {
1104 //
1105 // Skip "Name="
1106 //
1107 Value += StrLen (PrivateData->NameValueName[0]);
1108 Value++;
1109 //
1110 // Get Value String
1111 //
1112 StrPtr = StrStr (Value, L"&");
1113 if (StrPtr == NULL) {
1114 StrPtr = Value + StrLen (Value);
1115 }
1116 //
1117 // Convert Value to Buffer data
1118 //
1119 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar0;
1120 ZeroMem (TemStr, sizeof (TemStr));
1121 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {
1122 TemStr[0] = *StrPtr;
1123 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
1124 if ((Index & 1) == 0) {
1125 DataBuffer [Index/2] = DigitUint8;
1126 } else {
1127 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);
1128 }
1129 }
1130 }
1131
1132 //
1133 // Convert value for NameValueVar1
1134 //
1135 if ((Value = StrStr (Configuration, PrivateData->NameValueName[1])) != NULL) {
1136 //
1137 // Skip "Name="
1138 //
1139 Value += StrLen (PrivateData->NameValueName[1]);
1140 Value++;
1141 //
1142 // Get Value String
1143 //
1144 StrPtr = StrStr (Value, L"&");
1145 if (StrPtr == NULL) {
1146 StrPtr = Value + StrLen (Value);
1147 }
1148 //
1149 // Convert Value to Buffer data
1150 //
1151 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar1;
1152 ZeroMem (TemStr, sizeof (TemStr));
1153 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {
1154 TemStr[0] = *StrPtr;
1155 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
1156 if ((Index & 1) == 0) {
1157 DataBuffer [Index/2] = DigitUint8;
1158 } else {
1159 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);
1160 }
1161 }
1162 }
1163
1164 //
1165 // Convert value for NameValueVar2
1166 //
1167 if ((Value = StrStr (Configuration, PrivateData->NameValueName[2])) != NULL) {
1168 //
1169 // Skip "Name="
1170 //
1171 Value += StrLen (PrivateData->NameValueName[2]);
1172 Value++;
1173 //
1174 // Get Value String
1175 //
1176 StrPtr = StrStr (Value, L"&");
1177 if (StrPtr == NULL) {
1178 StrPtr = Value + StrLen (Value);
1179 }
1180 //
1181 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1182 //
1183 StrBuffer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;
1184 ZeroMem (TemStr, sizeof (TemStr));
1185 while (Value < StrPtr) {
1186 StrnCpy (TemStr, Value, 4);
1187 *(StrBuffer++) = (CHAR16) StrHexToUint64 (TemStr);
1188 Value += 4;
1189 }
1190 *StrBuffer = L'\0';
1191 }
1192
1193 //
1194 // Store Buffer Storage back to EFI variable
1195 //
1196 Status = gRT->SetVariable(
1197 VariableName,
1198 &gDriverSampleFormSetGuid,
1199 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1200 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1201 &PrivateData->Configuration
1202 );
1203
1204 return Status;
1205 }
1206
1207 //
1208 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1209 //
1210 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1211 Status = HiiConfigRouting->ConfigToBlock (
1212 HiiConfigRouting,
1213 Configuration,
1214 (UINT8 *) &PrivateData->Configuration,
1215 &BufferSize,
1216 Progress
1217 );
1218 if (EFI_ERROR (Status)) {
1219 return Status;
1220 }
1221
1222 //
1223 // Store Buffer Storage back to EFI variable
1224 //
1225 Status = gRT->SetVariable(
1226 VariableName,
1227 &gDriverSampleFormSetGuid,
1228 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1229 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1230 &PrivateData->Configuration
1231 );
1232
1233 return Status;
1234}
1235
1236
1237/**
1238 This function processes the results of changes in configuration.
1239
1240 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1241 @param Action Specifies the type of action taken by the browser.
1242 @param QuestionId A unique value which is sent to the original
1243 exporting driver so that it can identify the type
1244 of data to expect.
1245 @param Type The type of value for the question.
1246 @param Value A pointer to the data being sent to the original
1247 exporting driver.
1248 @param ActionRequest On return, points to the action requested by the
1249 callback function.
1250
1251 @retval EFI_SUCCESS The callback successfully handled the action.
1252 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1253 variable and its data.
1254 @retval EFI_DEVICE_ERROR The variable could not be saved.
1255 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1256 callback.
1257
1258**/
1259EFI_STATUS
1260EFIAPI
1261DriverCallback (
1262 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1263 IN EFI_BROWSER_ACTION Action,
1264 IN EFI_QUESTION_ID QuestionId,
1265 IN UINT8 Type,
1266 IN EFI_IFR_TYPE_VALUE *Value,
1267 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1268 )
1269{
1270 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
1271 EFI_STATUS Status;
1272 VOID *StartOpCodeHandle;
1273 VOID *OptionsOpCodeHandle;
1274 EFI_IFR_GUID_LABEL *StartLabel;
1275 VOID *EndOpCodeHandle;
1276 EFI_IFR_GUID_LABEL *EndLabel;
1277 EFI_INPUT_KEY Key;
1278 DRIVER_SAMPLE_CONFIGURATION *Configuration;
1279 MY_EFI_VARSTORE_DATA *EfiData;
1280 EFI_FORM_ID FormId;
1281
1282 if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||
1283 (ActionRequest == NULL)) {
1284 return EFI_INVALID_PARAMETER;
1285 }
1286
1287
1288 FormId = 0;
1289 Status = EFI_SUCCESS;
1290 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1291
1292 switch (Action) {
1293 case EFI_BROWSER_ACTION_FORM_OPEN:
1294 {
1295 if (QuestionId == 0x1234) {
1296 //
1297 // Sample CallBack for UEFI FORM_OPEN action:
1298 // Add Save action into Form 3 when Form 1 is opened.
1299 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1300 //
1301 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1302
1303 //
1304 // Initialize the container for dynamic opcodes
1305 //
1306 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1307 ASSERT (StartOpCodeHandle != NULL);
1308
1309 //
1310 // Create Hii Extend Label OpCode as the start opcode
1311 //
1312 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1313 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1314 StartLabel->Number = LABEL_UPDATE2;
1315
1316 HiiCreateActionOpCode (
1317 StartOpCodeHandle, // Container for dynamic created opcodes
1318 0x1238, // Question ID
1319 STRING_TOKEN(STR_SAVE_TEXT), // Prompt text
1320 STRING_TOKEN(STR_SAVE_TEXT), // Help text
1321 EFI_IFR_FLAG_CALLBACK, // Question flag
1322 0 // Action String ID
1323 );
1324
1325 HiiUpdateForm (
1326 PrivateData->HiiHandle[0], // HII handle
1327 &gDriverSampleFormSetGuid, // Formset GUID
1328 0x3, // Form ID
1329 StartOpCodeHandle, // Label for where to insert opcodes
1330 NULL // Insert data
1331 );
1332
1333 HiiFreeOpCodeHandle (StartOpCodeHandle);
1334 }
1335
1336 if (QuestionId == 0x1247) {
1337 Status = InternalStartMonitor ();
1338 ASSERT_EFI_ERROR (Status);
1339 }
1340 }
1341 break;
1342
1343 case EFI_BROWSER_ACTION_FORM_CLOSE:
1344 {
1345 if (QuestionId == 0x5678) {
1346 //
1347 // Sample CallBack for UEFI FORM_CLOSE action:
1348 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1349 //
1350 do {
1351 CreatePopUp (
1352 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1353 &Key,
1354 L"",
1355 L"You are going to leave third Form!",
1356 L"Press ESC or ENTER to continue ...",
1357 L"",
1358 NULL
1359 );
1360 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
1361 }
1362
1363 if (QuestionId == 0x1247) {
1364 Status = InternalStopMonitor ();
1365 ASSERT_EFI_ERROR (Status);
1366 }
1367 }
1368 break;
1369
1370 case EFI_BROWSER_ACTION_RETRIEVE:
1371 {
1372 if (QuestionId == 0x1248) {
1373 {
1374 if (Type != EFI_IFR_TYPE_REF) {
1375 return EFI_INVALID_PARAMETER;
1376 }
1377
1378 Value->ref.FormId = 0x3;
1379 }
1380 }
1381 }
1382 break;
1383
1384 case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
1385 {
1386 switch (QuestionId) {
1387 case 0x1240:
1388 Value->u8 = DEFAULT_CLASS_STANDARD_VALUE;
1389 break;
1390
1391 default:
1392 Status = EFI_UNSUPPORTED;
1393 break;
1394 }
1395 }
1396 break;
1397
1398 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
1399 {
1400 switch (QuestionId) {
1401 case 0x1240:
1402 Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE;
1403 break;
1404
1405 default:
1406 Status = EFI_UNSUPPORTED;
1407 break;
1408 }
1409 }
1410 break;
1411
1412 case EFI_BROWSER_ACTION_CHANGING:
1413 {
1414 switch (QuestionId) {
1415 case 0x1249:
1416 {
1417 if (Type != EFI_IFR_TYPE_REF) {
1418 return EFI_INVALID_PARAMETER;
1419 }
1420
1421 Value->ref.FormId = 0x1234;
1422 }
1423 break;
1424 case 0x1234:
1425 //
1426 // Initialize the container for dynamic opcodes
1427 //
1428 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1429 ASSERT (StartOpCodeHandle != NULL);
1430
1431 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
1432 ASSERT (EndOpCodeHandle != NULL);
1433
1434 //
1435 // Create Hii Extend Label OpCode as the start opcode
1436 //
1437 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1438 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1439 StartLabel->Number = LABEL_UPDATE1;
1440
1441 //
1442 // Create Hii Extend Label OpCode as the end opcode
1443 //
1444 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1445 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1446 EndLabel->Number = LABEL_END;
1447
1448 HiiCreateActionOpCode (
1449 StartOpCodeHandle, // Container for dynamic created opcodes
1450 0x1237, // Question ID
1451 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text
1452 STRING_TOKEN(STR_EXIT_TEXT), // Help text
1453 EFI_IFR_FLAG_CALLBACK, // Question flag
1454 0 // Action String ID
1455 );
1456
1457 //
1458 // Create Option OpCode
1459 //
1460 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1461 ASSERT (OptionsOpCodeHandle != NULL);
1462
1463 HiiCreateOneOfOptionOpCode (
1464 OptionsOpCodeHandle,
1465 STRING_TOKEN (STR_BOOT_OPTION1),
1466 0,
1467 EFI_IFR_NUMERIC_SIZE_1,
1468 1
1469 );
1470
1471 HiiCreateOneOfOptionOpCode (
1472 OptionsOpCodeHandle,
1473 STRING_TOKEN (STR_BOOT_OPTION2),
1474 0,
1475 EFI_IFR_NUMERIC_SIZE_1,
1476 2
1477 );
1478
1479 //
1480 // Prepare initial value for the dynamic created oneof Question
1481 //
1482 PrivateData->Configuration.DynamicOneof = 2;
1483 Status = gRT->SetVariable(
1484 VariableName,
1485 &gDriverSampleFormSetGuid,
1486 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1487 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1488 &PrivateData->Configuration
1489 );
1490
1491 //
1492 // Set initial vlaue of dynamic created oneof Question in Form Browser
1493 //
1494 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));
1495 ASSERT (Configuration != NULL);
1496 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) {
1497 Configuration->DynamicOneof = 2;
1498
1499 //
1500 // Update uncommitted data of Browser
1501 //
1502 HiiSetBrowserData (
1503 &gDriverSampleFormSetGuid,
1504 VariableName,
1505 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1506 (UINT8 *) Configuration,
1507 NULL
1508 );
1509 }
1510 FreePool (Configuration);
1511
1512 HiiCreateOneOfOpCode (
1513 StartOpCodeHandle, // Container for dynamic created opcodes
1514 0x8001, // Question ID (or call it "key")
1515 CONFIGURATION_VARSTORE_ID, // VarStore ID
1516 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage
1517 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text
1518 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text
1519 EFI_IFR_FLAG_CALLBACK, // Question flag
1520 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value
1521 OptionsOpCodeHandle, // Option Opcode list
1522 NULL // Default Opcode is NULl
1523 );
1524
1525 HiiCreateOrderedListOpCode (
1526 StartOpCodeHandle, // Container for dynamic created opcodes
1527 0x8002, // Question ID
1528 CONFIGURATION_VARSTORE_ID, // VarStore ID
1529 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage
1530 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text
1531 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text
1532 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
1533 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1534 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value
1535 5, // Maximum container
1536 OptionsOpCodeHandle, // Option Opcode list
1537 NULL // Default Opcode is NULl
1538 );
1539
1540 HiiCreateTextOpCode (
1541 StartOpCodeHandle,
1542 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),
1543 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),
1544 STRING_TOKEN(STR_TEXT_SAMPLE_STRING)
1545 );
1546
1547 HiiCreateDateOpCode (
1548 StartOpCodeHandle,
1549 0x8004,
1550 0x0,
1551 0x0,
1552 STRING_TOKEN(STR_DATE_SAMPLE_HELP),
1553 STRING_TOKEN(STR_DATE_SAMPLE_HELP),
1554 0,
1555 QF_DATE_STORAGE_TIME,
1556 NULL
1557 );
1558
1559 HiiCreateTimeOpCode (
1560 StartOpCodeHandle,
1561 0x8005,
1562 0x0,
1563 0x0,
1564 STRING_TOKEN(STR_TIME_SAMPLE_HELP),
1565 STRING_TOKEN(STR_TIME_SAMPLE_HELP),
1566 0,
1567 QF_TIME_STORAGE_TIME,
1568 NULL
1569 );
1570
1571 HiiCreateGotoOpCode (
1572 StartOpCodeHandle, // Container for dynamic created opcodes
1573 1, // Target Form ID
1574 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text
1575 STRING_TOKEN (STR_GOTO_HELP), // Help text
1576 0, // Question flag
1577 0x8003 // Question ID
1578 );
1579
1580 HiiUpdateForm (
1581 PrivateData->HiiHandle[0], // HII handle
1582 &gDriverSampleFormSetGuid, // Formset GUID
1583 0x1234, // Form ID
1584 StartOpCodeHandle, // Label for where to insert opcodes
1585 EndOpCodeHandle // Replace data
1586 );
1587
1588 HiiFreeOpCodeHandle (StartOpCodeHandle);
1589 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1590 HiiFreeOpCodeHandle (EndOpCodeHandle);
1591 break;
1592
1593 case 0x5678:
1594 case 0x1247:
1595 //
1596 // We will reach here once the Question is refreshed
1597 //
1598
1599 //
1600 // Initialize the container for dynamic opcodes
1601 //
1602 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1603 ASSERT (StartOpCodeHandle != NULL);
1604
1605 //
1606 // Create Hii Extend Label OpCode as the start opcode
1607 //
1608 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1609 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1610 if (QuestionId == 0x5678) {
1611 StartLabel->Number = LABEL_UPDATE2;
1612 FormId = 0x03;
1613 PrivateData->Configuration.DynamicRefresh++;
1614 } else if (QuestionId == 0x1247 ) {
1615 StartLabel->Number = LABEL_UPDATE3;
1616 FormId = 0x06;
1617 PrivateData->Configuration.RefreshGuidCount++;
1618 }
1619
1620 HiiCreateActionOpCode (
1621 StartOpCodeHandle, // Container for dynamic created opcodes
1622 0x1237, // Question ID
1623 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text
1624 STRING_TOKEN(STR_EXIT_TEXT), // Help text
1625 EFI_IFR_FLAG_CALLBACK, // Question flag
1626 0 // Action String ID
1627 );
1628
1629 HiiUpdateForm (
1630 PrivateData->HiiHandle[0], // HII handle
1631 &gDriverSampleFormSetGuid, // Formset GUID
1632 FormId, // Form ID
1633 StartOpCodeHandle, // Label for where to insert opcodes
1634 NULL // Insert data
1635 );
1636
1637 HiiFreeOpCodeHandle (StartOpCodeHandle);
1638
1639 //
1640 // Refresh the Question value
1641 //
1642 Status = gRT->SetVariable(
1643 VariableName,
1644 &gDriverSampleFormSetGuid,
1645 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1646 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1647 &PrivateData->Configuration
1648 );
1649
1650 if (QuestionId == 0x5678) {
1651 //
1652 // Update uncommitted data of Browser
1653 //
1654 EfiData = AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA));
1655 ASSERT (EfiData != NULL);
1656 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, MyEfiVar, sizeof (MY_EFI_VARSTORE_DATA), (UINT8 *) EfiData)) {
1657 EfiData->Field8 = 111;
1658 HiiSetBrowserData (
1659 &gDriverSampleFormSetGuid,
1660 MyEfiVar,
1661 sizeof (MY_EFI_VARSTORE_DATA),
1662 (UINT8 *) EfiData,
1663 NULL
1664 );
1665 }
1666 FreePool (EfiData);
1667 }
1668 break;
1669
1670 case 0x2000:
1671 //
1672 // Only used to update the state.
1673 //
1674 if ((Type == EFI_IFR_TYPE_STRING) && (Value->string == 0) &&
1675 (PrivateData->PasswordState == BROWSER_STATE_SET_PASSWORD)) {
1676 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1677 return EFI_INVALID_PARAMETER;
1678 }
1679
1680 //
1681 // When try to set a new password, user will be chanlleged with old password.
1682 // The Callback is responsible for validating old password input by user,
1683 // If Callback return EFI_SUCCESS, it indicates validation pass.
1684 //
1685 switch (PrivateData->PasswordState) {
1686 case BROWSER_STATE_VALIDATE_PASSWORD:
1687 Status = ValidatePassword (PrivateData, Value->string);
1688 if (Status == EFI_SUCCESS) {
1689 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;
1690 }
1691 break;
1692
1693 case BROWSER_STATE_SET_PASSWORD:
1694 Status = SetPassword (PrivateData, Value->string);
1695 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1696 break;
1697
1698 default:
1699 break;
1700 }
1701
1702 break;
1703
1704 default:
1705 break;
1706 }
1707 }
1708 break;
1709
1710 case EFI_BROWSER_ACTION_CHANGED:
1711 switch (QuestionId) {
1712 case 0x1237:
1713 //
1714 // User press "Exit now", request Browser to exit
1715 //
1716 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
1717 break;
1718
1719 case 0x1238:
1720 //
1721 // User press "Save now", request Browser to save the uncommitted data.
1722 //
1723 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
1724 break;
1725
1726 case 0x1241:
1727 case 0x1246:
1728 //
1729 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1730 //
1731 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1732 break;
1733
1734 case 0x1242:
1735 //
1736 // User press "Discard current form now", request Browser to discard the uncommitted data.
1737 //
1738 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD;
1739 break;
1740
1741 case 0x1243:
1742 //
1743 // User press "Submit current form now", request Browser to save the uncommitted data.
1744 //
1745 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
1746 break;
1747
1748 case 0x1244:
1749 case 0x1245:
1750 //
1751 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1752 //
1753 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1754 break;
1755
1756 default:
1757 break;
1758 }
1759 break;
1760
1761 default:
1762 Status = EFI_UNSUPPORTED;
1763 break;
1764 }
1765
1766 return Status;
1767}
1768
1769/**
1770 Main entry for this driver.
1771
1772 @param ImageHandle Image handle this driver.
1773 @param SystemTable Pointer to SystemTable.
1774
1775 @retval EFI_SUCESS This function always complete successfully.
1776
1777**/
1778EFI_STATUS
1779EFIAPI
1780DriverSampleInit (
1781 IN EFI_HANDLE ImageHandle,
1782 IN EFI_SYSTEM_TABLE *SystemTable
1783 )
1784{
1785 EFI_STATUS Status;
1786 EFI_HII_HANDLE HiiHandle[2];
1787 EFI_SCREEN_DESCRIPTOR Screen;
1788 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
1789 EFI_HII_STRING_PROTOCOL *HiiString;
1790 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
1791 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1792 CHAR16 *NewString;
1793 UINTN BufferSize;
1794 DRIVER_SAMPLE_CONFIGURATION *Configuration;
1795 BOOLEAN ActionFlag;
1796 EFI_STRING ConfigRequestHdr;
1797 MY_EFI_VARSTORE_DATA *VarStoreConfig;
1798
1799 //
1800 // Initialize the local variables.
1801 //
1802 ConfigRequestHdr = NULL;
1803 //
1804 // Initialize screen dimensions for SendForm().
1805 // Remove 3 characters from top and bottom
1806 //
1807 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));
1808 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);
1809
1810 Screen.TopRow = 3;
1811 Screen.BottomRow = Screen.BottomRow - 3;
1812
1813 //
1814 // Initialize driver private data
1815 //
1816 PrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));
1817 if (PrivateData == NULL) {
1818 return EFI_OUT_OF_RESOURCES;
1819 }
1820
1821 PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;
1822
1823 PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
1824 PrivateData->ConfigAccess.RouteConfig = RouteConfig;
1825 PrivateData->ConfigAccess.Callback = DriverCallback;
1826 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1827
1828 //
1829 // Locate Hii Database protocol
1830 //
1831 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
1832 if (EFI_ERROR (Status)) {
1833 return Status;
1834 }
1835 PrivateData->HiiDatabase = HiiDatabase;
1836
1837 //
1838 // Locate HiiString protocol
1839 //
1840 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
1841 if (EFI_ERROR (Status)) {
1842 return Status;
1843 }
1844 PrivateData->HiiString = HiiString;
1845
1846 //
1847 // Locate Formbrowser2 protocol
1848 //
1849 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
1850 if (EFI_ERROR (Status)) {
1851 return Status;
1852 }
1853 PrivateData->FormBrowser2 = FormBrowser2;
1854
1855 //
1856 // Locate ConfigRouting protocol
1857 //
1858 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
1859 if (EFI_ERROR (Status)) {
1860 return Status;
1861 }
1862 PrivateData->HiiConfigRouting = HiiConfigRouting;
1863
1864 Status = gBS->InstallMultipleProtocolInterfaces (
1865 &DriverHandle[0],
1866 &gEfiDevicePathProtocolGuid,
1867 &mHiiVendorDevicePath0,
1868 &gEfiHiiConfigAccessProtocolGuid,
1869 &PrivateData->ConfigAccess,
1870 NULL
1871 );
1872 ASSERT_EFI_ERROR (Status);
1873
1874 PrivateData->DriverHandle[0] = DriverHandle[0];
1875
1876 //
1877 // Publish our HII data
1878 //
1879 HiiHandle[0] = HiiAddPackages (
1880 &gDriverSampleFormSetGuid,
1881 DriverHandle[0],
1882 DriverSampleStrings,
1883 VfrBin,
1884 NULL
1885 );
1886 if (HiiHandle[0] == NULL) {
1887 return EFI_OUT_OF_RESOURCES;
1888 }
1889
1890 PrivateData->HiiHandle[0] = HiiHandle[0];
1891
1892 //
1893 // Publish another Fromset
1894 //
1895 Status = gBS->InstallMultipleProtocolInterfaces (
1896 &DriverHandle[1],
1897 &gEfiDevicePathProtocolGuid,
1898 &mHiiVendorDevicePath1,
1899 NULL
1900 );
1901 ASSERT_EFI_ERROR (Status);
1902
1903 PrivateData->DriverHandle[1] = DriverHandle[1];
1904
1905 HiiHandle[1] = HiiAddPackages (
1906 &gDriverSampleInventoryGuid,
1907 DriverHandle[1],
1908 DriverSampleStrings,
1909 InventoryBin,
1910 NULL
1911 );
1912 if (HiiHandle[1] == NULL) {
1913 DriverSampleUnload (ImageHandle);
1914 return EFI_OUT_OF_RESOURCES;
1915 }
1916
1917 PrivateData->HiiHandle[1] = HiiHandle[1];
1918
1919 //
1920 // Update the device path string.
1921 //
1922 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_DEVICE_PATH), (EFI_STRING) &mHiiVendorDevicePath0, NULL) == 0) {
1923 DriverSampleUnload (ImageHandle);
1924 return EFI_OUT_OF_RESOURCES;
1925 }
1926
1927 //
1928 // Very simple example of how one would update a string that is already
1929 // in the HII database
1930 //
1931 NewString = L"700 Mhz";
1932
1933 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {
1934 DriverSampleUnload (ImageHandle);
1935 return EFI_OUT_OF_RESOURCES;
1936 }
1937
1938 HiiSetString (HiiHandle[0], 0, NewString, NULL);
1939
1940 //
1941 // Initialize Name/Value name String ID
1942 //
1943 PrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0;
1944 PrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1;
1945 PrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2;
1946
1947 //
1948 // Initialize configuration data
1949 //
1950 Configuration = &PrivateData->Configuration;
1951 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));
1952
1953 //
1954 // Try to read NV config EFI variable first
1955 //
1956 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]);
1957 ASSERT (ConfigRequestHdr != NULL);
1958
1959 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1960 Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration);
1961 if (EFI_ERROR (Status)) {
1962 //
1963 // Store zero data Buffer Storage to EFI variable
1964 //
1965 Status = gRT->SetVariable(
1966 VariableName,
1967 &gDriverSampleFormSetGuid,
1968 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1969 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1970 Configuration
1971 );
1972 ASSERT (Status == EFI_SUCCESS);
1973 //
1974 // EFI variable for NV config doesn't exit, we should build this variable
1975 // based on default values stored in IFR
1976 //
1977 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
1978 ASSERT (ActionFlag);
1979 } else {
1980 //
1981 // EFI variable does exist and Validate Current Setting
1982 //
1983 ActionFlag = HiiValidateSettings (ConfigRequestHdr);
1984 ASSERT (ActionFlag);
1985 }
1986 FreePool (ConfigRequestHdr);
1987
1988 //
1989 // Initialize efi varstore configuration data
1990 //
1991 VarStoreConfig = &PrivateData->VarStoreConfig;
1992 ZeroMem (VarStoreConfig, sizeof (MY_EFI_VARSTORE_DATA));
1993
1994 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiVar, DriverHandle[0]);
1995 ASSERT (ConfigRequestHdr != NULL);
1996
1997 BufferSize = sizeof (MY_EFI_VARSTORE_DATA);
1998 Status = gRT->GetVariable (MyEfiVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, VarStoreConfig);
1999 if (EFI_ERROR (Status)) {
2000 //
2001 // Store zero data to EFI variable Storage.
2002 //
2003 Status = gRT->SetVariable(
2004 MyEfiVar,
2005 &gDriverSampleFormSetGuid,
2006 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
2007 sizeof (MY_EFI_VARSTORE_DATA),
2008 VarStoreConfig
2009 );
2010 ASSERT (Status == EFI_SUCCESS);
2011 //
2012 // EFI variable for NV config doesn't exit, we should build this variable
2013 // based on default values stored in IFR
2014 //
2015 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
2016 ASSERT (ActionFlag);
2017 } else {
2018 //
2019 // EFI variable does exist and Validate Current Setting
2020 //
2021 ActionFlag = HiiValidateSettings (ConfigRequestHdr);
2022 ASSERT (ActionFlag);
2023 }
2024 FreePool (ConfigRequestHdr);
2025
2026 Status = gBS->CreateEventEx (
2027 EVT_NOTIFY_SIGNAL,
2028 TPL_NOTIFY,
2029 DriverSampleInternalEmptyFunction,
2030 NULL,
2031 &gEfiIfrRefreshIdOpGuid,
2032 &mEvent
2033 );
2034 ASSERT_EFI_ERROR (Status);
2035 //
2036 // In default, this driver is built into Flash device image,
2037 // the following code doesn't run.
2038 //
2039
2040 //
2041 // Example of how to display only the item we sent to HII
2042 // When this driver is not built into Flash device image,
2043 // it need to call SendForm to show front page by itself.
2044 //
2045 if (DISPLAY_ONLY_MY_ITEM <= 1) {
2046 //
2047 // Have the browser pull out our copy of the data, and only display our data
2048 //
2049 Status = FormBrowser2->SendForm (
2050 FormBrowser2,
2051 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),
2052 1,
2053 NULL,
2054 0,
2055 NULL,
2056 NULL
2057 );
2058
2059 HiiRemovePackages (HiiHandle[0]);
2060
2061 HiiRemovePackages (HiiHandle[1]);
2062 }
2063
2064 return EFI_SUCCESS;
2065}
2066
2067/**
2068 Unloads the application and its installed protocol.
2069
2070 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2071
2072 @retval EFI_SUCCESS The image has been unloaded.
2073**/
2074EFI_STATUS
2075EFIAPI
2076DriverSampleUnload (
2077 IN EFI_HANDLE ImageHandle
2078 )
2079{
2080 UINTN Index;
2081
2082 ASSERT (PrivateData != NULL);
2083
2084 if (DriverHandle[0] != NULL) {
2085 gBS->UninstallMultipleProtocolInterfaces (
2086 DriverHandle[0],
2087 &gEfiDevicePathProtocolGuid,
2088 &mHiiVendorDevicePath0,
2089 &gEfiHiiConfigAccessProtocolGuid,
2090 &PrivateData->ConfigAccess,
2091 NULL
2092 );
2093 DriverHandle[0] = NULL;
2094 }
2095
2096 if (DriverHandle[1] != NULL) {
2097 gBS->UninstallMultipleProtocolInterfaces (
2098 DriverHandle[1],
2099 &gEfiDevicePathProtocolGuid,
2100 &mHiiVendorDevicePath1,
2101 NULL
2102 );
2103 DriverHandle[1] = NULL;
2104 }
2105
2106 if (PrivateData->HiiHandle[0] != NULL) {
2107 HiiRemovePackages (PrivateData->HiiHandle[0]);
2108 }
2109
2110 if (PrivateData->HiiHandle[1] != NULL) {
2111 HiiRemovePackages (PrivateData->HiiHandle[1]);
2112 }
2113
2114 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {
2115 if (PrivateData->NameValueName[Index] != NULL) {
2116 FreePool (PrivateData->NameValueName[Index]);
2117 }
2118 }
2119 FreePool (PrivateData);
2120 PrivateData = NULL;
2121
2122 gBS->CloseEvent (mEvent);
2123
2124 return EFI_SUCCESS;
2125}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette