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