| /** @file | |
| The device manager reference implementation | |
| Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "DeviceManager.h" | |
| DEVICE_MANAGER_CALLBACK_DATA gDeviceManagerPrivate = { | |
| DEVICE_MANAGER_CALLBACK_DATA_SIGNATURE, | |
| NULL, | |
| NULL, | |
| { | |
| DeviceManagerExtractConfig, | |
| DeviceManagerRouteConfig, | |
| DeviceManagerCallback | |
| } | |
| }; | |
| #define MAX_MAC_ADDRESS_NODE_LIST_LEN 10 | |
| EFI_GUID mDeviceManagerGuid = DEVICE_MANAGER_FORMSET_GUID; | |
| // | |
| // Which Mac Address string is select | |
| // it will decide what menu need to show in the NETWORK_DEVICE_FORM_ID form. | |
| // | |
| EFI_STRING mSelectedMacAddrString; | |
| // | |
| // The Mac Address show in the NETWORK_DEVICE_LIST_FORM_ID | |
| // | |
| MAC_ADDRESS_NODE_LIST mMacDeviceList; | |
| HII_VENDOR_DEVICE_PATH mDeviceManagerHiiVendorDevicePath = { | |
| { | |
| { | |
| HARDWARE_DEVICE_PATH, | |
| HW_VENDOR_DP, | |
| { | |
| (UINT8) (sizeof (VENDOR_DEVICE_PATH)), | |
| (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) | |
| } | |
| }, | |
| // | |
| // {102579A0-3686-466e-ACD8-80C087044F4A} | |
| // | |
| { 0x102579a0, 0x3686, 0x466e, { 0xac, 0xd8, 0x80, 0xc0, 0x87, 0x4, 0x4f, 0x4a } } | |
| }, | |
| { | |
| END_DEVICE_PATH_TYPE, | |
| END_ENTIRE_DEVICE_PATH_SUBTYPE, | |
| { | |
| (UINT8) (END_DEVICE_PATH_LENGTH), | |
| (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) | |
| } | |
| } | |
| }; | |
| /** | |
| Extract device path for given HII handle and class guid. | |
| @param Handle The HII handle. | |
| @retval NULL Fail to get the device path string. | |
| @return PathString Get the device path string. | |
| **/ | |
| CHAR16 * | |
| DmExtractDevicePathFromHiiHandle ( | |
| IN EFI_HII_HANDLE Handle | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_HANDLE DriverHandle; | |
| ASSERT (Handle != NULL); | |
| if (Handle == NULL) { | |
| return NULL; | |
| } | |
| Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle); | |
| if (EFI_ERROR (Status)) { | |
| return NULL; | |
| } | |
| // | |
| // Get device path string. | |
| // | |
| return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE); | |
| } | |
| /** | |
| Get the mac address string from the device path. | |
| if the device path has the vlan, get the vanid also. | |
| @param MacAddressNode Device path begin with mac address | |
| @param PBuffer Output string buffer contain mac address. | |
| **/ | |
| BOOLEAN | |
| GetMacAddressString( | |
| IN MAC_ADDR_DEVICE_PATH *MacAddressNode, | |
| OUT CHAR16 **PBuffer | |
| ) | |
| { | |
| UINTN HwAddressSize; | |
| UINTN Index; | |
| UINT8 *HwAddress; | |
| EFI_DEVICE_PATH_PROTOCOL *Node; | |
| UINT16 VlanId; | |
| CHAR16 *String; | |
| UINTN BufferLen; | |
| VlanId = 0; | |
| String = NULL; | |
| ASSERT(MacAddressNode != NULL); | |
| HwAddressSize = sizeof (EFI_MAC_ADDRESS); | |
| if (MacAddressNode->IfType == 0x01 || MacAddressNode->IfType == 0x00) { | |
| HwAddressSize = 6; | |
| } | |
| // | |
| // The output format is MAC:XX:XX:XX:...\XXXX | |
| // The size is the Number size + ":" size + Vlan size(\XXXX) + End | |
| // | |
| BufferLen = (4 + 2 * HwAddressSize + (HwAddressSize - 1) + 5 + 1) * sizeof (CHAR16); | |
| String = AllocateZeroPool (BufferLen); | |
| if (String == NULL) { | |
| return FALSE; | |
| } | |
| *PBuffer = String; | |
| StrCpyS(String, BufferLen / sizeof (CHAR16), L"MAC:"); | |
| String += 4; | |
| // | |
| // Convert the MAC address into a unicode string. | |
| // | |
| HwAddress = &MacAddressNode->MacAddress.Addr[0]; | |
| for (Index = 0; Index < HwAddressSize; Index++) { | |
| UnicodeValueToStringS ( | |
| String, | |
| BufferLen - ((UINTN)String - (UINTN)*PBuffer), | |
| PREFIX_ZERO | RADIX_HEX, | |
| *(HwAddress++), | |
| 2 | |
| ); | |
| String += StrnLenS (String, (BufferLen - ((UINTN)String - (UINTN)*PBuffer)) / sizeof (CHAR16)); | |
| if (Index < HwAddressSize - 1) { | |
| *String++ = L':'; | |
| } | |
| } | |
| // | |
| // If VLAN is configured, it will need extra 5 characters like "\0005". | |
| // Plus one unicode character for the null-terminator. | |
| // | |
| Node = (EFI_DEVICE_PATH_PROTOCOL *)MacAddressNode; | |
| while (!IsDevicePathEnd (Node)) { | |
| if (Node->Type == MESSAGING_DEVICE_PATH && Node->SubType == MSG_VLAN_DP) { | |
| VlanId = ((VLAN_DEVICE_PATH *) Node)->VlanId; | |
| } | |
| Node = NextDevicePathNode (Node); | |
| } | |
| if (VlanId != 0) { | |
| *String++ = L'\\'; | |
| UnicodeValueToStringS ( | |
| String, | |
| BufferLen - ((UINTN)String - (UINTN)*PBuffer), | |
| PREFIX_ZERO | RADIX_HEX, | |
| VlanId, | |
| 4 | |
| ); | |
| String += StrnLenS (String, (BufferLen - ((UINTN)String - (UINTN)*PBuffer)) / sizeof (CHAR16)); | |
| } | |
| // | |
| // Null terminate the Unicode string | |
| // | |
| *String = L'\0'; | |
| return TRUE; | |
| } | |
| /** | |
| Save question id and prompt id to the mac device list. | |
| If the same mac address has saved yet, no need to add more. | |
| @param MacAddrString Mac address string. | |
| @retval EFI_SUCCESS Add the item is successful. | |
| @return Other values if failed to Add the item. | |
| **/ | |
| BOOLEAN | |
| AddIdToMacDeviceList ( | |
| IN EFI_STRING MacAddrString | |
| ) | |
| { | |
| MENU_INFO_ITEM *TempDeviceList; | |
| UINTN Index; | |
| EFI_STRING StoredString; | |
| EFI_STRING_ID PromptId; | |
| EFI_HII_HANDLE HiiHandle; | |
| HiiHandle = gDeviceManagerPrivate.HiiHandle; | |
| TempDeviceList = NULL; | |
| for (Index = 0; Index < mMacDeviceList.CurListLen; Index ++) { | |
| StoredString = HiiGetString (HiiHandle, mMacDeviceList.NodeList[Index].PromptId, NULL); | |
| if (StoredString == NULL) { | |
| return FALSE; | |
| } | |
| // | |
| // Already has save the same mac address to the list. | |
| // | |
| if (StrCmp (MacAddrString, StoredString) == 0) { | |
| return FALSE; | |
| } | |
| } | |
| PromptId = HiiSetString(HiiHandle, 0, MacAddrString, NULL); | |
| // | |
| // If not in the list, save it. | |
| // | |
| if (mMacDeviceList.MaxListLen > mMacDeviceList.CurListLen + 1) { | |
| mMacDeviceList.NodeList[mMacDeviceList.CurListLen].PromptId = PromptId; | |
| mMacDeviceList.NodeList[mMacDeviceList.CurListLen].QuestionId = (EFI_QUESTION_ID) (mMacDeviceList.CurListLen + NETWORK_DEVICE_LIST_KEY_OFFSET); | |
| } else { | |
| mMacDeviceList.MaxListLen += MAX_MAC_ADDRESS_NODE_LIST_LEN; | |
| if (mMacDeviceList.CurListLen != 0) { | |
| TempDeviceList = ReallocatePool ( | |
| sizeof (MENU_INFO_ITEM) * mMacDeviceList.CurListLen, | |
| sizeof (MENU_INFO_ITEM) * mMacDeviceList.MaxListLen, | |
| mMacDeviceList.NodeList | |
| ); | |
| } else { | |
| TempDeviceList = (MENU_INFO_ITEM *)AllocatePool (sizeof (MENU_INFO_ITEM) * mMacDeviceList.MaxListLen); | |
| } | |
| if (TempDeviceList == NULL) { | |
| return FALSE; | |
| } | |
| TempDeviceList[mMacDeviceList.CurListLen].PromptId = PromptId; | |
| TempDeviceList[mMacDeviceList.CurListLen].QuestionId = (EFI_QUESTION_ID) (mMacDeviceList.CurListLen + NETWORK_DEVICE_LIST_KEY_OFFSET); | |
| mMacDeviceList.NodeList = TempDeviceList; | |
| } | |
| mMacDeviceList.CurListLen ++; | |
| return TRUE; | |
| } | |
| /** | |
| Check the devcie path, try to find whether it has mac address path. | |
| In this function, first need to check whether this path has mac address path. | |
| second, when the mac address device path has find, also need to deicide whether | |
| need to add this mac address relate info to the menu. | |
| @param *Node Input device which need to be check. | |
| @param NextShowFormId FormId Which need to be show. | |
| @param *NeedAddItem Whether need to add the menu in the network device list. | |
| @retval TRUE Has mac address device path. | |
| @retval FALSE NOT Has mac address device path. | |
| **/ | |
| BOOLEAN | |
| IsMacAddressDevicePath ( | |
| IN VOID *Node, | |
| IN EFI_FORM_ID NextShowFormId, | |
| OUT BOOLEAN *NeedAddItem | |
| ) | |
| { | |
| EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
| CHAR16 *Buffer; | |
| BOOLEAN ReturnVal; | |
| ASSERT (Node != NULL); | |
| *NeedAddItem = FALSE; | |
| ReturnVal = FALSE; | |
| Buffer = NULL; | |
| DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) Node; | |
| // | |
| // find the partition device path node | |
| // | |
| while (!IsDevicePathEnd (DevicePath)) { | |
| if ((DevicePathType (DevicePath) == MESSAGING_DEVICE_PATH) && | |
| (DevicePathSubType (DevicePath) == MSG_MAC_ADDR_DP)) { | |
| ReturnVal = TRUE; | |
| if (DEVICE_MANAGER_FORM_ID == NextShowFormId) { | |
| *NeedAddItem = TRUE; | |
| break; | |
| } | |
| if (!GetMacAddressString((MAC_ADDR_DEVICE_PATH*)DevicePath, &Buffer)) { | |
| break; | |
| } | |
| if (NETWORK_DEVICE_FORM_ID == NextShowFormId) { | |
| if (StrCmp (Buffer, mSelectedMacAddrString) == 0) { | |
| *NeedAddItem = TRUE; | |
| } | |
| break; | |
| } | |
| if (NETWORK_DEVICE_LIST_FORM_ID == NextShowFormId) { | |
| // | |
| // Same handle may has two network child handle, so the questionid | |
| // has the offset of SAME_HANDLE_KEY_OFFSET. | |
| // | |
| if (AddIdToMacDeviceList (Buffer)) { | |
| *NeedAddItem = TRUE; | |
| } | |
| break; | |
| } | |
| } | |
| DevicePath = NextDevicePathNode (DevicePath); | |
| } | |
| if (Buffer != NULL) { | |
| FreePool (Buffer); | |
| } | |
| return ReturnVal; | |
| } | |
| /** | |
| Check to see if the device path is for the network device. | |
| @param Handle The HII handle which include the mac address device path. | |
| @param NextShowFormId The FormId of the form which will be show next time. | |
| @param ItemCount The new add Mac address item count. | |
| @retval TRUE Need to add new item in the menu. | |
| @return FALSE Do not need to add the menu about the network. | |
| **/ | |
| BOOLEAN | |
| IsNeedAddNetworkMenu ( | |
| IN EFI_HII_HANDLE Handle, | |
| IN EFI_FORM_ID NextShowFormId, | |
| OUT UINTN *ItemCount | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| UINTN EntryCount; | |
| UINTN Index; | |
| EFI_HANDLE DriverHandle; | |
| EFI_HANDLE ControllerHandle; | |
| EFI_DEVICE_PATH_PROTOCOL *DevicePath; | |
| EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath; | |
| EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath; | |
| EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer; | |
| BOOLEAN IsNeedAdd; | |
| IsNeedAdd = FALSE; | |
| OpenInfoBuffer = NULL; | |
| if ((Handle == NULL) || (ItemCount == NULL)) { | |
| return FALSE; | |
| } | |
| *ItemCount = 0; | |
| Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle); | |
| if (EFI_ERROR (Status)) { | |
| return FALSE; | |
| } | |
| // | |
| // Get the device path by the got Driver handle . | |
| // | |
| Status = gBS->HandleProtocol (DriverHandle, &gEfiDevicePathProtocolGuid, (VOID **) &DevicePath); | |
| if (EFI_ERROR (Status)) { | |
| return FALSE; | |
| } | |
| TmpDevicePath = DevicePath; | |
| // | |
| // Check whether this device path include mac address device path. | |
| // If this path has mac address path, get the value whether need | |
| // add this info to the menu and return. | |
| // Else check more about the child handle devcie path. | |
| // | |
| if (IsMacAddressDevicePath(TmpDevicePath, NextShowFormId,&IsNeedAdd)) { | |
| if ((NETWORK_DEVICE_LIST_FORM_ID == NextShowFormId) && IsNeedAdd) { | |
| (*ItemCount) = 1; | |
| } | |
| return IsNeedAdd; | |
| } | |
| // | |
| // Search whether this path is the controller path, not he child handle path. | |
| // And the child handle has the network devcie connected. | |
| // | |
| TmpDevicePath = DevicePath; | |
| Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &TmpDevicePath, &ControllerHandle); | |
| if (EFI_ERROR (Status)) { | |
| return FALSE; | |
| } | |
| if (!IsDevicePathEnd (TmpDevicePath)) { | |
| return FALSE; | |
| } | |
| // | |
| // Retrieve the list of agents that are consuming the specific protocol | |
| // on ControllerHandle. | |
| // The buffer point by OpenInfoBuffer need be free at this function. | |
| // | |
| Status = gBS->OpenProtocolInformation ( | |
| ControllerHandle, | |
| &gEfiPciIoProtocolGuid, | |
| &OpenInfoBuffer, | |
| &EntryCount | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return FALSE; | |
| } | |
| // | |
| // Inspect if ChildHandle is one of the agents. | |
| // | |
| Status = EFI_UNSUPPORTED; | |
| for (Index = 0; Index < EntryCount; Index++) { | |
| // | |
| // Query all the children created by the controller handle's driver | |
| // | |
| if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) { | |
| Status = gBS->OpenProtocol ( | |
| OpenInfoBuffer[Index].ControllerHandle, | |
| &gEfiDevicePathProtocolGuid, | |
| (VOID **) &ChildDevicePath, | |
| NULL, | |
| NULL, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| continue; | |
| } | |
| // | |
| // Check whether this device path include mac address device path. | |
| // | |
| if (!IsMacAddressDevicePath(ChildDevicePath, NextShowFormId,&IsNeedAdd)) { | |
| // | |
| // If this path not has mac address path, check the other. | |
| // | |
| continue; | |
| } else { | |
| // | |
| // If need to update the NETWORK_DEVICE_LIST_FORM, try to get more. | |
| // | |
| if ((NETWORK_DEVICE_LIST_FORM_ID == NextShowFormId)) { | |
| if (IsNeedAdd) { | |
| (*ItemCount) += 1; | |
| } | |
| continue; | |
| } else { | |
| // | |
| // If need to update other form, return whether need to add to the menu. | |
| // | |
| goto Done; | |
| } | |
| } | |
| } | |
| } | |
| Done: | |
| if (OpenInfoBuffer != NULL) { | |
| FreePool (OpenInfoBuffer); | |
| } | |
| return IsNeedAdd; | |
| } | |
| /** | |
| Dynamic create Hii information for Device Manager. | |
| @param NextShowFormId The FormId which need to be show. | |
| **/ | |
| VOID | |
| CreateDeviceManagerForm( | |
| IN EFI_FORM_ID NextShowFormId | |
| ) | |
| { | |
| UINTN Index; | |
| EFI_STRING String; | |
| EFI_STRING_ID Token; | |
| EFI_STRING_ID TokenHelp; | |
| EFI_HII_HANDLE *HiiHandles; | |
| EFI_HII_HANDLE HiiHandle; | |
| EFI_GUID FormSetGuid; | |
| VOID *StartOpCodeHandle; | |
| VOID *EndOpCodeHandle; | |
| EFI_IFR_GUID_LABEL *StartLabel; | |
| EFI_IFR_GUID_LABEL *EndLabel; | |
| BOOLEAN AddNetworkMenu; | |
| UINTN AddItemCount; | |
| UINTN NewStringLen; | |
| EFI_STRING NewStringTitle; | |
| CHAR16 *DevicePathStr; | |
| EFI_STRING_ID DevicePathId; | |
| EFI_IFR_FORM_SET *Buffer; | |
| UINTN BufferSize; | |
| UINT8 ClassGuidNum; | |
| EFI_GUID *ClassGuid; | |
| UINTN TempSize; | |
| UINT8 *Ptr; | |
| EFI_STATUS Status; | |
| TempSize =0; | |
| BufferSize = 0; | |
| Buffer = NULL; | |
| HiiHandle = gDeviceManagerPrivate.HiiHandle; | |
| AddNetworkMenu = FALSE; | |
| AddItemCount = 0; | |
| // | |
| // If need show the Network device list form, clear the old save list first. | |
| // | |
| if ((NextShowFormId == NETWORK_DEVICE_LIST_FORM_ID) && (mMacDeviceList.CurListLen > 0)) { | |
| mMacDeviceList.CurListLen = 0; | |
| } | |
| // | |
| // Update the network device form titile. | |
| // | |
| if (NextShowFormId == NETWORK_DEVICE_FORM_ID) { | |
| String = HiiGetString (HiiHandle, STRING_TOKEN (STR_FORM_NETWORK_DEVICE_TITLE_HEAD), NULL); | |
| if (String == NULL) { | |
| return; | |
| } | |
| NewStringLen = StrLen (mSelectedMacAddrString) * 2; | |
| NewStringLen += (StrLen (String) + 2) * 2; | |
| NewStringTitle = AllocatePool (NewStringLen); | |
| UnicodeSPrint (NewStringTitle, NewStringLen, L"%s %s", String, mSelectedMacAddrString); | |
| HiiSetString (HiiHandle, STRING_TOKEN (STR_FORM_NETWORK_DEVICE_TITLE), NewStringTitle, NULL); | |
| FreePool (String); | |
| FreePool (NewStringTitle); | |
| } | |
| // | |
| // Allocate space for creation of UpdateData Buffer | |
| // | |
| StartOpCodeHandle = HiiAllocateOpCodeHandle (); | |
| ASSERT (StartOpCodeHandle != NULL); | |
| EndOpCodeHandle = HiiAllocateOpCodeHandle (); | |
| ASSERT (EndOpCodeHandle != NULL); | |
| // | |
| // Create Hii Extend Label OpCode as the start opcode | |
| // | |
| StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); | |
| StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; | |
| // | |
| // According to the next show Form id(mNextShowFormId) to decide which form need to update. | |
| // | |
| StartLabel->Number = (UINT16) (LABEL_FORM_ID_OFFSET + NextShowFormId); | |
| // | |
| // Create Hii Extend Label OpCode as the end opcode | |
| // | |
| EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); | |
| EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; | |
| EndLabel->Number = LABEL_END; | |
| // | |
| // Get all the Hii handles | |
| // | |
| HiiHandles = HiiGetHiiHandles (NULL); | |
| ASSERT (HiiHandles != NULL); | |
| // | |
| // Search for formset of each class type | |
| // | |
| for (Index = 0; HiiHandles[Index] != NULL; Index++) { | |
| Status = HiiGetFormSetFromHiiHandle(HiiHandles[Index], &Buffer,&BufferSize); | |
| if (EFI_ERROR (Status)){ | |
| continue; | |
| } | |
| Ptr = (UINT8 *)Buffer; | |
| while(TempSize < BufferSize) { | |
| TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length; | |
| if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){ | |
| Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length; | |
| continue; | |
| } | |
| ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3); | |
| ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET)); | |
| while (ClassGuidNum-- > 0) { | |
| if (CompareGuid (&gEfiHiiPlatformSetupFormsetGuid, ClassGuid)== 0) { | |
| ClassGuid ++; | |
| continue; | |
| } | |
| String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle, NULL); | |
| if (String == NULL) { | |
| String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL); | |
| ASSERT (String != NULL); | |
| } | |
| Token = HiiSetString (HiiHandle, 0, String, NULL); | |
| FreePool (String); | |
| String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->Help, NULL); | |
| if (String == NULL) { | |
| String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL); | |
| ASSERT (String != NULL); | |
| } | |
| TokenHelp = HiiSetString (HiiHandle, 0, String, NULL); | |
| FreePool (String); | |
| FormSetGuid = ((EFI_IFR_FORM_SET *)Ptr)->Guid; | |
| // | |
| // Network device process | |
| // | |
| if (IsNeedAddNetworkMenu (HiiHandles[Index], NextShowFormId,&AddItemCount)) { | |
| if (NextShowFormId == DEVICE_MANAGER_FORM_ID) { | |
| // | |
| // Only show one menu item "Network Config" in the device manger form. | |
| // | |
| if (!AddNetworkMenu) { | |
| AddNetworkMenu = TRUE; | |
| HiiCreateGotoOpCode ( | |
| StartOpCodeHandle, | |
| NETWORK_DEVICE_LIST_FORM_ID, | |
| STRING_TOKEN (STR_FORM_NETWORK_DEVICE_LIST_TITLE), | |
| STRING_TOKEN (STR_FORM_NETWORK_DEVICE_LIST_HELP), | |
| EFI_IFR_FLAG_CALLBACK, | |
| (EFI_QUESTION_ID) QUESTION_NETWORK_DEVICE_ID | |
| ); | |
| } | |
| } else if (NextShowFormId == NETWORK_DEVICE_LIST_FORM_ID) { | |
| // | |
| // In network device list form, same mac address device only show one menu. | |
| // | |
| while (AddItemCount > 0) { | |
| HiiCreateGotoOpCode ( | |
| StartOpCodeHandle, | |
| NETWORK_DEVICE_FORM_ID, | |
| mMacDeviceList.NodeList[mMacDeviceList.CurListLen - AddItemCount].PromptId, | |
| STRING_TOKEN (STR_NETWORK_DEVICE_HELP), | |
| EFI_IFR_FLAG_CALLBACK, | |
| mMacDeviceList.NodeList[mMacDeviceList.CurListLen - AddItemCount].QuestionId | |
| ); | |
| AddItemCount -= 1; | |
| } | |
| } else if (NextShowFormId == NETWORK_DEVICE_FORM_ID) { | |
| // | |
| // In network device form, only the selected mac address device need to be show. | |
| // | |
| DevicePathStr = DmExtractDevicePathFromHiiHandle(HiiHandles[Index]); | |
| DevicePathId = 0; | |
| if (DevicePathStr != NULL){ | |
| DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL); | |
| FreePool(DevicePathStr); | |
| } | |
| HiiCreateGotoExOpCode ( | |
| StartOpCodeHandle, | |
| 0, | |
| Token, | |
| TokenHelp, | |
| 0, | |
| (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET), | |
| 0, | |
| &FormSetGuid, | |
| DevicePathId | |
| ); | |
| } | |
| } else { | |
| // | |
| // Not network device process, only need to show at device manger form. | |
| // | |
| if (NextShowFormId == DEVICE_MANAGER_FORM_ID) { | |
| DevicePathStr = DmExtractDevicePathFromHiiHandle(HiiHandles[Index]); | |
| DevicePathId = 0; | |
| if (DevicePathStr != NULL){ | |
| DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL); | |
| FreePool(DevicePathStr); | |
| } | |
| HiiCreateGotoExOpCode ( | |
| StartOpCodeHandle, | |
| 0, | |
| Token, | |
| TokenHelp, | |
| 0, | |
| (EFI_QUESTION_ID) (Index + DEVICE_KEY_OFFSET), | |
| 0, | |
| &FormSetGuid, | |
| DevicePathId | |
| ); | |
| } | |
| } | |
| break; | |
| } | |
| Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length; | |
| } | |
| FreePool(Buffer); | |
| Buffer = NULL; | |
| TempSize = 0; | |
| BufferSize = 0; | |
| } | |
| HiiUpdateForm ( | |
| HiiHandle, | |
| &mDeviceManagerGuid, | |
| NextShowFormId, | |
| StartOpCodeHandle, | |
| EndOpCodeHandle | |
| ); | |
| HiiFreeOpCodeHandle (StartOpCodeHandle); | |
| HiiFreeOpCodeHandle (EndOpCodeHandle); | |
| FreePool (HiiHandles); | |
| } | |
| /** | |
| This function allows a caller to extract the current configuration for one | |
| or more named elements from the target driver. | |
| @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. | |
| @param Request A null-terminated Unicode string in <ConfigRequest> format. | |
| @param Progress On return, points to a character in the Request string. | |
| Points to the string's null terminator if request was successful. | |
| Points to the most recent '&' before the first failing name/value | |
| pair (or the beginning of the string if the failure is in the | |
| first name/value pair) if the request was not successful. | |
| @param Results A null-terminated Unicode string in <ConfigAltResp> format which | |
| has all values filled in for the names in the Request string. | |
| String to be allocated by the called function. | |
| @retval EFI_SUCCESS The Results is filled with the requested values. | |
| @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. | |
| @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. | |
| @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DeviceManagerExtractConfig ( | |
| IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
| IN CONST EFI_STRING Request, | |
| OUT EFI_STRING *Progress, | |
| OUT EFI_STRING *Results | |
| ) | |
| { | |
| if (Progress == NULL || Results == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| *Progress = Request; | |
| return EFI_NOT_FOUND; | |
| } | |
| /** | |
| This function processes the results of changes in configuration. | |
| @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. | |
| @param Configuration A null-terminated Unicode string in <ConfigResp> format. | |
| @param Progress A pointer to a string filled in with the offset of the most | |
| recent '&' before the first failing name/value pair (or the | |
| beginning of the string if the failure is in the first | |
| name/value pair) or the terminating NULL if all was successful. | |
| @retval EFI_SUCCESS The Results is processed successfully. | |
| @retval EFI_INVALID_PARAMETER Configuration is NULL. | |
| @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DeviceManagerRouteConfig ( | |
| IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
| IN CONST EFI_STRING Configuration, | |
| OUT EFI_STRING *Progress | |
| ) | |
| { | |
| if (Configuration == NULL || Progress == NULL) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| *Progress = Configuration; | |
| return EFI_NOT_FOUND; | |
| } | |
| /** | |
| This function is invoked if user selected a interactive opcode from Device Manager's | |
| Formset. If user set VBIOS, the new value is saved to EFI variable. | |
| @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. | |
| @param Action Specifies the type of action taken by the browser. | |
| @param QuestionId A unique value which is sent to the original exporting driver | |
| so that it can identify the type of data to expect. | |
| @param Type The type of value for the question. | |
| @param Value A pointer to the data being sent to the original exporting driver. | |
| @param ActionRequest On return, points to the action requested by the callback function. | |
| @retval EFI_SUCCESS The callback successfully handled the action. | |
| @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DeviceManagerCallback ( | |
| IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
| IN EFI_BROWSER_ACTION Action, | |
| IN EFI_QUESTION_ID QuestionId, | |
| IN UINT8 Type, | |
| IN EFI_IFR_TYPE_VALUE *Value, | |
| OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest | |
| ) | |
| { | |
| UINTN CurIndex; | |
| if (Action != EFI_BROWSER_ACTION_CHANGING) { | |
| // | |
| // Do nothing for other UEFI Action. Only do call back when data is changed. | |
| // | |
| return EFI_UNSUPPORTED; | |
| } | |
| if ((Value == NULL) || (ActionRequest == NULL)) { | |
| return EFI_INVALID_PARAMETER; | |
| } | |
| if ((QuestionId < MAX_KEY_SECTION_LEN + NETWORK_DEVICE_LIST_KEY_OFFSET) && (QuestionId >= NETWORK_DEVICE_LIST_KEY_OFFSET)) { | |
| // | |
| // If user select the mac address, need to record mac address string to support next form show. | |
| // | |
| for (CurIndex = 0; CurIndex < mMacDeviceList.CurListLen; CurIndex ++) { | |
| if (mMacDeviceList.NodeList[CurIndex].QuestionId == QuestionId) { | |
| mSelectedMacAddrString = HiiGetString (gDeviceManagerPrivate.HiiHandle, mMacDeviceList.NodeList[CurIndex].PromptId, NULL); | |
| } | |
| } | |
| CreateDeviceManagerForm(NETWORK_DEVICE_FORM_ID); | |
| } else if(QuestionId == QUESTION_NETWORK_DEVICE_ID){ | |
| CreateDeviceManagerForm(NETWORK_DEVICE_LIST_FORM_ID); | |
| } | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| Install Boot Manager Menu driver. | |
| @param ImageHandle The image handle. | |
| @param SystemTable The system table. | |
| @retval EFI_SUCEESS Install Boot manager menu success. | |
| @retval Other Return error status. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DeviceManagerUiLibConstructor ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| gDeviceManagerPrivate.DriverHandle = NULL; | |
| Status = gBS->InstallMultipleProtocolInterfaces ( | |
| &gDeviceManagerPrivate.DriverHandle, | |
| &gEfiDevicePathProtocolGuid, | |
| &mDeviceManagerHiiVendorDevicePath, | |
| &gEfiHiiConfigAccessProtocolGuid, | |
| &gDeviceManagerPrivate.ConfigAccess, | |
| NULL | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Publish our HII data. | |
| // | |
| gDeviceManagerPrivate.HiiHandle = HiiAddPackages ( | |
| &mDeviceManagerGuid, | |
| gDeviceManagerPrivate.DriverHandle, | |
| DeviceManagerVfrBin, | |
| DeviceManagerUiLibStrings, | |
| NULL | |
| ); | |
| ASSERT (gDeviceManagerPrivate.HiiHandle != NULL); | |
| // | |
| // Update boot manager page | |
| // | |
| CreateDeviceManagerForm (DEVICE_MANAGER_FORM_ID); | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| Unloads the application and its installed protocol. | |
| @param ImageHandle Handle that identifies the image to be unloaded. | |
| @param SystemTable The system table. | |
| @retval EFI_SUCCESS The image has been unloaded. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| DeviceManagerUiLibDestructor( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| Status = gBS->UninstallMultipleProtocolInterfaces ( | |
| gDeviceManagerPrivate.DriverHandle, | |
| &gEfiDevicePathProtocolGuid, | |
| &mDeviceManagerHiiVendorDevicePath, | |
| &gEfiHiiConfigAccessProtocolGuid, | |
| &gDeviceManagerPrivate.ConfigAccess, | |
| NULL | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| HiiRemovePackages (gDeviceManagerPrivate.HiiHandle); | |
| return EFI_SUCCESS; | |
| } | |