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