应用程序和驱动程序的通信过程是:应用程序使用CreateFile函数打开设备,然后用DeviceIoControl与驱动程序进行通信,包括读和写两种操作。还可以用ReadFile读数据用WriteFile写数据。操作完毕时用CloseHandle关闭设备。我们比较常用的就是用DeviceIoControl对设备进行读写操作。先看看DeviceIoControl是怎么定义的:
BOOL DeviceIoControl( HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);Parameters(参数)-
hDevice (CreateFile返回的设备句柄)
- [in] Handle to the device that is to perform the operation. To obtain a device handle, call the CreateFile function. dwIoControlCode (应用程序调用驱动程序的控制命令,就是IOCTL_XXX IOCTLs )
- [in] IOCTL for the operation. This value identifies the specific operation to perform and the type of device on which to perform the operation. There are no specific values defined for the dwIoControlCode parameter. However, you can define custom IOCTL_XXX IOCTLs with the CTL_CODE macro. You can then advertise these IOCTLs and an application can use these IOCTLs with DeviceIoControl to perform the driver-specific functions. lpInBuffer (应用程序传递给驱动程序的数据缓冲区地址)
- [in] Long pointer to a buffer that contains the data required to perform the operation. Set to NULL if the dwIoControlCode parameter specifies an operation that does not require input data. nInBufferSize (应用程序传递给驱动程序的数据缓冲区大小,字节数)
- [in] Size, in bytes, of the buffer pointed to by lpInBuffer. lpOutBuffer (驱动程序返回给应用程序的数据缓冲区地址)
- [out] Long pointer to a buffer that receives the output data for the operation. Set to NULL if the dwIoControlCode parameter specifies an operation that does not produce output data. nOutBufferSize (驱动程序返回给应用程序的数据缓冲区大小,字节数)
- [out] Size, in bytes, of the buffer pointed to by lpOutBuffer. lpBytesReturned (驱动程序实际返回给应用程序的数据字节数地址)
- [out] Long pointer to a variable that receives the size, in bytes, of the data stored in lpOutBuffer. The DeviceIoControl function may unnecessarily use this parameter. For example, if an operation does not produce data for lpOutBuffer and lpOutBuffer is NULL, the value of lpBytesReturned is meaningless. lpOverlapped (重叠操作结构)
- [in] Ignored; set to NULL.
Nonzero indicates success. Zero indicates failure. To obtain extended error information, call the GetLastError function. (非0成功,0失败)
具体使用我们看看列子:
1,向设备传递数据,我们定义一个函数来实现
bool CDeviceOperDlg::SendKeyData(HANDLE handle, BYTE *bData, int iSize)
{
ULONG nOutput;
BYTE bTemp[512];
//将数据放置到发送数组
memset(bTemp,0,sizeof(bTemp));
memcpy(bTemp,&bData[0],iSize);
//向设备发送
if (!DeviceIoControl(handle,
ATST2004_IOCTL_WRITE, //根据具体的设备有相关的定义
bTemp, //向设备传递的数据地址
iSize, //数据大小,字节数
NULL, //没有返回的数据,置为NULL
0, //没有返回的数据,置为0
&nOutput,
NULL)
)
{
return false;
}
return true;
}
2,从设备读取数据
bool CDeviceOperDlg::ReviceKeyData(HANDLE handle, BYTE *bData, int iSize)
{
ULONG nOutput;
BYTE bTemp[512];
//数组清零
memset(bTemp,0,sizeof(bTemp));
//向设备发送
if (!DeviceIoControl(handle,
ATST2004_IOCTL_READ, //根据具体的设备有相关的定义
NULL, //没有向设备传递的数据,置为NULL
0, //没有向设备传递的数据,置为NULL
bTemp, //读取设备的数据返回地址
iSize, //读取数据的字节数
&nOutput,
NULL)
)
{
return false;
}
//放置到公用数组
memcpy(&bData[0],&bTemp[0],iSize);
return true;
}
下面是对无线网卡操作的demo:
/**
* Program that demonstrates some of the functionality in Windows to
* manipulate the WLAN environment.
*
* @author: Asanga Udugama (adu@comnets.uni-bremen.de)
*
*/
#include "stdafx.h"
#include <windows.h>
#include <conio.h>
#include <atlbase.h>
#include <iostream>
#include <wlanapi.h>
DWORD dClientVersion, dNegotiatedVersion;
HANDLE hClientHandle;
PWLAN_INTERFACE_INFO_LIST pInterfaceList;
DWORD dSelectedInterfaceIndex;
PWLAN_CONNECTION_ATTRIBUTES pCurrentConnInfo;
DWORD dwSize;
INT iReqestedOp, iContinue;
/**
* Select a network interface function that uses WLAN API
* to get the wireless interface list.
*/
DWORD SelectNetworkInterface()
{
DWORD rtn;
dClientVersion = 1;
dNegotiatedVersion = 0;
rtn = WlanOpenHandle(dClientVersion, NULL, &dNegotiatedVersion, &hClientHandle);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanOpenHandle: %d\n", rtn);
return rtn;
}
pInterfaceList = NULL;
rtn = WlanEnumInterfaces(hClientHandle, NULL, &pInterfaceList);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanEnumInterfaces: %d\n", rtn);
return rtn;
}
_tprintf("List of WLAN Interfaces\n");
for(pInterfaceList->dwIndex = 0; pInterfaceList->dwIndex < pInterfaceList->dwNumberOfItems; pInterfaceList->dwIndex++)
{
CW2T szIfcName(pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].strInterfaceDescription);
_tprintf("%2d - %s\n", (pInterfaceList->dwIndex + 1), szIfcName);
}
dSelectedInterfaceIndex = 11000;
while(dSelectedInterfaceIndex < 1 || dSelectedInterfaceIndex > pInterfaceList->dwNumberOfItems)
{
fflush(stdin);
dSelectedInterfaceIndex = 11000;
_tprintf("\n");
_tprintf("Select the interface by typing the number and pressing enter - ");
_tscanf_s("%d", &dSelectedInterfaceIndex);
}
pInterfaceList->dwIndex = dSelectedInterfaceIndex - 1;
return rtn;
}
/**
* Shows a list of wireless interfaces using WLAN API.
*
*/
DWORD ListWLANInterfaceswithWLANAPI()
{
DWORD rtn;
dClientVersion = 1;
dNegotiatedVersion = 0;
rtn = WlanOpenHandle(dClientVersion, NULL, &dNegotiatedVersion, &hClientHandle);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanOpenHandle: %d\n", rtn);
return rtn;
}
pInterfaceList = NULL;
rtn = WlanEnumInterfaces(hClientHandle, NULL, &pInterfaceList);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanEnumInterfaces: %d\n", rtn);
return rtn;
}
for(pInterfaceList->dwIndex = 0; pInterfaceList->dwIndex < pInterfaceList->dwNumberOfItems; pInterfaceList->dwIndex++)
{
CW2T szIfcName(pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].strInterfaceDescription);
_tprintf("%2d - %s\n", (pInterfaceList->dwIndex + 1), szIfcName);
}
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Shows the list of network interfaces using the registry.
*
*/
DWORD ListWLANInterfacesusingRegistry()
{
LONG rtn, rtn2;
HKEY hNICListKey, hNICKey;
INT i;
TCHAR szKeyName[256];
DWORD dwSize, dwSize2;
FILETIME ftFileTime;
TCHAR szFullKeyName[256];
TCHAR szDevInfo[256];
TCHAR szDevDesc[256];
DWORD dwType;
rtn = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards",
0, KEY_READ, &hNICListKey);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in RegOpenKeyEx: %d\n", rtn);
return rtn;
}
dwSize = 256;
i = 0;
rtn = RegEnumKeyEx(hNICListKey, i, szKeyName,
&dwSize, NULL, NULL, NULL,
&ftFileTime);
while(rtn == ERROR_SUCCESS)
{
_stprintf_s(szFullKeyName, 256,
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards\\%s",
szKeyName);
rtn2 = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szFullKeyName,
0, KEY_READ, &hNICKey);
if(rtn2 != ERROR_SUCCESS)
{
i++;
continue;
}
dwType = REG_SZ;
dwSize2 = 256;
memset(szDevInfo, 0, 256);
rtn2 = RegQueryValueEx(hNICKey, "ServiceName", NULL,
&dwType, (BYTE *) szDevInfo, &dwSize2);
if(rtn2 != ERROR_SUCCESS)
{
i++;
continue;
}
dwType = REG_SZ;
dwSize2 = 256;
memset(szDevDesc, 0, 256);
rtn = RegQueryValueEx(hNICKey, "Description", NULL,
&dwType, (BYTE *) szDevDesc, &dwSize2);
if(rtn2 != ERROR_SUCCESS)
{
i++;
continue;
}
RegCloseKey(hNICKey);
_tprintf("%2d - %s\n", (i + 1), szDevDesc);
i++;
dwSize = 256;
rtn = RegEnumKeyEx(hNICListKey, i, szKeyName,
&dwSize, NULL, NULL, NULL,
&ftFileTime);
}
RegCloseKey(hNICListKey);
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn2;
}
/**
* Show the connected AP info using the WLAN API.
*/
DWORD ShowConnectedAPwithWLANAPI()
{
DWORD rtn;
TCHAR szCurrentESSID[256];
TCHAR szCurrentMACAddressStr[256];
INT iCurrentRSSI;
INT iCurrentLinkQuality;
dClientVersion = 1;
dNegotiatedVersion = 0;
rtn = WlanOpenHandle(dClientVersion, NULL, &dNegotiatedVersion, &hClientHandle);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanOpenHandle: %d\n", rtn);
return rtn;
}
// get connected AP info from WLAN API
dwSize = 0;
pCurrentConnInfo = NULL;
rtn = WlanQueryInterface(hClientHandle,
&pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].InterfaceGuid,
wlan_intf_opcode_current_connection,
NULL,
&dwSize,
(PVOID *) &pCurrentConnInfo,
NULL);
if(rtn == ERROR_INVALID_STATE)
{
// that means not connected to any AP
rtn = ERROR_SUCCESS;
if(pCurrentConnInfo != NULL)
{
WlanFreeMemory((PVOID) pCurrentConnInfo);
}
// close handle
WlanCloseHandle(hClientHandle, NULL);
_tprintf("Not connected to any AP\n");
return rtn;
}
else if(rtn != ERROR_SUCCESS)
{
if(pCurrentConnInfo != NULL)
{
WlanFreeMemory((PVOID) pCurrentConnInfo);
}
// close handle
WlanCloseHandle(hClientHandle, NULL);
_tprintf("Error occured in WlanQueryInterface: %d\n", rtn);
return rtn;
}
CW2T szESSID(pCurrentConnInfo->strProfileName);
memset(szCurrentESSID, 0, 256);
memcpy(szCurrentESSID, szESSID, 256);
memset(szCurrentMACAddressStr, 0, 256);
_stprintf_s(szCurrentMACAddressStr, 256, "%02x:%02x:%02x:%02x:%02x:%02x",
pCurrentConnInfo->wlanAssociationAttributes.dot11Bssid[0],
pCurrentConnInfo->wlanAssociationAttributes.dot11Bssid[1],
pCurrentConnInfo->wlanAssociationAttributes.dot11Bssid[2],
pCurrentConnInfo->wlanAssociationAttributes.dot11Bssid[3],
pCurrentConnInfo->wlanAssociationAttributes.dot11Bssid[4],
pCurrentConnInfo->wlanAssociationAttributes.dot11Bssid[5]);
iCurrentRSSI = (pCurrentConnInfo->wlanAssociationAttributes.wlanSignalQuality / 2) - 100;
iCurrentLinkQuality = pCurrentConnInfo->wlanAssociationAttributes.wlanSignalQuality;
rtn = ERROR_SUCCESS;
if(pCurrentConnInfo != NULL)
{
WlanFreeMemory((PVOID) pCurrentConnInfo);
}
// close handle
WlanCloseHandle(hClientHandle, NULL);
_tprintf("Network Name (Profile Name): %s\n", szCurrentESSID);
_tprintf("AP MAC Address : %s\n", szCurrentMACAddressStr);
_tprintf("RSSI : %d\n", iCurrentRSSI);
_tprintf("Link Quality : %d\n", iCurrentLinkQuality);
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Show the connected AP info using the NDIS 802.11 IOCTLs.
*/
INT ShowConnectedAPwithNDIS()
{
INT rtn;
TCHAR szCurrentESSID[256];
TCHAR szCurrentMACAddressStr[256];
INT iCurrentRSSI;
INT iCurrentLinkQuality;
NDIS_802_11_RSSI ndisRSSI;
NDIS_802_11_SSID ndisESSID;
NDIS_802_11_MAC_ADDRESS ndisMACAddress;
WCHAR wsNICGUIDinString[256];
char sNICIDFullPath[256];
DWORD dwMemSize;
ULONG ulBytesReturned;
ULONG ulOIDCode;
// open handle
memset(wsNICGUIDinString, 0, 256);
memset(sNICIDFullPath, 0, 256);
StringFromGUID2(pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].InterfaceGuid,
wsNICGUIDinString, 256);
sprintf_s(sNICIDFullPath, "\\\\.\\%S", wsNICGUIDinString);
hClientHandle = CreateFileA(sNICIDFullPath, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL) ;
if(hClientHandle == INVALID_HANDLE_VALUE)
{
_tprintf("Error in CreateFileA\n");
return 0;
}
// call to get connected ESSID
dwMemSize = sizeof(NDIS_802_11_SSID);
ulOIDCode = OID_802_11_SSID;
ulBytesReturned = 0;
rtn = DeviceIoControl(hClientHandle, IOCTL_NDIS_QUERY_GLOBAL_STATS,
&ulOIDCode, sizeof(ulOIDCode), (ULONG *) &ndisESSID,
dwMemSize, &ulBytesReturned, NULL);
if(rtn == 0)
{
_tprintf("Error in DeviceIoControl\n");
CloseHandle(hClientHandle);
return rtn;
}
memset(szCurrentESSID, 0, 256);
memcpy(szCurrentESSID, ndisESSID.Ssid, ndisESSID.SsidLength);
// call to get connected MAC Address
dwMemSize = sizeof(NDIS_802_11_MAC_ADDRESS);
ulOIDCode = OID_802_11_BSSID;
ulBytesReturned = 0;
rtn = DeviceIoControl(hClientHandle, IOCTL_NDIS_QUERY_GLOBAL_STATS,
&ulOIDCode, sizeof(ulOIDCode), (ULONG *) &ndisMACAddress,
dwMemSize, &ulBytesReturned, NULL);
if(rtn == 0)
{
_tprintf("Error in DeviceIoControl\n");
CloseHandle(hClientHandle);
return rtn;
}
memset(szCurrentMACAddressStr, 0, 256);
_stprintf_s(szCurrentMACAddressStr, 256, "%02x:%02x:%02x:%02x:%02x:%02x",
ndisMACAddress[0],
ndisMACAddress[1],
ndisMACAddress[2],
ndisMACAddress[3],
ndisMACAddress[4],
ndisMACAddress[5]);
// call to get RSSI
ndisRSSI = 0;
dwMemSize = sizeof(NDIS_802_11_RSSI);
ulOIDCode = OID_802_11_RSSI;
ulBytesReturned = 0;
rtn = DeviceIoControl(hClientHandle, IOCTL_NDIS_QUERY_GLOBAL_STATS,
&ulOIDCode, sizeof(ulOIDCode), (ULONG *) &ndisRSSI,
dwMemSize, &ulBytesReturned, NULL);
if(rtn == 0)
{
_tprintf("Error in DeviceIoControl\n");
CloseHandle(hClientHandle);
return rtn;
}
// close handle
CloseHandle(hClientHandle);
iCurrentRSSI = ndisRSSI;
// MS computes link quality as follows;
// range 1 to 100, maps rssi from -100 to -50, linear interpolation
iCurrentLinkQuality = (ndisRSSI + 100) * 2;
if(iCurrentLinkQuality < 0)
{
iCurrentLinkQuality = 0;
}
else if(iCurrentLinkQuality > 100)
{
iCurrentLinkQuality = 100;
}
_tprintf("Network Name (Profile Name): %s\n", szCurrentESSID);
_tprintf("AP MAC Address : %s\n", szCurrentMACAddressStr);
_tprintf("RSSI : %d\n", iCurrentRSSI);
_tprintf("Link Quality : %d\n", iCurrentLinkQuality);
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Issue a scan to find the visible APs using the WLAN API.
*/
DWORD ScanwithWLANAPI()
{
DWORD rtn;
// open handle for scanning
dClientVersion = 1;
dNegotiatedVersion = 0;
rtn = WlanOpenHandle(dClientVersion, NULL, &dNegotiatedVersion, &hClientHandle);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanOpenHandle: %d\n", rtn);
return rtn;
}
// send scan commmand
rtn = WlanScan(hClientHandle,
&pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].InterfaceGuid,
NULL, NULL, NULL);
// close handle
WlanCloseHandle(hClientHandle, NULL);
_tprintf("Scan issued...\n");
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Issue a scan to find the visible APs using the NDIS 802.11 IOCTL.
*
* Note: This function doesn't seem to be working. I will have to figure
* this out, later.
*/
DWORD ScanwithNDIS()
{
INT rtn;
WCHAR wsNICGUIDinString[256];
char sNICIDFullPath[256];
DWORD dwMemSize;
ULONG ulBytesReturned;
ULONG ulOIDCode;
// open handle
memset(wsNICGUIDinString, 0, 256);
memset(sNICIDFullPath, 0, 256);
StringFromGUID2(pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].InterfaceGuid,
wsNICGUIDinString, 256);
sprintf_s(sNICIDFullPath, "\\\\.\\%S", wsNICGUIDinString);
//hClientHandle = CreateFileA(sNICIDFullPath, GENERIC_READ | GENERIC_WRITE,
// FILE_SHARE_READ | FILE_SHARE_WRITE,
// NULL, OPEN_EXISTING,
// 0, NULL) ;
hClientHandle = CreateFileA(sNICIDFullPath, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL) ;
if(hClientHandle == INVALID_HANDLE_VALUE)
{
_tprintf("Error in CreateFileA\n");
return 0;
}
// call to get connected ESSID
dwMemSize = 0;
ulOIDCode = OID_802_11_BSSID_LIST_SCAN;
ulOIDCode |= 0x00800000;
ulBytesReturned = 0;
rtn = DeviceIoControl(hClientHandle, IOCTL_NDIS_QUERY_GLOBAL_STATS,
&ulOIDCode, sizeof(ulOIDCode), (ULONG *) NULL,
dwMemSize, &ulBytesReturned, NULL);
if(rtn == 0)
{
DWORD errnum = GetLastError();
_tprintf("Error in DeviceIoControl\n");
CloseHandle(hClientHandle);
return rtn;
}
// close handle
CloseHandle(hClientHandle);
_tprintf("Scan issued...\n");
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Show the list of WLAN networks currently visible. This uses the WLAN API
* and it only shows information by SSIDs and not by BSSIDs.
*
* Only a few pieces of information are printed. The structure
* WLAN_AVAILABLE_NETWORK has more information.
*/
DWORD ShowNetworkListwithWLANAPI()
{
DWORD rtn;
PWLAN_AVAILABLE_NETWORK_LIST pNwList;
PWLAN_AVAILABLE_NETWORK pAvailableNw;
TCHAR szESSIDStr1[256];
UINT i, j;
// open handle for scanning
dClientVersion = 1;
dNegotiatedVersion = 0;
rtn = WlanOpenHandle(dClientVersion, NULL, &dNegotiatedVersion, &hClientHandle);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanOpenHandle: %d\n", rtn);
return rtn;
}
pNwList = NULL;
rtn = WlanGetAvailableNetworkList(hClientHandle,
&pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].InterfaceGuid,
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES,
NULL,
&pNwList);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanGetAvailableNetworkList: %d\n", rtn);
WlanCloseHandle(hClientHandle, NULL);
if(pNwList != NULL)
{
WlanFreeMemory((PVOID) pNwList);
}
return ERROR_SUCCESS;
}
_tprintf("\n");
_tprintf(" SSID (Network) Mode BSSIDs SigQual SecStat AuthAlgo CiphAlgo \n");
// loop and show networks
for(i = 0; i < pNwList->dwNumberOfItems; i++)
{
// find the location of next element
j = 0;
pAvailableNw = pNwList->Network;
while(j < i)
{
pAvailableNw = (PWLAN_AVAILABLE_NETWORK) (((unsigned char *) pAvailableNw)
+ sizeof(WLAN_AVAILABLE_NETWORK));
j++;
}
memset(szESSIDStr1, 0, 256);
memcpy(szESSIDStr1, pAvailableNw->dot11Ssid.ucSSID, pAvailableNw->dot11Ssid.uSSIDLength);
_tprintf("%24s ", szESSIDStr1);
if(pAvailableNw->dot11BssType == dot11_BSS_type_infrastructure)
_tprintf("Infra ");
else if(pAvailableNw->dot11BssType == dot11_BSS_type_independent)
_tprintf("Ad-hoc ");
else if(pAvailableNw->dot11BssType == dot11_BSS_type_any)
_tprintf("Any ");
else
_tprintf(" ");
_tprintf("%6d ", pAvailableNw->uNumberOfBssids);
_tprintf("%7d ", pAvailableNw->wlanSignalQuality);
if(pAvailableNw->bSecurityEnabled)
_tprintf("yes ");
else
_tprintf("no ");
_tprintf("%8d ", pAvailableNw->dot11DefaultAuthAlgorithm);
_tprintf("%8d ", pAvailableNw->dot11DefaultCipherAlgorithm);
_tprintf("\n");
}
if(pNwList != NULL)
{
WlanFreeMemory((PVOID) pNwList);
}
// close handle
WlanCloseHandle(hClientHandle, NULL);
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Shows the list of WLAN APs currently visible. This uses the NDIS
* 802.11 IOCT to retrive this information. Itshows information by
* BSSIDs.
*
* Only a few pieces of information are printed. The structure
* NDIS_WLAN_BSSID has more information.
*/
DWORD ShowNetworkListwithNDIS()
{
INT rtn;
WCHAR wsNICGUIDinString[256];
char sNICIDFullPath[256];
DWORD dwMemSize;
ULONG ulBytesReturned;
ULONG ulOIDCode;
PNDIS_802_11_BSSID_LIST pNDIS80211BSSIDList;
PNDIS_WLAN_BSSID pNDIS80211BSSIDInfo;
TCHAR szESSIDStr1[256];
TCHAR szMACAddressStr[256];
UINT i, j;
// open handle
memset(wsNICGUIDinString, 0, 256);
memset(sNICIDFullPath, 0, 256);
StringFromGUID2(pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].InterfaceGuid,
wsNICGUIDinString, 256);
sprintf_s(sNICIDFullPath, "\\\\.\\%S", wsNICGUIDinString);
hClientHandle = CreateFileA(sNICIDFullPath, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING,
0, NULL) ;
if(hClientHandle == INVALID_HANDLE_VALUE)
{
_tprintf("Error in CreateFileA\n");
return 0;
}
// allocate temporary memory to check the number of
// AP entries
dwMemSize = sizeof(NDIS_802_11_BSSID_LIST) + (sizeof(NDIS_WLAN_BSSID) * 24);
pNDIS80211BSSIDList = (NDIS_802_11_BSSID_LIST *) VirtualAlloc(NULL,
dwMemSize, MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
memset(pNDIS80211BSSIDList, 0, dwMemSize);
// set OID
ulOIDCode = OID_802_11_BSSID_LIST;
ulBytesReturned = 0;
// call get AP list
rtn = DeviceIoControl(hClientHandle, IOCTL_NDIS_QUERY_GLOBAL_STATS,
&ulOIDCode, sizeof(ulOIDCode), (ULONG *) pNDIS80211BSSIDList,
dwMemSize, &ulBytesReturned, NULL);
if(!(rtn != 0 || (rtn == 0 && GetLastError() == ERROR_MORE_DATA)))
{
_tprintf("Error occured in DeviceIoControl OID_802_11_BSSID_LIST: %d\n", rtn);
// free memory allocation
VirtualFree(pNDIS80211BSSIDList, dwMemSize, MEM_RELEASE | MEM_DECOMMIT);
CloseHandle(hClientHandle);
return 0;
}
_tprintf("\n");
_tprintf(" SSID (Network) MAC Address RSSI \n");
// loop and print
for(i = 0; i < pNDIS80211BSSIDList->NumberOfItems; i++)
{
// find the location of next element
j = 0;
pNDIS80211BSSIDInfo = pNDIS80211BSSIDList->Bssid;
while(j < i)
{
pNDIS80211BSSIDInfo = (PNDIS_WLAN_BSSID) (((unsigned char *) pNDIS80211BSSIDInfo)
+ pNDIS80211BSSIDInfo->Length);
j++;
}
memset(szESSIDStr1, 0, 256);
memcpy(szESSIDStr1, pNDIS80211BSSIDInfo->Ssid.Ssid, pNDIS80211BSSIDInfo->Ssid.SsidLength);
_tprintf("%24s ", szESSIDStr1);
memset(szMACAddressStr, 0, 256);
_stprintf_s(szMACAddressStr, 256, "%02x:%02x:%02x:%02x:%02x:%02x",
pNDIS80211BSSIDInfo->MacAddress[0],
pNDIS80211BSSIDInfo->MacAddress[1],
pNDIS80211BSSIDInfo->MacAddress[2],
pNDIS80211BSSIDInfo->MacAddress[3],
pNDIS80211BSSIDInfo->MacAddress[4],
pNDIS80211BSSIDInfo->MacAddress[5]);
_tprintf("%s ", szMACAddressStr);
_tprintf("%4d ", pNDIS80211BSSIDInfo->Rssi);
_tprintf("\n");
}
VirtualFree(pNDIS80211BSSIDList, dwMemSize, MEM_RELEASE | MEM_DECOMMIT);
// close handle
CloseHandle(hClientHandle);
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Initiates a connection to a given WLAN network using the
* WLAN API. The user must create a profile before to connect
* to the given network. A profile is what you create using
* the "Wireless Networks" tab in the properties of the
* wireless interface.
*
*/
DWORD ConnectToNetworkwithWLANAPI()
{
DWORD rtn;
TCHAR szEssIDString[256];
WLAN_CONNECTION_PARAMETERS sWLANConnParam;
_tprintf("\n");
_tprintf("Type the network name (SSID) (a profile must exist)... ");
_tscanf_s("%s", szEssIDString, 256);
CT2W lpsXMLProfileName(szEssIDString);
// open handle for scanning
dClientVersion = 1;
dNegotiatedVersion = 0;
rtn = WlanOpenHandle(dClientVersion, NULL, &dNegotiatedVersion, &hClientHandle);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanOpenHandle: %d\n", rtn);
return rtn;
}
// set connection parameters
memset(&sWLANConnParam, 0, sizeof(WLAN_CONNECTION_PARAMETERS));
sWLANConnParam.wlanConnectionMode = wlan_connection_mode_profile;
sWLANConnParam.strProfile = lpsXMLProfileName;
sWLANConnParam.pDot11Ssid = NULL;
sWLANConnParam.pDesiredBssidList = NULL;
sWLANConnParam.dot11BssType = dot11_BSS_type_any;
sWLANConnParam.dwFlags = 0;
// connect to given AP
rtn = WlanConnect(hClientHandle,
&pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].InterfaceGuid,
&sWLANConnParam,
NULL);
// close handle
WlanCloseHandle(hClientHandle, NULL);
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Show the XML profile of a configured connection profile.
*
*/
DWORD ShowProfileInfowithWLANAPI()
{
DWORD rtn;
DWORD dwFlags;
LPWSTR lpsXMLProfile;
TCHAR szEssIDString[256];
_tprintf("\n");
_tprintf("Type the profile name (usually SSID) ... ");
_tscanf_s("%s", szEssIDString, 256);
CT2W lpsXMLProfileName(szEssIDString);
// open handle for scanning
dClientVersion = 1;
dNegotiatedVersion = 0;
rtn = WlanOpenHandle(dClientVersion, NULL, &dNegotiatedVersion, &hClientHandle);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanOpenHandle: %d\n", rtn);
return rtn;
}
dwFlags = 0;
lpsXMLProfile = NULL;
rtn = WlanGetProfile(hClientHandle,
&pInterfaceList->InterfaceInfo[pInterfaceList->dwIndex].InterfaceGuid,
lpsXMLProfileName,
NULL,
&lpsXMLProfile,
&dwFlags,
NULL);
if(rtn != ERROR_SUCCESS)
{
_tprintf("Error occured in WlanGetProfile: %d\n", rtn);
return rtn;
}
CW2T szProfileXML(lpsXMLProfile);
_tprintf("\n\n");
_tprintf("%s", szProfileXML);
_tprintf("\n\n");
_tprintf("Type 99 to continue ... ");
_tscanf_s("%d", &iContinue);
return rtn;
}
/**
* Main function that calls the other functions.
*
*/
int _tmain(int argc, _TCHAR* argv[])
{
DWORD rtn;
do
{
iReqestedOp = 0;
_tprintf("\n");
_tprintf("------------------------------------------------------- \n");
_tprintf("WLAN Operations ver 0.1 \n");
_tprintf("Developed by Asanga Udugama (adu@comnets.uni-bremen.de) \n");
_tprintf("------------------------------------------------------- \n");
_tprintf("\n");
_tprintf("Operations \n");
_tprintf(" 1. List the WLAN interfaces using WLAN API \n");
_tprintf(" 2. List the network interfaces using the Registry \n");
_tprintf(" 3. Show connected WLAN network using WLAN API \n");
_tprintf(" 4. Show connected WLAN network using NDIS \n");
_tprintf(" 5. Issue a Scan using WLAN API \n");
_tprintf(" 6. Issue a Scan using NDIS \n");
_tprintf(" 7. Show visible WLAN networks using WLAN API \n");
_tprintf(" 8. Show visible WLAN networks using NDIS \n");
_tprintf(" 9. Connect to network using WLANAPI \n");
_tprintf("10. Show connection profile information using WLANAPI \n");
_tprintf("\n");
_tprintf("99. Quit \n");
_tprintf("\n");
_tprintf("Type a number to run the operation ... ");
_tscanf_s("%d", &iReqestedOp);
_tprintf("\n\n");
if(iReqestedOp == 1)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("List the WLAN interfaces using WLAN API \n");
_tprintf("------------------------------------------------------- \n");
ListWLANInterfaceswithWLANAPI();
}
else if(iReqestedOp == 2)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("List the network interfaces using the Registry \n");
_tprintf("------------------------------------------------------- \n");
ListWLANInterfacesusingRegistry();
}
else if(iReqestedOp == 3)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("Show connected WLAN network using WLAN API \n");
_tprintf("------------------------------------------------------- \n");
rtn = SelectNetworkInterface();
if(rtn == ERROR_SUCCESS)
{
ShowConnectedAPwithWLANAPI();
}
}
else if(iReqestedOp == 4)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("Show connected WLAN network using NDIS \n");
_tprintf("------------------------------------------------------- \n");
rtn = SelectNetworkInterface();
if(rtn == ERROR_SUCCESS)
{
ShowConnectedAPwithNDIS();
}
}
else if(iReqestedOp == 5)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("Issue a Scan using WLAN API \n");
_tprintf("------------------------------------------------------- \n");
rtn = SelectNetworkInterface();
if(rtn == ERROR_SUCCESS)
{
ScanwithWLANAPI();
}
}
else if(iReqestedOp == 6)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("Issue a Scan using NDIS \n");
_tprintf("------------------------------------------------------- \n");
rtn = SelectNetworkInterface();
if(rtn == ERROR_SUCCESS)
{
ScanwithNDIS();
}
}
else if(iReqestedOp == 7)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("Show visible WLAN networks using WLAN API \n");
_tprintf("------------------------------------------------------- \n");
rtn = SelectNetworkInterface();
if(rtn == ERROR_SUCCESS)
{
ShowNetworkListwithWLANAPI();
}
}
else if(iReqestedOp == 8)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("Show visible WLAN networks using NDIS \n");
_tprintf("------------------------------------------------------- \n");
rtn = SelectNetworkInterface();
if(rtn == ERROR_SUCCESS)
{
ShowNetworkListwithNDIS();
}
}
else if(iReqestedOp == 9)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("Connect to network using WLANAP \n");
_tprintf("------------------------------------------------------- \n");
rtn = SelectNetworkInterface();
if(rtn == ERROR_SUCCESS)
{
ConnectToNetworkwithWLANAPI();
}
}
else if(iReqestedOp == 10)
{
_tprintf("------------------------------------------------------- \n");
_tprintf("Show connection profile information using WLANAPI \n");
_tprintf("------------------------------------------------------- \n");
rtn = SelectNetworkInterface();
if(rtn == ERROR_SUCCESS)
{
ShowProfileInfowithWLANAPI();
}
}
else if(iReqestedOp == 99)
{
}
else
{
_tprintf("You have entered an invalid operation number ... \n\n");
}
_tprintf("\n\n");
} while(iReqestedOp != 99);
return 0;
}