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