宿舍用手機連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須要較高權限吧)
原本準備過年就寫個新版本的,可是開學太忙就一直拖着沒開始。等時間多了我會針對你們反映的問題推出一個新的版本。