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