]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
MdeModulePkg: Replace [Ascii|Unicode]ValueToString
[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
ac72474d 5Copyright (c) 2004 - 2017, 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 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
38ebfecb
LG
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
93e3992d 280\r
ee31d1be
ED
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
46cc3885 391 NewLen = StrLen (Result);\r
33d41385
ED
392 //\r
393 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")\r
394 //\r
46cc3885 395 NewLen = (NewLen + ((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16);\r
ee31d1be
ED
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
5ad66ec6 403 StrCpyS (StringPtr, NewLen / sizeof (CHAR16), Result);\r
ee31d1be
ED
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
ee31d1be
ED
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
4e1005ec 473 TmpBuffer = NULL;\r
ee31d1be
ED
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
ee31d1be
ED
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
b18e7050 529 // Get Value\r
ee31d1be
ED
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
bfaa3b5b
DB
537 //\r
538 // Skip the character "&" before "OFFSET".\r
539 //\r
540 StringPtr ++;\r
541\r
ee31d1be
ED
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
33d41385
ED
550 *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth);\r
551 return;\r
ee31d1be
ED
552 }\r
553 }\r
554}\r
555\r
93e3992d 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
e35eb8af 577 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
93e3992d 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
84f9a9ec 595 EFI_STRING ConfigRequest;\r
086cd2c8 596 EFI_STRING ConfigRequestHdr;\r
84f9a9ec 597 UINTN Size;\r
38ebfecb
LG
598 EFI_STRING Value;\r
599 UINTN ValueStrLen;\r
600 CHAR16 BackupChar;\r
601 CHAR16 *StrPointer;\r
59aefb7e 602 BOOLEAN AllocatedRequest;\r
38ebfecb 603\r
59aefb7e 604 if (Progress == NULL || Results == NULL) {\r
ae79d2f9
LG
605 return EFI_INVALID_PARAMETER;\r
606 }\r
84f9a9ec
LG
607 //\r
608 // Initialize the local variables.\r
609 //\r
086cd2c8
LG
610 ConfigRequestHdr = NULL;\r
611 ConfigRequest = NULL;\r
612 Size = 0;\r
613 *Progress = Request;\r
59aefb7e 614 AllocatedRequest = FALSE;\r
93e3992d 615\r
616 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
617 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
618\r
8d00a0f1 619 //\r
84f9a9ec
LG
620 // Get Buffer Storage data from EFI variable.\r
621 // Try to get the current setting from variable.\r
93e3992d 622 //\r
623 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
04da0b4a
LG
624 Status = gRT->GetVariable (\r
625 VariableName,\r
c8ad2d7a 626 &gDriverSampleFormSetGuid,\r
04da0b4a
LG
627 NULL,\r
628 &BufferSize,\r
629 &PrivateData->Configuration\r
630 );\r
631 if (EFI_ERROR (Status)) {\r
de482998 632 return EFI_NOT_FOUND;\r
04da0b4a 633 }\r
a6973cff 634\r
8d00a0f1 635 if (Request == NULL) {\r
636 //\r
84f9a9ec 637 // Request is set to NULL, construct full request string.\r
7e3bcccb 638 //\r
84f9a9ec 639\r
84f9a9ec 640 //\r
a6973cff 641 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
84f9a9ec
LG
642 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
643 //\r
c8ad2d7a 644 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
59aefb7e 645 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
84f9a9ec 646 ConfigRequest = AllocateZeroPool (Size);\r
1bd57b6e 647 ASSERT (ConfigRequest != NULL);\r
59aefb7e 648 AllocatedRequest = TRUE;\r
086cd2c8
LG
649 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
650 FreePool (ConfigRequestHdr);\r
ee31d1be 651 ConfigRequestHdr = NULL;\r
84f9a9ec 652 } else {\r
de482998
LG
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
c8ad2d7a 657 if (!HiiIsConfigHdrMatch (Request, &gDriverSampleFormSetGuid, NULL)) {\r
de482998 658 return EFI_NOT_FOUND;\r
84f9a9ec 659 }\r
59aefb7e 660 //\r
78c2b9a3
ED
661 // Check whether request for EFI Varstore. EFI varstore get data\r
662 // through hii database, not support in this path.\r
663 //\r
c8ad2d7a 664 if (HiiIsConfigHdrMatch(Request, &gDriverSampleFormSetGuid, MyEfiVar)) {\r
78c2b9a3
ED
665 return EFI_UNSUPPORTED;\r
666 }\r
667 //\r
59aefb7e
LG
668 // Set Request to the unified request string.\r
669 //\r
de482998 670 ConfigRequest = Request;\r
38ebfecb 671 //\r
59aefb7e 672 // Check whether Request includes Request Element.\r
38ebfecb
LG
673 //\r
674 if (StrStr (Request, L"OFFSET") == NULL) {\r
675 //\r
59aefb7e 676 // Check Request Element does exist in Reques String\r
38ebfecb 677 //\r
59aefb7e
LG
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
1bd57b6e 685 ASSERT (ConfigRequest != NULL);\r
59aefb7e
LG
686 AllocatedRequest = TRUE;\r
687 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);\r
38ebfecb 688 }\r
59aefb7e
LG
689 }\r
690 }\r
38ebfecb 691\r
59aefb7e
LG
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
38ebfecb 703\r
59aefb7e
LG
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
5ad66ec6 715 StrCpyS (*Results, BufferSize / sizeof (CHAR16), ConfigRequest);\r
59aefb7e 716 Value = *Results;\r
38ebfecb 717\r
59aefb7e
LG
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
9f4048f7
HW
728 UnicodeValueToStringS (\r
729 Value,\r
730 BufferSize - ((UINTN)Value - (UINTN)*Results),\r
731 PREFIX_ZERO | RADIX_HEX,\r
732 PrivateData->Configuration.NameValueVar0,\r
733 sizeof (PrivateData->Configuration.NameValueVar0) * 2\r
734 );\r
735 Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16));\r
59aefb7e
LG
736 *Value = BackupChar;\r
737 }\r
738\r
739 //\r
740 // Append value of NameValueVar1, type is UINT16\r
741 //\r
742 if ((Value = StrStr (*Results, PrivateData->NameValueName[1])) != NULL) {\r
743 Value += StrLen (PrivateData->NameValueName[1]);\r
744 ValueStrLen = ((sizeof (PrivateData->Configuration.NameValueVar1) * 2) + 1);\r
745 CopyMem (Value + ValueStrLen, Value, StrSize (Value));\r
746\r
747 BackupChar = Value[ValueStrLen];\r
748 *Value++ = L'=';\r
9f4048f7
HW
749 UnicodeValueToStringS (\r
750 Value,\r
751 BufferSize - ((UINTN)Value - (UINTN)*Results),\r
752 PREFIX_ZERO | RADIX_HEX,\r
753 PrivateData->Configuration.NameValueVar1,\r
754 sizeof (PrivateData->Configuration.NameValueVar1) * 2\r
755 );\r
756 Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16));\r
59aefb7e
LG
757 *Value = BackupChar;\r
758 }\r
759\r
760 //\r
761 // Append value of NameValueVar2, type is CHAR16 *\r
762 //\r
763 if ((Value = StrStr (*Results, PrivateData->NameValueName[2])) != NULL) {\r
764 Value += StrLen (PrivateData->NameValueName[2]);\r
765 ValueStrLen = StrLen (PrivateData->Configuration.NameValueVar2) * 4 + 1;\r
766 CopyMem (Value + ValueStrLen, Value, StrSize (Value));\r
38ebfecb 767\r
59aefb7e 768 *Value++ = L'=';\r
38ebfecb 769 //\r
59aefb7e 770 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
38ebfecb 771 //\r
59aefb7e
LG
772 StrPointer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;\r
773 for (; *StrPointer != L'\0'; StrPointer++) {\r
9f4048f7
HW
774 UnicodeValueToStringS (\r
775 Value,\r
776 BufferSize - ((UINTN)Value - (UINTN)*Results),\r
777 PREFIX_ZERO | RADIX_HEX,\r
778 *StrPointer,\r
779 4\r
780 );\r
781 Value += StrnLenS (Value, (BufferSize - ((UINTN)Value - (UINTN)*Results)) / sizeof (CHAR16));\r
38ebfecb 782 }\r
38ebfecb 783 }\r
59aefb7e
LG
784 \r
785 Status = EFI_SUCCESS;\r
786 } else {\r
787 //\r
788 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
789 //\r
790 Status = HiiConfigRouting->BlockToConfig (\r
791 HiiConfigRouting,\r
792 ConfigRequest,\r
793 (UINT8 *) &PrivateData->Configuration,\r
794 BufferSize,\r
795 Results,\r
796 Progress\r
797 );\r
33d41385 798 if (!EFI_ERROR (Status)) {\r
c8ad2d7a 799 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
33d41385
ED
800 AppendAltCfgString(Results, ConfigRequestHdr);\r
801 }\r
8d00a0f1 802 }\r
803\r
93e3992d 804 //\r
59aefb7e 805 // Free the allocated config request string.\r
93e3992d 806 //\r
59aefb7e 807 if (AllocatedRequest) {\r
84f9a9ec 808 FreePool (ConfigRequest);\r
59aefb7e 809 }\r
ee31d1be
ED
810\r
811 if (ConfigRequestHdr != NULL) {\r
812 FreePool (ConfigRequestHdr);\r
813 }\r
59aefb7e
LG
814 //\r
815 // Set Progress string to the original request string.\r
816 //\r
817 if (Request == NULL) {\r
1f1cb2f2 818 *Progress = NULL;\r
59aefb7e
LG
819 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
820 *Progress = Request + StrLen (Request);\r
84f9a9ec
LG
821 }\r
822\r
93e3992d 823 return Status;\r
824}\r
825\r
826\r
827/**\r
828 This function processes the results of changes in configuration.\r
829\r
830 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
831 @param Configuration A null-terminated Unicode string in <ConfigResp>\r
832 format.\r
833 @param Progress A pointer to a string filled in with the offset of\r
834 the most recent '&' before the first failing\r
835 name/value pair (or the beginning of the string if\r
836 the failure is in the first name/value pair) or\r
837 the terminating NULL if all was successful.\r
838\r
839 @retval EFI_SUCCESS The Results is processed successfully.\r
840 @retval EFI_INVALID_PARAMETER Configuration is NULL.\r
841 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this\r
842 driver.\r
843\r
844**/\r
845EFI_STATUS\r
846EFIAPI\r
847RouteConfig (\r
848 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
849 IN CONST EFI_STRING Configuration,\r
850 OUT EFI_STRING *Progress\r
851 )\r
852{\r
853 EFI_STATUS Status;\r
854 UINTN BufferSize;\r
855 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
856 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
38ebfecb
LG
857 CHAR16 *Value;\r
858 CHAR16 *StrPtr;\r
859 CHAR16 TemStr[5];\r
860 UINT8 *DataBuffer;\r
861 UINT8 DigitUint8;\r
862 UINTN Index;\r
863 CHAR16 *StrBuffer;\r
93e3992d 864\r
f5e9ff82 865 if (Configuration == NULL || Progress == NULL) {\r
8d00a0f1 866 return EFI_INVALID_PARAMETER;\r
867 }\r
868\r
93e3992d 869 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
870 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
f5e9ff82 871 *Progress = Configuration;\r
93e3992d 872\r
84f9a9ec 873 //\r
8d00a0f1 874 // Check routing data in <ConfigHdr>.\r
875 // Note: if only one Storage is used, then this checking could be skipped.\r
876 //\r
c8ad2d7a 877 if (!HiiIsConfigHdrMatch (Configuration, &gDriverSampleFormSetGuid, NULL)) {\r
8d00a0f1 878 return EFI_NOT_FOUND;\r
879 }\r
880\r
78c2b9a3
ED
881 //\r
882 // Check whether request for EFI Varstore. EFI varstore get data\r
883 // through hii database, not support in this path.\r
884 //\r
c8ad2d7a 885 if (HiiIsConfigHdrMatch(Configuration, &gDriverSampleFormSetGuid, MyEfiVar)) {\r
78c2b9a3
ED
886 return EFI_UNSUPPORTED;\r
887 }\r
888\r
93e3992d 889 //\r
890 // Get Buffer Storage data from EFI variable\r
891 //\r
892 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
04da0b4a
LG
893 Status = gRT->GetVariable (\r
894 VariableName,\r
c8ad2d7a 895 &gDriverSampleFormSetGuid,\r
04da0b4a
LG
896 NULL,\r
897 &BufferSize,\r
898 &PrivateData->Configuration\r
899 );\r
900 if (EFI_ERROR (Status)) {\r
901 return Status;\r
902 }\r
93e3992d 903\r
38ebfecb
LG
904 //\r
905 // Check if configuring Name/Value storage\r
906 //\r
907 if (StrStr (Configuration, L"OFFSET") == NULL) {\r
908 //\r
909 // Update Name/Value storage Names\r
910 //\r
911 Status = LoadNameValueNames (PrivateData);\r
912 if (EFI_ERROR (Status)) {\r
913 return Status;\r
914 }\r
915\r
916 //\r
917 // Convert value for NameValueVar0\r
918 //\r
919 if ((Value = StrStr (Configuration, PrivateData->NameValueName[0])) != NULL) {\r
920 //\r
921 // Skip "Name="\r
922 //\r
923 Value += StrLen (PrivateData->NameValueName[0]);\r
924 Value++;\r
925 //\r
926 // Get Value String\r
927 //\r
928 StrPtr = StrStr (Value, L"&");\r
929 if (StrPtr == NULL) {\r
930 StrPtr = Value + StrLen (Value);\r
931 }\r
932 //\r
933 // Convert Value to Buffer data\r
934 //\r
935 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar0;\r
936 ZeroMem (TemStr, sizeof (TemStr));\r
937 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {\r
938 TemStr[0] = *StrPtr;\r
939 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
940 if ((Index & 1) == 0) {\r
941 DataBuffer [Index/2] = DigitUint8;\r
942 } else {\r
943 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);\r
944 }\r
945 }\r
946 }\r
947\r
948 //\r
949 // Convert value for NameValueVar1\r
950 //\r
951 if ((Value = StrStr (Configuration, PrivateData->NameValueName[1])) != NULL) {\r
952 //\r
953 // Skip "Name="\r
954 //\r
955 Value += StrLen (PrivateData->NameValueName[1]);\r
956 Value++;\r
957 //\r
958 // Get Value String\r
959 //\r
960 StrPtr = StrStr (Value, L"&");\r
961 if (StrPtr == NULL) {\r
962 StrPtr = Value + StrLen (Value);\r
963 }\r
964 //\r
965 // Convert Value to Buffer data\r
966 //\r
967 DataBuffer = (UINT8 *) &PrivateData->Configuration.NameValueVar1;\r
968 ZeroMem (TemStr, sizeof (TemStr));\r
969 for (Index = 0, StrPtr --; StrPtr >= Value; StrPtr --, Index ++) {\r
970 TemStr[0] = *StrPtr;\r
971 DigitUint8 = (UINT8) StrHexToUint64 (TemStr);\r
972 if ((Index & 1) == 0) {\r
973 DataBuffer [Index/2] = DigitUint8;\r
974 } else {\r
975 DataBuffer [Index/2] = (UINT8) ((UINT8) (DigitUint8 << 4) + DataBuffer [Index/2]);\r
976 }\r
977 }\r
978 }\r
979\r
980 //\r
981 // Convert value for NameValueVar2\r
982 //\r
983 if ((Value = StrStr (Configuration, PrivateData->NameValueName[2])) != NULL) {\r
984 //\r
985 // Skip "Name="\r
986 //\r
987 Value += StrLen (PrivateData->NameValueName[2]);\r
988 Value++;\r
989 //\r
990 // Get Value String\r
991 //\r
992 StrPtr = StrStr (Value, L"&");\r
993 if (StrPtr == NULL) {\r
994 StrPtr = Value + StrLen (Value);\r
995 }\r
996 //\r
997 // Convert Config String to Unicode String, e.g "0041004200430044" => "ABCD"\r
998 //\r
999 StrBuffer = (CHAR16 *) PrivateData->Configuration.NameValueVar2;\r
1000 ZeroMem (TemStr, sizeof (TemStr));\r
1001 while (Value < StrPtr) {\r
5ad66ec6 1002 StrnCpyS (TemStr, sizeof (TemStr) / sizeof (CHAR16), Value, 4);\r
38ebfecb
LG
1003 *(StrBuffer++) = (CHAR16) StrHexToUint64 (TemStr);\r
1004 Value += 4;\r
1005 }\r
1006 *StrBuffer = L'\0';\r
1007 }\r
1008\r
1009 //\r
1010 // Store Buffer Storage back to EFI variable\r
1011 //\r
1012 Status = gRT->SetVariable(\r
1013 VariableName,\r
c8ad2d7a 1014 &gDriverSampleFormSetGuid,\r
38ebfecb
LG
1015 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1016 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1017 &PrivateData->Configuration\r
1018 );\r
1019\r
1020 return Status;\r
1021 }\r
1022\r
93e3992d 1023 //\r
1024 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
1025 //\r
1026 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
1027 Status = HiiConfigRouting->ConfigToBlock (\r
1028 HiiConfigRouting,\r
1029 Configuration,\r
1030 (UINT8 *) &PrivateData->Configuration,\r
1031 &BufferSize,\r
1032 Progress\r
1033 );\r
1034 if (EFI_ERROR (Status)) {\r
1035 return Status;\r
1036 }\r
1037\r
1038 //\r
1039 // Store Buffer Storage back to EFI variable\r
1040 //\r
1041 Status = gRT->SetVariable(\r
1042 VariableName,\r
c8ad2d7a 1043 &gDriverSampleFormSetGuid,\r
93e3992d 1044 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1045 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1046 &PrivateData->Configuration\r
1047 );\r
1048\r
1049 return Status;\r
1050}\r
1051\r
1052\r
1053/**\r
1054 This function processes the results of changes in configuration.\r
1055\r
1056 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1057 @param Action Specifies the type of action taken by the browser.\r
1058 @param QuestionId A unique value which is sent to the original\r
1059 exporting driver so that it can identify the type\r
1060 of data to expect.\r
1061 @param Type The type of value for the question.\r
1062 @param Value A pointer to the data being sent to the original\r
1063 exporting driver.\r
1064 @param ActionRequest On return, points to the action requested by the\r
1065 callback function.\r
1066\r
1067 @retval EFI_SUCCESS The callback successfully handled the action.\r
1068 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
1069 variable and its data.\r
1070 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
1071 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
1072 callback.\r
1073\r
1074**/\r
1075EFI_STATUS\r
1076EFIAPI\r
1077DriverCallback (\r
1078 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1079 IN EFI_BROWSER_ACTION Action,\r
1080 IN EFI_QUESTION_ID QuestionId,\r
1081 IN UINT8 Type,\r
1082 IN EFI_IFR_TYPE_VALUE *Value,\r
1083 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
1084 )\r
1085{\r
1086 DRIVER_SAMPLE_PRIVATE_DATA *PrivateData;\r
1087 EFI_STATUS Status;\r
7e3bcccb
LG
1088 VOID *StartOpCodeHandle;\r
1089 VOID *OptionsOpCodeHandle;\r
1090 EFI_IFR_GUID_LABEL *StartLabel;\r
1091 VOID *EndOpCodeHandle;\r
1092 EFI_IFR_GUID_LABEL *EndLabel;\r
a6973cff 1093 EFI_INPUT_KEY Key;\r
1094 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
78c2b9a3 1095 MY_EFI_VARSTORE_DATA *EfiData;\r
211cc6e5 1096 EFI_FORM_ID FormId;\r
34326197
ED
1097 EFI_STRING Progress;\r
1098 EFI_STRING Results;\r
1099 UINT32 ProgressErr;\r
1100 CHAR16 *TmpStr;\r
622ce645
DB
1101 UINTN Index;\r
1102 UINT64 BufferValue;\r
1103\r
4a22b9bc
ED
1104 if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||\r
1105 (ActionRequest == NULL)) {\r
1106 return EFI_INVALID_PARAMETER;\r
1107 }\r
a6973cff 1108\r
a6973cff 1109\r
211cc6e5 1110 FormId = 0;\r
34326197 1111 ProgressErr = 0;\r
4a22b9bc 1112 Status = EFI_SUCCESS;\r
622ce645 1113 BufferValue = 3;\r
4a22b9bc
ED
1114 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
1115\r
1116 switch (Action) {\r
1117 case EFI_BROWSER_ACTION_FORM_OPEN:\r
1118 {\r
1119 if (QuestionId == 0x1234) {\r
1120 //\r
1121 // Sample CallBack for UEFI FORM_OPEN action:\r
1122 // Add Save action into Form 3 when Form 1 is opened.\r
1123 // This will be done only in FORM_OPEN CallBack of question with ID 0x1234 from Form 1.\r
1124 //\r
1125 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
1126\r
1127 //\r
1128 // Initialize the container for dynamic opcodes\r
1129 //\r
1130 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1131 ASSERT (StartOpCodeHandle != NULL);\r
1132\r
1133 //\r
1134 // Create Hii Extend Label OpCode as the start opcode\r
1135 //\r
1136 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1137 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1138 StartLabel->Number = LABEL_UPDATE2;\r
1139\r
1140 HiiCreateActionOpCode (\r
1141 StartOpCodeHandle, // Container for dynamic created opcodes\r
1142 0x1238, // Question ID\r
1143 STRING_TOKEN(STR_SAVE_TEXT), // Prompt text\r
1144 STRING_TOKEN(STR_SAVE_TEXT), // Help text\r
1145 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1146 0 // Action String ID\r
1147 );\r
1148\r
1149 HiiUpdateForm (\r
1150 PrivateData->HiiHandle[0], // HII handle\r
c8ad2d7a 1151 &gDriverSampleFormSetGuid, // Formset GUID\r
4a22b9bc
ED
1152 0x3, // Form ID\r
1153 StartOpCodeHandle, // Label for where to insert opcodes\r
1154 NULL // Insert data\r
1155 );\r
1156\r
1157 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1158 }\r
211cc6e5
ED
1159\r
1160 if (QuestionId == 0x1247) {\r
1161 Status = InternalStartMonitor ();\r
1162 ASSERT_EFI_ERROR (Status);\r
1163 }\r
4a22b9bc
ED
1164 }\r
1165 break;\r
1166\r
1167 case EFI_BROWSER_ACTION_FORM_CLOSE:\r
1168 {\r
1169 if (QuestionId == 0x5678) {\r
1170 //\r
1171 // Sample CallBack for UEFI FORM_CLOSE action:\r
1172 // Show up a pop-up to specify Form 3 will be closed when exit Form 3.\r
1173 //\r
1174 do {\r
1175 CreatePopUp (\r
1176 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1177 &Key,\r
1178 L"",\r
1179 L"You are going to leave third Form!",\r
1180 L"Press ESC or ENTER to continue ...",\r
1181 L"",\r
1182 NULL\r
1183 );\r
1184 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1185 }\r
211cc6e5
ED
1186\r
1187 if (QuestionId == 0x1247) {\r
1188 Status = InternalStopMonitor ();\r
1189 ASSERT_EFI_ERROR (Status);\r
1190 }\r
4a22b9bc
ED
1191 }\r
1192 break;\r
1193 \r
1194 case EFI_BROWSER_ACTION_RETRIEVE:\r
1195 {\r
40ffc3b9
DB
1196 switch (QuestionId ) {\r
1197 case 0x1248:\r
1198 if (Type != EFI_IFR_TYPE_REF) {\r
1199 return EFI_INVALID_PARAMETER;\r
1200 }\r
1201 Value->ref.FormId = 0x3;\r
1202 break;\r
1203\r
1204 case 0x5678:\r
1205 case 0x1247:\r
1206 //\r
1207 // We will reach here once the Question is refreshed\r
1208 //\r
1209\r
1210 //\r
1211 // Initialize the container for dynamic opcodes\r
1212 //\r
1213 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1214 ASSERT (StartOpCodeHandle != NULL);\r
1215\r
1216 //\r
1217 // Create Hii Extend Label OpCode as the start opcode\r
1218 //\r
1219 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1220 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1221 if (QuestionId == 0x5678) {\r
1222 StartLabel->Number = LABEL_UPDATE2;\r
1223 FormId = 0x03;\r
1224 PrivateData->Configuration.DynamicRefresh++;\r
1225 } else if (QuestionId == 0x1247 ) {\r
1226 StartLabel->Number = LABEL_UPDATE3;\r
1227 FormId = 0x06;\r
1228 PrivateData->Configuration.RefreshGuidCount++;\r
1229 }\r
1230\r
1231 HiiCreateActionOpCode (\r
1232 StartOpCodeHandle, // Container for dynamic created opcodes\r
1233 0x1237, // Question ID\r
1234 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
1235 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
1236 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1237 0 // Action String ID\r
1238 );\r
1239 \r
1240 HiiUpdateForm (\r
1241 PrivateData->HiiHandle[0], // HII handle\r
1242 &gDriverSampleFormSetGuid, // Formset GUID\r
1243 FormId, // Form ID\r
1244 StartOpCodeHandle, // Label for where to insert opcodes\r
1245 NULL // Insert data\r
1246 );\r
1247\r
1248 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1249\r
1250 //\r
1251 // Refresh the Question value\r
1252 //\r
1253 Status = gRT->SetVariable(\r
1254 VariableName,\r
1255 &gDriverSampleFormSetGuid,\r
1256 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1257 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1258 &PrivateData->Configuration\r
1259 );\r
1260\r
1261 if (QuestionId == 0x5678) {\r
1262 //\r
1263 // Update uncommitted data of Browser\r
1264 //\r
1265 EfiData = AllocateZeroPool (sizeof (MY_EFI_VARSTORE_DATA));\r
1266 ASSERT (EfiData != NULL);\r
1267 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, MyEfiVar, sizeof (MY_EFI_VARSTORE_DATA), (UINT8 *) EfiData)) {\r
1268 EfiData->Field8 = 111;\r
1269 HiiSetBrowserData (\r
1270 &gDriverSampleFormSetGuid,\r
1271 MyEfiVar,\r
1272 sizeof (MY_EFI_VARSTORE_DATA),\r
1273 (UINT8 *) EfiData,\r
1274 NULL\r
1275 );\r
78c2b9a3 1276 }\r
40ffc3b9 1277 FreePool (EfiData);\r
78c2b9a3 1278 }\r
40ffc3b9 1279 break;\r
4a22b9bc
ED
1280 }\r
1281 }\r
1282 break;\r
1283\r
ee31d1be
ED
1284 case EFI_BROWSER_ACTION_DEFAULT_STANDARD:\r
1285 {\r
1286 switch (QuestionId) {\r
1287 case 0x1240:\r
1288 Value->u8 = DEFAULT_CLASS_STANDARD_VALUE;\r
1289 break;\r
1290\r
622ce645
DB
1291 case 0x1252:\r
1292 for (Index = 0; Index < 3; Index ++) {\r
1293 SetArrayData (Value, EFI_IFR_TYPE_NUM_SIZE_8, Index, BufferValue--);\r
1294 }\r
1295 break;\r
1296\r
ee31d1be
ED
1297 default:\r
1298 Status = EFI_UNSUPPORTED;\r
1299 break;\r
1300 }\r
1301 }\r
1302 break;\r
1303\r
1304 case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:\r
1305 {\r
1306 switch (QuestionId) {\r
1307 case 0x1240:\r
1308 Value->u8 = DEFAULT_CLASS_MANUFACTURING_VALUE;\r
1309 break;\r
1310\r
1311 default:\r
1312 Status = EFI_UNSUPPORTED; \r
1313 break;\r
1314 }\r
1315 }\r
1316 break;\r
1317\r
4a22b9bc
ED
1318 case EFI_BROWSER_ACTION_CHANGING:\r
1319 {\r
1320 switch (QuestionId) {\r
78c2b9a3
ED
1321 case 0x1249:\r
1322 {\r
1323 if (Type != EFI_IFR_TYPE_REF) {\r
1324 return EFI_INVALID_PARAMETER;\r
1325 }\r
1326\r
1327 Value->ref.FormId = 0x1234;\r
1328 }\r
1329 break;\r
4a22b9bc 1330 case 0x1234:\r
5adb8db7
LG
1331 //\r
1332 // Initialize the container for dynamic opcodes\r
1333 //\r
1334 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1335 ASSERT (StartOpCodeHandle != NULL);\r
a6973cff 1336\r
4a22b9bc
ED
1337 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1338 ASSERT (EndOpCodeHandle != NULL);\r
1339\r
5adb8db7
LG
1340 //\r
1341 // Create Hii Extend Label OpCode as the start opcode\r
1342 //\r
1343 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1344 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
4a22b9bc
ED
1345 StartLabel->Number = LABEL_UPDATE1;\r
1346\r
1347 //\r
1348 // Create Hii Extend Label OpCode as the end opcode\r
1349 //\r
1350 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1351 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1352 EndLabel->Number = LABEL_END;\r
5adb8db7
LG
1353\r
1354 HiiCreateActionOpCode (\r
1355 StartOpCodeHandle, // Container for dynamic created opcodes\r
4a22b9bc
ED
1356 0x1237, // Question ID\r
1357 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
1358 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
5adb8db7
LG
1359 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1360 0 // Action String ID\r
a6973cff 1361 );\r
1362\r
4a22b9bc
ED
1363 //\r
1364 // Create Option OpCode\r
1365 //\r
1366 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1367 ASSERT (OptionsOpCodeHandle != NULL);\r
1368\r
1369 HiiCreateOneOfOptionOpCode (\r
1370 OptionsOpCodeHandle,\r
1371 STRING_TOKEN (STR_BOOT_OPTION1),\r
1372 0,\r
1373 EFI_IFR_NUMERIC_SIZE_1,\r
1374 1\r
5adb8db7
LG
1375 );\r
1376\r
4a22b9bc
ED
1377 HiiCreateOneOfOptionOpCode (\r
1378 OptionsOpCodeHandle,\r
1379 STRING_TOKEN (STR_BOOT_OPTION2),\r
1380 0,\r
1381 EFI_IFR_NUMERIC_SIZE_1,\r
1382 2\r
1383 );\r
1384\r
1385 //\r
1386 // Prepare initial value for the dynamic created oneof Question\r
1387 //\r
1388 PrivateData->Configuration.DynamicOneof = 2;\r
1389 Status = gRT->SetVariable(\r
1390 VariableName,\r
c8ad2d7a 1391 &gDriverSampleFormSetGuid,\r
4a22b9bc
ED
1392 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1393 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1394 &PrivateData->Configuration\r
1395 );\r
a6973cff 1396\r
5adb8db7 1397 //\r
4a22b9bc 1398 // Set initial vlaue of dynamic created oneof Question in Form Browser\r
5adb8db7 1399 //\r
4a22b9bc
ED
1400 Configuration = AllocateZeroPool (sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
1401 ASSERT (Configuration != NULL);\r
c8ad2d7a 1402 if (HiiGetBrowserData (&gDriverSampleFormSetGuid, VariableName, sizeof (DRIVER_SAMPLE_CONFIGURATION), (UINT8 *) Configuration)) {\r
4a22b9bc
ED
1403 Configuration->DynamicOneof = 2;\r
1404\r
1405 //\r
1406 // Update uncommitted data of Browser\r
1407 //\r
1408 HiiSetBrowserData (\r
c8ad2d7a 1409 &gDriverSampleFormSetGuid,\r
4a22b9bc
ED
1410 VariableName,\r
1411 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1412 (UINT8 *) Configuration,\r
5adb8db7
LG
1413 NULL\r
1414 );\r
4a22b9bc
ED
1415 }\r
1416 FreePool (Configuration);\r
1417\r
1418 HiiCreateOneOfOpCode (\r
1419 StartOpCodeHandle, // Container for dynamic created opcodes\r
1420 0x8001, // Question ID (or call it "key")\r
1421 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
1422 (UINT16) DYNAMIC_ONE_OF_VAR_OFFSET, // Offset in Buffer Storage\r
1423 STRING_TOKEN (STR_ONE_OF_PROMPT), // Question prompt text\r
1424 STRING_TOKEN (STR_ONE_OF_HELP), // Question help text\r
1425 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1426 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question Value\r
1427 OptionsOpCodeHandle, // Option Opcode list\r
1428 NULL // Default Opcode is NULl\r
1429 );\r
7e3bcccb 1430\r
4a22b9bc
ED
1431 HiiCreateOrderedListOpCode (\r
1432 StartOpCodeHandle, // Container for dynamic created opcodes\r
1433 0x8002, // Question ID\r
1434 CONFIGURATION_VARSTORE_ID, // VarStore ID\r
1435 (UINT16) DYNAMIC_ORDERED_LIST_VAR_OFFSET, // Offset in Buffer Storage\r
1436 STRING_TOKEN (STR_BOOT_OPTIONS), // Question prompt text\r
1437 STRING_TOKEN (STR_BOOT_OPTIONS), // Question help text\r
1438 EFI_IFR_FLAG_RESET_REQUIRED, // Question flag\r
1439 0, // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET\r
1440 EFI_IFR_NUMERIC_SIZE_1, // Data type of Question value\r
1441 5, // Maximum container\r
1442 OptionsOpCodeHandle, // Option Opcode list\r
1443 NULL // Default Opcode is NULl\r
1444 );\r
7e3bcccb 1445\r
4a22b9bc
ED
1446 HiiCreateTextOpCode (\r
1447 StartOpCodeHandle,\r
1448 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),\r
1449 STRING_TOKEN(STR_TEXT_SAMPLE_HELP),\r
1450 STRING_TOKEN(STR_TEXT_SAMPLE_STRING)\r
7e3bcccb
LG
1451 );\r
1452\r
4a22b9bc
ED
1453 HiiCreateDateOpCode (\r
1454 StartOpCodeHandle,\r
1455 0x8004,\r
1456 0x0,\r
1457 0x0,\r
1458 STRING_TOKEN(STR_DATE_SAMPLE_HELP),\r
1459 STRING_TOKEN(STR_DATE_SAMPLE_HELP),\r
1460 0,\r
1461 QF_DATE_STORAGE_TIME,\r
1462 NULL\r
1463 );\r
7e3bcccb 1464\r
4a22b9bc
ED
1465 HiiCreateTimeOpCode (\r
1466 StartOpCodeHandle,\r
1467 0x8005,\r
1468 0x0,\r
1469 0x0,\r
1470 STRING_TOKEN(STR_TIME_SAMPLE_HELP),\r
1471 STRING_TOKEN(STR_TIME_SAMPLE_HELP),\r
1472 0,\r
1473 QF_TIME_STORAGE_TIME,\r
1474 NULL\r
1475 );\r
7e3bcccb 1476\r
4a22b9bc
ED
1477 HiiCreateGotoOpCode (\r
1478 StartOpCodeHandle, // Container for dynamic created opcodes\r
1479 1, // Target Form ID\r
1480 STRING_TOKEN (STR_GOTO_FORM1), // Prompt text\r
1481 STRING_TOKEN (STR_GOTO_HELP), // Help text\r
1482 0, // Question flag\r
1483 0x8003 // Question ID\r
1484 );\r
a6973cff 1485\r
4a22b9bc
ED
1486 HiiUpdateForm (\r
1487 PrivateData->HiiHandle[0], // HII handle\r
c8ad2d7a 1488 &gDriverSampleFormSetGuid, // Formset GUID\r
4a22b9bc
ED
1489 0x1234, // Form ID\r
1490 StartOpCodeHandle, // Label for where to insert opcodes\r
1491 EndOpCodeHandle // Replace data\r
a6973cff 1492 );\r
7e3bcccb 1493\r
4a22b9bc
ED
1494 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1495 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
1496 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1497 break;\r
7e3bcccb 1498\r
93e3992d 1499 default:\r
1500 break;\r
1501 }\r
4a22b9bc
ED
1502 }\r
1503 break;\r
93e3992d 1504\r
3a4e7a3e
ED
1505 case EFI_BROWSER_ACTION_CHANGED:\r
1506 switch (QuestionId) {\r
1507 case 0x1237:\r
1508 //\r
1509 // User press "Exit now", request Browser to exit\r
1510 //\r
1511 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
1512 break;\r
1513 \r
1514 case 0x1238:\r
1515 //\r
1516 // User press "Save now", request Browser to save the uncommitted data.\r
1517 //\r
1518 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
1519 break;\r
1520 \r
1521 case 0x1241:\r
1522 case 0x1246:\r
1523 //\r
1524 // User press "Submit current form and Exit now", request Browser to submit current form and exit\r
1525 //\r
1526 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1527 break;\r
1528 \r
1529 case 0x1242:\r
1530 //\r
1531 // User press "Discard current form now", request Browser to discard the uncommitted data.\r
1532 //\r
1533 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD;\r
1534 break;\r
1535 \r
1536 case 0x1243:\r
1537 //\r
1538 // User press "Submit current form now", request Browser to save the uncommitted data.\r
1539 //\r
1540 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
1541 break;\r
1542 \r
1543 case 0x1244:\r
1544 case 0x1245:\r
1545 //\r
1546 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.\r
1547 //\r
1548 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1549 break;\r
34326197
ED
1550\r
1551 case 0x1231:\r
1552 //\r
1553 // 1. Check to see whether system support keyword.\r
1554 //\r
1555 Status = PrivateData->HiiKeywordHandler->GetData (PrivateData->HiiKeywordHandler,\r
1556 L"NAMESPACE=x-UEFI-ns",\r
1557 L"KEYWORD=iSCSIBootEnable",\r
1558 &Progress,\r
1559 &ProgressErr,\r
1560 &Results\r
1561 );\r
1562 if (EFI_ERROR (Status)) {\r
1563 do {\r
1564 CreatePopUp (\r
1565 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1566 &Key,\r
1567 L"",\r
1568 L"This system not support this keyword!",\r
1569 L"Press ENTER to continue ...",\r
1570 L"",\r
1571 NULL\r
1572 );\r
1573 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1574\r
1575 Status = EFI_SUCCESS;\r
1576 break;\r
1577 }\r
1578\r
1579 //\r
1580 // 2. If system support this keyword, just try to change value.\r
1581 //\r
3a4e7a3e 1582 \r
34326197
ED
1583 //\r
1584 // Change value from '0' to '1' or from '1' to '0'\r
1585 //\r
1586 TmpStr = StrStr (Results, L"&VALUE=");\r
1587 ASSERT (TmpStr != NULL);\r
1588 TmpStr += StrLen (L"&VALUE=");\r
1589 TmpStr++;\r
1590 if (*TmpStr == L'0') {\r
1591 *TmpStr = L'1';\r
1592 } else {\r
1593 *TmpStr = L'0';\r
1594 }\r
1595\r
1596 //\r
1597 // 3. Call the keyword handler protocol to change the value.\r
1598 //\r
1599 Status = PrivateData->HiiKeywordHandler->SetData (PrivateData->HiiKeywordHandler,\r
1600 Results,\r
1601 &Progress,\r
1602 &ProgressErr\r
1603 );\r
1604 if (EFI_ERROR (Status)) {\r
1605 do {\r
1606 CreatePopUp (\r
1607 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1608 &Key,\r
1609 L"",\r
1610 L"Set keyword to the system failed!",\r
1611 L"Press ENTER to continue ...",\r
1612 L"",\r
1613 NULL\r
1614 );\r
1615 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);\r
1616\r
1617 Status = EFI_SUCCESS;\r
1618 break;\r
1619 }\r
1620 break;\r
1621\r
3a4e7a3e
ED
1622 default:\r
1623 break;\r
1624 }\r
1625 break;\r
1626\r
003f3c00
DB
1627 case EFI_BROWSER_ACTION_SUBMITTED:\r
1628 {\r
1629 if (QuestionId == 0x1250) {\r
1630 //\r
1631 // Sample CallBack for EFI_BROWSER_ACTION_SUBMITTED action:\r
1632 // Show up a pop-up to show SUBMITTED callback has been triggered.\r
1633 //\r
1634 do {\r
1635 CreatePopUp (\r
1636 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1637 &Key,\r
1638 L"",\r
1639 L"EfiVarstore value has been submitted!",\r
1640 L"Press ESC or ENTER to continue ...",\r
1641 L"",\r
1642 NULL\r
1643 );\r
1644 } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));\r
1645 }\r
1646 }\r
1647 break;\r
1648\r
93e3992d 1649 default:\r
4a22b9bc 1650 Status = EFI_UNSUPPORTED;\r
93e3992d 1651 break;\r
1652 }\r
1653\r
1654 return Status;\r
1655}\r
1656\r
7064c0a5 1657/**\r
1658 Main entry for this driver.\r
a6973cff 1659\r
7064c0a5 1660 @param ImageHandle Image handle this driver.\r
1661 @param SystemTable Pointer to SystemTable.\r
1662\r
1663 @retval EFI_SUCESS This function always complete successfully.\r
1664\r
1665**/\r
93e3992d 1666EFI_STATUS\r
1667EFIAPI\r
1668DriverSampleInit (\r
1669 IN EFI_HANDLE ImageHandle,\r
1670 IN EFI_SYSTEM_TABLE *SystemTable\r
1671 )\r
1672{\r
1673 EFI_STATUS Status;\r
93e3992d 1674 EFI_HII_HANDLE HiiHandle[2];\r
93e3992d 1675 EFI_SCREEN_DESCRIPTOR Screen;\r
1676 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
1677 EFI_HII_STRING_PROTOCOL *HiiString;\r
1678 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
1679 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
34326197 1680 EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;\r
93e3992d 1681 CHAR16 *NewString;\r
1682 UINTN BufferSize;\r
1683 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
84f9a9ec 1684 BOOLEAN ActionFlag;\r
a6973cff 1685 EFI_STRING ConfigRequestHdr;\r
82e8c138 1686 EFI_STRING NameRequestHdr;\r
78c2b9a3 1687 MY_EFI_VARSTORE_DATA *VarStoreConfig;\r
2b826e21 1688 EFI_INPUT_KEY HotKey;\r
2fa0e11d 1689 EDKII_FORM_BROWSER_EXTENSION_PROTOCOL *FormBrowserEx;\r
a6973cff 1690\r
93e3992d 1691 //\r
84f9a9ec 1692 // Initialize the local variables.\r
93e3992d 1693 //\r
84f9a9ec 1694 ConfigRequestHdr = NULL;\r
33efdf51
ED
1695 NewString = NULL;\r
1696\r
93e3992d 1697 //\r
1698 // Initialize screen dimensions for SendForm().\r
1699 // Remove 3 characters from top and bottom\r
1700 //\r
1701 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
1702 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);\r
1703\r
1704 Screen.TopRow = 3;\r
1705 Screen.BottomRow = Screen.BottomRow - 3;\r
1706\r
1707 //\r
1708 // Initialize driver private data\r
1709 //\r
7b2c31ae
LG
1710 mPrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));\r
1711 if (mPrivateData == NULL) {\r
93e3992d 1712 return EFI_OUT_OF_RESOURCES;\r
1713 }\r
1714\r
7b2c31ae 1715 mPrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;\r
93e3992d 1716\r
7b2c31ae
LG
1717 mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;\r
1718 mPrivateData->ConfigAccess.RouteConfig = RouteConfig;\r
1719 mPrivateData->ConfigAccess.Callback = DriverCallback;\r
93e3992d 1720\r
1721 //\r
1722 // Locate Hii Database protocol\r
1723 //\r
1724 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
1725 if (EFI_ERROR (Status)) {\r
1726 return Status;\r
1727 }\r
7b2c31ae 1728 mPrivateData->HiiDatabase = HiiDatabase;\r
93e3992d 1729\r
1730 //\r
1731 // Locate HiiString protocol\r
1732 //\r
1733 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
1734 if (EFI_ERROR (Status)) {\r
1735 return Status;\r
1736 }\r
7b2c31ae 1737 mPrivateData->HiiString = HiiString;\r
93e3992d 1738\r
1739 //\r
1740 // Locate Formbrowser2 protocol\r
1741 //\r
1742 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
1743 if (EFI_ERROR (Status)) {\r
1744 return Status;\r
1745 }\r
7b2c31ae 1746 mPrivateData->FormBrowser2 = FormBrowser2;\r
93e3992d 1747\r
1748 //\r
1749 // Locate ConfigRouting protocol\r
1750 //\r
1751 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);\r
1752 if (EFI_ERROR (Status)) {\r
1753 return Status;\r
1754 }\r
7b2c31ae 1755 mPrivateData->HiiConfigRouting = HiiConfigRouting;\r
93e3992d 1756\r
34326197
ED
1757 //\r
1758 // Locate keyword handler protocol\r
1759 //\r
1760 Status = gBS->LocateProtocol (&gEfiConfigKeywordHandlerProtocolGuid, NULL, (VOID **) &HiiKeywordHandler);\r
1761 if (EFI_ERROR (Status)) {\r
1762 return Status;\r
1763 }\r
7b2c31ae 1764 mPrivateData->HiiKeywordHandler = HiiKeywordHandler;\r
34326197 1765\r
f6f910dd 1766 Status = gBS->InstallMultipleProtocolInterfaces (\r
93e3992d 1767 &DriverHandle[0],\r
f6f910dd 1768 &gEfiDevicePathProtocolGuid,\r
2f3065c0 1769 &mHiiVendorDevicePath0,\r
93e3992d 1770 &gEfiHiiConfigAccessProtocolGuid,\r
7b2c31ae 1771 &mPrivateData->ConfigAccess,\r
f6f910dd 1772 NULL\r
93e3992d 1773 );\r
1774 ASSERT_EFI_ERROR (Status);\r
1775\r
7b2c31ae 1776 mPrivateData->DriverHandle[0] = DriverHandle[0];\r
f6f910dd 1777\r
93e3992d 1778 //\r
1779 // Publish our HII data\r
1780 //\r
cb7d01c0 1781 HiiHandle[0] = HiiAddPackages (\r
c8ad2d7a 1782 &gDriverSampleFormSetGuid,\r
cb7d01c0 1783 DriverHandle[0],\r
1784 DriverSampleStrings,\r
1785 VfrBin,\r
1786 NULL\r
1787 );\r
1788 if (HiiHandle[0] == NULL) {\r
93e3992d 1789 return EFI_OUT_OF_RESOURCES;\r
1790 }\r
1791\r
7b2c31ae 1792 mPrivateData->HiiHandle[0] = HiiHandle[0];\r
93e3992d 1793\r
1794 //\r
1795 // Publish another Fromset\r
1796 //\r
f6f910dd 1797 Status = gBS->InstallMultipleProtocolInterfaces (\r
1798 &DriverHandle[1],\r
1799 &gEfiDevicePathProtocolGuid,\r
2f3065c0 1800 &mHiiVendorDevicePath1,\r
34326197 1801 &gEfiHiiConfigAccessProtocolGuid,\r
7b2c31ae 1802 &mPrivateData->ConfigAccess,\r
f6f910dd 1803 NULL\r
1804 );\r
1805 ASSERT_EFI_ERROR (Status);\r
1806\r
7b2c31ae 1807 mPrivateData->DriverHandle[1] = DriverHandle[1];\r
93e3992d 1808\r
cb7d01c0 1809 HiiHandle[1] = HiiAddPackages (\r
c8ad2d7a 1810 &gDriverSampleInventoryGuid,\r
cb7d01c0 1811 DriverHandle[1],\r
1812 DriverSampleStrings,\r
1813 InventoryBin,\r
1814 NULL\r
1815 );\r
1816 if (HiiHandle[1] == NULL) {\r
38ebfecb 1817 DriverSampleUnload (ImageHandle);\r
93e3992d 1818 return EFI_OUT_OF_RESOURCES;\r
1819 }\r
1820\r
7b2c31ae 1821 mPrivateData->HiiHandle[1] = HiiHandle[1];\r
93e3992d 1822\r
b204f2b5
ED
1823 //\r
1824 // Update the device path string.\r
1825 //\r
863986b3 1826 NewString = ConvertDevicePathToText((EFI_DEVICE_PATH_PROTOCOL*)&mHiiVendorDevicePath0, FALSE, FALSE);\r
33efdf51 1827 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_DEVICE_PATH), NewString, NULL) == 0) {\r
b204f2b5
ED
1828 DriverSampleUnload (ImageHandle);\r
1829 return EFI_OUT_OF_RESOURCES;\r
1830 }\r
33efdf51
ED
1831 if (NewString != NULL) {\r
1832 FreePool (NewString);\r
1833 }\r
1834\r
93e3992d 1835 //\r
1836 // Very simple example of how one would update a string that is already\r
1837 // in the HII database\r
1838 //\r
1839 NewString = L"700 Mhz";\r
1840\r
cb7d01c0 1841 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {\r
38ebfecb 1842 DriverSampleUnload (ImageHandle);\r
cb7d01c0 1843 return EFI_OUT_OF_RESOURCES;\r
93e3992d 1844 }\r
1845\r
38ebfecb
LG
1846 HiiSetString (HiiHandle[0], 0, NewString, NULL);\r
1847\r
1848 //\r
1849 // Initialize Name/Value name String ID\r
1850 //\r
7b2c31ae
LG
1851 mPrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0;\r
1852 mPrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1;\r
1853 mPrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2;\r
38ebfecb 1854\r
93e3992d 1855 //\r
1856 // Initialize configuration data\r
1857 //\r
7b2c31ae 1858 Configuration = &mPrivateData->Configuration;\r
93e3992d 1859 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
1860\r
1861 //\r
1862 // Try to read NV config EFI variable first\r
1863 //\r
c8ad2d7a 1864 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, VariableName, DriverHandle[0]);\r
84f9a9ec
LG
1865 ASSERT (ConfigRequestHdr != NULL);\r
1866\r
82e8c138
ED
1867 NameRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, NULL, DriverHandle[0]);\r
1868 ASSERT (NameRequestHdr != NULL);\r
1869\r
93e3992d 1870 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
c8ad2d7a 1871 Status = gRT->GetVariable (VariableName, &gDriverSampleFormSetGuid, NULL, &BufferSize, Configuration);\r
84f9a9ec 1872 if (EFI_ERROR (Status)) {\r
04da0b4a
LG
1873 //\r
1874 // Store zero data Buffer Storage to EFI variable\r
1875 //\r
1876 Status = gRT->SetVariable(\r
1877 VariableName,\r
c8ad2d7a 1878 &gDriverSampleFormSetGuid,\r
04da0b4a
LG
1879 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1880 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1881 Configuration\r
1882 );\r
2c775600
ED
1883 if (EFI_ERROR (Status)) {\r
1884 DriverSampleUnload (ImageHandle);\r
1885 return Status;\r
1886 }\r
93e3992d 1887 //\r
1888 // EFI variable for NV config doesn't exit, we should build this variable\r
1889 // based on default values stored in IFR\r
1890 //\r
82e8c138 1891 ActionFlag = HiiSetToDefaults (NameRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
2c775600
ED
1892 if (!ActionFlag) {\r
1893 DriverSampleUnload (ImageHandle);\r
1894 return EFI_INVALID_PARAMETER;\r
1895 }\r
82e8c138 1896\r
84f9a9ec 1897 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
2c775600
ED
1898 if (!ActionFlag) {\r
1899 DriverSampleUnload (ImageHandle);\r
1900 return EFI_INVALID_PARAMETER;\r
1901 }\r
84f9a9ec
LG
1902 } else {\r
1903 //\r
1904 // EFI variable does exist and Validate Current Setting\r
1905 //\r
82e8c138 1906 ActionFlag = HiiValidateSettings (NameRequestHdr);\r
2c775600
ED
1907 if (!ActionFlag) {\r
1908 DriverSampleUnload (ImageHandle);\r
1909 return EFI_INVALID_PARAMETER;\r
1910 }\r
82e8c138 1911\r
84f9a9ec 1912 ActionFlag = HiiValidateSettings (ConfigRequestHdr);\r
2c775600
ED
1913 if (!ActionFlag) {\r
1914 DriverSampleUnload (ImageHandle);\r
1915 return EFI_INVALID_PARAMETER;\r
1916 }\r
93e3992d 1917 }\r
78c2b9a3 1918 FreePool (ConfigRequestHdr);\r
a6973cff 1919\r
78c2b9a3
ED
1920 //\r
1921 // Initialize efi varstore configuration data\r
1922 //\r
7b2c31ae 1923 VarStoreConfig = &mPrivateData->VarStoreConfig;\r
78c2b9a3
ED
1924 ZeroMem (VarStoreConfig, sizeof (MY_EFI_VARSTORE_DATA));\r
1925\r
c8ad2d7a 1926 ConfigRequestHdr = HiiConstructConfigHdr (&gDriverSampleFormSetGuid, MyEfiVar, DriverHandle[0]);\r
78c2b9a3
ED
1927 ASSERT (ConfigRequestHdr != NULL);\r
1928\r
1929 BufferSize = sizeof (MY_EFI_VARSTORE_DATA);\r
c8ad2d7a 1930 Status = gRT->GetVariable (MyEfiVar, &gDriverSampleFormSetGuid, NULL, &BufferSize, VarStoreConfig);\r
78c2b9a3
ED
1931 if (EFI_ERROR (Status)) {\r
1932 //\r
1933 // Store zero data to EFI variable Storage.\r
1934 //\r
1935 Status = gRT->SetVariable(\r
1936 MyEfiVar,\r
c8ad2d7a 1937 &gDriverSampleFormSetGuid,\r
78c2b9a3
ED
1938 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1939 sizeof (MY_EFI_VARSTORE_DATA),\r
1940 VarStoreConfig\r
1941 );\r
2c775600
ED
1942 if (EFI_ERROR (Status)) {\r
1943 DriverSampleUnload (ImageHandle);\r
1944 return Status;\r
1945 }\r
78c2b9a3
ED
1946 //\r
1947 // EFI variable for NV config doesn't exit, we should build this variable\r
1948 // based on default values stored in IFR\r
1949 //\r
1950 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
2c775600
ED
1951 if (!ActionFlag) {\r
1952 DriverSampleUnload (ImageHandle);\r
1953 return EFI_INVALID_PARAMETER;\r
1954 }\r
78c2b9a3
ED
1955 } else {\r
1956 //\r
1957 // EFI variable does exist and Validate Current Setting\r
1958 //\r
1959 ActionFlag = HiiValidateSettings (ConfigRequestHdr);\r
2c775600
ED
1960 if (!ActionFlag) {\r
1961 DriverSampleUnload (ImageHandle);\r
1962 return EFI_INVALID_PARAMETER;\r
1963 }\r
78c2b9a3 1964 }\r
84f9a9ec
LG
1965 FreePool (ConfigRequestHdr);\r
1966\r
211cc6e5
ED
1967 Status = gBS->CreateEventEx (\r
1968 EVT_NOTIFY_SIGNAL, \r
1969 TPL_NOTIFY,\r
ac72474d 1970 EfiEventEmptyFunction,\r
211cc6e5 1971 NULL,\r
c8ad2d7a 1972 &gEfiIfrRefreshIdOpGuid,\r
211cc6e5
ED
1973 &mEvent\r
1974 );\r
1975 ASSERT_EFI_ERROR (Status);\r
2b826e21
LG
1976\r
1977 //\r
1978 // Example of how to use BrowserEx protocol to register HotKey.\r
1979 // \r
2fa0e11d 1980 Status = gBS->LocateProtocol (&gEdkiiFormBrowserExProtocolGuid, NULL, (VOID **) &FormBrowserEx);\r
2b826e21
LG
1981 if (!EFI_ERROR (Status)) {\r
1982 //\r
1983 // First unregister the default hot key F9 and F10.\r
1984 //\r
1985 HotKey.UnicodeChar = CHAR_NULL;\r
1986 HotKey.ScanCode = SCAN_F9;\r
1987 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);\r
1988 HotKey.ScanCode = SCAN_F10;\r
1989 FormBrowserEx->RegisterHotKey (&HotKey, 0, 0, NULL);\r
1990 \r
1991 //\r
1992 // Register the default HotKey F9 and F10 again.\r
1993 //\r
1994 HotKey.ScanCode = SCAN_F10;\r
7b2c31ae 1995 NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_TEN_STRING), NULL);\r
2b826e21
LG
1996 ASSERT (NewString != NULL);\r
1997 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_SUBMIT, 0, NewString);\r
1998 HotKey.ScanCode = SCAN_F9;\r
7b2c31ae 1999 NewString = HiiGetString (mPrivateData->HiiHandle[0], STRING_TOKEN (FUNCTION_NINE_STRING), NULL);\r
2b826e21
LG
2000 ASSERT (NewString != NULL);\r
2001 FormBrowserEx->RegisterHotKey (&HotKey, BROWSER_ACTION_DEFAULT, EFI_HII_DEFAULT_CLASS_STANDARD, NewString);\r
2002 }\r
2003\r
93e3992d 2004 //\r
a6973cff 2005 // In default, this driver is built into Flash device image,\r
7e3bcccb 2006 // the following code doesn't run.\r
93e3992d 2007 //\r
7e3bcccb 2008\r
2f3065c0 2009 //\r
7e3bcccb 2010 // Example of how to display only the item we sent to HII\r
a6973cff 2011 // When this driver is not built into Flash device image,\r
7e3bcccb 2012 // it need to call SendForm to show front page by itself.\r
2f3065c0 2013 //\r
7e3bcccb
LG
2014 if (DISPLAY_ONLY_MY_ITEM <= 1) {\r
2015 //\r
2016 // Have the browser pull out our copy of the data, and only display our data\r
2017 //\r
2018 Status = FormBrowser2->SendForm (\r
2019 FormBrowser2,\r
2020 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),\r
2021 1,\r
2022 NULL,\r
2023 0,\r
2024 NULL,\r
2025 NULL\r
2026 );\r
a6973cff 2027\r
14d59fa1 2028 HiiRemovePackages (HiiHandle[0]);\r
a6973cff 2029\r
14d59fa1 2030 HiiRemovePackages (HiiHandle[1]);\r
2f3065c0
LG
2031 }\r
2032\r
84f9a9ec 2033 return EFI_SUCCESS;\r
2f3065c0
LG
2034}\r
2035\r
2036/**\r
2037 Unloads the application and its installed protocol.\r
2038\r
2039 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
2040\r
2041 @retval EFI_SUCCESS The image has been unloaded.\r
2042**/\r
2043EFI_STATUS\r
2044EFIAPI\r
2045DriverSampleUnload (\r
2046 IN EFI_HANDLE ImageHandle\r
2047 )\r
2048{\r
38ebfecb 2049 UINTN Index;\r
f0c855b2 2050\r
7b2c31ae 2051 ASSERT (mPrivateData != NULL);\r
f0c855b2 2052\r
2f3065c0
LG
2053 if (DriverHandle[0] != NULL) {\r
2054 gBS->UninstallMultipleProtocolInterfaces (\r
2055 DriverHandle[0],\r
2056 &gEfiDevicePathProtocolGuid,\r
2057 &mHiiVendorDevicePath0,\r
2058 &gEfiHiiConfigAccessProtocolGuid,\r
7b2c31ae 2059 &mPrivateData->ConfigAccess,\r
2f3065c0
LG
2060 NULL\r
2061 );\r
ccee6099 2062 DriverHandle[0] = NULL;\r
2f3065c0
LG
2063 }\r
2064\r
2065 if (DriverHandle[1] != NULL) {\r
2066 gBS->UninstallMultipleProtocolInterfaces (\r
2067 DriverHandle[1],\r
2068 &gEfiDevicePathProtocolGuid,\r
2069 &mHiiVendorDevicePath1,\r
41c244b6
DB
2070 &gEfiHiiConfigAccessProtocolGuid,\r
2071 &mPrivateData->ConfigAccess,\r
2f3065c0
LG
2072 NULL\r
2073 );\r
ccee6099 2074 DriverHandle[1] = NULL;\r
2f3065c0
LG
2075 }\r
2076\r
7b2c31ae
LG
2077 if (mPrivateData->HiiHandle[0] != NULL) {\r
2078 HiiRemovePackages (mPrivateData->HiiHandle[0]);\r
14d59fa1
LG
2079 }\r
2080\r
7b2c31ae
LG
2081 if (mPrivateData->HiiHandle[1] != NULL) {\r
2082 HiiRemovePackages (mPrivateData->HiiHandle[1]);\r
14d59fa1
LG
2083 }\r
2084\r
f0c855b2 2085 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {\r
7b2c31ae
LG
2086 if (mPrivateData->NameValueName[Index] != NULL) {\r
2087 FreePool (mPrivateData->NameValueName[Index]);\r
38ebfecb 2088 }\r
93e3992d 2089 }\r
7b2c31ae
LG
2090 FreePool (mPrivateData);\r
2091 mPrivateData = NULL;\r
93e3992d 2092\r
211cc6e5
ED
2093 gBS->CloseEvent (mEvent);\r
2094\r
93e3992d 2095 return EFI_SUCCESS;\r
2096}\r