VC++ win7下实现WIFI共享工具 附源代码(无线承载网络)

Wesley13
• 阅读 501

宿舍用手机连wifi总是要用浏览器登录联通的wlan登陆页面,无奈手机太挫内存只有512M,开个网页再干其他的事情就卡的要死,所以果断下载了个wifi共享精灵。用了一次就果断卸载了,为啥呢?竟然有广告,受不了啊。正好在学VC++ 算了自己做一个吧。  VC++ win7下实现WIFI共享工具 附源代码(无线承载网络)

关于无线承载网络

无线承载网络(Wireless Hosted Network)是指安装有无线局域网服务的Windows 7和Windows Server 2008 R2所提供的一种WLAN功能,具备两项主要功能:

第一、把一个物理无线网卡虚拟化成一个或多个虚拟无线网卡,称为虚拟的WiFi。

第二、借助无线网卡把当前接网络虚拟成为一个基于软件的无线接入点,称为虚拟AP或软AP。

=========================万恶的分割线===========================

项目需要包含wlanapi.h 头文件和wlanapi.lib 库

备注:测试环境win7_64,建议关闭一些安全软件,(比如我测试的时候忘了关comodo导致防火墙总是拒绝其他设备的连接)。

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

功能不复杂,用到的主要函数有下面几个

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.启用和禁用无线承载网络。

打开网络和共享中心 单击更改适配器设置,如果启用了无线承载网络 面板里面就会有描述为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需要较高权限吧)

本来准备过年就写个新版本的,但是开学太忙就一直拖着没开始。等时间多了我会针对大家反映的问题推出一个新的版本。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
移动路由器如果隐藏了该如何恢复
家中的移动路由器(https://www.ruijie.com.cn/cp/lyydly/)之前设置了隐藏wifi,现在不想隐藏wifi了。我该怎么恢复呢?首先用电脑或手机连接你的移动路由器网络,然后登录它的设置界面。登录设置界面后,进入无线设置
Stella981 Stella981
2年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
2年前
C# Aspose.Cells导出xlsx格式Excel,打开文件报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
报错信息:最近打开下载的Excel,会报如下错误。(xls格式不受影响)!(https://oscimg.oschina.net/oscnet/2b6f0c8d7f97368d095d9f0c96bcb36d410.png)!(https://oscimg.oschina.net/oscnet/fe1a8000d00cec3c
Stella981 Stella981
2年前
Linux查看GPU信息和使用情况
1、Linux查看显卡信息:lspci|grepivga2、使用nvidiaGPU可以:lspci|grepinvidia!(https://oscimg.oschina.net/oscnet/36e7c7382fa9fe49068e7e5f8825bc67a17.png)前边的序号"00:0f.0"是显卡的代
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
2年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Python进阶者 Python进阶者
1个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这