VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Library/DeviceManagerUiLib/DeviceManager.c@ 105681

Last change on this file since 105681 was 99404, checked in by vboxsync, 2 years ago

Devices/EFI/FirmwareNew: Update to edk2-stable202302 and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 28.8 KB
Line 
1/** @file
2The device manager reference implementation
3
4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5SPDX-License-Identifier: BSD-2-Clause-Patent
6
7**/
8
9#include "DeviceManager.h"
10
11DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate = {
12 DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE,
13 NULL,
14 NULL,
15 {
16 DeviceManagerExtractConfig,
17 DeviceManagerRouteConfig,
18 DeviceManagerCallback
19 }
20};
21
22#define MAX_MAC_ADDRESS_NODE_LIST_LEN 10
23
24EFI_GUID mDeviceManagerGuid = DEVICE_MANAGER_FORMSET_GUID;
25
26//
27// Which Mac Address string is select
28// it will decide what menu need to show in the NETWORK_DEVICE_FORM_ID form.
29//
30EFI_STRING mSelectedMacAddrString;
31
32//
33// The Mac Address show in the NETWORK_DEVICE_LIST_FORM_ID
34//
35MAC_ADDRESS_NODE_LIST mMacDeviceList;
36
37HII_VENDOR_DEVICE_PATH mDeviceManagerHiiVendorDevicePath = {
38 {
39 {
40 HARDWARE_DEVICE_PATH,
41 HW_VENDOR_DP,
42 {
43 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
44 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
45 }
46 },
47 //
48 // {102579A0-3686-466e-ACD8-80C087044F4A}
49 //
50 { 0x102579a0, 0x3686, 0x466e, { 0xac, 0xd8, 0x80, 0xc0, 0x87, 0x4, 0x4f, 0x4a }
51 }
52 },
53 {
54 END_DEVICE_PATH_TYPE,
55 END_ENTIRE_DEVICE_PATH_SUBTYPE,
56 {
57 (UINT8)(END_DEVICE_PATH_LENGTH),
58 (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
59 }
60 }
61};
62
63/**
64 Extract device path for given HII handle and class guid.
65
66 @param Handle The HII handle.
67
68 @retval NULL Fail to get the device path string.
69 @return PathString Get the device path string.
70
71**/
72CHAR16 *
73DmExtractDevicePathFromHiiHandle (
74 IN EFI_HII_HANDLE Handle
75 )
76{
77 EFI_STATUS Status;
78 EFI_HANDLE DriverHandle;
79
80 ASSERT (Handle != NULL);
81
82 if (Handle == NULL) {
83 return NULL;
84 }
85
86 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
87 if (EFI_ERROR (Status)) {
88 return NULL;
89 }
90
91 //
92 // Get device path string.
93 //
94 return ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, FALSE);
95}
96
97/**
98 Get the mac address string from the device path.
99 if the device path has the vlan, get the vanid also.
100
101 @param MacAddressNode Device path begin with mac address
102 @param PBuffer Output string buffer contain mac address.
103
104**/
105BOOLEAN
106GetMacAddressString (
107 IN MAC_ADDR_DEVICE_PATH *MacAddressNode,
108 OUT CHAR16 **PBuffer
109 )
110{
111 UINTN HwAddressSize;
112 UINTN Index;
113 UINT8 *HwAddress;
114 EFI_DEVICE_PATH_PROTOCOL *Node;
115 UINT16 VlanId;
116 CHAR16 *String;
117 UINTN BufferLen;
118
119 VlanId = 0;
120 String = NULL;
121 ASSERT (MacAddressNode != NULL);
122
123 HwAddressSize = sizeof (EFI_MAC_ADDRESS);
124 if ((MacAddressNode->IfType == 0x01) || (MacAddressNode->IfType == 0x00)) {
125 HwAddressSize = 6;
126 }
127
128 //
129 // The output format is MAC:XX:XX:XX:...\XXXX
130 // The size is the Number size + ":" size + Vlan size(\XXXX) + End
131 //
132 BufferLen = (4 + 2 * HwAddressSize + (HwAddressSize - 1) + 5 + 1) * sizeof (CHAR16);
133 String = AllocateZeroPool (BufferLen);
134 if (String == NULL) {
135 return FALSE;
136 }
137
138 *PBuffer = String;
139 StrCpyS (String, BufferLen / sizeof (CHAR16), L"MAC:");
140 String += 4;
141
142 //
143 // Convert the MAC address into a unicode string.
144 //
145 HwAddress = &MacAddressNode->MacAddress.Addr[0];
146 for (Index = 0; Index < HwAddressSize; Index++) {
147 UnicodeValueToStringS (
148 String,
149 BufferLen - ((UINTN)String - (UINTN)*PBuffer),
150 PREFIX_ZERO | RADIX_HEX,
151 *(HwAddress++),
152 2
153 );
154 String += StrnLenS (String, (BufferLen - ((UINTN)String - (UINTN)*PBuffer)) / sizeof (CHAR16));
155 if (Index < HwAddressSize - 1) {
156 *String++ = L':';
157 }
158 }
159
160 //
161 // If VLAN is configured, it will need extra 5 characters like "\0005".
162 // Plus one unicode character for the null-terminator.
163 //
164 Node = (EFI_DEVICE_PATH_PROTOCOL *)MacAddressNode;
165 while (!IsDevicePathEnd (Node)) {
166 if ((Node->Type == MESSAGING_DEVICE_PATH) && (Node->SubType == MSG_VLAN_DP)) {
167 VlanId = ((VLAN_DEVICE_PATH *)Node)->VlanId;
168 }
169
170 Node = NextDevicePathNode (Node);
171 }
172
173 if (VlanId != 0) {
174 *String++ = L'\\';
175 UnicodeValueToStringS (
176 String,
177 BufferLen - ((UINTN)String - (UINTN)*PBuffer),
178 PREFIX_ZERO | RADIX_HEX,
179 VlanId,
180 4
181 );
182 String += StrnLenS (String, (BufferLen - ((UINTN)String - (UINTN)*PBuffer)) / sizeof (CHAR16));
183 }
184
185 //
186 // Null terminate the Unicode string
187 //
188 *String = L'\0';
189
190 return TRUE;
191}
192
193/**
194 Save question id and prompt id to the mac device list.
195 If the same mac address has saved yet, no need to add more.
196
197 @param MacAddrString Mac address string.
198
199 @retval EFI_SUCCESS Add the item is successful.
200 @return Other values if failed to Add the item.
201**/
202BOOLEAN
203AddIdToMacDeviceList (
204 IN EFI_STRING MacAddrString
205 )
206{
207 MENU_INFO_ITEM *TempDeviceList;
208 UINTN Index;
209 EFI_STRING StoredString;
210 EFI_STRING_ID PromptId;
211 EFI_HII_HANDLE HiiHandle;
212
213 HiiHandle = gDeviceManagerPrivate.HiiHandle;
214 TempDeviceList = NULL;
215
216 for (Index = 0; Index < mMacDeviceList.CurListLen; Index++) {
217 StoredString = HiiGetString (HiiHandle, mMacDeviceList.NodeList[Index].PromptId, NULL);
218 if (StoredString == NULL) {
219 return FALSE;
220 }
221
222 //
223 // Already has save the same mac address to the list.
224 //
225 if (StrCmp (MacAddrString, StoredString) == 0) {
226 return FALSE;
227 }
228 }
229
230 PromptId = HiiSetString (HiiHandle, 0, MacAddrString, NULL);
231 //
232 // If not in the list, save it.
233 //
234 if (mMacDeviceList.MaxListLen > mMacDeviceList.CurListLen + 1) {
235 mMacDeviceList.NodeList[mMacDeviceList.CurListLen].PromptId = PromptId;
236 mMacDeviceList.NodeList[mMacDeviceList.CurListLen].QuestionId = (EFI_QUESTION_ID)(mMacDeviceList.CurListLen + NETWORK_DEVICE_LIST_KEY_OFFSET);
237 } else {
238 mMacDeviceList.MaxListLen += MAX_MAC_ADDRESS_NODE_LIST_LEN;
239 if (mMacDeviceList.CurListLen != 0) {
240 TempDeviceList = ReallocatePool (
241 sizeof (MENU_INFO_ITEM) * mMacDeviceList.CurListLen,
242 sizeof (MENU_INFO_ITEM) * mMacDeviceList.MaxListLen,
243 mMacDeviceList.NodeList
244 );
245 } else {
246 TempDeviceList = (MENU_INFO_ITEM *)AllocatePool (sizeof (MENU_INFO_ITEM) * mMacDeviceList.MaxListLen);
247 }
248
249 if (TempDeviceList == NULL) {
250 return FALSE;
251 }
252
253 TempDeviceList[mMacDeviceList.CurListLen].PromptId = PromptId;
254 TempDeviceList[mMacDeviceList.CurListLen].QuestionId = (EFI_QUESTION_ID)(mMacDeviceList.CurListLen + NETWORK_DEVICE_LIST_KEY_OFFSET);
255
256 mMacDeviceList.NodeList = TempDeviceList;
257 }
258
259 mMacDeviceList.CurListLen++;
260
261 return TRUE;
262}
263
264/**
265 Check the devcie path, try to find whether it has mac address path.
266
267 In this function, first need to check whether this path has mac address path.
268 second, when the mac address device path has find, also need to deicide whether
269 need to add this mac address relate info to the menu.
270
271 @param *Node Input device which need to be check.
272 @param NextShowFormId FormId Which need to be show.
273 @param *NeedAddItem Whether need to add the menu in the network device list.
274
275 @retval TRUE Has mac address device path.
276 @retval FALSE NOT Has mac address device path.
277
278**/
279BOOLEAN
280IsMacAddressDevicePath (
281 IN VOID *Node,
282 IN EFI_FORM_ID NextShowFormId,
283 OUT BOOLEAN *NeedAddItem
284 )
285{
286 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
287 CHAR16 *Buffer;
288 BOOLEAN ReturnVal;
289
290 ASSERT (Node != NULL);
291 *NeedAddItem = FALSE;
292 ReturnVal = FALSE;
293 Buffer = NULL;
294
295 DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Node;
296
297 //
298 // find the partition device path node
299 //
300 while (!IsDevicePathEnd (DevicePath)) {
301 if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) &&
302 (DevicePathSubType (DevicePath) == MSG_MAC_ADDR_DP))
303 {
304 ReturnVal = TRUE;
305
306 if (DEVICE_MANAGER_FORM_ID == NextShowFormId) {
307 *NeedAddItem = TRUE;
308 break;
309 }
310
311 if (!GetMacAddressString ((MAC_ADDR_DEVICE_PATH *)DevicePath, &Buffer)) {
312 break;
313 }
314
315 if (NETWORK_DEVICE_FORM_ID == NextShowFormId) {
316 if (StrCmp (Buffer, mSelectedMacAddrString) == 0) {
317 *NeedAddItem = TRUE;
318 }
319
320 break;
321 }
322
323 if (NETWORK_DEVICE_LIST_FORM_ID == NextShowFormId) {
324 //
325 // Same handle may has two network child handle, so the questionid
326 // has the offset of SAME_HANDLE_KEY_OFFSET.
327 //
328 if (AddIdToMacDeviceList (Buffer)) {
329 *NeedAddItem = TRUE;
330 }
331
332 break;
333 }
334 }
335
336 DevicePath = NextDevicePathNode (DevicePath);
337 }
338
339 if (Buffer != NULL) {
340 FreePool (Buffer);
341 }
342
343 return ReturnVal;
344}
345
346/**
347 Check to see if the device path is for the network device.
348
349 @param Handle The HII handle which include the mac address device path.
350 @param NextShowFormId The FormId of the form which will be show next time.
351 @param ItemCount The new add Mac address item count.
352
353 @retval TRUE Need to add new item in the menu.
354 @return FALSE Do not need to add the menu about the network.
355
356**/
357BOOLEAN
358IsNeedAddNetworkMenu (
359 IN EFI_HII_HANDLE Handle,
360 IN EFI_FORM_ID NextShowFormId,
361 OUT UINTN *ItemCount
362 )
363{
364 EFI_STATUS Status;
365 UINTN EntryCount;
366 UINTN Index;
367 EFI_HANDLE DriverHandle;
368 EFI_HANDLE ControllerHandle;
369 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
370 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
371 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
372 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
373 BOOLEAN IsNeedAdd;
374
375 IsNeedAdd = FALSE;
376 OpenInfoBuffer = NULL;
377 if ((Handle == NULL) || (ItemCount == NULL)) {
378 return FALSE;
379 }
380
381 *ItemCount = 0;
382
383 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
384 if (EFI_ERROR (Status)) {
385 return FALSE;
386 }
387
388 //
389 // Get the device path by the got Driver handle .
390 //
391 Status = gBS->HandleProtocol (DriverHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath);
392 if (EFI_ERROR (Status)) {
393 return FALSE;
394 }
395
396 TmpDevicePath = DevicePath;
397
398 //
399 // Check whether this device path include mac address device path.
400 // If this path has mac address path, get the value whether need
401 // add this info to the menu and return.
402 // Else check more about the child handle devcie path.
403 //
404 if (IsMacAddressDevicePath (TmpDevicePath, NextShowFormId, &IsNeedAdd)) {
405 if ((NETWORK_DEVICE_LIST_FORM_ID == NextShowFormId) && IsNeedAdd) {
406 (*ItemCount) = 1;
407 }
408
409 return IsNeedAdd;
410 }
411
412 //
413 // Search whether this path is the controller path, not he child handle path.
414 // And the child handle has the network devcie connected.
415 //
416 TmpDevicePath = DevicePath;
417 Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &TmpDevicePath, &ControllerHandle);
418 if (EFI_ERROR (Status)) {
419 return FALSE;
420 }
421
422 if (!IsDevicePathEnd (TmpDevicePath)) {
423 return FALSE;
424 }
425
426 //
427 // Retrieve the list of agents that are consuming the specific protocol
428 // on ControllerHandle.
429 // The buffer point by OpenInfoBuffer need be free at this function.
430 //
431 Status = gBS->OpenProtocolInformation (
432 ControllerHandle,
433 &gEfiPciIoProtocolGuid,
434 &OpenInfoBuffer,
435 &EntryCount
436 );
437 if (EFI_ERROR (Status)) {
438 return FALSE;
439 }
440
441 //
442 // Inspect if ChildHandle is one of the agents.
443 //
444 Status = EFI_UNSUPPORTED;
445 for (Index = 0; Index < EntryCount; Index++) {
446 //
447 // Query all the children created by the controller handle's driver
448 //
449 if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
450 Status = gBS->OpenProtocol (
451 OpenInfoBuffer[Index].ControllerHandle,
452 &gEfiDevicePathProtocolGuid,
453 (VOID **)&ChildDevicePath,
454 NULL,
455 NULL,
456 EFI_OPEN_PROTOCOL_GET_PROTOCOL
457 );
458 if (EFI_ERROR (Status)) {
459 continue;
460 }
461
462 //
463 // Check whether this device path include mac address device path.
464 //
465 if (!IsMacAddressDevicePath (ChildDevicePath, NextShowFormId, &IsNeedAdd)) {
466 //
467 // If this path not has mac address path, check the other.
468 //
469 continue;
470 } else {
471 //
472 // If need to update the NETWORK_DEVICE_LIST_FORM, try to get more.
473 //
474 if ((NETWORK_DEVICE_LIST_FORM_ID == NextShowFormId)) {
475 if (IsNeedAdd) {
476 (*ItemCount) += 1;
477 }
478
479 continue;
480 } else {
481 //
482 // If need to update other form, return whether need to add to the menu.
483 //
484 goto Done;
485 }
486 }
487 }
488 }
489
490Done:
491 if (OpenInfoBuffer != NULL) {
492 FreePool (OpenInfoBuffer);
493 }
494
495 return IsNeedAdd;
496}
497
498/**
499 Dynamic create Hii information for Device Manager.
500
501 @param NextShowFormId The FormId which need to be show.
502
503**/
504VOID
505CreateDeviceManagerForm (
506 IN EFI_FORM_ID NextShowFormId
507 )
508{
509 UINTN Index;
510 EFI_STRING String;
511 EFI_STRING_ID Token;
512 EFI_STRING_ID TokenHelp;
513 EFI_HII_HANDLE *HiiHandles;
514 EFI_HII_HANDLE HiiHandle;
515 EFI_GUID FormSetGuid;
516 VOID *StartOpCodeHandle;
517 VOID *EndOpCodeHandle;
518 EFI_IFR_GUID_LABEL *StartLabel;
519 EFI_IFR_GUID_LABEL *EndLabel;
520 BOOLEAN AddNetworkMenu;
521 UINTN AddItemCount;
522 UINTN NewStringLen;
523 EFI_STRING NewStringTitle;
524 CHAR16 *DevicePathStr;
525 EFI_STRING_ID DevicePathId;
526 EFI_IFR_FORM_SET *Buffer;
527 UINTN BufferSize;
528 UINT8 ClassGuidNum;
529 EFI_GUID *ClassGuid;
530 UINTN TempSize;
531 UINT8 *Ptr;
532 EFI_STATUS Status;
533
534 TempSize = 0;
535 BufferSize = 0;
536 Buffer = NULL;
537
538 HiiHandle = gDeviceManagerPrivate.HiiHandle;
539 AddNetworkMenu = FALSE;
540 AddItemCount = 0;
541 //
542 // If need show the Network device list form, clear the old save list first.
543 //
544 if ((NextShowFormId == NETWORK_DEVICE_LIST_FORM_ID) && (mMacDeviceList.CurListLen > 0)) {
545 mMacDeviceList.CurListLen = 0;
546 }
547
548 //
549 // Update the network device form titile.
550 //
551 if (NextShowFormId == NETWORK_DEVICE_FORM_ID) {
552 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_FORM_NETWORK_DEVICE_TITLE_HEAD), NULL);
553 if (String == NULL) {
554 return;
555 }
556
557 NewStringLen = StrLen (mSelectedMacAddrString) * 2;
558 NewStringLen += (StrLen (String) + 2) * 2;
559 NewStringTitle = AllocatePool (NewStringLen);
560 UnicodeSPrint (NewStringTitle, NewStringLen, L"%s %s", String, mSelectedMacAddrString);
561 HiiSetString (HiiHandle, STRING_TOKEN (STR_FORM_NETWORK_DEVICE_TITLE), NewStringTitle, NULL);
562 FreePool (String);
563 FreePool (NewStringTitle);
564 }
565
566 //
567 // Allocate space for creation of UpdateData Buffer
568 //
569 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
570 ASSERT (StartOpCodeHandle != NULL);
571
572 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
573 ASSERT (EndOpCodeHandle != NULL);
574
575 //
576 // Create Hii Extend Label OpCode as the start opcode
577 //
578 StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
579 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
580 //
581 // According to the next show Form id(mNextShowFormId) to decide which form need to update.
582 //
583 StartLabel->Number = (UINT16)(LABEL_FORM_ID_OFFSET + NextShowFormId);
584
585 //
586 // Create Hii Extend Label OpCode as the end opcode
587 //
588 EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
589 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
590 EndLabel->Number = LABEL_END;
591
592 //
593 // Get all the Hii handles
594 //
595 HiiHandles = HiiGetHiiHandles (NULL);
596 ASSERT (HiiHandles != NULL);
597
598 //
599 // Search for formset of each class type
600 //
601 for (Index = 0; HiiHandles[Index] != NULL; Index++) {
602 Status = HiiGetFormSetFromHiiHandle (HiiHandles[Index], &Buffer, &BufferSize);
603 if (EFI_ERROR (Status)) {
604 continue;
605 }
606
607 Ptr = (UINT8 *)Buffer;
608 while (TempSize < BufferSize) {
609 TempSize += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
610 if (((EFI_IFR_OP_HEADER *)Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
611 Ptr += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
612 continue;
613 }
614
615 ClassGuidNum = (UINT8)(((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);
616 ClassGuid = (EFI_GUID *)(VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));
617 while (ClassGuidNum-- > 0) {
618 if (CompareGuid (&gEfiHiiPlatformSetupFormsetGuid, ClassGuid) == 0) {
619 ClassGuid++;
620 continue;
621 }
622
623 String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle, NULL);
624 if (String == NULL) {
625 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
626 ASSERT (String != NULL);
627 }
628
629 Token = HiiSetString (HiiHandle, 0, String, NULL);
630 FreePool (String);
631
632 String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->Help, NULL);
633 if (String == NULL) {
634 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
635 ASSERT (String != NULL);
636 }
637
638 TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);
639 FreePool (String);
640
641 CopyMem (&FormSetGuid, &((EFI_IFR_FORM_SET *)Ptr)->Guid, sizeof (EFI_GUID));
642
643 //
644 // Network device process
645 //
646 if (IsNeedAddNetworkMenu (HiiHandles[Index], NextShowFormId, &AddItemCount)) {
647 if (NextShowFormId == DEVICE_MANAGER_FORM_ID) {
648 //
649 // Only show one menu item "Network Config" in the device manger form.
650 //
651 if (!AddNetworkMenu) {
652 AddNetworkMenu = TRUE;
653 HiiCreateGotoOpCode (
654 StartOpCodeHandle,
655 NETWORK_DEVICE_LIST_FORM_ID,
656 STRING_TOKEN (STR_FORM_NETWORK_DEVICE_LIST_TITLE),
657 STRING_TOKEN (STR_FORM_NETWORK_DEVICE_LIST_HELP),
658 EFI_IFR_FLAG_CALLBACK,
659 (EFI_QUESTION_ID)QUESTION_NETWORK_DEVICE_ID
660 );
661 }
662 } else if (NextShowFormId == NETWORK_DEVICE_LIST_FORM_ID) {
663 //
664 // In network device list form, same mac address device only show one menu.
665 //
666 while (AddItemCount > 0) {
667 HiiCreateGotoOpCode (
668 StartOpCodeHandle,
669 NETWORK_DEVICE_FORM_ID,
670 mMacDeviceList.NodeList[mMacDeviceList.CurListLen - AddItemCount].PromptId,
671 STRING_TOKEN (STR_NETWORK_DEVICE_HELP),
672 EFI_IFR_FLAG_CALLBACK,
673 mMacDeviceList.NodeList[mMacDeviceList.CurListLen - AddItemCount].QuestionId
674 );
675 AddItemCount -= 1;
676 }
677 } else if (NextShowFormId == NETWORK_DEVICE_FORM_ID) {
678 //
679 // In network device form, only the selected mac address device need to be show.
680 //
681 DevicePathStr = DmExtractDevicePathFromHiiHandle (HiiHandles[Index]);
682 DevicePathId = 0;
683 if (DevicePathStr != NULL) {
684 DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
685 FreePool (DevicePathStr);
686 }
687
688 HiiCreateGotoExOpCode (
689 StartOpCodeHandle,
690 0,
691 Token,
692 TokenHelp,
693 0,
694 (EFI_QUESTION_ID)(Index + DEVICE_KEY_OFFSET),
695 0,
696 &FormSetGuid,
697 DevicePathId
698 );
699 }
700 } else {
701 //
702 // Not network device process, only need to show at device manger form.
703 //
704 if (NextShowFormId == DEVICE_MANAGER_FORM_ID) {
705 DevicePathStr = DmExtractDevicePathFromHiiHandle (HiiHandles[Index]);
706 DevicePathId = 0;
707 if (DevicePathStr != NULL) {
708 DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
709 FreePool (DevicePathStr);
710 }
711
712 HiiCreateGotoExOpCode (
713 StartOpCodeHandle,
714 0,
715 Token,
716 TokenHelp,
717 0,
718 (EFI_QUESTION_ID)(Index + DEVICE_KEY_OFFSET),
719 0,
720 &FormSetGuid,
721 DevicePathId
722 );
723 }
724 }
725
726 break;
727 }
728
729 Ptr += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
730 }
731
732 FreePool (Buffer);
733 Buffer = NULL;
734 TempSize = 0;
735 BufferSize = 0;
736 }
737
738 HiiUpdateForm (
739 HiiHandle,
740 &mDeviceManagerGuid,
741 NextShowFormId,
742 StartOpCodeHandle,
743 EndOpCodeHandle
744 );
745
746 HiiFreeOpCodeHandle (StartOpCodeHandle);
747 HiiFreeOpCodeHandle (EndOpCodeHandle);
748 FreePool (HiiHandles);
749}
750
751/**
752 This function allows a caller to extract the current configuration for one
753 or more named elements from the target driver.
754
755
756 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
757 @param Request A null-terminated Unicode string in <ConfigRequest> format.
758 @param Progress On return, points to a character in the Request string.
759 Points to the string's null terminator if request was successful.
760 Points to the most recent '&' before the first failing name/value
761 pair (or the beginning of the string if the failure is in the
762 first name/value pair) if the request was not successful.
763 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
764 has all values filled in for the names in the Request string.
765 String to be allocated by the called function.
766
767 @retval EFI_SUCCESS The Results is filled with the requested values.
768 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
769 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
770 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
771
772**/
773EFI_STATUS
774EFIAPI
775DeviceManagerExtractConfig (
776 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
777 IN CONST EFI_STRING Request,
778 OUT EFI_STRING *Progress,
779 OUT EFI_STRING *Results
780 )
781{
782 if ((Progress == NULL) || (Results == NULL)) {
783 return EFI_INVALID_PARAMETER;
784 }
785
786 *Progress = Request;
787 return EFI_NOT_FOUND;
788}
789
790/**
791 This function processes the results of changes in configuration.
792
793 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
794 @param Configuration A null-terminated Unicode string in <ConfigResp> format.
795 @param Progress A pointer to a string filled in with the offset of the most
796 recent '&' before the first failing name/value pair (or the
797 beginning of the string if the failure is in the first
798 name/value pair) or the terminating NULL if all was successful.
799
800 @retval EFI_SUCCESS The Results is processed successfully.
801 @retval EFI_INVALID_PARAMETER Configuration is NULL.
802 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
803
804**/
805EFI_STATUS
806EFIAPI
807DeviceManagerRouteConfig (
808 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
809 IN CONST EFI_STRING Configuration,
810 OUT EFI_STRING *Progress
811 )
812{
813 if ((Configuration == NULL) || (Progress == NULL)) {
814 return EFI_INVALID_PARAMETER;
815 }
816
817 *Progress = Configuration;
818
819 return EFI_NOT_FOUND;
820}
821
822/**
823 This function is invoked if user selected a interactive opcode from Device Manager's
824 Formset. If user set VBIOS, the new value is saved to EFI variable.
825
826 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
827 @param Action Specifies the type of action taken by the browser.
828 @param QuestionId A unique value which is sent to the original exporting driver
829 so that it can identify the type of data to expect.
830 @param Type The type of value for the question.
831 @param Value A pointer to the data being sent to the original exporting driver.
832 @param ActionRequest On return, points to the action requested by the callback function.
833
834 @retval EFI_SUCCESS The callback successfully handled the action.
835 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
836
837**/
838EFI_STATUS
839EFIAPI
840DeviceManagerCallback (
841 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
842 IN EFI_BROWSER_ACTION Action,
843 IN EFI_QUESTION_ID QuestionId,
844 IN UINT8 Type,
845 IN EFI_IFR_TYPE_VALUE *Value,
846 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
847 )
848{
849 UINTN CurIndex;
850
851 if (Action != EFI_BROWSER_ACTION_CHANGING) {
852 //
853 // Do nothing for other UEFI Action. Only do call back when data is changed.
854 //
855 return EFI_UNSUPPORTED;
856 }
857
858 if ((Value == NULL) || (ActionRequest == NULL)) {
859 return EFI_INVALID_PARAMETER;
860 }
861
862 if ((QuestionId < MAX_KEY_SECTION_LEN + NETWORK_DEVICE_LIST_KEY_OFFSET) && (QuestionId >= NETWORK_DEVICE_LIST_KEY_OFFSET)) {
863 //
864 // If user select the mac address, need to record mac address string to support next form show.
865 //
866 for (CurIndex = 0; CurIndex < mMacDeviceList.CurListLen; CurIndex++) {
867 if (mMacDeviceList.NodeList[CurIndex].QuestionId == QuestionId) {
868 mSelectedMacAddrString = HiiGetString (gDeviceManagerPrivate.HiiHandle, mMacDeviceList.NodeList[CurIndex].PromptId, NULL);
869 }
870 }
871
872 CreateDeviceManagerForm (NETWORK_DEVICE_FORM_ID);
873 } else if (QuestionId == QUESTION_NETWORK_DEVICE_ID) {
874 CreateDeviceManagerForm (NETWORK_DEVICE_LIST_FORM_ID);
875 }
876
877 return EFI_SUCCESS;
878}
879
880/**
881 Install Boot Manager Menu driver.
882
883 @param ImageHandle The image handle.
884 @param SystemTable The system table.
885
886 @retval EFI_SUCEESS Install Boot manager menu success.
887 @retval Other Return error status.
888
889**/
890EFI_STATUS
891EFIAPI
892DeviceManagerUiLibConstructor (
893 IN EFI_HANDLE ImageHandle,
894 IN EFI_SYSTEM_TABLE *SystemTable
895 )
896{
897 EFI_STATUS Status;
898
899 gDeviceManagerPrivate.DriverHandle = NULL;
900 Status = gBS->InstallMultipleProtocolInterfaces (
901 &gDeviceManagerPrivate.DriverHandle,
902 &gEfiDevicePathProtocolGuid,
903 &mDeviceManagerHiiVendorDevicePath,
904 &gEfiHiiConfigAccessProtocolGuid,
905 &gDeviceManagerPrivate.ConfigAccess,
906 NULL
907 );
908 ASSERT_EFI_ERROR (Status);
909
910 //
911 // Publish our HII data.
912 //
913 gDeviceManagerPrivate.HiiHandle = HiiAddPackages (
914 &mDeviceManagerGuid,
915 gDeviceManagerPrivate.DriverHandle,
916 DeviceManagerVfrBin,
917 DeviceManagerUiLibStrings,
918 NULL
919 );
920 ASSERT (gDeviceManagerPrivate.HiiHandle != NULL);
921
922 //
923 // The device manager form contains a page listing all the network
924 // controllers in the system. This list can only be populated if all
925 // handles have been connected, so do it here.
926 //
927 EfiBootManagerConnectAll ();
928
929 //
930 // Update boot manager page
931 //
932 CreateDeviceManagerForm (DEVICE_MANAGER_FORM_ID);
933
934 return EFI_SUCCESS;
935}
936
937/**
938 Unloads the application and its installed protocol.
939
940 @param ImageHandle Handle that identifies the image to be unloaded.
941 @param SystemTable The system table.
942
943 @retval EFI_SUCCESS The image has been unloaded.
944**/
945EFI_STATUS
946EFIAPI
947DeviceManagerUiLibDestructor (
948 IN EFI_HANDLE ImageHandle,
949 IN EFI_SYSTEM_TABLE *SystemTable
950 )
951{
952 EFI_STATUS Status;
953
954 Status = gBS->UninstallMultipleProtocolInterfaces (
955 gDeviceManagerPrivate.DriverHandle,
956 &gEfiDevicePathProtocolGuid,
957 &mDeviceManagerHiiVendorDevicePath,
958 &gEfiHiiConfigAccessProtocolGuid,
959 &gDeviceManagerPrivate.ConfigAccess,
960 NULL
961 );
962 ASSERT_EFI_ERROR (Status);
963
964 HiiRemovePackages (gDeviceManagerPrivate.HiiHandle);
965
966 return EFI_SUCCESS;
967}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette