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