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