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