]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Universal/DriverSampleDxe/DriverSample.c
Add new call back return value; also add some sample code to use it.
[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 - 2011, 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 NewLen = StrLen (Result);\r
448 //\r
449 // String Len = ConfigResp + AltConfig + AltConfig + 1("\0")\r
450 //\r
451 NewLen = (NewLen + ((1 + StrLen (ConfigHdr) + 8 + 4) + (8 + 4 + 7 + 4 + 7 + 4)) * 2 + 1) * sizeof (CHAR16);\r
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 Value\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
606 *RequestResult = CreateAltCfgString(*RequestResult, ConfigRequestHdr, ValueOffset, ValueWidth);\r
607 return;\r
608 }\r
609 }\r
610}\r
611\r
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
633 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.\r
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
651 EFI_STRING ConfigRequest;\r
652 EFI_STRING ConfigRequestHdr;\r
653 UINTN Size;\r
654 EFI_STRING Value;\r
655 UINTN ValueStrLen;\r
656 CHAR16 BackupChar;\r
657 CHAR16 *StrPointer;\r
658 BOOLEAN AllocatedRequest;\r
659\r
660 if (Progress == NULL || Results == NULL) {\r
661 return EFI_INVALID_PARAMETER;\r
662 }\r
663 //\r
664 // Initialize the local variables.\r
665 //\r
666 ConfigRequestHdr = NULL;\r
667 ConfigRequest = NULL;\r
668 Size = 0;\r
669 *Progress = Request;\r
670 AllocatedRequest = FALSE;\r
671\r
672 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
673 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
674\r
675 //\r
676 // Get Buffer Storage data from EFI variable.\r
677 // Try to get the current setting from variable.\r
678 //\r
679 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
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
688 return EFI_NOT_FOUND;\r
689 }\r
690\r
691 if (Request == NULL) {\r
692 //\r
693 // Request is set to NULL, construct full request string.\r
694 //\r
695\r
696 //\r
697 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
698 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
699 //\r
700 ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
701 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
702 ConfigRequest = AllocateZeroPool (Size);\r
703 ASSERT (ConfigRequest != NULL);\r
704 AllocatedRequest = TRUE;\r
705 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
706 FreePool (ConfigRequestHdr);\r
707 ConfigRequestHdr = NULL;\r
708 } else {\r
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
713 if (!HiiIsConfigHdrMatch (Request, &mFormSetGuid, NULL)) {\r
714 return EFI_NOT_FOUND;\r
715 }\r
716 //\r
717 // Set Request to the unified request string.\r
718 //\r
719 ConfigRequest = Request;\r
720 //\r
721 // Check whether Request includes Request Element.\r
722 //\r
723 if (StrStr (Request, L"OFFSET") == NULL) {\r
724 //\r
725 // Check Request Element does exist in Reques String\r
726 //\r
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
734 ASSERT (ConfigRequest != NULL);\r
735 AllocatedRequest = TRUE;\r
736 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);\r
737 }\r
738 }\r
739 }\r
740\r
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
752\r
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
766\r
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
812\r
813 *Value++ = L'=';\r
814 //\r
815 // Convert Unicode String to Config String, e.g. "ABCD" => "0041004200430044"\r
816 //\r
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
820 }\r
821 }\r
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
836 if (!EFI_ERROR (Status)) {\r
837 ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, PrivateData->DriverHandle[0]);\r
838 AppendAltCfgString(Results, ConfigRequestHdr);\r
839 }\r
840 }\r
841\r
842 //\r
843 // Free the allocated config request string.\r
844 //\r
845 if (AllocatedRequest) {\r
846 FreePool (ConfigRequest);\r
847 }\r
848\r
849 if (ConfigRequestHdr != NULL) {\r
850 FreePool (ConfigRequestHdr);\r
851 }\r
852 //\r
853 // Set Progress string to the original request string.\r
854 //\r
855 if (Request == NULL) {\r
856 *Progress = NULL;\r
857 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
858 *Progress = Request + StrLen (Request);\r
859 }\r
860\r
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
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
902\r
903 if (Configuration == NULL || Progress == NULL) {\r
904 return EFI_INVALID_PARAMETER;\r
905 }\r
906\r
907 PrivateData = DRIVER_SAMPLE_PRIVATE_FROM_THIS (This);\r
908 HiiConfigRouting = PrivateData->HiiConfigRouting;\r
909 *Progress = Configuration;\r
910\r
911 //\r
912 // Check routing data in <ConfigHdr>.\r
913 // Note: if only one Storage is used, then this checking could be skipped.\r
914 //\r
915 if (!HiiIsConfigHdrMatch (Configuration, &mFormSetGuid, NULL)) {\r
916 return EFI_NOT_FOUND;\r
917 }\r
918\r
919 //\r
920 // Get Buffer Storage data from EFI variable\r
921 //\r
922 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
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
933\r
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
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
1118 UINT8 MyVar;\r
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
1124 EFI_INPUT_KEY Key;\r
1125 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
1126 UINTN MyVarSize;\r
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
1132\r
1133\r
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
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
1254 case EFI_BROWSER_ACTION_CHANGING:\r
1255 {\r
1256 switch (QuestionId) {\r
1257 case 0x1234:\r
1258 //\r
1259 // Initialize the container for dynamic opcodes\r
1260 //\r
1261 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1262 ASSERT (StartOpCodeHandle != NULL);\r
1263\r
1264 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1265 ASSERT (EndOpCodeHandle != NULL);\r
1266\r
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
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
1280\r
1281 HiiCreateActionOpCode (\r
1282 StartOpCodeHandle, // Container for dynamic created opcodes\r
1283 0x1237, // Question ID\r
1284 STRING_TOKEN(STR_EXIT_TEXT), // Prompt text\r
1285 STRING_TOKEN(STR_EXIT_TEXT), // Help text\r
1286 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1287 0 // Action String ID\r
1288 );\r
1289\r
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
1302 );\r
1303\r
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
1323\r
1324 //\r
1325 // Set initial vlaue of dynamic created oneof Question in Form Browser\r
1326 //\r
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
1340 NULL\r
1341 );\r
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
1357\r
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
1372\r
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
1378 );\r
1379\r
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
1391\r
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
1403\r
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
1412\r
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
1419 );\r
1420\r
1421 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1422 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
1423 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1424 break;\r
1425\r
1426 case 0x5678:\r
1427 //\r
1428 // We will reach here once the Question is refreshed\r
1429 //\r
1430\r
1431 //\r
1432 // Initialize the container for dynamic opcodes\r
1433 //\r
1434 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1435 ASSERT (StartOpCodeHandle != NULL);\r
1436\r
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
1443\r
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
1451 );\r
1452\r
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
1460\r
1461 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1462\r
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
1474\r
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
1489\r
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
1496\r
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
1503\r
1504 case 0x1241:\r
1505 //\r
1506 // User press "Submit current form and Exit now", request Browser to submit current form and exit\r
1507 //\r
1508 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1509 break;\r
1510\r
1511 case 0x1242:\r
1512 //\r
1513 // User press "Discard current form now", request Browser to discard the uncommitted data.\r
1514 //\r
1515 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD;\r
1516 break;\r
1517\r
1518 case 0x1243:\r
1519 //\r
1520 // User press "Submit current form now", request Browser to save the uncommitted data.\r
1521 //\r
1522 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;\r
1523 break;\r
1524\r
1525 case 0x1244:\r
1526 //\r
1527 // User press "Discard current form and Exit now", request Browser to discard the uncommitted data and exit.\r
1528 //\r
1529 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1530 break;\r
1531\r
1532 case 0x2000:\r
1533 //\r
1534 // Only used to update the state.\r
1535 //\r
1536 if ((Type == EFI_IFR_TYPE_STRING) && (Value->string == 0) && \r
1537 (PrivateData->PasswordState == BROWSER_STATE_SET_PASSWORD)) {\r
1538 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
1539 return EFI_INVALID_PARAMETER;\r
1540 }\r
1541\r
1542 //\r
1543 // When try to set a new password, user will be chanlleged with old password.\r
1544 // The Callback is responsible for validating old password input by user,\r
1545 // If Callback return EFI_SUCCESS, it indicates validation pass.\r
1546 //\r
1547 switch (PrivateData->PasswordState) {\r
1548 case BROWSER_STATE_VALIDATE_PASSWORD:\r
1549 Status = ValidatePassword (PrivateData, Value->string);\r
1550 if (Status == EFI_SUCCESS) {\r
1551 PrivateData->PasswordState = BROWSER_STATE_SET_PASSWORD;\r
1552 }\r
1553 break;\r
1554\r
1555 case BROWSER_STATE_SET_PASSWORD:\r
1556 Status = SetPassword (PrivateData, Value->string);\r
1557 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
1558 break;\r
1559\r
1560 default:\r
1561 break;\r
1562 }\r
1563\r
1564 break;\r
1565\r
1566 case 0x1111:\r
1567 //\r
1568 // EfiVarstore question takes sample action (print value as debug information) \r
1569 // after read/write question.\r
1570 //\r
1571 MyVarSize = 1;\r
1572 Status = gRT->GetVariable(\r
1573 L"MyVar",\r
1574 &mFormSetGuid,\r
1575 NULL,\r
1576 &MyVarSize,\r
1577 &MyVar\r
1578 );\r
1579 ASSERT_EFI_ERROR (Status);\r
1580 DEBUG ((DEBUG_INFO, "EfiVarstore question: Tall value is %d with value width %d\n", MyVar, MyVarSize));\r
1581 default:\r
1582 break;\r
1583 }\r
1584 }\r
1585 break;\r
1586\r
1587 default:\r
1588 Status = EFI_UNSUPPORTED;\r
1589 break;\r
1590 }\r
1591\r
1592 return Status;\r
1593}\r
1594\r
1595/**\r
1596 Main entry for this driver.\r
1597\r
1598 @param ImageHandle Image handle this driver.\r
1599 @param SystemTable Pointer to SystemTable.\r
1600\r
1601 @retval EFI_SUCESS This function always complete successfully.\r
1602\r
1603**/\r
1604EFI_STATUS\r
1605EFIAPI\r
1606DriverSampleInit (\r
1607 IN EFI_HANDLE ImageHandle,\r
1608 IN EFI_SYSTEM_TABLE *SystemTable\r
1609 )\r
1610{\r
1611 EFI_STATUS Status;\r
1612 EFI_HII_HANDLE HiiHandle[2];\r
1613 EFI_SCREEN_DESCRIPTOR Screen;\r
1614 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
1615 EFI_HII_STRING_PROTOCOL *HiiString;\r
1616 EFI_FORM_BROWSER2_PROTOCOL *FormBrowser2;\r
1617 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
1618 CHAR16 *NewString;\r
1619 UINTN BufferSize;\r
1620 DRIVER_SAMPLE_CONFIGURATION *Configuration;\r
1621 BOOLEAN ActionFlag;\r
1622 EFI_STRING ConfigRequestHdr;\r
1623\r
1624 //\r
1625 // Initialize the local variables.\r
1626 //\r
1627 ConfigRequestHdr = NULL;\r
1628 //\r
1629 // Initialize screen dimensions for SendForm().\r
1630 // Remove 3 characters from top and bottom\r
1631 //\r
1632 ZeroMem (&Screen, sizeof (EFI_SCREEN_DESCRIPTOR));\r
1633 gST->ConOut->QueryMode (gST->ConOut, gST->ConOut->Mode->Mode, &Screen.RightColumn, &Screen.BottomRow);\r
1634\r
1635 Screen.TopRow = 3;\r
1636 Screen.BottomRow = Screen.BottomRow - 3;\r
1637\r
1638 //\r
1639 // Initialize driver private data\r
1640 //\r
1641 PrivateData = AllocateZeroPool (sizeof (DRIVER_SAMPLE_PRIVATE_DATA));\r
1642 if (PrivateData == NULL) {\r
1643 return EFI_OUT_OF_RESOURCES;\r
1644 }\r
1645\r
1646 PrivateData->Signature = DRIVER_SAMPLE_PRIVATE_SIGNATURE;\r
1647\r
1648 PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;\r
1649 PrivateData->ConfigAccess.RouteConfig = RouteConfig;\r
1650 PrivateData->ConfigAccess.Callback = DriverCallback;\r
1651 PrivateData->PasswordState = BROWSER_STATE_VALIDATE_PASSWORD;\r
1652\r
1653 //\r
1654 // Locate Hii Database protocol\r
1655 //\r
1656 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &HiiDatabase);\r
1657 if (EFI_ERROR (Status)) {\r
1658 return Status;\r
1659 }\r
1660 PrivateData->HiiDatabase = HiiDatabase;\r
1661\r
1662 //\r
1663 // Locate HiiString protocol\r
1664 //\r
1665 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);\r
1666 if (EFI_ERROR (Status)) {\r
1667 return Status;\r
1668 }\r
1669 PrivateData->HiiString = HiiString;\r
1670\r
1671 //\r
1672 // Locate Formbrowser2 protocol\r
1673 //\r
1674 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &FormBrowser2);\r
1675 if (EFI_ERROR (Status)) {\r
1676 return Status;\r
1677 }\r
1678 PrivateData->FormBrowser2 = FormBrowser2;\r
1679\r
1680 //\r
1681 // Locate ConfigRouting protocol\r
1682 //\r
1683 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &HiiConfigRouting);\r
1684 if (EFI_ERROR (Status)) {\r
1685 return Status;\r
1686 }\r
1687 PrivateData->HiiConfigRouting = HiiConfigRouting;\r
1688\r
1689 Status = gBS->InstallMultipleProtocolInterfaces (\r
1690 &DriverHandle[0],\r
1691 &gEfiDevicePathProtocolGuid,\r
1692 &mHiiVendorDevicePath0,\r
1693 &gEfiHiiConfigAccessProtocolGuid,\r
1694 &PrivateData->ConfigAccess,\r
1695 NULL\r
1696 );\r
1697 ASSERT_EFI_ERROR (Status);\r
1698\r
1699 PrivateData->DriverHandle[0] = DriverHandle[0];\r
1700\r
1701 //\r
1702 // Publish our HII data\r
1703 //\r
1704 HiiHandle[0] = HiiAddPackages (\r
1705 &mFormSetGuid,\r
1706 DriverHandle[0],\r
1707 DriverSampleStrings,\r
1708 VfrBin,\r
1709 NULL\r
1710 );\r
1711 if (HiiHandle[0] == NULL) {\r
1712 return EFI_OUT_OF_RESOURCES;\r
1713 }\r
1714\r
1715 PrivateData->HiiHandle[0] = HiiHandle[0];\r
1716\r
1717 //\r
1718 // Publish another Fromset\r
1719 //\r
1720 Status = gBS->InstallMultipleProtocolInterfaces (\r
1721 &DriverHandle[1],\r
1722 &gEfiDevicePathProtocolGuid,\r
1723 &mHiiVendorDevicePath1,\r
1724 NULL\r
1725 );\r
1726 ASSERT_EFI_ERROR (Status);\r
1727\r
1728 PrivateData->DriverHandle[1] = DriverHandle[1];\r
1729\r
1730 HiiHandle[1] = HiiAddPackages (\r
1731 &mInventoryGuid,\r
1732 DriverHandle[1],\r
1733 DriverSampleStrings,\r
1734 InventoryBin,\r
1735 NULL\r
1736 );\r
1737 if (HiiHandle[1] == NULL) {\r
1738 DriverSampleUnload (ImageHandle);\r
1739 return EFI_OUT_OF_RESOURCES;\r
1740 }\r
1741\r
1742 PrivateData->HiiHandle[1] = HiiHandle[1];\r
1743\r
1744 //\r
1745 // Very simple example of how one would update a string that is already\r
1746 // in the HII database\r
1747 //\r
1748 NewString = L"700 Mhz";\r
1749\r
1750 if (HiiSetString (HiiHandle[0], STRING_TOKEN (STR_CPU_STRING2), NewString, NULL) == 0) {\r
1751 DriverSampleUnload (ImageHandle);\r
1752 return EFI_OUT_OF_RESOURCES;\r
1753 }\r
1754\r
1755 HiiSetString (HiiHandle[0], 0, NewString, NULL);\r
1756\r
1757 //\r
1758 // Initialize Name/Value name String ID\r
1759 //\r
1760 PrivateData->NameStringId[0] = STR_NAME_VALUE_VAR_NAME0;\r
1761 PrivateData->NameStringId[1] = STR_NAME_VALUE_VAR_NAME1;\r
1762 PrivateData->NameStringId[2] = STR_NAME_VALUE_VAR_NAME2;\r
1763\r
1764 //\r
1765 // Initialize configuration data\r
1766 //\r
1767 Configuration = &PrivateData->Configuration;\r
1768 ZeroMem (Configuration, sizeof (DRIVER_SAMPLE_CONFIGURATION));\r
1769\r
1770 //\r
1771 // Try to read NV config EFI variable first\r
1772 //\r
1773 ConfigRequestHdr = HiiConstructConfigHdr (&mFormSetGuid, VariableName, DriverHandle[0]);\r
1774 ASSERT (ConfigRequestHdr != NULL);\r
1775\r
1776 BufferSize = sizeof (DRIVER_SAMPLE_CONFIGURATION);\r
1777 Status = gRT->GetVariable (VariableName, &mFormSetGuid, NULL, &BufferSize, Configuration);\r
1778 if (EFI_ERROR (Status)) {\r
1779 //\r
1780 // Store zero data Buffer Storage to EFI variable\r
1781 //\r
1782 Status = gRT->SetVariable(\r
1783 VariableName,\r
1784 &mFormSetGuid,\r
1785 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,\r
1786 sizeof (DRIVER_SAMPLE_CONFIGURATION),\r
1787 Configuration\r
1788 );\r
1789 ASSERT (Status == EFI_SUCCESS);\r
1790 //\r
1791 // EFI variable for NV config doesn't exit, we should build this variable\r
1792 // based on default values stored in IFR\r
1793 //\r
1794 ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);\r
1795 ASSERT (ActionFlag);\r
1796 } else {\r
1797 //\r
1798 // EFI variable does exist and Validate Current Setting\r
1799 //\r
1800 ActionFlag = HiiValidateSettings (ConfigRequestHdr);\r
1801 ASSERT (ActionFlag);\r
1802 }\r
1803\r
1804 FreePool (ConfigRequestHdr);\r
1805\r
1806\r
1807 //\r
1808 // In default, this driver is built into Flash device image,\r
1809 // the following code doesn't run.\r
1810 //\r
1811\r
1812 //\r
1813 // Example of how to display only the item we sent to HII\r
1814 // When this driver is not built into Flash device image,\r
1815 // it need to call SendForm to show front page by itself.\r
1816 //\r
1817 if (DISPLAY_ONLY_MY_ITEM <= 1) {\r
1818 //\r
1819 // Have the browser pull out our copy of the data, and only display our data\r
1820 //\r
1821 Status = FormBrowser2->SendForm (\r
1822 FormBrowser2,\r
1823 &(HiiHandle[DISPLAY_ONLY_MY_ITEM]),\r
1824 1,\r
1825 NULL,\r
1826 0,\r
1827 NULL,\r
1828 NULL\r
1829 );\r
1830\r
1831 HiiRemovePackages (HiiHandle[0]);\r
1832\r
1833 HiiRemovePackages (HiiHandle[1]);\r
1834 }\r
1835\r
1836 return EFI_SUCCESS;\r
1837}\r
1838\r
1839/**\r
1840 Unloads the application and its installed protocol.\r
1841\r
1842 @param[in] ImageHandle Handle that identifies the image to be unloaded.\r
1843\r
1844 @retval EFI_SUCCESS The image has been unloaded.\r
1845**/\r
1846EFI_STATUS\r
1847EFIAPI\r
1848DriverSampleUnload (\r
1849 IN EFI_HANDLE ImageHandle\r
1850 )\r
1851{\r
1852 UINTN Index;\r
1853\r
1854 ASSERT (PrivateData != NULL);\r
1855\r
1856 if (DriverHandle[0] != NULL) {\r
1857 gBS->UninstallMultipleProtocolInterfaces (\r
1858 DriverHandle[0],\r
1859 &gEfiDevicePathProtocolGuid,\r
1860 &mHiiVendorDevicePath0,\r
1861 &gEfiHiiConfigAccessProtocolGuid,\r
1862 &PrivateData->ConfigAccess,\r
1863 NULL\r
1864 );\r
1865 DriverHandle[0] = NULL;\r
1866 }\r
1867\r
1868 if (DriverHandle[1] != NULL) {\r
1869 gBS->UninstallMultipleProtocolInterfaces (\r
1870 DriverHandle[1],\r
1871 &gEfiDevicePathProtocolGuid,\r
1872 &mHiiVendorDevicePath1,\r
1873 NULL\r
1874 );\r
1875 DriverHandle[1] = NULL;\r
1876 }\r
1877\r
1878 if (PrivateData->HiiHandle[0] != NULL) {\r
1879 HiiRemovePackages (PrivateData->HiiHandle[0]);\r
1880 }\r
1881\r
1882 if (PrivateData->HiiHandle[1] != NULL) {\r
1883 HiiRemovePackages (PrivateData->HiiHandle[1]);\r
1884 }\r
1885\r
1886 for (Index = 0; Index < NAME_VALUE_NAME_NUMBER; Index++) {\r
1887 if (PrivateData->NameValueName[Index] != NULL) {\r
1888 FreePool (PrivateData->NameValueName[Index]);\r
1889 }\r
1890 }\r
1891 FreePool (PrivateData);\r
1892 PrivateData = NULL;\r
1893\r
1894 return EFI_SUCCESS;\r
1895}\r