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