https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com>
		
			
				
	
	
		
			2018 lines
		
	
	
		
			64 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2018 lines
		
	
	
		
			64 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @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;
 | |
| }
 |