VirtualBox

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

Last change on this file since 67912 was 58466, checked in by vboxsync, 9 years ago

EFI/Firmware: Merged in the svn:eol-style, svn:mime-type and trailing whitespace cleanup that was done after the initial UDK2014.SP1 import: svn merge /vendor/edk2/UDK2014.SP1 /vendor/edk2/current .

  • Property svn:eol-style set to native
File size: 64.8 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 - 2014, 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;
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 TmpBuffer = NULL;
675 StringPtr = *RequestResult;
676 StringPtr = StrStr (StringPtr, L"OFFSET");
677 BlockSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
678 ValueOffset = OFFSET_OF (DRIVER_SAMPLE_CONFIGURATION, GetDefaultValueFromAccess);
679 ValueWidth = sizeof (((DRIVER_SAMPLE_CONFIGURATION *)0)->GetDefaultValueFromAccess);
680
681 if (StringPtr == NULL) {
682 return;
683 }
684
685 while (*StringPtr != 0 && StrnCmp (StringPtr, L"OFFSET=", StrLen (L"OFFSET=")) == 0) {
686 StringPtr += StrLen (L"OFFSET=");
687 //
688 // Get Offset
689 //
690 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
691 if (EFI_ERROR (Status)) {
692 return;
693 }
694 Offset = 0;
695 CopyMem (
696 &Offset,
697 TmpBuffer,
698 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
699 );
700 FreePool (TmpBuffer);
701
702 StringPtr += Length;
703 if (StrnCmp (StringPtr, L"&WIDTH=", StrLen (L"&WIDTH=")) != 0) {
704 return;
705 }
706 StringPtr += StrLen (L"&WIDTH=");
707
708 //
709 // Get Width
710 //
711 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
712 if (EFI_ERROR (Status)) {
713 return;
714 }
715 Width = 0;
716 CopyMem (
717 &Width,
718 TmpBuffer,
719 (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
720 );
721 FreePool (TmpBuffer);
722
723 StringPtr += Length;
724 if (StrnCmp (StringPtr, L"&VALUE=", StrLen (L"&VALUE=")) != 0) {
725 return;
726 }
727 StringPtr += StrLen (L"&VALUE=");
728
729 //
730 // Get Value
731 //
732 Status = GetValueOfNumber (StringPtr, &TmpBuffer, &Length);
733 if (EFI_ERROR (Status)) {
734 return;
735 }
736 StringPtr += Length;
737
738 //
739 // Calculate Value and convert it to hex string.
740 //
741 if (Offset + Width > BlockSize) {
742 return;
743 }
744
745 if (Offset <= ValueOffset && Offset + Width >= ValueOffset + ValueWidth) {
746 *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth);
747 return;
748 }
749 }
750}
751
752/**
753 This function allows a caller to extract the current configuration for one
754 or more named elements from the target driver.
755
756 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
757 @param Request A null-terminated Unicode string in
758 <ConfigRequest> format.
759 @param Progress On return, points to a character in the Request
760 string. Points to the string's null terminator if
761 request was successful. Points to the most recent
762 '&' before the first failing name/value pair (or
763 the beginning of the string if the failure is in
764 the first name/value pair) if the request was not
765 successful.
766 @param Results A null-terminated Unicode string in
767 <ConfigAltResp> format which has all values filled
768 in for the names in the Request string. String to
769 be allocated by the called function.
770
771 @retval EFI_SUCCESS The Results is filled with the requested values.
772 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
773 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
774 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
775 driver.
776
777**/
778EFI_STATUS
779EFIAPI
780ExtractConfig (
781 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
782 IN CONST EFI_STRING Request,
783 OUT EFI_STRING *Progress,
784 OUT EFI_STRING *Results
785 )
786{
787 EFI_STATUS Status;
788 UINTN BufferSize;
789 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
790 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
791 EFI_STRING ConfigRequest;
792 EFI_STRING ConfigRequestHdr;
793 UINTN Size;
794 EFI_STRING Value;
795 UINTN ValueStrLen;
796 CHAR16 BackupChar;
797 CHAR16 *StrPointer;
798 BOOLEAN AllocatedRequest;
799
800 if (Progress == NULL || Results == NULL) {
801 return EFI_INVALID_PARAMETER;
802 }
803 //
804 // Initialize the local variables.
805 //
806 ConfigRequestHdr = NULL;
807 ConfigRequest = NULL;
808 Size = 0;
809 *Progress = Request;
810 AllocatedRequest = FALSE;
811
812 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
813 HiiConfigRouting = PrivateData->HiiConfigRouting;
814
815 //
816 // Get Buffer Storage data from EFI variable.
817 // Try to get the current setting from variable.
818 //
819 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
820 Status = gRT->GetVariable (
821 VariableName,
822 &gDriverSampleFormSetGuid,
823 NULL,
824 &BufferSize,
825 &PrivateData->Configuration
826 );
827 if (EFI_ERROR (Status)) {
828 return EFI_NOT_FOUND;
829 }
830
831 if (Request == NULL) {
832 //
833 // Request is set to NULL, construct full request string.
834 //
835
836 //
837 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
838 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
839 //
840 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);
841 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
842 ConfigRequest = AllocateZeroPool (Size);
843 ASSERT (ConfigRequest != NULL);
844 AllocatedRequest = TRUE;
845 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
846 FreePool (ConfigRequestHdr);
847 ConfigRequestHdr = NULL;
848 } else {
849 //
850 // Check routing data in <ConfigHdr>.
851 // Note: if only one Storage is used, then this checking could be skipped.
852 //
853 if (!HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, NULL)) {
854 return EFI_NOT_FOUND;
855 }
856 //
857 // Check whether request for EFI Varstore. EFI varstore get data
858 // through hii database, not support in this path.
859 //
860 if (HiiIsConfigHdrMatch(Request, &gDriverSampleFormSetGuid, MyEfiVar)) {
861 return EFI_UNSUPPORTED;
862 }
863 //
864 // Set Request to the unified request string.
865 //
866 ConfigRequest = Request;
867 //
868 // Check whether Request includes Request Element.
869 //
870 if (StrStr (Request, L"OFFSET") == NULL) {
871 //
872 // Check Request Element does exist in Reques String
873 //
874 StrPointer = StrStr (Request, L"PATH");
875 if (StrPointer == NULL) {
876 return EFI_INVALID_PARAMETER;
877 }
878 if (StrStr (StrPointer, L"&") == NULL) {
879 Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
880 ConfigRequest = AllocateZeroPool (Size);
881 ASSERT (ConfigRequest != NULL);
882 AllocatedRequest = TRUE;
883 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);
884 }
885 }
886 }
887
888 //
889 // Check if requesting Name/Value storage
890 //
891 if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
892 //
893 // Update Name/Value storage Names
894 //
895 Status = LoadNameValueNames (PrivateData);
896 if (EFI_ERROR (Status)) {
897 return Status;
898 }
899
900 //
901 // Allocate memory for <ConfigResp>, e.g. Name0=0x11, Name1=0x1234, Name2="ABCD"
902 // <Request> ::=<ConfigHdr>&Name0&Name1&Name2
903 // <ConfigResp>::=<ConfigHdr>&Name0=11&Name1=1234&Name2=0041004200430044
904 //
905 BufferSize = (StrLen (ConfigRequest) +
906 1 + sizeof (PrivateData->Configuration.NameValueVar0) * 2 +
907 1 + sizeof (PrivateData->Configuration.NameValueVar1) * 2 +
908 1 + sizeof (PrivateData->Configuration.NameValueVar2) * 2 + 1) * sizeof (CHAR16);
909 *Results = AllocateZeroPool (BufferSize);
910 ASSERT (*Results != NULL);
911 StrCpy (*Results, ConfigRequest);
912 Value = *Results;
913
914 //
915 // Append value of NameValueVar0, type is UINT8
916 //
917 if ((Value = StrStr (*Results, PrivateData->NameValueName[0])) != NULL) {
918 Value += StrLen (PrivateData->NameValueName[0]);
919 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar0) * 2) + 1);
920 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
921
922 BackupChar = Value[ValueStrLen];
923 *Value++ = L'=';
924 Value += UnicodeValueToString (
925 Value,
926 PREFIX_ZERO | RADIX_HEX,
927 PrivateData->Configuration.NameValueVar0,
928 sizeof (PrivateData->Configuration.NameValueVar0) * 2
929 );
930 *Value = BackupChar;
931 }
932
933 //
934 // Append value of NameValueVar1, type is UINT16
935 //
936 if ((Value = StrStr (*Results, PrivateData->NameValueName[1])) != NULL) {
937 Value += StrLen (PrivateData->NameValueName[1]);
938 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar1) * 2) + 1);
939 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
940
941 BackupChar = Value[ValueStrLen];
942 *Value++ = L'=';
943 Value += UnicodeValueToString (
944 Value,
945 PREFIX_ZERO | RADIX_HEX,
946 PrivateData->Configuration.NameValueVar1,
947 sizeof (PrivateData->Configuration.NameValueVar1) * 2
948 );
949 *Value = BackupChar;
950 }
951
952 //
953 // Append value of NameValueVar2, type is CHAR16 *
954 //
955 if ((Value = StrStr (*Results, PrivateData->NameValueName[2])) != NULL) {
956 Value += StrLen (PrivateData->NameValueName[2]);
957 ValueStrLen = StrLen (PrivateData->Configuration.NameValueVar2) * 4 + 1;
958 CopyMem (Value + ValueStrLen, Value, StrSize (Value));
959
960 *Value++ = L'=';
961 //
962 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"
963 //
964 StrPointer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;
965 for (; *StrPointer != L'\0'; StrPointer++) {
966 Value += UnicodeValueToString (Value, PREFIX_ZERO | RADIX_HEX, *StrPointer, 4);
967 }
968 }
969
970 Status = EFI_SUCCESS;
971 } else {
972 //
973 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
974 //
975 Status = HiiConfigRouting->BlockToConfig (
976 HiiConfigRouting,
977 ConfigRequest,
978 (UINT8 *) &PrivateData->Configuration,
979 BufferSize,
980 Results,
981 Progress
982 );
983 if (!EFI_ERROR (Status)) {
984 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);
985 AppendAltCfgString(Results, ConfigRequestHdr);
986 }
987 }
988
989 //
990 // Free the allocated config request string.
991 //
992 if (AllocatedRequest) {
993 FreePool (ConfigRequest);
994 }
995
996 if (ConfigRequestHdr != NULL) {
997 FreePool (ConfigRequestHdr);
998 }
999 //
1000 // Set Progress string to the original request string.
1001 //
1002 if (Request == NULL) {
1003 *Progress = NULL;
1004 } else if (StrStr (Request, L"OFFSET") == NULL) {
1005 *Progress = Request + StrLen (Request);
1006 }
1007
1008 return Status;
1009}
1010
1011
1012/**
1013 This function processes the results of changes in configuration.
1014
1015 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1016 @param Configuration A null-terminated Unicode string in <ConfigResp>
1017 format.
1018 @param Progress A pointer to a string filled in with the offset of
1019 the most recent '&' before the first failing
1020 name/value pair (or the beginning of the string if
1021 the failure is in the first name/value pair) or
1022 the terminating NULL if all was successful.
1023
1024 @retval EFI_SUCCESS The Results is processed successfully.
1025 @retval EFI_INVALID_PARAMETER Configuration is NULL.
1026 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
1027 driver.
1028
1029**/
1030EFI_STATUS
1031EFIAPI
1032RouteConfig (
1033 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1034 IN CONST EFI_STRING Configuration,
1035 OUT EFI_STRING *Progress
1036 )
1037{
1038 EFI_STATUS Status;
1039 UINTN BufferSize;
1040 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
1041 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1042 CHAR16 *Value;
1043 CHAR16 *StrPtr;
1044 CHAR16 TemStr[5];
1045 UINT8 *DataBuffer;
1046 UINT8 DigitUint8;
1047 UINTN Index;
1048 CHAR16 *StrBuffer;
1049
1050 if (Configuration == NULL || Progress == NULL) {
1051 return EFI_INVALID_PARAMETER;
1052 }
1053
1054 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1055 HiiConfigRouting = PrivateData->HiiConfigRouting;
1056 *Progress = Configuration;
1057
1058 //
1059 // Check routing data in <ConfigHdr>.
1060 // Note: if only one Storage is used, then this checking could be skipped.
1061 //
1062 if (!HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, NULL)) {
1063 return EFI_NOT_FOUND;
1064 }
1065
1066 //
1067 // Check whether request for EFI Varstore. EFI varstore get data
1068 // through hii database, not support in this path.
1069 //
1070 if (HiiIsConfigHdrMatch(Configuration, &gDriverSampleFormSetGuid, MyEfiVar)) {
1071 return EFI_UNSUPPORTED;
1072 }
1073
1074 //
1075 // Get Buffer Storage data from EFI variable
1076 //
1077 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1078 Status = gRT->GetVariable (
1079 VariableName,
1080 &gDriverSampleFormSetGuid,
1081 NULL,
1082 &BufferSize,
1083 &PrivateData->Configuration
1084 );
1085 if (EFI_ERROR (Status)) {
1086 return Status;
1087 }
1088
1089 //
1090 // Check if configuring Name/Value storage
1091 //
1092 if (StrStr (Configuration, L"OFFSET") == NULL) {
1093 //
1094 // Update Name/Value storage Names
1095 //
1096 Status = LoadNameValueNames (PrivateData);
1097 if (EFI_ERROR (Status)) {
1098 return Status;
1099 }
1100
1101 //
1102 // Convert value for NameValueVar0
1103 //
1104 if ((Value = StrStr (Configuration, PrivateData->NameValueName[0])) != NULL) {
1105 //
1106 // Skip "Name="
1107 //
1108 Value += StrLen (PrivateData->NameValueName[0]);
1109 Value++;
1110 //
1111 // Get Value String
1112 //
1113 StrPtr = StrStr (Value, L"&");
1114 if (StrPtr == NULL) {
1115 StrPtr = Value + StrLen (Value);
1116 }
1117 //
1118 // Convert Value to Buffer data
1119 //
1120 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar0;
1121 ZeroMem (TemStr, sizeof (TemStr));
1122 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {
1123 TemStr[0] = *StrPtr;
1124 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
1125 if ((Index & 1) == 0) {
1126 DataBuffer [Index/2] = DigitUint8;
1127 } else {
1128 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);
1129 }
1130 }
1131 }
1132
1133 //
1134 // Convert value for NameValueVar1
1135 //
1136 if ((Value = StrStr (Configuration, PrivateData->NameValueName[1])) != NULL) {
1137 //
1138 // Skip "Name="
1139 //
1140 Value += StrLen (PrivateData->NameValueName[1]);
1141 Value++;
1142 //
1143 // Get Value String
1144 //
1145 StrPtr = StrStr (Value, L"&");
1146 if (StrPtr == NULL) {
1147 StrPtr = Value + StrLen (Value);
1148 }
1149 //
1150 // Convert Value to Buffer data
1151 //
1152 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar1;
1153 ZeroMem (TemStr, sizeof (TemStr));
1154 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {
1155 TemStr[0] = *StrPtr;
1156 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);
1157 if ((Index & 1) == 0) {
1158 DataBuffer [Index/2] = DigitUint8;
1159 } else {
1160 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);
1161 }
1162 }
1163 }
1164
1165 //
1166 // Convert value for NameValueVar2
1167 //
1168 if ((Value = StrStr (Configuration, PrivateData->NameValueName[2])) != NULL) {
1169 //
1170 // Skip "Name="
1171 //
1172 Value += StrLen (PrivateData->NameValueName[2]);
1173 Value++;
1174 //
1175 // Get Value String
1176 //
1177 StrPtr = StrStr (Value, L"&");
1178 if (StrPtr == NULL) {
1179 StrPtr = Value + StrLen (Value);
1180 }
1181 //
1182 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"
1183 //
1184 StrBuffer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;
1185 ZeroMem (TemStr, sizeof (TemStr));
1186 while (Value < StrPtr) {
1187 StrnCpy (TemStr, Value, 4);
1188 *(StrBuffer++) = (CHAR16) StrHexToUint64 (TemStr);
1189 Value += 4;
1190 }
1191 *StrBuffer = L'\0';
1192 }
1193
1194 //
1195 // Store Buffer Storage back to EFI variable
1196 //
1197 Status = gRT->SetVariable(
1198 VariableName,
1199 &gDriverSampleFormSetGuid,
1200 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1201 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1202 &PrivateData->Configuration
1203 );
1204
1205 return Status;
1206 }
1207
1208 //
1209 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
1210 //
1211 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1212 Status = HiiConfigRouting->ConfigToBlock (
1213 HiiConfigRouting,
1214 Configuration,
1215 (UINT8 *) &PrivateData->Configuration,
1216 &BufferSize,
1217 Progress
1218 );
1219 if (EFI_ERROR (Status)) {
1220 return Status;
1221 }
1222
1223 //
1224 // Store Buffer Storage back to EFI variable
1225 //
1226 Status = gRT->SetVariable(
1227 VariableName,
1228 &gDriverSampleFormSetGuid,
1229 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1230 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1231 &PrivateData->Configuration
1232 );
1233
1234 return Status;
1235}
1236
1237
1238/**
1239 This function processes the results of changes in configuration.
1240
1241 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1242 @param Action Specifies the type of action taken by the browser.
1243 @param QuestionId A unique value which is sent to the original
1244 exporting driver so that it can identify the type
1245 of data to expect.
1246 @param Type The type of value for the question.
1247 @param Value A pointer to the data being sent to the original
1248 exporting driver.
1249 @param ActionRequest On return, points to the action requested by the
1250 callback function.
1251
1252 @retval EFI_SUCCESS The callback successfully handled the action.
1253 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1254 variable and its data.
1255 @retval EFI_DEVICE_ERROR The variable could not be saved.
1256 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1257 callback.
1258
1259**/
1260EFI_STATUS
1261EFIAPI
1262DriverCallback (
1263 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1264 IN EFI_BROWSER_ACTION Action,
1265 IN EFI_QUESTION_ID QuestionId,
1266 IN UINT8 Type,
1267 IN EFI_IFR_TYPE_VALUE *Value,
1268 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1269 )
1270{
1271 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;
1272 EFI_STATUS Status;
1273 VOID *StartOpCodeHandle;
1274 VOID *OptionsOpCodeHandle;
1275 EFI_IFR_GUID_LABEL *StartLabel;
1276 VOID *EndOpCodeHandle;
1277 EFI_IFR_GUID_LABEL *EndLabel;
1278 EFI_INPUT_KEY Key;
1279 DRIVER_SAMPLE_CONFIGURATION *Configuration;
1280 MY_EFI_VARSTORE_DATA *EfiData;
1281 EFI_FORM_ID FormId;
1282
1283 if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||
1284 (ActionRequest == NULL)) {
1285 return EFI_INVALID_PARAMETER;
1286 }
1287
1288
1289 FormId = 0;
1290 Status = EFI_SUCCESS;
1291 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1292
1293 switch (Action) {
1294 case EFI_BROWSER_ACTION_FORM_OPEN:
1295 {
1296 if (QuestionId == 0x1234) {
1297 //
1298 // Sample CallBack for UEFI FORM_OPEN action:
1299 // Add Save action into Form 3 when Form 1 is opened.
1300 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.
1301 //
1302 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);
1303
1304 //
1305 // Initialize the container for dynamic opcodes
1306 //
1307 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1308 ASSERT (StartOpCodeHandle != NULL);
1309
1310 //
1311 // Create Hii Extend Label OpCode as the start opcode
1312 //
1313 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1314 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1315 StartLabel->Number = LABEL_UPDATE2;
1316
1317 HiiCreateActionOpCode (
1318 StartOpCodeHandle, // Container for dynamic created opcodes
1319 0x1238, // Question ID
1320 STRING_TOKEN(STR_SAVE_TEXT), // Prompt text
1321 STRING_TOKEN(STR_SAVE_TEXT), // Help text
1322 EFI_IFR_FLAG_CALLBACK, // Question flag
1323 0 // Action String ID
1324 );
1325
1326 HiiUpdateForm (
1327 PrivateData->HiiHandle[0], // HII handle
1328 &gDriverSampleFormSetGuid, // Formset GUID
1329 0x3, // Form ID
1330 StartOpCodeHandle, // Label for where to insert opcodes
1331 NULL // Insert data
1332 );
1333
1334 HiiFreeOpCodeHandle (StartOpCodeHandle);
1335 }
1336
1337 if (QuestionId == 0x1247) {
1338 Status = InternalStartMonitor ();
1339 ASSERT_EFI_ERROR (Status);
1340 }
1341 }
1342 break;
1343
1344 case EFI_BROWSER_ACTION_FORM_CLOSE:
1345 {
1346 if (QuestionId == 0x5678) {
1347 //
1348 // Sample CallBack for UEFI FORM_CLOSE action:
1349 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.
1350 //
1351 do {
1352 CreatePopUp (
1353 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1354 &Key,
1355 L"",
1356 L"You are going to leave third Form!",
1357 L"Press ESC or ENTER to continue ...",
1358 L"",
1359 NULL
1360 );
1361 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));
1362 }
1363
1364 if (QuestionId == 0x1247) {
1365 Status = InternalStopMonitor ();
1366 ASSERT_EFI_ERROR (Status);
1367 }
1368 }
1369 break;
1370
1371 case EFI_BROWSER_ACTION_RETRIEVE:
1372 {
1373 if (QuestionId == 0x1248) {
1374 {
1375 if (Type != EFI_IFR_TYPE_REF) {
1376 return EFI_INVALID_PARAMETER;
1377 }
1378
1379 Value->ref.FormId = 0x3;
1380 }
1381 }
1382 }
1383 break;
1384
1385 case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
1386 {
1387 switch (QuestionId) {
1388 case 0x1240:
1389 Value->u8 = DEFAULT_CLASS_STANDARD_VALUE;
1390 break;
1391
1392 default:
1393 Status = EFI_UNSUPPORTED;
1394 break;
1395 }
1396 }
1397 break;
1398
1399 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
1400 {
1401 switch (QuestionId) {
1402 case 0x1240:
1403 Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE;
1404 break;
1405
1406 default:
1407 Status = EFI_UNSUPPORTED;
1408 break;
1409 }
1410 }
1411 break;
1412
1413 case EFI_BROWSER_ACTION_CHANGING:
1414 {
1415 switch (QuestionId) {
1416 case 0x1249:
1417 {
1418 if (Type != EFI_IFR_TYPE_REF) {
1419 return EFI_INVALID_PARAMETER;
1420 }
1421
1422 Value->ref.FormId = 0x1234;
1423 }
1424 break;
1425 case 0x1234:
1426 //
1427 // Initialize the container for dynamic opcodes
1428 //
1429 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1430 ASSERT (StartOpCodeHandle != NULL);
1431
1432 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
1433 ASSERT (EndOpCodeHandle != NULL);
1434
1435 //
1436 // Create Hii Extend Label OpCode as the start opcode
1437 //
1438 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1439 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1440 StartLabel->Number = LABEL_UPDATE1;
1441
1442 //
1443 // Create Hii Extend Label OpCode as the end opcode
1444 //
1445 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1446 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1447 EndLabel->Number = LABEL_END;
1448
1449 HiiCreateActionOpCode (
1450 StartOpCodeHandle, // Container for dynamic created opcodes
1451 0x1237, // Question ID
1452 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text
1453 STRING_TOKEN(STR_EXIT_TEXT), // Help text
1454 EFI_IFR_FLAG_CALLBACK, // Question flag
1455 0 // Action String ID
1456 );
1457
1458 //
1459 // Create Option OpCode
1460 //
1461 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
1462 ASSERT (OptionsOpCodeHandle != NULL);
1463
1464 HiiCreateOneOfOptionOpCode (
1465 OptionsOpCodeHandle,
1466 STRING_TOKEN (STR_BOOT_OPTION1),
1467 0,
1468 EFI_IFR_NUMERIC_SIZE_1,
1469 1
1470 );
1471
1472 HiiCreateOneOfOptionOpCode (
1473 OptionsOpCodeHandle,
1474 STRING_TOKEN (STR_BOOT_OPTION2),
1475 0,
1476 EFI_IFR_NUMERIC_SIZE_1,
1477 2
1478 );
1479
1480 //
1481 // Prepare initial value for the dynamic created oneof Question
1482 //
1483 PrivateData->Configuration.DynamicOneof = 2;
1484 Status = gRT->SetVariable(
1485 VariableName,
1486 &gDriverSampleFormSetGuid,
1487 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1488 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1489 &PrivateData->Configuration
1490 );
1491
1492 //
1493 // Set initial vlaue of dynamic created oneof Question in Form Browser
1494 //
1495 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));
1496 ASSERT (Configuration != NULL);
1497 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) {
1498 Configuration->DynamicOneof = 2;
1499
1500 //
1501 // Update uncommitted data of Browser
1502 //
1503 HiiSetBrowserData (
1504 &gDriverSampleFormSetGuid,
1505 VariableName,
1506 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1507 (UINT8 *) Configuration,
1508 NULL
1509 );
1510 }
1511 FreePool (Configuration);
1512
1513 HiiCreateOneOfOpCode (
1514 StartOpCodeHandle, // Container for dynamic created opcodes
1515 0x8001, // Question ID (or call it "key")
1516 CONFIGURATION_VARSTORE_ID, // VarStore ID
1517 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage
1518 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text
1519 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text
1520 EFI_IFR_FLAG_CALLBACK, // Question flag
1521 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value
1522 OptionsOpCodeHandle, // Option Opcode list
1523 NULL // Default Opcode is NULl
1524 );
1525
1526 HiiCreateOrderedListOpCode (
1527 StartOpCodeHandle, // Container for dynamic created opcodes
1528 0x8002, // Question ID
1529 CONFIGURATION_VARSTORE_ID, // VarStore ID
1530 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage
1531 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text
1532 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text
1533 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
1534 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
1535 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value
1536 5, // Maximum container
1537 OptionsOpCodeHandle, // Option Opcode list
1538 NULL // Default Opcode is NULl
1539 );
1540
1541 HiiCreateTextOpCode (
1542 StartOpCodeHandle,
1543 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),
1544 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),
1545 STRING_TOKEN(STR_TEXT_SAMPLE_STRING)
1546 );
1547
1548 HiiCreateDateOpCode (
1549 StartOpCodeHandle,
1550 0x8004,
1551 0x0,
1552 0x0,
1553 STRING_TOKEN(STR_DATE_SAMPLE_HELP),
1554 STRING_TOKEN(STR_DATE_SAMPLE_HELP),
1555 0,
1556 QF_DATE_STORAGE_TIME,
1557 NULL
1558 );
1559
1560 HiiCreateTimeOpCode (
1561 StartOpCodeHandle,
1562 0x8005,
1563 0x0,
1564 0x0,
1565 STRING_TOKEN(STR_TIME_SAMPLE_HELP),
1566 STRING_TOKEN(STR_TIME_SAMPLE_HELP),
1567 0,
1568 QF_TIME_STORAGE_TIME,
1569 NULL
1570 );
1571
1572 HiiCreateGotoOpCode (
1573 StartOpCodeHandle, // Container for dynamic created opcodes
1574 1, // Target Form ID
1575 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text
1576 STRING_TOKEN (STR_GOTO_HELP), // Help text
1577 0, // Question flag
1578 0x8003 // Question ID
1579 );
1580
1581 HiiUpdateForm (
1582 PrivateData->HiiHandle[0], // HII handle
1583 &gDriverSampleFormSetGuid, // Formset GUID
1584 0x1234, // Form ID
1585 StartOpCodeHandle, // Label for where to insert opcodes
1586 EndOpCodeHandle // Replace data
1587 );
1588
1589 HiiFreeOpCodeHandle (StartOpCodeHandle);
1590 HiiFreeOpCodeHandle (OptionsOpCodeHandle);
1591 HiiFreeOpCodeHandle (EndOpCodeHandle);
1592 break;
1593
1594 case 0x5678:
1595 case 0x1247:
1596 //
1597 // We will reach here once the Question is refreshed
1598 //
1599
1600 //
1601 // Initialize the container for dynamic opcodes
1602 //
1603 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1604 ASSERT (StartOpCodeHandle != NULL);
1605
1606 //
1607 // Create Hii Extend Label OpCode as the start opcode
1608 //
1609 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1610 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1611 if (QuestionId == 0x5678) {
1612 StartLabel->Number = LABEL_UPDATE2;
1613 FormId = 0x03;
1614 PrivateData->Configuration.DynamicRefresh++;
1615 } else if (QuestionId == 0x1247 ) {
1616 StartLabel->Number = LABEL_UPDATE3;
1617 FormId = 0x06;
1618 PrivateData->Configuration.RefreshGuidCount++;
1619 }
1620
1621 HiiCreateActionOpCode (
1622 StartOpCodeHandle, // Container for dynamic created opcodes
1623 0x1237, // Question ID
1624 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text
1625 STRING_TOKEN(STR_EXIT_TEXT), // Help text
1626 EFI_IFR_FLAG_CALLBACK, // Question flag
1627 0 // Action String ID
1628 );
1629
1630 HiiUpdateForm (
1631 PrivateData->HiiHandle[0], // HII handle
1632 &gDriverSampleFormSetGuid, // Formset GUID
1633 FormId, // Form ID
1634 StartOpCodeHandle, // Label for where to insert opcodes
1635 NULL // Insert data
1636 );
1637
1638 HiiFreeOpCodeHandle (StartOpCodeHandle);
1639
1640 //
1641 // Refresh the Question value
1642 //
1643 Status = gRT->SetVariable(
1644 VariableName,
1645 &gDriverSampleFormSetGuid,
1646 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1647 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1648 &PrivateData->Configuration
1649 );
1650
1651 if (QuestionId == 0x5678) {
1652 //
1653 // Update uncommitted data of Browser
1654 //
1655 EfiData = AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA));
1656 ASSERT (EfiData != NULL);
1657 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, MyEfiVar, sizeof (MY_EFI_VARSTORE_DATA), (UINT8 *) EfiData)) {
1658 EfiData->Field8 = 111;
1659 HiiSetBrowserData (
1660 &gDriverSampleFormSetGuid,
1661 MyEfiVar,
1662 sizeof (MY_EFI_VARSTORE_DATA),
1663 (UINT8 *) EfiData,
1664 NULL
1665 );
1666 }
1667 FreePool (EfiData);
1668 }
1669 break;
1670
1671 case 0x2000:
1672 //
1673 // Only used to update the state.
1674 //
1675 if ((Type == EFI_IFR_TYPE_STRING) && (Value->string == 0) &&
1676 (PrivateData->PasswordState == BROWSER_STATE_SET_PASSWORD)) {
1677 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1678 return EFI_INVALID_PARAMETER;
1679 }
1680
1681 //
1682 // When try to set a new password, user will be chanlleged with old password.
1683 // The Callback is responsible for validating old password input by user,
1684 // If Callback return EFI_SUCCESS, it indicates validation pass.
1685 //
1686 switch (PrivateData->PasswordState) {
1687 case BROWSER_STATE_VALIDATE_PASSWORD:
1688 Status = ValidatePassword (PrivateData, Value->string);
1689 if (Status == EFI_SUCCESS) {
1690 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;
1691 }
1692 break;
1693
1694 case BROWSER_STATE_SET_PASSWORD:
1695 Status = SetPassword (PrivateData, Value->string);
1696 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1697 break;
1698
1699 default:
1700 break;
1701 }
1702
1703 break;
1704
1705 default:
1706 break;
1707 }
1708 }
1709 break;
1710
1711 case EFI_BROWSER_ACTION_CHANGED:
1712 switch (QuestionId) {
1713 case 0x1237:
1714 //
1715 // User press "Exit now", request Browser to exit
1716 //
1717 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
1718 break;
1719
1720 case 0x1238:
1721 //
1722 // User press "Save now", request Browser to save the uncommitted data.
1723 //
1724 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
1725 break;
1726
1727 case 0x1241:
1728 case 0x1246:
1729 //
1730 // User press "Submit current form and Exit now", request Browser to submit current form and exit
1731 //
1732 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1733 break;
1734
1735 case 0x1242:
1736 //
1737 // User press "Discard current form now", request Browser to discard the uncommitted data.
1738 //
1739 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD;
1740 break;
1741
1742 case 0x1243:
1743 //
1744 // User press "Submit current form now", request Browser to save the uncommitted data.
1745 //
1746 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
1747 break;
1748
1749 case 0x1244:
1750 case 0x1245:
1751 //
1752 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.
1753 //
1754 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1755 break;
1756
1757 default:
1758 break;
1759 }
1760 break;
1761
1762 default:
1763 Status = EFI_UNSUPPORTED;
1764 break;
1765 }
1766
1767 return Status;
1768}
1769
1770/**
1771 Main entry for this driver.
1772
1773 @param ImageHandle Image handle this driver.
1774 @param SystemTable Pointer to SystemTable.
1775
1776 @retval EFI_SUCESS This function always complete successfully.
1777
1778**/
1779EFI_STATUS
1780EFIAPI
1781DriverSampleInit (
1782 IN EFI_HANDLE ImageHandle,
1783 IN EFI_SYSTEM_TABLE *SystemTable
1784 )
1785{
1786 EFI_STATUS Status;
1787 EFI_HII_HANDLE HiiHandle[2];
1788 EFI_SCREEN_DESCRIPTOR Screen;
1789 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;
1790 EFI_HII_STRING_PROTOCOL *HiiString;
1791 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;
1792 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
1793 CHAR16 *NewString;
1794 UINTN BufferSize;
1795 DRIVER_SAMPLE_CONFIGURATION *Configuration;
1796 BOOLEAN ActionFlag;
1797 EFI_STRING ConfigRequestHdr;
1798 EFI_STRING NameRequestHdr;
1799 MY_EFI_VARSTORE_DATA *VarStoreConfig;
1800 EFI_INPUT_KEY HotKey;
1801 EFI_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx;
1802
1803 //
1804 // Initialize the local variables.
1805 //
1806 ConfigRequestHdr = NULL;
1807 NewString = NULL;
1808
1809 //
1810 // Initialize screen dimensions for SendForm().
1811 // Remove 3 characters from top and bottom
1812 //
1813 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));
1814 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);
1815
1816 Screen.TopRow = 3;
1817 Screen.BottomRow = Screen.BottomRow - 3;
1818
1819 //
1820 // Initialize driver private data
1821 //
1822 PrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));
1823 if (PrivateData == NULL) {
1824 return EFI_OUT_OF_RESOURCES;
1825 }
1826
1827 PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;
1828
1829 PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
1830 PrivateData->ConfigAccess.RouteConfig = RouteConfig;
1831 PrivateData->ConfigAccess.Callback = DriverCallback;
1832 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;
1833
1834 //
1835 // Locate Hii Database protocol
1836 //
1837 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);
1838 if (EFI_ERROR (Status)) {
1839 return Status;
1840 }
1841 PrivateData->HiiDatabase = HiiDatabase;
1842
1843 //
1844 // Locate HiiString protocol
1845 //
1846 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
1847 if (EFI_ERROR (Status)) {
1848 return Status;
1849 }
1850 PrivateData->HiiString = HiiString;
1851
1852 //
1853 // Locate Formbrowser2 protocol
1854 //
1855 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);
1856 if (EFI_ERROR (Status)) {
1857 return Status;
1858 }
1859 PrivateData->FormBrowser2 = FormBrowser2;
1860
1861 //
1862 // Locate ConfigRouting protocol
1863 //
1864 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);
1865 if (EFI_ERROR (Status)) {
1866 return Status;
1867 }
1868 PrivateData->HiiConfigRouting = HiiConfigRouting;
1869
1870 Status = gBS->InstallMultipleProtocolInterfaces (
1871 &DriverHandle[0],
1872 &gEfiDevicePathProtocolGuid,
1873 &mHiiVendorDevicePath0,
1874 &gEfiHiiConfigAccessProtocolGuid,
1875 &PrivateData->ConfigAccess,
1876 NULL
1877 );
1878 ASSERT_EFI_ERROR (Status);
1879
1880 PrivateData->DriverHandle[0] = DriverHandle[0];
1881
1882 //
1883 // Publish our HII data
1884 //
1885 HiiHandle[0] = HiiAddPackages (
1886 &gDriverSampleFormSetGuid,
1887 DriverHandle[0],
1888 DriverSampleStrings,
1889 VfrBin,
1890 NULL
1891 );
1892 if (HiiHandle[0] == NULL) {
1893 return EFI_OUT_OF_RESOURCES;
1894 }
1895
1896 PrivateData->HiiHandle[0] = HiiHandle[0];
1897
1898 //
1899 // Publish another Fromset
1900 //
1901 Status = gBS->InstallMultipleProtocolInterfaces (
1902 &DriverHandle[1],
1903 &gEfiDevicePathProtocolGuid,
1904 &mHiiVendorDevicePath1,
1905 NULL
1906 );
1907 ASSERT_EFI_ERROR (Status);
1908
1909 PrivateData->DriverHandle[1] = DriverHandle[1];
1910
1911 HiiHandle[1] = HiiAddPackages (
1912 &gDriverSampleInventoryGuid,
1913 DriverHandle[1],
1914 DriverSampleStrings,
1915 InventoryBin,
1916 NULL
1917 );
1918 if (HiiHandle[1] == NULL) {
1919 DriverSampleUnload (ImageHandle);
1920 return EFI_OUT_OF_RESOURCES;
1921 }
1922
1923 PrivateData->HiiHandle[1] = HiiHandle[1];
1924
1925 //
1926 // Update the device path string.
1927 //
1928 NewString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)&mHiiVendorDevicePath0, FALSE, FALSE);
1929 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_DEVICE_PATH), NewString, NULL) == 0) {
1930 DriverSampleUnload (ImageHandle);
1931 return EFI_OUT_OF_RESOURCES;
1932 }
1933 if (NewString != NULL) {
1934 FreePool (NewString);
1935 }
1936
1937 //
1938 // Very simple example of how one would update a string that is already
1939 // in the HII database
1940 //
1941 NewString = L"700 Mhz";
1942
1943 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {
1944 DriverSampleUnload (ImageHandle);
1945 return EFI_OUT_OF_RESOURCES;
1946 }
1947
1948 HiiSetString (HiiHandle[0], 0, NewString, NULL);
1949
1950 //
1951 // Initialize Name/Value name String ID
1952 //
1953 PrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0;
1954 PrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1;
1955 PrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2;
1956
1957 //
1958 // Initialize configuration data
1959 //
1960 Configuration = &PrivateData->Configuration;
1961 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));
1962
1963 //
1964 // Try to read NV config EFI variable first
1965 //
1966 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]);
1967 ASSERT (ConfigRequestHdr != NULL);
1968
1969 NameRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, NULL, DriverHandle[0]);
1970 ASSERT (NameRequestHdr != NULL);
1971
1972 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);
1973 Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration);
1974 if (EFI_ERROR (Status)) {
1975 //
1976 // Store zero data Buffer Storage to EFI variable
1977 //
1978 Status = gRT->SetVariable(
1979 VariableName,
1980 &gDriverSampleFormSetGuid,
1981 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
1982 sizeof (DRIVER_SAMPLE_CONFIGURATION),
1983 Configuration
1984 );
1985 if (EFI_ERROR (Status)) {
1986 DriverSampleUnload (ImageHandle);
1987 return Status;
1988 }
1989 //
1990 // EFI variable for NV config doesn't exit, we should build this variable
1991 // based on default values stored in IFR
1992 //
1993 ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
1994 if (!ActionFlag) {
1995 DriverSampleUnload (ImageHandle);
1996 return EFI_INVALID_PARAMETER;
1997 }
1998
1999 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
2000 if (!ActionFlag) {
2001 DriverSampleUnload (ImageHandle);
2002 return EFI_INVALID_PARAMETER;
2003 }
2004 } else {
2005 //
2006 // EFI variable does exist and Validate Current Setting
2007 //
2008 ActionFlag = HiiValidateSettings (NameRequestHdr);
2009 if (!ActionFlag) {
2010 DriverSampleUnload (ImageHandle);
2011 return EFI_INVALID_PARAMETER;
2012 }
2013
2014 ActionFlag = HiiValidateSettings (ConfigRequestHdr);
2015 if (!ActionFlag) {
2016 DriverSampleUnload (ImageHandle);
2017 return EFI_INVALID_PARAMETER;
2018 }
2019 }
2020 FreePool (ConfigRequestHdr);
2021
2022 //
2023 // Initialize efi varstore configuration data
2024 //
2025 VarStoreConfig = &PrivateData->VarStoreConfig;
2026 ZeroMem (VarStoreConfig, sizeof (MY_EFI_VARSTORE_DATA));
2027
2028 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiVar, DriverHandle[0]);
2029 ASSERT (ConfigRequestHdr != NULL);
2030
2031 BufferSize = sizeof (MY_EFI_VARSTORE_DATA);
2032 Status = gRT->GetVariable (MyEfiVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, VarStoreConfig);
2033 if (EFI_ERROR (Status)) {
2034 //
2035 // Store zero data to EFI variable Storage.
2036 //
2037 Status = gRT->SetVariable(
2038 MyEfiVar,
2039 &gDriverSampleFormSetGuid,
2040 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
2041 sizeof (MY_EFI_VARSTORE_DATA),
2042 VarStoreConfig
2043 );
2044 if (EFI_ERROR (Status)) {
2045 DriverSampleUnload (ImageHandle);
2046 return Status;
2047 }
2048 //
2049 // EFI variable for NV config doesn't exit, we should build this variable
2050 // based on default values stored in IFR
2051 //
2052 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
2053 if (!ActionFlag) {
2054 DriverSampleUnload (ImageHandle);
2055 return EFI_INVALID_PARAMETER;
2056 }
2057 } else {
2058 //
2059 // EFI variable does exist and Validate Current Setting
2060 //
2061 ActionFlag = HiiValidateSettings (ConfigRequestHdr);
2062 if (!ActionFlag) {
2063 DriverSampleUnload (ImageHandle);
2064 return EFI_INVALID_PARAMETER;
2065 }
2066 }
2067 FreePool (ConfigRequestHdr);
2068
2069 Status = gBS->CreateEventEx (
2070 EVT_NOTIFY_SIGNAL,
2071 TPL_NOTIFY,
2072 DriverSampleInternalEmptyFunction,
2073 NULL,
2074 &gEfiIfrRefreshIdOpGuid,
2075 &mEvent
2076 );
2077 ASSERT_EFI_ERROR (Status);
2078
2079 //
2080 // Example of how to use BrowserEx protocol to register HotKey.
2081 //
2082 Status = gBS->LocateProtocol (&gEfiFormBrowserExProtocolGuid, NULL, (VOID **) &FormBrowserEx);
2083 if (!EFI_ERROR (Status)) {
2084 //
2085 // First unregister the default hot key F9 and F10.
2086 //
2087 HotKey.UnicodeChar = CHAR_NULL;
2088 HotKey.ScanCode = SCAN_F9;
2089 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);
2090 HotKey.ScanCode = SCAN_F10;
2091 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);
2092
2093 //
2094 // Register the default HotKey F9 and F10 again.
2095 //
2096 HotKey.ScanCode = SCAN_F10;
2097 NewString = HiiGetString (PrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_TEN_STRING), NULL);
2098 ASSERT (NewString != NULL);
2099 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);
2100 HotKey.ScanCode = SCAN_F9;
2101 NewString = HiiGetString (PrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_NINE_STRING), NULL);
2102 ASSERT (NewString != NULL);
2103 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);
2104 }
2105
2106 //
2107 // In default, this driver is built into Flash device image,
2108 // the following code doesn't run.
2109 //
2110
2111 //
2112 // Example of how to display only the item we sent to HII
2113 // When this driver is not built into Flash device image,
2114 // it need to call SendForm to show front page by itself.
2115 //
2116 if (DISPLAY_ONLY_MY_ITEM <= 1) {
2117 //
2118 // Have the browser pull out our copy of the data, and only display our data
2119 //
2120 Status = FormBrowser2->SendForm (
2121 FormBrowser2,
2122 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),
2123 1,
2124 NULL,
2125 0,
2126 NULL,
2127 NULL
2128 );
2129
2130 HiiRemovePackages (HiiHandle[0]);
2131
2132 HiiRemovePackages (HiiHandle[1]);
2133 }
2134
2135 return EFI_SUCCESS;
2136}
2137
2138/**
2139 Unloads the application and its installed protocol.
2140
2141 @param[in] ImageHandle Handle that identifies the image to be unloaded.
2142
2143 @retval EFI_SUCCESS The image has been unloaded.
2144**/
2145EFI_STATUS
2146EFIAPI
2147DriverSampleUnload (
2148 IN EFI_HANDLE ImageHandle
2149 )
2150{
2151 UINTN Index;
2152
2153 ASSERT (PrivateData != NULL);
2154
2155 if (DriverHandle[0] != NULL) {
2156 gBS->UninstallMultipleProtocolInterfaces (
2157 DriverHandle[0],
2158 &gEfiDevicePathProtocolGuid,
2159 &mHiiVendorDevicePath0,
2160 &gEfiHiiConfigAccessProtocolGuid,
2161 &PrivateData->ConfigAccess,
2162 NULL
2163 );
2164 DriverHandle[0] = NULL;
2165 }
2166
2167 if (DriverHandle[1] != NULL) {
2168 gBS->UninstallMultipleProtocolInterfaces (
2169 DriverHandle[1],
2170 &gEfiDevicePathProtocolGuid,
2171 &mHiiVendorDevicePath1,
2172 NULL
2173 );
2174 DriverHandle[1] = NULL;
2175 }
2176
2177 if (PrivateData->HiiHandle[0] != NULL) {
2178 HiiRemovePackages (PrivateData->HiiHandle[0]);
2179 }
2180
2181 if (PrivateData->HiiHandle[1] != NULL) {
2182 HiiRemovePackages (PrivateData->HiiHandle[1]);
2183 }
2184
2185 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {
2186 if (PrivateData->NameValueName[Index] != NULL) {
2187 FreePool (PrivateData->NameValueName[Index]);
2188 }
2189 }
2190 FreePool (PrivateData);
2191 PrivateData = NULL;
2192
2193 gBS->CloseEvent (mEvent);
2194
2195 return EFI_SUCCESS;
2196}
Note: See TracBrowser for help on using the repository browser.

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