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