/** @file | |
The Hii functions for WiFi Connection Manager. | |
Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#include "WifiConnectionMgrDxe.h" | |
CHAR16 mVendorStorageName[] = L"WIFI_MANAGER_IFR_NVDATA"; | |
HII_VENDOR_DEVICE_PATH mWifiMgrDxeHiiVendorDevicePath = { | |
{ | |
{ | |
HARDWARE_DEVICE_PATH, | |
HW_VENDOR_DP, | |
{ | |
(UINT8)(sizeof (VENDOR_DEVICE_PATH)), | |
(UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8) | |
} | |
}, | |
WIFI_CONNECTION_MANAGER_CONFIG_GUID | |
}, | |
{ | |
END_DEVICE_PATH_TYPE, | |
END_ENTIRE_DEVICE_PATH_SUBTYPE, | |
{ | |
(UINT8)(END_DEVICE_PATH_LENGTH), | |
(UINT8)((END_DEVICE_PATH_LENGTH) >> 8) | |
} | |
} | |
}; | |
// | |
// HII Config Access Protocol instance | |
// | |
GLOBAL_REMOVE_IF_UNREFERENCED | |
EFI_HII_CONFIG_ACCESS_PROTOCOL gWifiMgrDxeHiiConfigAccess = { | |
WifiMgrDxeHiiConfigAccessExtractConfig, | |
WifiMgrDxeHiiConfigAccessRouteConfig, | |
WifiMgrDxeHiiConfigAccessCallback | |
}; | |
CHAR16 *mSecurityType[] = { | |
L"OPEN ", | |
L"WPA-Enterprise ", | |
L"WPA2-Enterprise", | |
L"WPA-Personal ", | |
L"WPA2-Personal ", | |
L"WEP ", | |
L"WPA3-Personal ", | |
L"WPA3-Enterprise", | |
L"UnKnown " | |
}; | |
CHAR16 *mSignalStrengthBar[] = { | |
L"[-----]", | |
L"[*----]", | |
L"[**---]", | |
L"[***--]", | |
L"[****-]", | |
L"[*****]" | |
}; | |
#define RSSI_TO_SIGNAL_STRENGTH_BAR(Rssi) mSignalStrengthBar[((Rssi + 19)/20)] | |
#define NET_LIST_FOR_EACH_FROM_NODE(Entry, Node, ListHead) \ | |
for(Entry = Node->ForwardLink; Entry != (ListHead); Entry = Entry->ForwardLink) | |
extern EFI_GUID gWifiConfigFormSetGuid; | |
/** | |
Create Hii Extend Label OpCode as the start opcode and end opcode. | |
The caller is responsible for freeing the OpCode with HiiFreeOpCodeHandle(). | |
@param[in] StartLabelNumber The number of start label. | |
@param[out] StartOpCodeHandle Points to the start opcode handle. | |
@param[out] EndOpCodeHandle Points to the end opcode handle. | |
@retval EFI_OUT_OF_RESOURCES Do not have sufficient resource to finish this | |
operation. | |
@retval EFI_INVALID_PARAMETER Any input parameter is invalid. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
@retval Other Errors Returned errors when updating the HII form. | |
**/ | |
EFI_STATUS | |
WifiMgrCreateOpCode ( | |
IN UINT16 StartLabelNumber, | |
OUT VOID **StartOpCodeHandle, | |
OUT VOID **EndOpCodeHandle | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_IFR_GUID_LABEL *InternalStartLabel; | |
EFI_IFR_GUID_LABEL *InternalEndLabel; | |
if ((StartOpCodeHandle == NULL) || (EndOpCodeHandle == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Status = EFI_OUT_OF_RESOURCES; | |
*StartOpCodeHandle = NULL; | |
*EndOpCodeHandle = NULL; | |
// | |
// Initialize the container for dynamic opcodes. | |
// | |
*StartOpCodeHandle = HiiAllocateOpCodeHandle (); | |
if (*StartOpCodeHandle == NULL) { | |
goto Exit; | |
} | |
*EndOpCodeHandle = HiiAllocateOpCodeHandle (); | |
if (*EndOpCodeHandle == NULL) { | |
goto Exit; | |
} | |
// | |
// Create Hii Extend Label OpCode as the start opcode. | |
// | |
InternalStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( | |
*StartOpCodeHandle, | |
&gEfiIfrTianoGuid, | |
NULL, | |
sizeof (EFI_IFR_GUID_LABEL) | |
); | |
if (InternalStartLabel == NULL) { | |
goto Exit; | |
} | |
InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; | |
InternalStartLabel->Number = StartLabelNumber; | |
// | |
// Create Hii Extend Label OpCode as the end opcode. | |
// | |
InternalEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode ( | |
*EndOpCodeHandle, | |
&gEfiIfrTianoGuid, | |
NULL, | |
sizeof (EFI_IFR_GUID_LABEL) | |
); | |
if (InternalEndLabel == NULL) { | |
goto Exit; | |
} | |
InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; | |
InternalEndLabel->Number = LABEL_END; | |
return EFI_SUCCESS; | |
Exit: | |
if (*StartOpCodeHandle != NULL) { | |
HiiFreeOpCodeHandle (*StartOpCodeHandle); | |
} | |
if (*EndOpCodeHandle != NULL) { | |
HiiFreeOpCodeHandle (*EndOpCodeHandle); | |
} | |
return Status; | |
} | |
/** | |
Display the Nic list contains all available Nics. | |
@param[in] Private The pointer to the global private data structure. | |
@retval EFI_INVALID_PARAMETER Any input parameter is invalid. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
**/ | |
EFI_STATUS | |
WifiMgrShowNicList ( | |
IN WIFI_MGR_PRIVATE_DATA *Private | |
) | |
{ | |
EFI_STATUS Status; | |
CHAR16 MacString[WIFI_MGR_MAX_MAC_STRING_LEN]; | |
CHAR16 PortString[WIFI_STR_MAX_SIZE]; | |
EFI_STRING_ID PortTitleToken; | |
EFI_STRING_ID PortTitleHelpToken; | |
WIFI_MGR_DEVICE_DATA *Nic; | |
LIST_ENTRY *Entry; | |
VOID *StartOpCodeHandle; | |
VOID *EndOpCodeHandle; | |
if (Private == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Status = WifiMgrCreateOpCode ( | |
LABEL_MAC_ENTRY, | |
&StartOpCodeHandle, | |
&EndOpCodeHandle | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
NET_LIST_FOR_EACH (Entry, &Private->NicList) { | |
Nic = NET_LIST_USER_STRUCT_S (Entry, WIFI_MGR_DEVICE_DATA, Link, WIFI_MGR_DEVICE_DATA_SIGNATURE); | |
WifiMgrMacAddrToStr (&Nic->MacAddress, sizeof (MacString), MacString); | |
UnicodeSPrint (PortString, sizeof (PortString), L"MAC %s", MacString); | |
PortTitleToken = HiiSetString ( | |
Private->RegisteredHandle, | |
0, | |
PortString, | |
NULL | |
); | |
if (PortTitleToken == 0) { | |
Status = EFI_INVALID_PARAMETER; | |
goto Exit; | |
} | |
UnicodeSPrint (PortString, sizeof (PortString), L"MAC Address"); | |
PortTitleHelpToken = HiiSetString ( | |
Private->RegisteredHandle, | |
0, | |
PortString, | |
NULL | |
); | |
if (PortTitleHelpToken == 0) { | |
Status = EFI_INVALID_PARAMETER; | |
goto Exit; | |
} | |
HiiCreateGotoOpCode ( | |
StartOpCodeHandle, | |
FORMID_WIFI_MAINPAGE, | |
PortTitleToken, | |
PortTitleHelpToken, | |
EFI_IFR_FLAG_CALLBACK, | |
(UINT16)(KEY_MAC_ENTRY_BASE + Nic->NicIndex) | |
); | |
} | |
Status = HiiUpdateForm ( | |
Private->RegisteredHandle, // HII handle | |
&gWifiConfigFormSetGuid, // Formset GUID | |
FORMID_MAC_SELECTION, // Form ID | |
StartOpCodeHandle, // Label for where to insert opcodes | |
EndOpCodeHandle // Replace data | |
); | |
Exit: | |
HiiFreeOpCodeHandle (StartOpCodeHandle); | |
HiiFreeOpCodeHandle (EndOpCodeHandle); | |
return Status; | |
} | |
/** | |
Retreive the unicode string of the AKM Suite list of a profile. | |
The caller is responsible for freeing the string with FreePool(). | |
@param[in] Profile The network profile contains a AKM suite list. | |
@return the unicode string of AKM suite list or "None". | |
**/ | |
CHAR16 * | |
WifiMgrGetStrAKMList ( | |
IN WIFI_MGR_NETWORK_PROFILE *Profile | |
) | |
{ | |
UINT8 Index; | |
UINT16 AKMSuiteCount; | |
CHAR16 *AKMListDisplay; | |
UINTN Length; | |
AKMListDisplay = NULL; | |
if ((Profile == NULL) || (Profile->Network.AKMSuite == NULL)) { | |
goto Exit; | |
} | |
AKMSuiteCount = Profile->Network.AKMSuite->AKMSuiteCount; | |
if (AKMSuiteCount != 0) { | |
// | |
// Current AKM Suite is between 1-18 | |
// | |
AKMListDisplay = (CHAR16 *)AllocateZeroPool (sizeof (CHAR16) * (AKMSuiteCount * 3 + 1)); | |
Length = 0; | |
if (AKMListDisplay != NULL) { | |
for (Index = 0; Index < AKMSuiteCount; Index++) { | |
// | |
// The size of buffer should be 4 CHAR16 for Null-terminated Unicode string. | |
// | |
UnicodeSPrint ( | |
AKMListDisplay + Length, | |
sizeof (CHAR16) * 4, | |
L"%d ", | |
Profile->Network.AKMSuite->AKMSuiteList[Index].SuiteType | |
); | |
Length = StrLen (AKMListDisplay + Length) + Length; | |
if (Index == AKMSuiteCount - 1) { | |
*(AKMListDisplay + (Length - 1)) = L'\0'; | |
} | |
} | |
} | |
} | |
Exit: | |
if (AKMListDisplay == NULL) { | |
AKMListDisplay = AllocateCopyPool (sizeof (L"None"), L"None"); | |
} | |
return AKMListDisplay; | |
} | |
/** | |
Retreive the unicode string of the Cipher Suite list of a profile. | |
The caller is responsible for freeing the string with FreePool(). | |
@param[in] Profile The network profile contains a Cipher suite list. | |
@return the unicode string of Cipher suite list or "None". | |
**/ | |
CHAR16 * | |
WifiMgrGetStrCipherList ( | |
IN WIFI_MGR_NETWORK_PROFILE *Profile | |
) | |
{ | |
UINT8 Index; | |
UINT16 CipherSuiteCount; | |
CHAR16 *CipherListDisplay; | |
CipherListDisplay = NULL; | |
if ((Profile == NULL) || (Profile->Network.CipherSuite == NULL)) { | |
goto Exit; | |
} | |
CipherSuiteCount = Profile->Network.CipherSuite->CipherSuiteCount; | |
if (CipherSuiteCount != 0) { | |
// | |
// Current Cipher Suite is between 1-9 | |
// | |
CipherListDisplay = (CHAR16 *)AllocateZeroPool (sizeof (CHAR16) * (CipherSuiteCount * 2 + 1)); | |
if (CipherListDisplay != NULL) { | |
for (Index = 0; Index < CipherSuiteCount; Index++) { | |
// | |
// The size of buffer should be 3 CHAR16 for Null-terminated Unicode string. | |
// The first char is the Cipher Suite number, the second char is ' ', the third char is '\0'. | |
// | |
UnicodeSPrint ( | |
CipherListDisplay + (Index * 2), | |
sizeof (CHAR16) * 3, | |
L"%d ", | |
Profile->Network.CipherSuite->CipherSuiteList[Index].SuiteType | |
); | |
if (Index == CipherSuiteCount - 1) { | |
*(CipherListDisplay + (Index * 2 + 1)) = L'\0'; | |
} | |
} | |
} | |
} | |
Exit: | |
if (CipherListDisplay == NULL) { | |
CipherListDisplay = AllocateCopyPool (sizeof (L"None"), L"None"); | |
} | |
return CipherListDisplay; | |
} | |
/** | |
Refresh the network list display of the current Nic. | |
@param[in] Private The pointer to the global private data structure. | |
@param[out] IfrNvData The IFR NV data. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory. | |
@retval Other Errors Returned errors when creating Opcodes or updating the | |
Hii form. | |
**/ | |
EFI_STATUS | |
WifiMgrRefreshNetworkList ( | |
IN WIFI_MGR_PRIVATE_DATA *Private, | |
OUT WIFI_MANAGER_IFR_NVDATA *IfrNvData | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_TPL OldTpl; | |
UINT32 AvailableCount; | |
EFI_STRING_ID PortPromptToken; | |
EFI_STRING_ID PortTextToken; | |
EFI_STRING_ID PortHelpToken; | |
WIFI_MGR_NETWORK_PROFILE *Profile; | |
LIST_ENTRY *Entry; | |
VOID *StartOpCodeHandle; | |
VOID *EndOpCodeHandle; | |
CHAR16 *AKMListDisplay; | |
CHAR16 *CipherListDisplay; | |
CHAR16 PortString[WIFI_STR_MAX_SIZE]; | |
UINTN PortStringSize; | |
WIFI_MGR_NETWORK_PROFILE *ConnectedProfile; | |
if (Private->CurrentNic == NULL) { | |
return EFI_SUCCESS; | |
} | |
Status = WifiMgrCreateOpCode ( | |
LABEL_NETWORK_LIST_ENTRY, | |
&StartOpCodeHandle, | |
&EndOpCodeHandle | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
OldTpl = gBS->RaiseTPL (TPL_CALLBACK); | |
AvailableCount = 0; | |
PortStringSize = sizeof (PortString); | |
ConnectedProfile = NULL; | |
AKMListDisplay = NULL; | |
CipherListDisplay = NULL; | |
if (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp) { | |
// | |
// Display the current connected network. | |
// Find the current operate network under connected status. | |
// | |
if ((Private->CurrentNic->CurrentOperateNetwork != NULL) && | |
Private->CurrentNic->CurrentOperateNetwork->IsAvailable) | |
{ | |
Profile = Private->CurrentNic->CurrentOperateNetwork; | |
AvailableCount++; | |
AKMListDisplay = WifiMgrGetStrAKMList (Profile); | |
if (AKMListDisplay == NULL) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
CipherListDisplay = WifiMgrGetStrCipherList (Profile); | |
if (CipherListDisplay == NULL) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
UnicodeSPrint (PortString, PortStringSize, L"%s (Connected)", Profile->SSId); | |
PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); | |
if (Profile->SecurityType == SECURITY_TYPE_NONE) { | |
PortHelpToken = 0; | |
} else { | |
UnicodeSPrint (PortString, PortStringSize, L"AKMSuite: %s CipherSuite: %s", AKMListDisplay, CipherListDisplay); | |
PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); | |
} | |
FreePool (AKMListDisplay); | |
FreePool (CipherListDisplay); | |
AKMListDisplay = NULL; | |
CipherListDisplay = NULL; | |
HiiCreateGotoOpCode ( | |
StartOpCodeHandle, | |
FORMID_CONNECT_NETWORK, | |
PortPromptToken, | |
PortHelpToken, | |
EFI_IFR_FLAG_CALLBACK, | |
(UINT16)(KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex) | |
); | |
UnicodeSPrint ( | |
PortString, | |
PortStringSize, | |
L"%s %s %s", | |
(Profile->SecurityType != SECURITY_TYPE_NONE ? L"Secured" : L"Open "), | |
mSecurityType[Profile->SecurityType], | |
RSSI_TO_SIGNAL_STRENGTH_BAR (Profile->NetworkQuality) | |
); | |
PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); | |
HiiCreateTextOpCode ( | |
StartOpCodeHandle, | |
PortTextToken, | |
0, | |
0 | |
); | |
ConnectedProfile = Profile; | |
} else { | |
Private->CurrentNic->HasDisconnectPendingNetwork = TRUE; | |
} | |
} | |
// | |
// Display all supported available networks. | |
// | |
NET_LIST_FOR_EACH (Entry, &Private->CurrentNic->ProfileList) { | |
Profile = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_MGR_NETWORK_PROFILE, | |
Link, | |
WIFI_MGR_PROFILE_SIGNATURE | |
); | |
if (ConnectedProfile == Profile) { | |
continue; | |
} | |
if (Profile->IsAvailable && Profile->CipherSuiteSupported) { | |
AvailableCount++; | |
AKMListDisplay = WifiMgrGetStrAKMList (Profile); | |
if (AKMListDisplay == NULL) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
CipherListDisplay = WifiMgrGetStrCipherList (Profile); | |
if (CipherListDisplay == NULL) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, Profile->SSId, NULL); | |
if (PortPromptToken == 0) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
if (Profile->SecurityType == SECURITY_TYPE_NONE) { | |
PortHelpToken = 0; | |
} else { | |
UnicodeSPrint ( | |
PortString, | |
PortStringSize, | |
L"AKMSuite: %s CipherSuite: %s", | |
AKMListDisplay, | |
CipherListDisplay | |
); | |
PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); | |
if (PortHelpToken == 0) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
} | |
FreePool (AKMListDisplay); | |
FreePool (CipherListDisplay); | |
AKMListDisplay = NULL; | |
CipherListDisplay = NULL; | |
HiiCreateGotoOpCode ( | |
StartOpCodeHandle, | |
FORMID_CONNECT_NETWORK, | |
PortPromptToken, | |
PortHelpToken, | |
EFI_IFR_FLAG_CALLBACK, | |
(UINT16)(KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex) | |
); | |
UnicodeSPrint ( | |
PortString, | |
PortStringSize, | |
L"%s %s %s", | |
(Profile->SecurityType != SECURITY_TYPE_NONE ? L"Secured" : L"Open "), | |
mSecurityType[Profile->SecurityType], | |
RSSI_TO_SIGNAL_STRENGTH_BAR (Profile->NetworkQuality) | |
); | |
PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); | |
if (PortTextToken == 0) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
HiiCreateTextOpCode ( | |
StartOpCodeHandle, | |
PortTextToken, | |
0, | |
0 | |
); | |
} | |
} | |
// | |
// Display all Unsupported available networks. | |
// | |
NET_LIST_FOR_EACH (Entry, &Private->CurrentNic->ProfileList) { | |
Profile = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_MGR_NETWORK_PROFILE, | |
Link, | |
WIFI_MGR_PROFILE_SIGNATURE | |
); | |
if (ConnectedProfile == Profile) { | |
continue; | |
} | |
if (Profile->IsAvailable && !Profile->CipherSuiteSupported) { | |
AvailableCount++; | |
AKMListDisplay = WifiMgrGetStrAKMList (Profile); | |
if (AKMListDisplay == NULL) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
CipherListDisplay = WifiMgrGetStrCipherList (Profile); | |
if (CipherListDisplay == NULL) { | |
Status = EFI_OUT_OF_RESOURCES; | |
goto Exit; | |
} | |
PortPromptToken = HiiSetString (Private->RegisteredHandle, 0, Profile->SSId, NULL); | |
if (Profile->AKMSuiteSupported) { | |
UnicodeSPrint ( | |
PortString, | |
PortStringSize, | |
L"AKMSuite: %s CipherSuite(UnSupported): %s", | |
AKMListDisplay, | |
CipherListDisplay | |
); | |
} else { | |
UnicodeSPrint ( | |
PortString, | |
PortStringSize, | |
L"AKMSuite(UnSupported): %s CipherSuite(UnSupported): %s", | |
AKMListDisplay, | |
CipherListDisplay | |
); | |
} | |
FreePool (AKMListDisplay); | |
FreePool (CipherListDisplay); | |
AKMListDisplay = NULL; | |
CipherListDisplay = NULL; | |
PortHelpToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); | |
HiiCreateGotoOpCode ( | |
StartOpCodeHandle, | |
FORMID_CONNECT_NETWORK, | |
PortPromptToken, | |
PortHelpToken, | |
EFI_IFR_FLAG_CALLBACK, | |
(UINT16)(KEY_AVAILABLE_NETWORK_ENTRY_BASE + Profile->ProfileIndex) | |
); | |
UnicodeSPrint ( | |
PortString, | |
PortStringSize, | |
L"%s %s %s", | |
L"UnSupported", | |
mSecurityType[Profile->SecurityType], | |
RSSI_TO_SIGNAL_STRENGTH_BAR (Profile->NetworkQuality) | |
); | |
PortTextToken = HiiSetString (Private->RegisteredHandle, 0, PortString, NULL); | |
HiiCreateTextOpCode ( | |
StartOpCodeHandle, | |
PortTextToken, | |
0, | |
0 | |
); | |
} | |
} | |
Status = HiiUpdateForm ( | |
Private->RegisteredHandle, // HII handle | |
&gWifiConfigFormSetGuid, // Formset GUID | |
FORMID_NETWORK_LIST, // Form ID | |
StartOpCodeHandle, // Label for where to insert opcodes | |
EndOpCodeHandle // Replace data | |
); | |
Exit: | |
gBS->RestoreTPL (OldTpl); | |
if (AKMListDisplay != NULL) { | |
FreePool (AKMListDisplay); | |
} | |
if (CipherListDisplay != NULL) { | |
FreePool (CipherListDisplay); | |
} | |
HiiFreeOpCodeHandle (StartOpCodeHandle); | |
HiiFreeOpCodeHandle (EndOpCodeHandle); | |
DEBUG ((DEBUG_INFO, "[WiFi Connection Manager] Network List is Refreshed!\n")); | |
return Status; | |
} | |
/** | |
Refresh the hidden network list configured by user. | |
@param[in] Private The pointer to the global private data structure. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
@retval Other Errors Returned errors when creating Opcodes or updating the | |
Hii form. | |
**/ | |
EFI_STATUS | |
WifiMgrRefreshHiddenList ( | |
IN WIFI_MGR_PRIVATE_DATA *Private | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_TPL OldTpl; | |
UINTN Index; | |
EFI_STRING_ID StringId; | |
VOID *StartOpCodeHandle; | |
VOID *EndOpCodeHandle; | |
WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; | |
LIST_ENTRY *Entry; | |
if (Private == NULL) { | |
return EFI_SUCCESS; | |
} | |
Status = WifiMgrCreateOpCode ( | |
LABEL_HIDDEN_NETWORK_ENTRY, | |
&StartOpCodeHandle, | |
&EndOpCodeHandle | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
OldTpl = gBS->RaiseTPL (TPL_CALLBACK); | |
Index = 0; | |
NET_LIST_FOR_EACH (Entry, &Private->HiddenNetworkList) { | |
HiddenNetwork = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_HIDDEN_NETWORK_DATA, | |
Link, | |
WIFI_MGR_HIDDEN_NETWORK_SIGNATURE | |
); | |
StringId = HiiSetString (Private->RegisteredHandle, 0, HiddenNetwork->SSId, NULL); | |
HiiCreateCheckBoxOpCode ( | |
StartOpCodeHandle, | |
(EFI_QUESTION_ID)(KEY_HIDDEN_NETWORK_ENTRY_BASE + Index), | |
MANAGER_VARSTORE_ID, | |
(UINT16)(HIDDEN_NETWORK_LIST_VAR_OFFSET + Index), | |
StringId, | |
0, | |
0, | |
0, | |
NULL | |
); | |
Index++; | |
} | |
Status = HiiUpdateForm ( | |
Private->RegisteredHandle, // HII handle | |
&gWifiConfigFormSetGuid, // Formset GUID | |
FORMID_HIDDEN_NETWORK_LIST, // Form ID | |
StartOpCodeHandle, // Label for where to insert opcodes | |
EndOpCodeHandle // Replace data | |
); | |
gBS->RestoreTPL (OldTpl); | |
HiiFreeOpCodeHandle (StartOpCodeHandle); | |
HiiFreeOpCodeHandle (EndOpCodeHandle); | |
return Status; | |
} | |
/** | |
Callback function for user to select a Nic. | |
@param[in] Private The pointer to the global private data structure. | |
@param[in] KeyValue The key value received from HII input. | |
@retval EFI_NOT_FOUND The corresponding Nic is not found. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
**/ | |
EFI_STATUS | |
WifiMgrSelectNic ( | |
IN WIFI_MGR_PRIVATE_DATA *Private, | |
IN EFI_QUESTION_ID KeyValue | |
) | |
{ | |
WIFI_MGR_DEVICE_DATA *Nic; | |
UINT32 NicIndex; | |
CHAR16 MacString[WIFI_MGR_MAX_MAC_STRING_LEN]; | |
NicIndex = KeyValue - KEY_MAC_ENTRY_BASE; | |
Nic = WifiMgrGetNicByIndex (Private, NicIndex); | |
if (Nic == NULL) { | |
return EFI_NOT_FOUND; | |
} | |
Private->CurrentNic = Nic; | |
WifiMgrMacAddrToStr (&Nic->MacAddress, sizeof (MacString), MacString); | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_MAC_ADDRESS), MacString, NULL); | |
return EFI_SUCCESS; | |
} | |
/** | |
Restore the NV data to be default. | |
@param[in] Private The pointer to the global private data structure. | |
@param[out] IfrNvData The IFR NV data. | |
**/ | |
VOID | |
WifiMgrCleanUserInput ( | |
IN WIFI_MGR_PRIVATE_DATA *Private | |
) | |
{ | |
Private->SecurityType = SECURITY_TYPE_NONE; | |
Private->EapAuthMethod = EAP_AUTH_METHOD_TTLS; | |
Private->EapSecondAuthMethod = EAP_SEAUTH_METHOD_MSCHAPV2; | |
Private->FileType = FileTypeMax; | |
} | |
/** | |
UI handle function when user select a network to connect. | |
@param[in] Private The pointer to the global private data structure. | |
@param[in] ProfileIndex The profile index user selected to connect. | |
@retval EFI_INVALID_PARAMETER Nic is null. | |
@retval EFI_NOT_FOUND Profile could not be found. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
**/ | |
EFI_STATUS | |
WifiMgrUserSelectProfileToConnect ( | |
IN WIFI_MGR_PRIVATE_DATA *Private, | |
IN UINT32 ProfileIndex | |
) | |
{ | |
WIFI_MGR_NETWORK_PROFILE *Profile; | |
WIFI_MGR_DEVICE_DATA *Nic; | |
Nic = Private->CurrentNic; | |
if (Nic == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
// | |
// Initialize the connection page | |
// | |
WifiMgrCleanUserInput (Private); | |
Profile = WifiMgrGetProfileByProfileIndex (ProfileIndex, &Nic->ProfileList); | |
if (Profile == NULL) { | |
return EFI_NOT_FOUND; | |
} | |
Private->CurrentNic->UserSelectedProfile = Profile; | |
return EFI_SUCCESS; | |
} | |
/** | |
Record password from a HII input string. | |
@param[in] Private The pointer to the global private data structure. | |
@param[in] StringId The QuestionId received from HII input. | |
@param[in] StringBuffer The unicode string buffer to store password. | |
@param[in] StringBufferLen The len of unicode string buffer. | |
@retval EFI_INVALID_PARAMETER Any input parameter is invalid. | |
@retval EFI_NOT_FOUND The password string is not found or invalid. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
**/ | |
EFI_STATUS | |
WifiMgrRecordPassword ( | |
IN WIFI_MGR_PRIVATE_DATA *Private, | |
IN EFI_STRING_ID StringId, | |
IN CHAR16 *StringBuffer, | |
IN UINTN StringBufferLen | |
) | |
{ | |
CHAR16 *Password; | |
if ((StringId == 0) || (StringBuffer == NULL) || (StringBufferLen <= 0)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Password = HiiGetString (Private->RegisteredHandle, StringId, NULL); | |
if (Password == NULL) { | |
return EFI_NOT_FOUND; | |
} | |
if (StrLen (Password) > StringBufferLen) { | |
FreePool (Password); | |
return EFI_NOT_FOUND; | |
} | |
StrnCpyS (StringBuffer, StringBufferLen, Password, StrLen (Password)); | |
ZeroMem (Password, (StrLen (Password) + 1) * sizeof (CHAR16)); | |
FreePool (Password); | |
// | |
// Clean password in string package | |
// | |
HiiSetString (Private->RegisteredHandle, StringId, L"", NULL); | |
return EFI_SUCCESS; | |
} | |
/** | |
Update connection message on connect configuration page, and trigger related form refresh. | |
@param[in] Nic The related Nic for updating message. | |
@param[in] ConnectStateChanged The tag to tell if the connection state has been changed, only | |
when the connection changes from "Connected" or "Disconnecting" | |
to "Disconnected", or from "Disconnected" or "Connecting" to | |
"Connected", this tag can be set as TRUE. | |
@param[in] ConnectStatusMessage The message to show on connected status bar, if NULL, will | |
use default message. | |
**/ | |
VOID | |
WifiMgrUpdateConnectMessage ( | |
IN WIFI_MGR_DEVICE_DATA *Nic, | |
IN BOOLEAN ConnectStateChanged, | |
IN EFI_STRING ConnectStatusMessage | |
) | |
{ | |
CHAR16 ConnectStatusStr[WIFI_STR_MAX_SIZE]; | |
WIFI_MGR_PRIVATE_DATA *Private; | |
Private = Nic->Private; | |
if ((Private == NULL) || (Private->CurrentNic != Nic)) { | |
return; | |
} | |
// | |
// Update Connection Status Bar | |
// | |
if (ConnectStatusMessage != NULL) { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusMessage, NULL); | |
} else { | |
if (Nic->ConnectState == WifiMgrConnectedToAp) { | |
UnicodeSPrint ( | |
ConnectStatusStr, | |
sizeof (ConnectStatusStr), | |
L"Connected to %s", | |
Nic->CurrentOperateNetwork->SSId | |
); | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); | |
} else if (Nic->ConnectState == WifiMgrDisconnected) { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), L"Disconnected", NULL); | |
} else if (Nic->ConnectState == WifiMgrConnectingToAp) { | |
UnicodeSPrint ( | |
ConnectStatusStr, | |
sizeof (ConnectStatusStr), | |
L"Connecting to %s ...", | |
Nic->CurrentOperateNetwork->SSId | |
); | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); | |
} else if (Nic->ConnectState == WifiMgrDisconnectingToAp) { | |
UnicodeSPrint ( | |
ConnectStatusStr, | |
sizeof (ConnectStatusStr), | |
L"Disconnecting from %s ...", | |
Nic->CurrentOperateNetwork->SSId | |
); | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_STATUS), ConnectStatusStr, NULL); | |
} else { | |
return; | |
} | |
} | |
// | |
// Update Connect Button | |
// | |
if ((Nic->ConnectState == WifiMgrConnectedToAp) && (Nic->UserSelectedProfile == Nic->CurrentOperateNetwork)) { | |
HiiSetString ( | |
Private->RegisteredHandle, | |
STRING_TOKEN (STR_CONNECT_NOW), | |
L"Disconnect from this Network", | |
NULL | |
); | |
} else { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECT_NOW), L"Connect to this Network", NULL); | |
} | |
gBS->SignalEvent (Private->ConnectFormRefreshEvent); | |
// | |
// Update Main Page and Network List | |
// | |
if (ConnectStateChanged) { | |
if (Nic->ConnectState == WifiMgrConnectedToAp) { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTION_INFO), L"Connected to", NULL); | |
HiiSetString ( | |
Private->RegisteredHandle, | |
STRING_TOKEN (STR_CONNECTED_SSID), | |
Nic->CurrentOperateNetwork->SSId, | |
NULL | |
); | |
} else { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTION_INFO), L"Disconnected", NULL); | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_CONNECTED_SSID), L"", NULL); | |
} | |
gBS->SignalEvent (Private->NetworkListRefreshEvent); | |
gBS->SignalEvent (Private->MainPageRefreshEvent); | |
} | |
} | |
/** | |
Convert the driver configuration data into the IFR data. | |
@param[in] Private The pointer to the global private data structure. | |
@param[out] IfrNvData The IFR NV data. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
**/ | |
EFI_STATUS | |
WifiMgrConvertConfigDataToIfrNvData ( | |
IN WIFI_MGR_PRIVATE_DATA *Private, | |
OUT WIFI_MANAGER_IFR_NVDATA *IfrNvData | |
) | |
{ | |
// | |
// Private shouldn't be NULL here, assert if Private is NULL. | |
// | |
ASSERT (Private != NULL); | |
if (Private->CurrentNic != NULL) { | |
IfrNvData->ProfileCount = Private->CurrentNic->AvailableCount; | |
} else { | |
IfrNvData->ProfileCount = 0; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Convert the IFR data into the driver configuration data. | |
@param[in] Private The pointer to the global private data structure. | |
@param[in, out] IfrNvData The IFR NV data. | |
@retval EFI_SUCCESS The operation is completed successfully. | |
**/ | |
EFI_STATUS | |
WifiMgrConvertIfrNvDataToConfigData ( | |
IN WIFI_MGR_PRIVATE_DATA *Private, | |
IN OUT WIFI_MANAGER_IFR_NVDATA *IfrNvData | |
) | |
{ | |
return EFI_SUCCESS; | |
} | |
/** | |
This function allows the caller to request the current | |
configuration for one or more named elements. The resulting | |
string is in <ConfigAltResp> format. Any and all alternative | |
configuration strings shall also be appended to the end of the | |
current configuration string. If they are, they must appear | |
after the current configuration. They must contain the same | |
routing (GUID, NAME, PATH) as the current configuration string. | |
They must have an additional description indicating the type of | |
alternative configuration the string represents, | |
"ALTCFG=<StringToken>". That <StringToken> (when | |
converted from Hex UNICODE to binary) is a reference to a | |
string in the associated string pack. | |
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. | |
@param Request A null-terminated Unicode string in | |
<ConfigRequest> format. Note that this | |
includes the routing information as well as | |
the configurable name / value pairs. It is | |
invalid for this string to be in | |
<MultiConfigRequest> format. | |
If a NULL is passed in for the Request field, | |
all of the settings being abstracted by this function | |
will be returned in the Results field. In addition, | |
if a ConfigHdr is passed in with no request elements, | |
all of the settings being abstracted for that particular | |
ConfigHdr reference will be returned in the Results Field. | |
@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 | |
<MultiConfigAltResp> 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 string is filled with the | |
values corresponding to all requested | |
names. | |
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the | |
parts of the results that must be | |
stored awaiting possible future | |
protocols. | |
@retval EFI_NOT_FOUND Routing data doesn't match any | |
known driver. Progress set to the | |
first character in the routing header. | |
Note: There is no requirement that the | |
driver validate the routing data. It | |
must skip the <ConfigHdr> in order to | |
process the names. | |
@retval EFI_INVALID_PARAMETER Illegal syntax. Progress set | |
to most recent "&" before the | |
error or the beginning of the | |
string. | |
@retval EFI_INVALID_PARAMETER Unknown name. Progress points | |
to the & before the name in | |
question. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
WifiMgrDxeHiiConfigAccessExtractConfig ( | |
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
IN CONST EFI_STRING Request, | |
OUT EFI_STRING *Progress, | |
OUT EFI_STRING *Results | |
) | |
{ | |
WIFI_MGR_PRIVATE_DATA *Private; | |
WIFI_MANAGER_IFR_NVDATA *IfrNvData; | |
EFI_STRING ConfigRequestHdr; | |
EFI_STRING ConfigRequest; | |
UINTN Size; | |
BOOLEAN AllocatedRequest; | |
UINTN BufferSize; | |
EFI_STATUS Status; | |
if ((This == NULL) || (Progress == NULL) || (Results == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
*Progress = Request; | |
if ((Request != NULL) && | |
!HiiIsConfigHdrMatch (Request, &gWifiConfigFormSetGuid, mVendorStorageName)) | |
{ | |
return EFI_NOT_FOUND; | |
} | |
ConfigRequestHdr = NULL; | |
ConfigRequest = NULL; | |
AllocatedRequest = FALSE; | |
Size = 0; | |
Private = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This); | |
BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA); | |
IfrNvData = AllocateZeroPool (BufferSize); | |
if (IfrNvData == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
WifiMgrConvertConfigDataToIfrNvData (Private, IfrNvData); | |
ConfigRequest = Request; | |
if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { | |
// | |
// Request has no request element, construct full request string. | |
// Allocate and fill a buffer large enough to hold the <ConfigHdr> template | |
// followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator. | |
// | |
ConfigRequestHdr = HiiConstructConfigHdr ( | |
&gWifiConfigFormSetGuid, | |
mVendorStorageName, | |
Private->DriverHandle | |
); | |
if (ConfigRequestHdr == NULL) { | |
FreePool (IfrNvData); | |
return EFI_OUT_OF_RESOURCES; | |
} | |
Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); | |
ConfigRequest = AllocateZeroPool (Size); | |
if (ConfigRequest == NULL) { | |
FreePool (IfrNvData); | |
FreePool (ConfigRequestHdr); | |
return EFI_OUT_OF_RESOURCES; | |
} | |
AllocatedRequest = TRUE; | |
UnicodeSPrint ( | |
ConfigRequest, | |
Size, | |
L"%s&OFFSET=0&WIDTH=%016LX", | |
ConfigRequestHdr, | |
(UINT64)BufferSize | |
); | |
FreePool (ConfigRequestHdr); | |
} | |
// | |
// Convert buffer data to <ConfigResp> by helper function BlockToConfig() | |
// | |
Status = gHiiConfigRouting->BlockToConfig ( | |
gHiiConfigRouting, | |
ConfigRequest, | |
(UINT8 *)IfrNvData, | |
BufferSize, | |
Results, | |
Progress | |
); | |
FreePool (IfrNvData); | |
// | |
// Free the allocated config request string. | |
// | |
if (AllocatedRequest) { | |
FreePool (ConfigRequest); | |
ConfigRequest = NULL; | |
} | |
// | |
// Set Progress string to the original request string. | |
// | |
if (Request == NULL) { | |
*Progress = NULL; | |
} else if (StrStr (Request, L"OFFSET") == NULL) { | |
*Progress = Request + StrLen (Request); | |
} | |
return Status; | |
} | |
/** | |
This function applies changes in a driver's configuration. | |
Input is a Configuration, which has the routing data for this | |
driver followed by name / value configuration pairs. The driver | |
must apply those pairs to its configurable storage. If the | |
driver's configuration is stored in a linear block of data | |
and the driver's name / value pairs are in <BlockConfig> | |
format, it may use the ConfigToBlock helper function (above) to | |
simplify the job. | |
@param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. | |
@param Configuration A null-terminated Unicode string in | |
<ConfigString> 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 | |
beginn ing 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 have been distributed or are | |
awaiting distribution. | |
@retval EFI_OUT_OF_RESOURCES Not enough memory to store the | |
parts of the results that must be | |
stored awaiting possible future | |
protocols. | |
@retval EFI_INVALID_PARAMETERS Passing in a NULL for the | |
Results parameter would result | |
in this type of error. | |
@retval EFI_NOT_FOUND Target for the specified routing data | |
was not found | |
**/ | |
EFI_STATUS | |
EFIAPI | |
WifiMgrDxeHiiConfigAccessRouteConfig ( | |
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
IN CONST EFI_STRING Configuration, | |
OUT EFI_STRING *Progress | |
) | |
{ | |
EFI_STATUS Status; | |
UINTN BufferSize; | |
WIFI_MGR_PRIVATE_DATA *Private; | |
WIFI_MANAGER_IFR_NVDATA *IfrNvData; | |
if ((Configuration == NULL) || (Progress == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
IfrNvData = NULL; | |
*Progress = Configuration; | |
BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA); | |
Private = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This); | |
if (!HiiIsConfigHdrMatch (Configuration, &gWifiConfigFormSetGuid, mVendorStorageName)) { | |
return EFI_NOT_FOUND; | |
} | |
IfrNvData = AllocateZeroPool (BufferSize); | |
if (IfrNvData == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
WifiMgrConvertConfigDataToIfrNvData (Private, IfrNvData); | |
Status = gHiiConfigRouting->ConfigToBlock ( | |
gHiiConfigRouting, | |
Configuration, | |
(UINT8 *)IfrNvData, | |
&BufferSize, | |
Progress | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
Status = WifiMgrConvertIfrNvDataToConfigData (Private, IfrNvData); | |
ZeroMem (IfrNvData, sizeof (WIFI_MANAGER_IFR_NVDATA)); | |
FreePool (IfrNvData); | |
return Status; | |
} | |
/** | |
This function is called to provide results data to the driver. | |
This data consists of a unique key that is used to identify | |
which data is either being passed back or being asked for. | |
@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. The format of the data tends to | |
vary based on the opcode that generated the callback. | |
@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_OUT_OF_RESOURCES Not enough storage is available to hold the | |
variable and its data. | |
@retval EFI_DEVICE_ERROR The variable could not be saved. | |
@retval EFI_UNSUPPORTED The specified Action is not supported by the | |
callback. | |
**/ | |
EFI_STATUS | |
EFIAPI | |
WifiMgrDxeHiiConfigAccessCallback ( | |
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, | |
IN EFI_BROWSER_ACTION Action, | |
IN EFI_QUESTION_ID QuestionId, | |
IN UINT8 Type, | |
IN OUT EFI_IFR_TYPE_VALUE *Value, | |
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest | |
) | |
{ | |
EFI_STATUS Status; | |
EFI_INPUT_KEY Key; | |
UINTN BufferSize; | |
WIFI_MGR_PRIVATE_DATA *Private; | |
WIFI_MANAGER_IFR_NVDATA *IfrNvData; | |
EFI_DEVICE_PATH_PROTOCOL *FilePath; | |
WIFI_MGR_NETWORK_PROFILE *Profile; | |
WIFI_MGR_NETWORK_PROFILE *ProfileToConnect; | |
WIFI_HIDDEN_NETWORK_DATA *HiddenNetwork; | |
UINTN TempDataSize; | |
VOID *TempData; | |
LIST_ENTRY *Entry; | |
UINT32 Index; | |
UINT32 RemoveCount; | |
CHAR16 *TempPassword; | |
CHAR16 *ErrorMessage; | |
if ((Action != EFI_BROWSER_ACTION_FORM_OPEN) && | |
(Action != EFI_BROWSER_ACTION_FORM_CLOSE) && | |
(Action != EFI_BROWSER_ACTION_CHANGING) && | |
(Action != EFI_BROWSER_ACTION_CHANGED) && | |
(Action != EFI_BROWSER_ACTION_RETRIEVE)) | |
{ | |
return EFI_UNSUPPORTED; | |
} | |
if ((Value == NULL) || (ActionRequest == NULL)) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Status = EFI_SUCCESS; | |
Private = WIFI_MGR_PRIVATE_DATA_FROM_CONFIG_ACCESS (This); | |
if (Private->CurrentNic == NULL) { | |
return EFI_DEVICE_ERROR; | |
} | |
// | |
// Retrieve uncommitted data from Browser | |
// | |
BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA); | |
IfrNvData = AllocateZeroPool (BufferSize); | |
if (IfrNvData == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
if (Action != EFI_BROWSER_ACTION_FORM_OPEN) { | |
HiiGetBrowserData (&gWifiConfigFormSetGuid, mVendorStorageName, BufferSize, (UINT8 *)IfrNvData); | |
} | |
if (Action == EFI_BROWSER_ACTION_FORM_OPEN) { | |
switch (QuestionId) { | |
case KEY_MAC_LIST: | |
Status = WifiMgrShowNicList (Private); | |
break; | |
case KEY_REFRESH_NETWORK_LIST: | |
if (Private->CurrentNic->UserSelectedProfile != NULL) { | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
// | |
// Erase secrets since user has left Connection Page | |
// Connection Page may direct to Network List Page or Eap Configuration Page, | |
// secrets only need to be erased when head to Network List Page | |
// | |
WifiMgrCleanProfileSecrets (Profile); | |
Private->CurrentNic->UserSelectedProfile = NULL; | |
} | |
break; | |
case KEY_ENROLLED_CERT_NAME: | |
if (Private->CurrentNic->UserSelectedProfile == NULL) { | |
break; | |
} | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
// | |
// Enter the key enrollment page | |
// For TTLS and PEAP, only CA cert needs to be cared | |
// | |
if (Private->FileType == FileTypeCACert) { | |
if (Profile->CACertData != NULL) { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), Profile->CACertName, NULL); | |
} else { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL); | |
} | |
} else if (Private->FileType == FileTypeClientCert) { | |
if (Profile->ClientCertData != NULL) { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), Profile->ClientCertName, NULL); | |
} else { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_CERT_NAME), L"", NULL); | |
} | |
} | |
break; | |
case KEY_ENROLLED_PRIVATE_KEY_NAME: | |
if (Private->CurrentNic->UserSelectedProfile == NULL) { | |
break; | |
} | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
if (Profile->PrivateKeyData != NULL) { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), Profile->PrivateKeyName, NULL); | |
} else { | |
HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_EAP_ENROLLED_PRIVATE_KEY_NAME), L"", NULL); | |
} | |
break; | |
default: | |
break; | |
} | |
} else if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) { | |
switch (QuestionId) { | |
case KEY_EAP_ENROLL_CERT_FROM_FILE: | |
if (Private->CurrentNic->UserSelectedProfile == NULL) { | |
break; | |
} | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
// | |
// Enter the network connection configuration page | |
// Recovery from restored data | |
// | |
if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SSID), Profile->SSId, NULL) == 0) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
IfrNvData->SecurityType = Profile->SecurityType; | |
if (HiiSetString ( | |
Private->RegisteredHandle, | |
STRING_TOKEN (STR_SECURITY_TYPE), | |
mSecurityType[IfrNvData->SecurityType], | |
NULL | |
) == 0) | |
{ | |
return EFI_OUT_OF_RESOURCES; | |
} | |
if ( (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) | |
|| (IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE)) | |
{ | |
IfrNvData->EapAuthMethod = Profile->EapAuthMethod; | |
IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod; | |
StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity); | |
} | |
break; | |
case KEY_CONNECT_ACTION: | |
if (Private->CurrentNic->UserSelectedProfile == NULL) { | |
break; | |
} | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
// | |
// Restore User Config Data for Page recovery | |
// | |
if ((IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) || | |
(IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE)) | |
{ | |
Profile->EapAuthMethod = IfrNvData->EapAuthMethod; | |
Profile->EapSecondAuthMethod = IfrNvData->EapSecondAuthMethod; | |
StrCpyS (Profile->EapIdentity, EAP_IDENTITY_SIZE, IfrNvData->EapIdentity); | |
} | |
break; | |
default: | |
break; | |
} | |
} else if (Action == EFI_BROWSER_ACTION_CHANGING) { | |
switch (QuestionId) { | |
case KEY_NETWORK_LIST: | |
// | |
// User triggered a scan process. | |
// | |
Private->CurrentNic->OneTimeScanRequest = TRUE; | |
break; | |
case KEY_PASSWORD_CONNECT_NETWORK: | |
case KEY_EAP_PASSWORD_CONNECT_NETWORK: | |
case KEY_PRIVATE_KEY_PASSWORD: | |
if (Private->CurrentNic->UserSelectedProfile == NULL) { | |
break; | |
} | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
if (QuestionId == KEY_PASSWORD_CONNECT_NETWORK) { | |
TempPassword = Profile->Password; | |
} else if (QuestionId == KEY_EAP_PASSWORD_CONNECT_NETWORK) { | |
TempPassword = Profile->EapPassword; | |
} else { | |
TempPassword = Profile->PrivateKeyPassword; | |
} | |
Status = WifiMgrRecordPassword (Private, Value->string, TempPassword, PASSWORD_STORAGE_SIZE); | |
if (EFI_ERROR (Status)) { | |
DEBUG ((DEBUG_ERROR, "[WiFi Connection Manager] Error: Failed to input password!")); | |
break; | |
} | |
// | |
// This password is not a new created password, so no need to confirm. | |
// | |
Status = EFI_NOT_FOUND; | |
break; | |
case KEY_CONNECT_ACTION: | |
ErrorMessage = NULL; | |
ProfileToConnect = NULL; | |
if (Private->CurrentNic->UserSelectedProfile == NULL) { | |
break; | |
} | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
if ((Private->CurrentNic->ConnectState == WifiMgrDisconnected) || | |
(Profile != Private->CurrentNic->CurrentOperateNetwork)) | |
{ | |
// | |
// When this network is not currently connected, pend it to connect. | |
// | |
if (Profile->AKMSuiteSupported && Profile->CipherSuiteSupported) { | |
if ((Profile->SecurityType == SECURITY_TYPE_NONE) || | |
(Profile->SecurityType == SECURITY_TYPE_WPA2_PERSONAL) || | |
(Profile->SecurityType == SECURITY_TYPE_WPA3_PERSONAL)) | |
{ | |
// | |
// For Open network, connect directly. | |
// | |
ProfileToConnect = Profile; | |
} else if ((Profile->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) || | |
(Profile->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE)) | |
{ | |
// | |
// For WPA/WPA2-Enterprise network, conduct eap configuration first. | |
// Only EAP-TLS, TTLS and PEAP is supported now! | |
// | |
Profile->EapAuthMethod = IfrNvData->EapAuthMethod; | |
StrCpyS (Profile->EapIdentity, EAP_IDENTITY_SIZE, IfrNvData->EapIdentity); | |
if ((IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_TTLS) || (IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_PEAP)) { | |
Profile->EapSecondAuthMethod = IfrNvData->EapSecondAuthMethod; | |
ProfileToConnect = Profile; | |
} else if (IfrNvData->EapAuthMethod == EAP_AUTH_METHOD_TLS) { | |
ProfileToConnect = Profile; | |
} else { | |
ErrorMessage = L"ERROR: Only EAP-TLS, TTLS or PEAP is supported now!"; | |
} | |
} else { | |
ErrorMessage = L"ERROR: Can't connect to this network!"; | |
} | |
} else { | |
ErrorMessage = L"ERROR: This network is not supported!"; | |
} | |
if (ErrorMessage != NULL) { | |
CreatePopUp ( | |
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, | |
&Key, | |
ErrorMessage, | |
NULL | |
); | |
} | |
if (ProfileToConnect != NULL) { | |
Private->CurrentNic->OneTimeConnectRequest = TRUE; | |
Private->CurrentNic->ConnectPendingNetwork = ProfileToConnect; | |
} | |
} else if (Private->CurrentNic->ConnectState == WifiMgrConnectedToAp) { | |
// | |
// This network is currently connected, just disconnect from it. | |
// | |
Private->CurrentNic->OneTimeDisconnectRequest = TRUE; | |
Private->CurrentNic->HasDisconnectPendingNetwork = TRUE; | |
} | |
break; | |
case KEY_ENROLL_CA_CERT_CONNECT_NETWORK: | |
Private->FileType = FileTypeCACert; | |
break; | |
case KEY_ENROLL_CLIENT_CERT_CONNECT_NETWORK: | |
Private->FileType = FileTypeClientCert; | |
break; | |
case KEY_EAP_ENROLL_PRIVATE_KEY_FROM_FILE: | |
FilePath = NULL; | |
ChooseFile (NULL, NULL, NULL, &FilePath); | |
if (FilePath != NULL) { | |
UpdatePrivateKeyFromFile (Private, FilePath); | |
FreePool (FilePath); | |
} | |
break; | |
case KEY_EAP_ENROLL_CERT_FROM_FILE: | |
// | |
// User will select a cert file from File Explore | |
// | |
FilePath = NULL; | |
ChooseFile (NULL, NULL, NULL, &FilePath); | |
if (FilePath != NULL) { | |
UpdateCAFromFile (Private, FilePath); | |
FreePool (FilePath); | |
} | |
break; | |
case KEY_SAVE_PRIVATE_KEY_TO_MEM: | |
if ((Private->FileContext != NULL) && (Private->FileContext->FHandle != NULL) && | |
(Private->CurrentNic->UserSelectedProfile != NULL)) | |
{ | |
// | |
// Read Private Key file to Buffer | |
// | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
if (Profile->PrivateKeyData != NULL) { | |
ZeroMem (Profile->PrivateKeyData, Profile->PrivateKeyDataSize); | |
FreePool (Profile->PrivateKeyData); | |
Profile->PrivateKeyData = NULL; | |
} | |
Status = WifiMgrReadFileToBuffer ( | |
Private->FileContext, | |
&TempData, | |
&TempDataSize | |
); | |
if (EFI_ERROR (Status)) { | |
CreatePopUp ( | |
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, | |
&Key, | |
L"ERROR: Can't read this private key file!", | |
NULL | |
); | |
} else { | |
ASSERT (Private->FileContext->FileName != NULL); | |
Profile->PrivateKeyData = TempData; | |
Profile->PrivateKeyDataSize = TempDataSize; | |
StrCpyS (Profile->PrivateKeyName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName); | |
DEBUG (( | |
DEBUG_INFO, | |
"[WiFi Connection Manager] Private Key: %s has been enrolled! Size: %d\n", | |
Profile->PrivateKeyName, | |
Profile->PrivateKeyDataSize | |
)); | |
} | |
} | |
break; | |
case KEY_SAVE_CERT_TO_MEM: | |
if ((Private->FileContext != NULL) && (Private->FileContext->FHandle != NULL) && | |
(Private->CurrentNic->UserSelectedProfile != NULL)) | |
{ | |
// | |
// Read Cert file to Buffer | |
// | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
if (Private->FileType == FileTypeCACert) { | |
if (Profile->CACertData != NULL) { | |
ZeroMem (Profile->CACertData, Profile->CACertSize); | |
FreePool (Profile->CACertData); | |
Profile->CACertData = NULL; | |
} | |
} else if (Private->FileType == FileTypeClientCert) { | |
if (Profile->ClientCertData != NULL) { | |
ZeroMem (Profile->ClientCertData, Profile->ClientCertSize); | |
FreePool (Profile->ClientCertData); | |
Profile->ClientCertData = NULL; | |
} | |
} else { | |
break; | |
} | |
Status = WifiMgrReadFileToBuffer ( | |
Private->FileContext, | |
&TempData, | |
&TempDataSize | |
); | |
if (EFI_ERROR (Status)) { | |
CreatePopUp ( | |
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, | |
&Key, | |
L"ERROR: Can't read this certificate file!", | |
NULL | |
); | |
} else { | |
ASSERT (Private->FileContext->FileName != NULL); | |
if (Private->FileType == FileTypeCACert) { | |
Profile->CACertData = TempData; | |
Profile->CACertSize = TempDataSize; | |
StrCpyS (Profile->CACertName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName); | |
DEBUG (( | |
DEBUG_INFO, | |
"[WiFi Connection Manager] CA Cert: %s has been enrolled! Size: %d\n", | |
Profile->CACertName, | |
Profile->CACertSize | |
)); | |
} else { | |
Profile->ClientCertData = TempData; | |
Profile->ClientCertSize = TempDataSize; | |
StrCpyS (Profile->ClientCertName, WIFI_FILENAME_STR_MAX_SIZE, Private->FileContext->FileName); | |
DEBUG (( | |
DEBUG_INFO, | |
"[WiFi Connection Manager] Client Cert: %s has been enrolled! Size: %d\n", | |
Profile->ClientCertName, | |
Profile->ClientCertSize | |
)); | |
} | |
} | |
} | |
break; | |
case KEY_ADD_HIDDEN_NETWORK: | |
// | |
// Add a Hidden Network | |
// | |
if ((StrLen (IfrNvData->SSId) < SSID_MIN_LEN) || | |
(Private->HiddenNetworkCount >= HIDDEN_NETWORK_LIST_COUNT_MAX)) | |
{ | |
Status = EFI_ABORTED; | |
break; | |
} else { | |
// | |
// Check if this SSId is already in Hidden Network List | |
// | |
NET_LIST_FOR_EACH (Entry, &Private->HiddenNetworkList) { | |
HiddenNetwork = NET_LIST_USER_STRUCT_S ( | |
Entry, | |
WIFI_HIDDEN_NETWORK_DATA, | |
Link, | |
WIFI_MGR_HIDDEN_NETWORK_SIGNATURE | |
); | |
if (StrCmp (HiddenNetwork->SSId, IfrNvData->SSId) == 0) { | |
Status = EFI_ABORTED; | |
break; | |
} | |
} | |
} | |
HiddenNetwork = (WIFI_HIDDEN_NETWORK_DATA *)AllocateZeroPool (sizeof (WIFI_HIDDEN_NETWORK_DATA)); | |
if (HiddenNetwork == NULL) { | |
Status = EFI_OUT_OF_RESOURCES; | |
break; | |
} | |
HiddenNetwork->Signature = WIFI_MGR_HIDDEN_NETWORK_SIGNATURE; | |
StrCpyS (HiddenNetwork->SSId, SSID_STORAGE_SIZE, IfrNvData->SSId); | |
InsertTailList (&Private->HiddenNetworkList, &HiddenNetwork->Link); | |
Private->HiddenNetworkCount++; | |
WifiMgrRefreshHiddenList (Private); | |
break; | |
case KEY_REMOVE_HIDDEN_NETWORK: | |
// | |
// Remove Hidden Networks | |
// | |
Entry = GetFirstNode (&Private->HiddenNetworkList); | |
RemoveCount = 0; | |
for (Index = 0; Index < Private->HiddenNetworkCount; Index++) { | |
if (IfrNvData->HiddenNetworkList[Index] != 0) { | |
HiddenNetwork = NET_LIST_USER_STRUCT_S (Entry, WIFI_HIDDEN_NETWORK_DATA, Link, WIFI_MGR_HIDDEN_NETWORK_SIGNATURE); | |
Entry = RemoveEntryList (Entry); | |
RemoveCount++; | |
FreePool (HiddenNetwork); | |
} else { | |
Entry = GetNextNode (&Private->HiddenNetworkList, Entry); | |
} | |
} | |
Private->HiddenNetworkCount -= RemoveCount; | |
WifiMgrRefreshHiddenList (Private); | |
break; | |
default: | |
if ((QuestionId >= KEY_MAC_ENTRY_BASE) && (QuestionId < KEY_MAC_ENTRY_BASE + Private->NicCount)) { | |
// | |
// User selects a wireless NIC. | |
// | |
Status = WifiMgrSelectNic (Private, QuestionId); | |
if (EFI_ERROR (Status)) { | |
CreatePopUp ( | |
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, | |
&Key, | |
L"ERROR: Fail to operate the wireless NIC!", | |
NULL | |
); | |
} | |
} else if (Private->CurrentNic != NULL) { | |
if ((QuestionId >= KEY_AVAILABLE_NETWORK_ENTRY_BASE) && | |
(QuestionId <= KEY_AVAILABLE_NETWORK_ENTRY_BASE + Private->CurrentNic->MaxProfileIndex)) | |
{ | |
Status = WifiMgrUserSelectProfileToConnect (Private, QuestionId - KEY_AVAILABLE_NETWORK_ENTRY_BASE); | |
if (!EFI_ERROR (Status)) { | |
WifiMgrUpdateConnectMessage (Private->CurrentNic, FALSE, NULL); | |
} | |
} | |
if (EFI_ERROR (Status)) { | |
CreatePopUp ( | |
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, | |
&Key, | |
L"ERROR: Fail to operate this profile!", | |
NULL | |
); | |
} | |
if (Private->CurrentNic->UserSelectedProfile == NULL) { | |
break; | |
} | |
Profile = Private->CurrentNic->UserSelectedProfile; | |
// | |
// Enter the network connection configuration page | |
// Recovery from restored data | |
// | |
if (HiiSetString (Private->RegisteredHandle, STRING_TOKEN (STR_SSID), Profile->SSId, NULL) == 0) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
IfrNvData->SecurityType = Profile->SecurityType; | |
if (HiiSetString ( | |
Private->RegisteredHandle, | |
STRING_TOKEN (STR_SECURITY_TYPE), | |
mSecurityType[IfrNvData->SecurityType], | |
NULL | |
) == 0) | |
{ | |
return EFI_OUT_OF_RESOURCES; | |
} | |
if ( (IfrNvData->SecurityType == SECURITY_TYPE_WPA2_ENTERPRISE) | |
|| (IfrNvData->SecurityType == SECURITY_TYPE_WPA3_ENTERPRISE)) | |
{ | |
IfrNvData->EapAuthMethod = Profile->EapAuthMethod; | |
IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod; | |
StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity); | |
} | |
} | |
break; | |
} | |
} else if (Action == EFI_BROWSER_ACTION_CHANGED) { | |
switch (QuestionId) { | |
case KEY_SAVE_CERT_TO_MEM: | |
case KEY_SAVE_PRIVATE_KEY_TO_MEM: | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT; | |
break; | |
case KEY_NO_SAVE_CERT_TO_MEM: | |
case KEY_NO_SAVE_PRIVATE_KEY_TO_MEM: | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT; | |
break; | |
default: | |
*ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; | |
break; | |
} | |
} else if (Action == EFI_BROWSER_ACTION_RETRIEVE) { | |
switch (QuestionId) { | |
case KEY_REFRESH_NETWORK_LIST: | |
WifiMgrRefreshNetworkList (Private, IfrNvData); | |
break; | |
default: | |
break; | |
} | |
} | |
if (!EFI_ERROR (Status) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)) { | |
// | |
// Pass changed uncommitted data back to Form Browser. | |
// | |
BufferSize = sizeof (WIFI_MANAGER_IFR_NVDATA); | |
HiiSetBrowserData (&gWifiConfigFormSetGuid, mVendorStorageName, BufferSize, (UINT8 *)IfrNvData, NULL); | |
} | |
ZeroMem (IfrNvData, sizeof (WIFI_MANAGER_IFR_NVDATA)); | |
FreePool (IfrNvData); | |
return Status; | |
} | |
/** | |
Initialize the WiFi configuration form. | |
@param[in] Private The pointer to the global private data structure. | |
@retval EFI_SUCCESS The configuration form is initialized. | |
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory. | |
@retval EFI_INVALID_PARAMETER Any input parameter is invalid. | |
@retval Other Erros Returned Errors when installing protocols. | |
**/ | |
EFI_STATUS | |
WifiMgrDxeConfigFormInit ( | |
WIFI_MGR_PRIVATE_DATA *Private | |
) | |
{ | |
EFI_STATUS Status; | |
if (Private == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
Private->ConfigAccess.ExtractConfig = WifiMgrDxeHiiConfigAccessExtractConfig; | |
Private->ConfigAccess.RouteConfig = WifiMgrDxeHiiConfigAccessRouteConfig; | |
Private->ConfigAccess.Callback = WifiMgrDxeHiiConfigAccessCallback; | |
// | |
// Install Device Path Protocol and Config Access protocol to driver handle. | |
// | |
Status = gBS->InstallMultipleProtocolInterfaces ( | |
&Private->DriverHandle, | |
&gEfiDevicePathProtocolGuid, | |
&mWifiMgrDxeHiiVendorDevicePath, | |
&gEfiHiiConfigAccessProtocolGuid, | |
&Private->ConfigAccess, | |
NULL | |
); | |
if (EFI_ERROR (Status)) { | |
return Status; | |
} | |
// | |
// Publish our HII data. | |
// | |
Private->RegisteredHandle = HiiAddPackages ( | |
&gWifiConfigFormSetGuid, | |
Private->DriverHandle, | |
WifiConnectionManagerDxeStrings, | |
WifiConnectionManagerDxeBin, | |
NULL | |
); | |
if (Private->RegisteredHandle == NULL) { | |
gBS->UninstallMultipleProtocolInterfaces ( | |
Private->DriverHandle, | |
&gEfiDevicePathProtocolGuid, | |
&mWifiMgrDxeHiiVendorDevicePath, | |
&gEfiHiiConfigAccessProtocolGuid, | |
&Private->ConfigAccess, | |
NULL | |
); | |
return EFI_OUT_OF_RESOURCES; | |
} | |
Private->FileContext = AllocateZeroPool (sizeof (WIFI_MGR_FILE_CONTEXT)); | |
if (Private->FileContext == NULL) { | |
return EFI_OUT_OF_RESOURCES; | |
} | |
return EFI_SUCCESS; | |
} | |
/** | |
Unload the WiFi configuration form. | |
@param[in] Private The pointer to the global private data structure. | |
@retval EFI_SUCCESS The configuration form is unloaded successfully. | |
@retval EFI_INVALID_PARAMETER Any input parameter is invalid. | |
@retval Other Errors Returned Erros when uninstalling protocols. | |
**/ | |
EFI_STATUS | |
WifiMgrDxeConfigFormUnload ( | |
WIFI_MGR_PRIVATE_DATA *Private | |
) | |
{ | |
EFI_STATUS Status; | |
if (Private == NULL) { | |
return EFI_INVALID_PARAMETER; | |
} | |
if (Private->FileContext != NULL) { | |
if (Private->FileContext->FHandle != NULL) { | |
Private->FileContext->FHandle->Close (Private->FileContext->FHandle); | |
} | |
if (Private->FileContext->FileName != NULL) { | |
FreePool (Private->FileContext->FileName); | |
} | |
FreePool (Private->FileContext); | |
} | |
HiiRemovePackages (Private->RegisteredHandle); | |
Status = gBS->UninstallMultipleProtocolInterfaces ( | |
Private->DriverHandle, | |
&gEfiDevicePathProtocolGuid, | |
&mWifiMgrDxeHiiVendorDevicePath, | |
&gEfiHiiConfigAccessProtocolGuid, | |
&Private->ConfigAccess, | |
NULL | |
); | |
return Status; | |
} |