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