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