VC++ win7下實現WIFI共享工具 附源代碼(無線承載網絡)

宿舍用手機連wifi老是要用瀏覽器登陸聯通的wlan登錄頁面,無奈手機太挫內存只有512M,開個網頁再幹其餘的事情就卡的要死,因此果斷下載了個wifi共享精靈。用了一次就果斷卸載了,爲啥呢?居然有廣告,受不了啊。正好在學VC++ 算了本身作一個吧。  api

關於無線承載網絡

無線承載網絡(Wireless Hosted Network)是指安裝有無線局域網服務的Windows 7和Windows Server 2008 R2所提供的一種WLAN功能,具有兩項主要功能:

第1、把一個物理無線網卡虛擬化成一個或多個虛擬無線網卡,稱爲虛擬的WiFi。

第2、藉助無線網卡把當前接網絡虛擬成爲一個基於軟件的無線接入點,稱爲虛擬AP或軟AP。數組

=========================萬惡的分割線===========================瀏覽器

項目須要包含wlanapi.h 頭文件和wlanapi.lib 庫安全

備註:測試環境win7_64,建議關閉一些安全軟件,(好比我測試的時候忘了關comodo致使防火牆老是拒絕其餘設備的鏈接)。網絡

=============================================================less

功能不復雜,用到的主要函數有下面幾個函數

1.調用WlanOpenHandled獲得一個鏈接hClientHandle,下面的操做都要用到這個鏈接。固然程序退出的時候記得調用WlanCloseHandle關閉這個鏈接。學習

DWORD WINAPI WlanOpenHandle(
  _In_        DWORD dwClientVersion,
  _Reserved_  PVOID pReserved,
  _Out_       PDWORD pdwNegotiatedVersion,
  _Out_       PHANDLE phClientHandle
);

DWORD WINAPI WlanCloseHandle(
  _In_        HANDLE hClientHandle,
  _Reserved_  PVOID pReserved
);



2.下面的函數用來設置承載網絡的一些屬性。測試

DWORD WINAPI WlanHostedNetworkSetProperty(
  _In_        HANDLE hClientHandle,
  _In_        WLAN_HOSTED_NETWORK_OPCODE OpCode,
  _In_        DWORD dwDataSize,
  _In_        PVOID pvData,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);typedef enum _WLAN_HOSTED_NETWORK_OPCODE { 
  wlan_hosted_network_opcode_connection_settings,          //設置一些鏈接屬性
  wlan_hosted_network_opcode_security_settings,            //設置安全屬性
  wlan_hosted_network_opcode_station_profile,              //query the wireless Hosted Network station profile
  wlan_hosted_network_opcode_enable                        //query or set the wireless Hosted Network enabled flag
} WLAN_HOSTED_NETWORK_OPCODE, *PWLAN_HOSTED_NETWORK_OPCODE;

3.啓用和禁用無線承載網絡。spa

打開網絡和共享中心 單擊更改適配器設置,若是啓用了無線承載網絡 面板裏面就會有描述爲Microsoft Virtual WiFi Miniport Adapter的一個虛擬網卡。禁用以後這個虛擬網卡就會消失了。

固然只有啓用了無線承載網絡才能分享wifi啦

DWORD WINAPI WlanHostedNetworkForceStart(
  _In_        HANDLE hClientHandle,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);

DWORD WINAPI WlanHostedNetworkForceStop(
  _In_        HANDLE hClientHandle,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);


4.鏈接和斷開網絡

DWORD WINAPI WlanHostedNetworkStartUsing(
  _In_        HANDLE hClientHandle,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);

DWORD WINAPI WlanHostedNetworkStopUsing(
  _In_        HANDLE hClientHandle,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);

5.用來查詢承載網絡的網絡情況。

DWORD WINAPI WlanHostedNetworkQueryStatus(
  _In_        HANDLE hClientHandle,
  _Out_       PWLAN_HOSTED_NETWORK_STATUS *ppWlanHostedNetworkStatus,
  _Reserved_  PVOID pvReserved
);

typedef struct _WLAN_HOSTED_NETWORK_STATUS {
  WLAN_HOSTED_NETWORK_STATE      HostedNetworkState;
  GUID                           IPDeviceID;
  DOT11_MAC_ADDRESS              wlanHostedNetworkBSSID;
  DOT11_PHY_TYPE                 dot11PhyType;
  ULONG                          ulChannelFrequency;
  DWORD                          dwNumberOfPeers;            //已鏈接的節點數目
  WLAN_HOSTED_NETWORK_PEER_STATE PeerList[1];                //存放節點信息的數組
} WLAN_HOSTED_NETWORK_STATUS, *PWLAN_HOSTED_NETWORK_STATUS;

