2015年3月28日 星期六

Connect to a Specified Wifi Router in Windows, by C



      For my feeble brain, it made me exhausted to forage a example code which is on switching/connecting  to specified wifi router. I post the code which I have sorted out. I will explain those windows api I have used.

     For use the code , you should download the windows SDK . Add that  the SDK's header path (default be C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include ) in include path; and add SDK's libraries path (default be C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib) in libraries path; and add wlanapi.lib in additional dependencies.



The  code be :


#include <winsock2.h>
#include <Wlanapi.h>

#include <iphlpapi.h>

#include <stdio.h>

#pragma warning(disable:4996) /*fuss sprintf*/

#define SSID_MAX_LEN      (32)




int ConnectToTargetWifiSSID(char *pSSIDName, char *pPassword)
{
 DWORD dwVersion; 
#if(0)
 DWORD dwMajorVersion;
 dwVersion = 0 = dwMajorVersion;

    dwVersion = GetVersion();
 dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));

 DWORD dwClientVersion;
 dwClientVersion = ( dwMajorVersion >= 6) ?  2 : 1 ;  /*vista or latter*/

#endif 

 DWORD result;
 HANDLE iWifiHandle;

 PWLAN_INTERFACE_INFO_LIST iAvailableInterfaces;
 PWLAN_AVAILABLE_NETWORK_LIST availableNetworkList;

 GUID iInterfaceGuid;

 int isHavingProfile;
 
 char authentication[64];
 char encryption[64];
 int isOpenedAP;
 unsigned int i;
 unsigned int iii;


 WLAN_CONNECTION_PARAMETERS connParam;


 iWifiHandle = NULL;
 iAvailableInterfaces = NULL;
 availableNetworkList = NULL;

 
 /*part zero : one a wlan handle*/
 result = WlanOpenHandle(WLAN_API_VERSION_1_0,NULL,&dwVersion, &iWifiHandle);

 if(NULL != iWifiHandle)
 {   
   /*get wireless network card*/
   result = WlanEnumInterfaces(iWifiHandle, NULL, &iAvailableInterfaces);

   if(ERROR_SUCCESS == result && iAvailableInterfaces->dwNumberOfItems > 0)
   {
    /*chose the zeroth one*/ 
    iInterfaceGuid = iAvailableInterfaces->InterfaceInfo[0].InterfaceGuid;
   }
   else
   {
    /*no wireless card*/ 
    result = -2;
    goto Exit_ConnectToTargetSSID;
   }
   
 }
 else
 {
  result = -1;
  goto Exit_ConnectToTargetSSID;
 }/*if NULL != iWifiHandle*/




 /*part one: scan available wifi routers(SSID)*/ 
 result= WlanGetAvailableNetworkList(iWifiHandle, &iInterfaceGuid, 
  WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES, NULL, &availableNetworkList);


 if(ERROR_SUCCESS != result)
  return -3;

 isHavingProfile = FALSE;
 isOpenedAP = FALSE;
 iii = -1;

 memset(&authentication[0], 0, 64);
 memset(&encryption[0], 0, 64);

 if( 0 == availableNetworkList->dwNumberOfItems)
 {
  /*on wifi router has been found*/
  result = -4;
  goto Exit_ConnectToTargetSSID;
 }/*if 0 < wifiList->dwNumberOfItems*/ 


 for(i = 0; i < availableNetworkList->dwNumberOfItems; i++)
 {
         DWORD flag;

   printf("SSID:\t\t\t%s\nSIGNAL:\t\t\t%d\n",
                availableNetworkList->Network[i].dot11Ssid.ucSSID,
                availableNetworkList->Network[i].wlanSignalQuality);
   
  

        printf("SECURITY:\t\t");
        switch(availableNetworkList->Network[i].dot11DefaultAuthAlgorithm)
        {
                case DOT11_AUTH_ALGO_80211_OPEN:
     printf("OPEN\n");
     break;
                case DOT11_AUTH_ALGO_80211_SHARED_KEY:
                    printf("WEP\n");
                break;
                     
                case DOT11_AUTH_ALGO_WPA:
                case DOT11_AUTH_ALGO_WPA_PSK:
                case DOT11_AUTH_ALGO_WPA_NONE:
                    printf("WPA\n");
                break;

                case DOT11_AUTH_ALGO_RSNA:
                case DOT11_AUTH_ALGO_RSNA_PSK:
                    printf("WPA2\n");
                break;

                default:
                    printf("UNKNOWN\n");
                break;
        }

  printf("encryption:\t\t");

  switch(availableNetworkList->Network[i].dot11DefaultCipherAlgorithm)
  {
       case DOT11_CIPHER_ALGO_NONE:
     printf("NONE\n");
     break;

    case DOT11_CIPHER_ALGO_WEP40:
     printf("WEP40\n");
    break;

    case DOT11_CIPHER_ALGO_TKIP:
     printf("TKIP\n");
    break;

    case DOT11_CIPHER_ALGO_WEP104:
     printf("WEP104\n");
    break;

    case DOT11_CIPHER_ALGO_CCMP:
     printf("CCMP\n");
    break;

                default:
                    printf("UNKNOWN\n");
                break;
  }/*switch*/

  
  flag = availableNetworkList->Network[i].dwFlags;

  if(flag & WLAN_AVAILABLE_NETWORK_CONNECTED)
   printf("\t NOTE : Current connecting\n");

  if(flag & WLAN_AVAILABLE_NETWORK_HAS_PROFILE)
   printf("\t NOTE : WLAN_AVAILABLE_NETWORK_HAS_PROFILE\n");

  if(flag & WLAN_AVAILABLE_NETWORK_CONSOLE_USER_PROFILE)
   printf("\t NOTE : WLAN_AVAILABLE_NETWORK_CONSOLE_USER_PROFILE\n");
        printf("\n");
 }/*for */

 

 /*part two: save target SSID propertis*/  
 for(i = 0; i < availableNetworkList->dwNumberOfItems; i++)
 {

  if(0 == strncmp(pSSIDName, (char*)availableNetworkList->Network[i].dot11Ssid.ucSSID , SSID_MAX_LEN))
  {

   if( WLAN_AVAILABLE_NETWORK_CONNECTED & availableNetworkList->Network[i].dwFlags)
   {    
    printf("%s is current connecting!!\n", pSSIDName);
    result = 1;
    goto Exit_ConnectToTargetSSID;
   }/*if*/

   iii = i;


   if(WLAN_AVAILABLE_NETWORK_HAS_PROFILE  & availableNetworkList->Network[i].dwFlags)
    isHavingProfile = TRUE;

   /*list the target SSID properties*/

   switch(availableNetworkList->Network[i].dot11DefaultAuthAlgorithm)
   {
   case DOT11_AUTH_ALGO_80211_OPEN:
    sprintf(&authentication[0], "OPEN");
    break;
   case DOT11_AUTH_ALGO_80211_SHARED_KEY:
      sprintf(&authentication[0], "WEP");
   break;
                 
   case DOT11_AUTH_ALGO_WPA:
   case DOT11_AUTH_ALGO_WPA_PSK:
   case DOT11_AUTH_ALGO_WPA_NONE:
    sprintf(&authentication[0], "WPAPSK");
   break;

   case DOT11_AUTH_ALGO_RSNA:
   case DOT11_AUTH_ALGO_RSNA_PSK:
    sprintf(&authentication[0], "WPA2PSK");
   break;

   default:
    sprintf(&authentication[0], "UNKNOWN");
   break;
   }/*switch dot11DefaultAuthAlgorithm*/

   switch(availableNetworkList->Network[i].dot11DefaultCipherAlgorithm)
   {
    case DOT11_CIPHER_ALGO_NONE:
     sprintf(&encryption[0], "NOEN");
    break;

    case DOT11_CIPHER_ALGO_TKIP:
     sprintf(&encryption[0], "TKIP");
    break;

    case DOT11_CIPHER_ALGO_CCMP:
     sprintf(&encryption[0], "AES");
    break;


                default:
                    sprintf(&encryption[0], "WEP");
                break;
   }/*/*switch dot11DefaultCipherAlgorithm*/
   
   break; 
  }/*if 0 == strncmp(pSSIDName, (char*)availableNetworkList->Network[i].dot11Ssid.ucSSID , SSID_MAX_LEN)*/

 }/*for i*/


 if(-1 == iii)
 {
  /*target router could not found */
  result = -5;
  goto Exit_ConnectToTargetSSID;
 }/*if */
  
 
 /*part there, set XML profile*/
 if(FALSE == isHavingProfile)
 {
  /*if current computer has never connected to target router..*/

  wchar_t profileXMLUnicode[4096];
  char buff[4096];
  
  DWORD reasonCode;

  char profileTemplateXML[] = "<?xml version=\"1.0\"?>" \
 "<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">"\
 " <name>%s</name>" \
 "       <SSIDConfig> " \
 "                <SSID>" \
 "                        <name>%s</name>"\
 "                </SSID>"\
 "        </SSIDConfig>"\
 "        <connectionType>ESS</connectionType>"\
 "        <connectionMode>auto</connectionMode>"\
 "        <MSM>"\
 "                <security>"\
 "                        <authEncryption>"\
 "                                <authentication>%s</authentication>"\
 "                                <encryption>%s</encryption>"\
 "                                <useOneX>false</useOneX>"\
 "                        </authEncryption>"\
 "                        <sharedKey>"\
 "                                <keyType>passPhrase</keyType>"\
 "                                <protected>false</protected>"\
 "                                <keyMaterial>%s</keyMaterial>"\
 "                        </sharedKey>"\
 "                </security>" \
 "        </MSM>" \
 "</WLANProfile>" ;


  reasonCode = 0;
    
  sprintf(buff, profileTemplateXML, availableNetworkList->Network[iii].dot11Ssid.ucSSID, 
   availableNetworkList->Network[iii].dot11Ssid.ucSSID, 
   &authentication[0], &encryption[0], pPassword);

  /*Covert ansi to unicode*/ 
  MultiByteToWideChar(CP_ACP, 0, &buff[0], -1, &profileXMLUnicode[0], 4096);

  result = WlanSetProfile(iWifiHandle, &iInterfaceGuid, 0,  &profileXMLUnicode[0], 
   NULL, TRUE, NULL, &reasonCode);

  wprintf( L"%s", profileXMLUnicode); 

  if(ERROR_SUCCESS != result)
  {
   result = -6;
   goto Exit_ConnectToTargetSSID;
  }/*if */
 }
 else
 {
  /*if current computer had connected to target router, and remember who it is ...*/
  DWORD dwFlags;
  DWORD dwGrantedAccess;
  LPWSTR xml;
  result = WlanGetProfile(iWifiHandle, &iInterfaceGuid, 
   availableNetworkList->Network[iii].strProfileName, NULL, &xml ,&dwFlags,&dwGrantedAccess);
  wprintf( L"%s", xml);  
 }/*if FASLSE == isHavingProfile*/

 
 /*part four, connect to target ssid */

 connParam.pDot11Ssid= NULL;
 connParam.strProfile= availableNetworkList->Network[iii].strProfileName;

 connParam.wlanConnectionMode = wlan_connection_mode_profile;
 connParam.pDesiredBssidList=NULL;

 connParam.dot11BssType= availableNetworkList->Network[iii].dot11BssType;
 connParam.dwFlags = 0;

 //wprintf( L"%s", &iInterfaceGuid,wifiList->Network[iii].strProfileName);
 result = WlanConnect(iWifiHandle, &iInterfaceGuid, &connParam, NULL); 
 
 if(ERROR_SUCCESS != result)
  result = -7;
  
 

Exit_ConnectToTargetSSID:

 if(NULL != availableNetworkList)
  WlanFreeMemory(availableNetworkList);

 if(NULL != iAvailableInterfaces)
  WlanFreeMemory(iAvailableInterfaces);

 if(NULL != iWifiHandle)
  WlanCloseHandle(iWifiHandle, NULL);

 return result;
}/*ConnectToTargetWifiSSID*/


int main(int argc, char *argv[])
{
 ConnectToTargetWifiSSID("GAIGER TOTO", "qwertyui");
 return 0;
}/*main*/


           you should modify the function agruments pSSIDName(I used "GAIGER TOTO") and pPassword (I used "qwertyui") as your ssid/password. To test the code, you had better let your computer forget the information of target ssid, and disconnnect your wireless network. Otherwise,  the code would display "be current conncting" or the variable "isHavingProfile" be TRUE always.

In "manage wireless networks" of windows, you could set/delete it.



沒有留言:

張貼留言