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