typedef struct _WLAN_HOSTED_NETWORK_PEER_STATE {
  DOT11_MAC_ADDRESS                   PeerMacAddress;        //節點設備的MAC地址
  WLAN_HOSTED_NETWORK_PEER_AUTH_STATE PeerAuthState;            //節點的認證狀態
} WLAN_HOSTED_NETWORK_PEER_STATE, *PWLAN_HOSTED_NETWORK_PEER_STATE;

調用WlanHostedNetworkQueryStatus將獲得一個WLAN_HOSTED_NETWORK_STATUS結構體,就能夠查詢一些網絡基本信息了,好比dwNumberOfPeers鏈接到這個網絡的節點數,PeerList數組存放着對應節點的詳細信息,包括MAC地址和認證狀態。

6.用來設置密碼

注意密碼長度必須 大於8  小於63 不然會調用失敗

DWORD WINAPI WlanHostedNetworkSetSecondaryKey(
  _In_        HANDLE hClientHandle,
  _In_        DWORD dwKeyLength,
  _In_        PUCHAR pucKeyData,
  _In_        BOOL bIsPassPhrase,
  _In_        BOOL bPersistent,
  _Out_opt_   PWLAN_HOSTED_NETWORK_REASON pFailReason,
  _Reserved_  PVOID pvReserved
);

======================貼代碼==========================


//WIFIMAIN.h  實現文件
#pragma once
#include <wlanapi.h>
#pragma comment(lib,"wlanapi.lib")

// WIFIMAIN

class WIFIMAIN : public CWnd
{
	DECLARE_DYNAMIC(WIFIMAIN)

public:
	WIFIMAIN();
	virtual ~WIFIMAIN();

protected:
	DECLARE_MESSAGE_MAP()
private:
	bool allow;
	bool start;
	HANDLE hClient;
public:
	int Init(void);
	int AllowHostedNetWork(void);
	int DisallowHostedNetWork(void);
	int StartHostedNetWork(void);
	int StopHostedNetWork(void);
	bool isStart(void);
	bool isAllow(void);
	int Resume(void);
	int getpeernumber(void);
	int SetKEY(CString key);
	int SetSSID(CString ssidname);
};



// WIFIMAIN.cpp : 實現文件
//

#include "stdafx.h"
#include "wifi共享1028.h"
#include "WIFIMAIN.h"


// WIFIMAIN

IMPLEMENT_DYNAMIC(WIFIMAIN, CWnd)

WIFIMAIN::WIFIMAIN()
: allow(false)
, start(false)
{
	Init();
}

WIFIMAIN::~WIFIMAIN()
{
	StopHostedNetWork();
	WlanCloseHandle(hClient, NULL);
}


BEGIN_MESSAGE_MAP(WIFIMAIN, CWnd)
END_MESSAGE_MAP()



// WIFIMAIN 消息處理程序






int WIFIMAIN::Init(void)
{
	DWORD dwCurVersion = 0;
    DWORD dwResult = 0;
    
    dwResult = WlanOpenHandle(WLAN_API_VERSION, NULL, &dwCurVersion, &hClient);
	if( ERROR_SUCCESS != dwResult )
	{
		return -1;
	}


	BOOL bIsAllow = true;
    WLAN_HOSTED_NETWORK_REASON dwFailedReason;
	dwResult = WlanHostedNetworkSetProperty(hClient,
											wlan_hosted_network_opcode_enable, 
											sizeof(BOOL),
											&bIsAllow,
											&dwFailedReason,
											NULL);
	if( ERROR_SUCCESS != dwResult )
	{
		return -2;
	}
	
	return 0;
}


int WIFIMAIN::AllowHostedNetWork(void)
{
	PWLAN_HOSTED_NETWORK_REASON pFailReason = NULL;
	
	DWORD dwResult= 0;
	dwResult=WlanHostedNetworkForceStart(hClient,pFailReason,NULL);
	if( dwResult != ERROR_SUCCESS )
	{
		return -1;
	}
	allow=true;
	return 0;
}


int WIFIMAIN::DisallowHostedNetWork(void)
{
	PWLAN_HOSTED_NETWORK_REASON pFailReason = NULL;
	DWORD dwResult= 0;
	dwResult=WlanHostedNetworkForceStop(hClient,pFailReason,NULL);
	if( dwResult != ERROR_SUCCESS )
	{
		return -1;
	}
	allow=false;
	return 0;
}


int WIFIMAIN::StartHostedNetWork(void)
{
	PWLAN_HOSTED_NETWORK_REASON pFailReason = NULL;
	DWORD dwResult= 0;
	dwResult=WlanHostedNetworkStartUsing(hClient,pFailReason,NULL);
	if( dwResult != ERROR_SUCCESS )
	{
		return -1;
	}
	start=true;
	return 0;
}


