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