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