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