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