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