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