I have this code right here I am using mingw to compile and I am running windows XP. When I run the output executable it gives me error prompt about the application..
Do I set everything correctly ? How do I set the SSID password for it to connect ? Also I want to know if I am using the correct network interface to connect (I have an external wifi adapter)..
I got the code from this link any help is very much appreciated..
//#define _WIN32_DCOM
#define _WIN32_WINNT 0x0600
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <objbase.h>
#include <rpcsal.h>
#include <objbase.h>
#include <wlanapi.h>
int main(){
PDOT11_SSID pSsid;
strcpy(pSsid->ucSSID, "SUPERONLINE-WiFi_24811");
pSsid->uSSIDLength = 25;
HANDLE wlanHandle;
unsigned long nv;
WlanOpenHandle(1, NULL, &nv, &wlanHandle);
DWORD dwResult = 0;
WLAN_CONNECTION_PARAMETERS cp;
memset(&cp, 0, sizeof(WLAN_CONNECTION_PARAMETERS));
cp.wlanConnectionMode = wlan_connection_mode_profile;
cp.strProfile = NULL;
cp.dwFlags = 0;
cp.pDot11Ssid = pSsid;
cp.pDesiredBssidList = 0;
cp.dot11BssType = dot11_BSS_type_any;
PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
PWLAN_INTERFACE_INFO pIfInfo = NULL;
// only use the first wifi interface
dwResult = WlanEnumInterfaces(wlanHandle, NULL, &pIfList);
pIfInfo = (WLAN_INTERFACE_INFO *)&pIfList->InterfaceInfo[1];
if (dwResult == ERROR_SUCCESS)
{
dwResult = WlanConnect(wlanHandle, &(pIfInfo->InterfaceGuid), &cp, NULL);
if (dwResult == ERROR_SUCCESS)
{
printf("Connected..\n");
//connected = true;
}
}
return 0;
}
This is the error I get:
Edit: I have made it this far to the code below.. But still I can not assign the value to PDOT11_SSID
struct.. It seems the struct has UCHAR
array yet I can't assign.. Here is the link
PDOT11_SSID pSsid;
UCHAR arr[22] = { 0 };
//memset(pSsid->ucSSID, '\0', 32); //this causes the same error too
memcpy(
arr,
(unsigned char[]){ 'S','U','P','E','R','O','N','L','I','N','E','-','W','i','F','i','_','2','4','8','1','1' },
sizeof(arr)); //memcpy to arr struct works..
ULONG len = 22;
pSsid->uSSIDLength = len;
memcpy(pSsid->ucSSID, arr, sizeof(arr)); // this line fails still..
Edit: I ran with -Wall -Wextra -pedantic -Werror
Like David mentioned and with the code segment below:
PDOT11_SSID pSsid;
memset(pSsid->ucSSID, '\0', 32); //fails
I got this error
yet if I initialized with
PDOT11_SSID pSsid = { 0 };
or
PDOT11_SSID pSsid = NULL;
It compiled but I got the crash image above I used to get.. Important to note that memset(pSsid->ucSSID, '\0', 32);
causes the crash as well. I can know this by commenting out each line and compiling/running again.
This is a burden since I am yet to figure out how to add SSID password with wlanapi.h
so help for these will be much appreciated for me to move on forward.
Fyi: I use basic gcc to compile gcc.exe wlan.c -lwlanapi
. If there is any working solution code to connect to an ssid with the ssid
and password
using wlanapi, a link to that is also appreciated.
Wlan connect from msdn is this link.. I can't see any security parameters, how do I set the password of the SSID I want to connect to ?
Wlanapi helps us list available interfaces in windows OS. For your purpose of connecting to a network, first we want to get available interfaces with WlanEnumInterfaces()
function into PWLAN_INTERFACE_INFO_LIST
structure.
After a working interface is found, we want to check for the available network list to see if our desired ssid matches with the result:
iAvailableInterfaces = NULL;
availableNetworkList = NULL;
/*part zero : one a wlan handle*/
result = WlanOpenHandle(1,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*/
printf("InterFaceName: %ls",iAvailableInterfaces->InterfaceInfo[0].strInterfaceDescription);
iInterfaceGuid = iAvailableInterfaces->InterfaceInfo[0].InterfaceGuid;
}else//no interface found..
You can also check available networks with WlanGetAvailableNetworkList(iWifiHandle, &iInterfaceGuid...);
, hence that is not a must. You would want to do that in order to loop through some useful information such as encryption method and signal strength, or to see if the corresponding network already has a profile.
What is a network profile?
In windows, to connect to an SSID, there needs to be Profile that is set. It can either be saved from a previous connection, or if you are connecting to a new network, it has to create a profile before connecting. This profile will have information like the ssid of the network, security parameters, encryption details, if you want it to autoconnect on next finding etc.. We want to create an xml buffer for that next, just like the OS does at lower levels, which looks similar to this:
char profileTemplateXML[] = "<?xml version=\"1.0\"?>" \
"<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">"\
" <name>ssidname</name>" \
" <SSIDConfig> " \
" <SSID>" \
" <name>ssidname</name>"\
" </SSID>"\
" </SSIDConfig>"\
" <connectionType>ESS</connectionType>"\
" <connectionMode>auto</connectionMode>"\
" <MSM>"\
" <security>"\
" <authEncryption>"\
" <authentication>WPA2PSK</authentication>"\
" <encryption>AES</encryption>"\
" <useOneX>false</useOneX>"\
" </authEncryption>"\
" <sharedKey>"\
" <keyType>passPhrase</keyType>"\
" <protected>false</protected>"\
" <keyMaterial>pass123</keyMaterial>"\
" </sharedKey>"\
" </security>" \
" </MSM>" \
"</WLANProfile>" ;
I also recommend reading this thread on how to extract saved profiles(in xml format) on Windows.
Network profile needs to be set in wlanapi by converting this xml structure to unicode and calling the set profile function..
WlanSetProfile(iWifiHandle, &iInterfaceGuid, 0,&profileXMLUnicode[0]...);
Next you need to use WlanConnect
function to initialize connection. For that WLAN_CONNECTION_PARAMETERS
structure needs to be set. Here is msdn link for the structure. I recommend you read it to have an idea. Most important thing is setting the profile here, again as I mentioned.
Note that interface guid is taken from the enumeration of interfaces. Handle is just the handle open with wlan's open handle function..
WlanConnect(iWifiHandle, &iInterfaceGuid, &connParam, NULL);
You can check if the connection was successful using the return code.
Here is a full working code for the wlan connection api. Note that this code block works for any windows version.
#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(1,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*/
printf("InterFaceName: %ls",iAvailableInterfaces->InterfaceInfo[0].strInterfaceDescription);
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,
0x00000001, NULL, &availableNetworkList);
//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 & 0x00000001)
printf("\t NOTE : Current connecting\n");
if(flag & 0x00000002)
printf("\t NOTE : WLAN_AVAILABLE_NETWORK_HAS_PROFILE\n");
if(flag & 0x00000004)
printf("\t NOTE : WLAN_AVAILABLE_NETWORK_CONSOLE_USER_PROFILE\n");
/*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))
{
//WLAN_AVAILABLE_NETWORK_CONNECTED
if( 0x00000001 & availableNetworkList->Network[i].dwFlags)
{
printf("%s is current connecting!!\n", pSSIDName);
result = 1;
goto Exit_ConnectToTargetSSID;
}/*if*/
iii = i;
if(0x00000002 & availableNetworkList->Network[i].dwFlags)
//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>%s</keyType>"\
" <protected>false</protected>"\
" <keyMaterial>password123</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 */
WLAN_CONNECTION_PARAMETERS connParam;
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("SUPERONLINE-WiFi_24811", "pass123");
return 0;
}/*main*/