]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
Fixed SCT test failed caused by driver sample.
[mirror_edk2.git] / MdeModulePkg / Universal / DriverSampleDxe / DriverSample.c
... / ...
CommitLineData
1/** @file\r
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
5Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
6This program and the accompanying materials\r
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
14**/\r
15\r
16\r
17#include "DriverSample.h"\r
18\r
19#define DISPLAY_ONLY_MY_ITEM 0x0002\r
20\r
21EFI_GUID mFormSetGuid = FORMSET_GUID;\r
22EFI_GUID mInventoryGuid = INVENTORY_GUID;\r
23\r
24CHAR16 VariableName[] = L"MyIfrNVData";\r
25EFI_HANDLE DriverHandle[2] = {NULL, NULL};\r
26DRIVER_SAMPLE_PRIVATE_DATA *PrivateData = NULL;\r
27\r
28HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath0 = {\r
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
46 {\r
47 (UINT8) (END_DEVICE_PATH_LENGTH),\r
48 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
49 }\r
50 }\r
51};\r
52\r
53HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath1 = {\r
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
71 {\r
72 (UINT8) (END_DEVICE_PATH_LENGTH),\r
73 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
74 }\r
75 }\r
76};\r
77\r
78/**\r
79 Encode the password using a simple algorithm.\r
80\r
81 @param Password The string to be encoded.\r
82 @param MaxSize The size of the string.\r
83\r
84**/\r
85VOID\r
86EncodePassword (\r
87 IN CHAR16 *Password,\r
88 IN UINTN MaxSize\r
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
108 FreePool (Buffer);\r
109 return ;\r
110}\r
111\r
112/**\r
113 Validate the user's password.\r
114\r
115 @param PrivateData This driver's private context data.\r
116 @param StringId The user's input.\r
117\r
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
121EFI_STATUS\r
122ValidatePassword (\r
123 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,\r
124 IN EFI_STRING_ID StringId\r
125 )\r
126{\r
127 EFI_STATUS Status;\r
128 UINTN Index;\r
129 UINTN BufferSize;\r
130 UINTN PasswordMaxSize;\r
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
154 PasswordMaxSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);\r
155 //\r
156 // Check whether we have any old password set\r
157 //\r
158 for (Index = 0; Index < PasswordMaxSize / sizeof (UINT16); Index++) {\r
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
174 Password = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL);\r
175 if (Password == NULL) {\r
176 return EFI_NOT_READY;\r
177 }\r
178 if (StrSize (Password) > PasswordMaxSize) {\r
179 FreePool (Password);\r
180 return EFI_NOT_READY;\r
181 }\r
182\r
183 //\r
184 // Validate old password\r
185 //\r
186 EncodedPassword = AllocateZeroPool (PasswordMaxSize);\r
187 ASSERT (EncodedPassword != NULL);\r
188 StrnCpy (EncodedPassword, Password, StrLen (Password));\r
189 EncodePassword (EncodedPassword, StrLen (EncodedPassword) * sizeof (CHAR16));\r
190 if (CompareMem (EncodedPassword, PrivateData->Configuration.WhatIsThePassword2, PasswordMaxSize) != 0) {\r
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
199 FreePool (Password);\r
200 FreePool (EncodedPassword);\r
201\r
202 return Status;\r
203}\r
204\r
205/**\r
206 Encode the password using a simple algorithm.\r
207\r
208 @param PrivateData This driver's private context data.\r
209 @param StringId The password from User.\r
210\r
211 @retval EFI_SUCESS The operation is successful.\r
212 @return Other value if gRT->SetVariable () fails.\r
213\r
214**/\r
215EFI_STATUS\r
216SetPassword (\r
217 IN DRIVER_SAMPLE_PRIVATE_DATA *PrivateData,\r
218 IN EFI_STRING_ID StringId\r
219 )\r
220{\r
221 EFI_STATUS Status;\r
222 CHAR16 *Password;\r
223 CHAR16 *TempPassword;\r
224 UINTN PasswordSize;\r
225 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
226 UINTN BufferSize;\r
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
247 PasswordSize = sizeof (PrivateData->Configuration.WhatIsThePassword2);\r
248 ZeroMem (Password, PasswordSize);\r
249\r
250 TempPassword = HiiGetString (PrivateData->HiiHandle[0], StringId, NULL);\r
251 if (TempPassword == NULL) {\r
252 return EFI_NOT_READY;\r
253 }\r
254 if (StrSize (TempPassword) > PasswordSize) {\r
255 FreePool (TempPassword);\r
256 return EFI_NOT_READY;\r
257 }\r
258 StrnCpy (Password, TempPassword, StrLen (TempPassword));\r
259 FreePool (TempPassword);\r
260\r
261 //\r
262 // Retrive uncommitted data from Browser\r
263 //\r
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
267 //\r
268 // Update password's clear text in the screen\r
269 //\r
270 CopyMem (Configuration->PasswordClearText, Password, StrSize (Password));\r
271\r
272 //\r
273 // Update uncommitted data of Browser\r
274 //\r
275 HiiSetBrowserData (\r
276 &mFormSetGuid,\r
277 VariableName,\r
278 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
279 (UINT8 *) Configuration,\r
280 NULL\r
281 );\r
282 }\r
283\r
284 //\r
285 // Free Configuration Buffer\r
286 //\r
287 FreePool (Configuration);\r
288\r
289\r
290 //\r
291 // Set password\r
292 //\r
293 EncodePassword (Password, StrLen (Password) * 2);\r
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
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
336\r
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
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
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
605 *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth);\r
606 return;\r
607 }\r
608 }\r
609}\r
610\r
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
632 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
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
650 EFI_STRING ConfigRequest;\r
651 EFI_STRING ConfigRequestHdr;\r
652 UINTN Size;\r
653 EFI_STRING Value;\r
654 UINTN ValueStrLen;\r
655 CHAR16 BackupChar;\r
656 CHAR16 *StrPointer;\r
657 BOOLEAN AllocatedRequest;\r
658\r
659 if (Progress == NULL || Results == NULL) {\r
660 return EFI_INVALID_PARAMETER;\r
661 }\r
662 //\r
663 // Initialize the local variables.\r
664 //\r
665 ConfigRequestHdr = NULL;\r
666 ConfigRequest = NULL;\r
667 Size = 0;\r
668 *Progress = Request;\r
669 AllocatedRequest = FALSE;\r
670\r
671 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
672 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
673\r
674 //\r
675 // Get Buffer Storage data from EFI variable.\r
676 // Try to get the current setting from variable.\r
677 //\r
678 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
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
687 return EFI_NOT_FOUND;\r
688 }\r
689\r
690 if (Request == NULL) {\r
691 //\r
692 // Request is set to NULL, construct full request string.\r
693 //\r
694\r
695 //\r
696 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
697 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
698 //\r
699 ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
700 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
701 ConfigRequest = AllocateZeroPool (Size);\r
702 ASSERT (ConfigRequest != NULL);\r
703 AllocatedRequest = TRUE;\r
704 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
705 FreePool (ConfigRequestHdr);\r
706 ConfigRequestHdr = NULL;\r
707 } else {\r
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
712 if (!HiiIsConfigHdrMatch (Request, &mFormSetGuid, NULL)) {\r
713 return EFI_NOT_FOUND;\r
714 }\r
715 //\r
716 // Set Request to the unified request string.\r
717 //\r
718 ConfigRequest = Request;\r
719 //\r
720 // Check whether Request includes Request Element.\r
721 //\r
722 if (StrStr (Request, L"OFFSET") == NULL) {\r
723 //\r
724 // Check Request Element does exist in Reques String\r
725 //\r
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
733 ASSERT (ConfigRequest != NULL);\r
734 AllocatedRequest = TRUE;\r
735 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);\r
736 }\r
737 }\r
738 }\r
739\r
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
751\r
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
765\r
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
811\r
812 *Value++ = L'=';\r
813 //\r
814 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
815 //\r
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
819 }\r
820 }\r
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
835 if (!EFI_ERROR (Status)) {\r
836 ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
837 AppendAltCfgString(Results, ConfigRequestHdr);\r
838 }\r
839 }\r
840\r
841 //\r
842 // Free the allocated config request string.\r
843 //\r
844 if (AllocatedRequest) {\r
845 FreePool (ConfigRequest);\r
846 }\r
847\r
848 if (ConfigRequestHdr != NULL) {\r
849 FreePool (ConfigRequestHdr);\r
850 }\r
851 //\r
852 // Set Progress string to the original request string.\r
853 //\r
854 if (Request == NULL) {\r
855 *Progress = NULL;\r
856 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
857 *Progress = Request + StrLen (Request);\r
858 }\r
859\r
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
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
901\r
902 if (Configuration == NULL || Progress == NULL) {\r
903 return EFI_INVALID_PARAMETER;\r
904 }\r
905\r
906 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
907 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
908 *Progress = Configuration;\r
909\r
910 //\r
911 // Check routing data in <ConfigHdr>.\r
912 // Note: if only one Storage is used, then this checking could be skipped.\r
913 //\r
914 if (!HiiIsConfigHdrMatch (Configuration, &mFormSetGuid, NULL)) {\r
915 return EFI_NOT_FOUND;\r
916 }\r
917\r
918 //\r
919 // Get Buffer Storage data from EFI variable\r
920 //\r
921 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
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
932\r
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
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
1117 UINT8 MyVar;\r
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
1123 EFI_INPUT_KEY Key;\r
1124 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
1125 UINTN MyVarSize;\r
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
1131\r
1132\r
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
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
1253 case EFI_BROWSER_ACTION_CHANGING:\r
1254 {\r
1255 switch (QuestionId) {\r
1256 case 0x1234:\r
1257 //\r
1258 // Initialize the container for dynamic opcodes\r
1259 //\r
1260 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1261 ASSERT (StartOpCodeHandle != NULL);\r
1262\r
1263 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1264 ASSERT (EndOpCodeHandle != NULL);\r
1265\r
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
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
1279\r
1280 HiiCreateActionOpCode (\r
1281 StartOpCodeHandle, // Container for dynamic created opcodes\r
1282 0x1237, // Question ID\r
1283 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
1284 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
1285 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1286 0 // Action String ID\r
1287 );\r
1288\r
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
1301 );\r
1302\r
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
1322\r
1323 //\r
1324 // Set initial vlaue of dynamic created oneof Question in Form Browser\r
1325 //\r
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
1339 NULL\r
1340 );\r
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
1356\r
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
1371\r
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
1377 );\r
1378\r
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
1390\r
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
1402\r
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
1411\r
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
1418 );\r
1419\r
1420 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1421 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
1422 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1423 break;\r
1424\r
1425 case 0x5678:\r
1426 //\r
1427 // We will reach here once the Question is refreshed\r
1428 //\r
1429\r
1430 //\r
1431 // Initialize the container for dynamic opcodes\r
1432 //\r
1433 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1434 ASSERT (StartOpCodeHandle != NULL);\r
1435\r
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
1442\r
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
1450 );\r
1451\r
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
1459\r
1460 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1461\r
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
1473\r
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
1488\r
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
1495\r
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
1502\r
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
1512\r
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
1525\r
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
1530\r
1531 default:\r
1532 break;\r
1533 }\r
1534\r
1535 break;\r
1536\r
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
1552 default:\r
1553 break;\r
1554 }\r
1555 }\r
1556 break;\r
1557\r
1558 default:\r
1559 Status = EFI_UNSUPPORTED;\r
1560 break;\r
1561 }\r
1562\r
1563 return Status;\r
1564}\r
1565\r
1566/**\r
1567 Main entry for this driver.\r
1568\r
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
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
1583 EFI_HII_HANDLE HiiHandle[2];\r
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
1592 BOOLEAN ActionFlag;\r
1593 EFI_STRING ConfigRequestHdr;\r
1594\r
1595 //\r
1596 // Initialize the local variables.\r
1597 //\r
1598 ConfigRequestHdr = NULL;\r
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
1612 PrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));\r
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
1660 Status = gBS->InstallMultipleProtocolInterfaces (\r
1661 &DriverHandle[0],\r
1662 &gEfiDevicePathProtocolGuid,\r
1663 &mHiiVendorDevicePath0,\r
1664 &gEfiHiiConfigAccessProtocolGuid,\r
1665 &PrivateData->ConfigAccess,\r
1666 NULL\r
1667 );\r
1668 ASSERT_EFI_ERROR (Status);\r
1669\r
1670 PrivateData->DriverHandle[0] = DriverHandle[0];\r
1671\r
1672 //\r
1673 // Publish our HII data\r
1674 //\r
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
1683 return EFI_OUT_OF_RESOURCES;\r
1684 }\r
1685\r
1686 PrivateData->HiiHandle[0] = HiiHandle[0];\r
1687\r
1688 //\r
1689 // Publish another Fromset\r
1690 //\r
1691 Status = gBS->InstallMultipleProtocolInterfaces (\r
1692 &DriverHandle[1],\r
1693 &gEfiDevicePathProtocolGuid,\r
1694 &mHiiVendorDevicePath1,\r
1695 NULL\r
1696 );\r
1697 ASSERT_EFI_ERROR (Status);\r
1698\r
1699 PrivateData->DriverHandle[1] = DriverHandle[1];\r
1700\r
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
1709 DriverSampleUnload (ImageHandle);\r
1710 return EFI_OUT_OF_RESOURCES;\r
1711 }\r
1712\r
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
1721 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {\r
1722 DriverSampleUnload (ImageHandle);\r
1723 return EFI_OUT_OF_RESOURCES;\r
1724 }\r
1725\r
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
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
1744 ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, DriverHandle[0]);\r
1745 ASSERT (ConfigRequestHdr != NULL);\r
1746\r
1747 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
1748 Status = gRT->GetVariable (VariableName, &mFormSetGuid, NULL, &BufferSize, Configuration);\r
1749 if (EFI_ERROR (Status)) {\r
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
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
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
1773 }\r
1774\r
1775 FreePool (ConfigRequestHdr);\r
1776\r
1777\r
1778 //\r
1779 // In default, this driver is built into Flash device image,\r
1780 // the following code doesn't run.\r
1781 //\r
1782\r
1783 //\r
1784 // Example of how to display only the item we sent to HII\r
1785 // When this driver is not built into Flash device image,\r
1786 // it need to call SendForm to show front page by itself.\r
1787 //\r
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
1801\r
1802 HiiRemovePackages (HiiHandle[0]);\r
1803\r
1804 HiiRemovePackages (HiiHandle[1]);\r
1805 }\r
1806\r
1807 return EFI_SUCCESS;\r
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
1823 UINTN Index;\r
1824\r
1825 ASSERT (PrivateData != NULL);\r
1826\r
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
1836 DriverHandle[0] = NULL;\r
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
1846 DriverHandle[1] = NULL;\r
1847 }\r
1848\r
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
1857 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {\r
1858 if (PrivateData->NameValueName[Index] != NULL) {\r
1859 FreePool (PrivateData->NameValueName[Index]);\r
1860 }\r
1861 }\r
1862 FreePool (PrivateData);\r
1863 PrivateData = NULL;\r
1864\r
1865 return EFI_SUCCESS;\r
1866}\r