int WIFIMAIN::StopHostedNetWork(void)
{
	PWLAN_HOSTED_NETWORK_REASON pFailReason = NULL;
	DWORD dwResult= 0;
	dwResult=WlanHostedNetworkStopUsing(hClient,pFailReason,NULL);
	if( dwResult != ERROR_SUCCESS )
	{
		return -1;
	}
	start=false;
	return 0;
}



bool WIFIMAIN::isStart(void)
{
	return start;
}


bool WIFIMAIN::isAllow(void)
{
	return allow;
}


int WIFIMAIN::Resume(void)
{
	DWORD dwResult = 0;
    
	BOOL bIsAllow = false;
    WLAN_HOSTED_NETWORK_REASON dwFailedReason;
	dwResult = WlanHostedNetworkSetProperty(hClient,
											wlan_hosted_network_opcode_enable, 
											sizeof(BOOL),
											&bIsAllow,
											&dwFailedReason,
											NULL);
	if( ERROR_SUCCESS != dwResult )
	{
		return -2;
	}
	
	return 0;
}


int WIFIMAIN::getpeernumber(void)
{
	PWLAN_HOSTED_NETWORK_STATUS ppWlanHostedNetworkStatus=NULL;
	int retval = WlanHostedNetworkQueryStatus(hClient,&ppWlanHostedNetworkStatus,NULL);
	if(  retval != ERROR_SUCCESS ){
		return -1;
	}
	return ppWlanHostedNetworkStatus->dwNumberOfPeers;
}


int WIFIMAIN::SetKEY(CString key)
{
	char chkey[64];
	int index;
	for(index=0; index<key.GetLength(); index++ )
	{
		chkey[index] = key[index];
	}
	chkey[index]='\0';


	WLAN_HOSTED_NETWORK_REASON dwFailedReason;
		
	DWORD dwResult= 0;
	dwResult = WlanHostedNetworkSetSecondaryKey(hClient,
												strlen((const char*)chkey) + 1,
												(PUCHAR)chkey,
												TRUE,
												FALSE,
												&dwFailedReason,
												NULL);
    if(ERROR_SUCCESS != dwResult)
    {
       return -1;
    }

	return 0;
}


int WIFIMAIN::SetSSID(CString ssidname)
{
	
	char chname[64];
	int index;
	for(index=0; index<ssidname.GetLength(); index++ )
	{
		chname[index] = ssidname[index];
	}
	chname[index]='\0';
	
	DWORD dwResult= 0;
	WLAN_HOSTED_NETWORK_REASON dwFailedReason;
	WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS cfg;
    memset(&cfg, 0, sizeof(WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS));

	memcpy( cfg.hostedNetworkSSID.ucSSID, chname, strlen(chname)  ) ;
    cfg.hostedNetworkSSID.uSSIDLength = strlen((const char*)cfg.hostedNetworkSSID.ucSSID);
    cfg.dwMaxNumberOfPeers = 20;		//最大鏈接數    

    dwResult = WlanHostedNetworkSetProperty(hClient, 
											wlan_hosted_network_opcode_connection_settings, 
											sizeof(WLAN_HOSTED_NETWORK_CONNECTION_SETTINGS), 
											&cfg,
											&dwFailedReason,
											NULL);
     if(ERROR_SUCCESS != dwResult )
	 {
		return -1;
	 }

	 return 0;
}


==========================================

這裏只貼出了比較重要的代碼,其餘的略去了,須要的能夠去個人網盤下載完整項目代碼。

代碼和程序下載:http://pan.baidu.com/s/1GI0kG
程序只完成了基本功能,還有待完善,可是學習的過程仍是頗有意思的。

下面是幾篇關於無線承載網絡比較不錯的文章,當時對我幫助很大。

關於無線承載網絡http://blog.wbpluto.com/2010/08/about-wireless-hosted-network/

==========================================

2014-3-14 修改:

實在抱歉,之前寫的時候有些東西沒有補充完整,致使讓好多網友走了彎路,今天把你們問的幾個較多的問題回覆補充一下,以避免給你們在帶來困擾。

1.我寫程序的時候環境是win7 64位,vs2010.須要用到的某些api可能在xp下沒法編譯。

2.這個版本的程序尚未加入 自動設置網絡鏈接共享的功能,須要手動設置在網卡(接入internet的網卡)屬性中設置網絡鏈接共享,相關api參考http://msdn.microsoft.com/en-us/library/bb525393%28v=vs.85%29.aspx

3.面板上的開機自動啓動代碼沒有加入,發佈的時候都忘記取消這個控件了,哎 犯罪了。

4.win8 下會提示某些運行庫找不到,這個屬於兼容性問題,屬性中設置以win7兼容模式運行便可。部分電腦須要以管理員權限運行。(估計是啓用虛擬網卡的api須要較高權限吧)

原本準備過年就寫個新版本的,可是開學太忙就一直拖着沒開始。等時間多了我會針對你們反映的問題推出一個新的版本。

相關文章
相關標籤/搜索