summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c2017
1 files changed, 2017 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c
new file mode 100644
index 00000000..73fce8a8
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/NetworkPkg/WifiConnectionManagerDxe/WifiConnectionMgrHiiConfigAccess.c
@@ -0,0 +1,2017 @@
+/** @file
+ The Hii functions for WiFi Connection Manager.
+
+ Copyright (c) 2019, 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"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;
+
+ 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-9
+ //
+ AKMListDisplay = (CHAR16 *) AllocateZeroPool(sizeof (CHAR16) * AKMSuiteCount * 2);
+ if (AKMListDisplay != NULL) {
+ for (Index = 0; Index < AKMSuiteCount; Index ++) {
+ UnicodeSPrint (
+ AKMListDisplay + (Index * 2),
+ sizeof (CHAR16) * 2,
+ L"%d ",
+ Profile->Network.AKMSuite->AKMSuiteList[Index].SuiteType
+ );
+ if (Index == AKMSuiteCount - 1) {
+ *(AKMListDisplay + (Index * 2 + 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);
+ if (CipherListDisplay != NULL) {
+ for (Index = 0; Index < CipherSuiteCount; Index ++) {
+ UnicodeSPrint (
+ CipherListDisplay + (Index * 2),
+ sizeof (CHAR16) * 2,
+ 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;
+ }
+ 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_CONNECT_ACTION:
+
+ 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->EapAuthMethod = Profile->EapAuthMethod;
+ IfrNvData->EapSecondAuthMethod = Profile->EapSecondAuthMethod;
+ StrCpyS (IfrNvData->EapIdentity, EAP_IDENTITY_SIZE, Profile->EapIdentity);
+ }
+
+ 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_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) {
+
+ 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) {
+
+ //
+ // For Open network, connect directly.
+ //
+ ProfileToConnect = Profile;
+
+ } else if (Profile->SecurityType == SECURITY_TYPE_WPA2_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
+ );
+ }
+ }
+
+ 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)) {
+ //
+ // 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;
+}