VC-如何用VC读取网卡MAC地址?

发布于 2016-12-16 17:30:50 字数 66 浏览 1151 评论 4

在实际应用程序中,往往会需要在程序运行时获取当前机器网卡的MAC地址,以便作为某种标识之用。如何用VC实现这个功能呢?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

瑾兮 2017-08-03 17:33:33

通用的方法是通过Windows 9x/NT/Win2000 中内置的NetApi32.DLL 的功能来实现的。首先通过发送NCBENUM 命令,获取网卡的数目和每张网卡的内部编号,然后对每个网卡标号发送NCBASTAT 命令获取其MAC 地址。注意:这里的网卡是指捆绑了NetBEIU 协议的通信协议栈,可以在网卡的属性处查看到。

示例代码:
// Mac-Reader.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"
#include <windows.h>
#include <wincon.h>
#include <nb30.h>
// 因为是通过NetAPI来获取网卡信息,所以需要包含其题头文件nb30.h
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
}ASTAT, * PASTAT;

ASTAT Adapter;

// 定义一个存放返回网卡信息的变量
// 输入参数:lana_num为网卡编号,一般地,从0开始,但在Windows 2000中并不一定是连续分配的

void getmac_one (int lana_num)
{
NCB ncb;
UCHAR uRetCode;

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBRESET;
ncb.ncb_lana_num = lana_num;
// 指定网卡号

// 首先对选定的网卡发送一个NCBRESET命令,以便进行初始化
uRetCode = Netbios( &ncb );
printf( "The NCBRESET return code is:0x%x /n", uRetCode );

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBASTAT;
ncb.ncb_lana_num = lana_num; // 指定网卡号

strcpy( (char *)ncb.ncb_callname,"* " );
ncb.ncb_buffer = (unsigned char *) &Adapter;

// 指定返回的信息存放的变量
ncb.ncb_length = sizeof(Adapter);

// 接着,可以发送NCBASTAT命令以获取网卡的信息
uRetCode = Netbios( &ncb );
printf( "The NCBASTAT eturn code is: 0x%x /n", uRetCode );
if ( uRetCode == 0 )
{

// 把网卡MAC地址格式化成常用的16进制形式,如0010-A4E4-5802
printf( "The Ethernet Number[%d] is: %02X-%02X-%02X-%02X-%02X-%02X/n",
lana_num,
Adapter.adapt.adapter_address[0],
Adapter.adapt.adapter_address[1],
Adapter.adapt.adapter_address[2],
Adapter.adapt.adapter_address[3],
Adapter.adapt.adapter_address[4],
Adapter.adapt.adapter_address[5] );
}
}

int main(int argc, char* argv[])
{
NCB ncb;
UCHAR uRetCode;
LANA_ENUM lana_enum;

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBENUM;

ncb.ncb_buffer = (unsigned char *) &lana_enum;
ncb.ncb_length = sizeof(lana_enum);

// 向网卡发送NCBENUM命令,以获取当前机器的网卡信息,如有多少个网卡、每张网卡的编号等
uRetCode = Netbios( &ncb );
printf( "The NCBENUM return code is:0x%x /n", uRetCode );
if ( uRetCode == 0 )
{
printf( "Ethernet Count is : %d/n/n", lana_enum.length);

getmac_one( lana_enum.lana[0]);//对第一个网卡
//如果你有多张网卡
/*
for ( int i=0; i< lana_enum.length; ++i)
// getmac_one( lana_enum.lana[i]);
*/
}
return 0;
}

想挽留 2017-07-20 02:06:24

网上找到的一份代码,LZ可以参考一下

// Mac-Reader.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <wincon.h>
#include <nb30.h>
// 因为是通过NetAPI来获取网卡信息,所以需要包含其题头文件nb30.h
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

typedef struct _ASTAT_
{
ADAPTER_STATUS adapt;
NAME_BUFFER NameBuff [30];
}ASTAT, * PASTAT;

ASTAT Adapter;

// 定义一个存放返回网卡信息的变量
// 输入参数:lana_num为网卡编号,一般地,从0开始,但在Windows 2000中并不一定是连续分配的

void getmac_one (int lana_num)
{
NCB ncb;
UCHAR uRetCode;

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBRESET;
ncb.ncb_lana_num = lana_num;
// 指定网卡号

// 首先对选定的网卡发送一个NCBRESET命令,以便进行初始化
uRetCode = Netbios( &ncb );
printf( "The NCBRESET return code is:0x%x /n", uRetCode );

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBASTAT;
ncb.ncb_lana_num = lana_num; // 指定网卡号

strcpy( (char *)ncb.ncb_callname,"* " );
ncb.ncb_buffer = (unsigned char *) &Adapter;

// 指定返回的信息存放的变量
ncb.ncb_length = sizeof(Adapter);

// 接着,可以发送NCBASTAT命令以获取网卡的信息
uRetCode = Netbios( &ncb );
printf( "The NCBASTAT eturn code is: 0x%x /n", uRetCode );
if ( uRetCode == 0 )
{

// 把网卡MAC地址格式化成常用的16进制形式,如0010-A4E4-5802
printf( "The Ethernet Number[%d] is: %02X-%02X-%02X-%02X-%02X-%02X/n",
lana_num,
Adapter.adapt.adapter_address[0],
Adapter.adapt.adapter_address[1],
Adapter.adapt.adapter_address[2],
Adapter.adapt.adapter_address[3],
Adapter.adapt.adapter_address[4],
Adapter.adapt.adapter_address[5] );
}
}

int main(int argc, char* argv[])
{
NCB ncb;
UCHAR uRetCode;
LANA_ENUM lana_enum;

memset( &ncb, 0, sizeof(ncb) );
ncb.ncb_command = NCBENUM;

ncb.ncb_buffer = (unsigned char *) &lana_enum;
ncb.ncb_length = sizeof(lana_enum);

// 向网卡发送NCBENUM命令,以获取当前机器的网卡信息,如有多少个网卡、每张网卡的编号等
uRetCode = Netbios( &ncb );
printf( "The NCBENUM return code is:0x%x /n", uRetCode );
if ( uRetCode == 0 )
{
printf( "Ethernet Count is : %d/n/n", lana_enum.length);

getmac_one( lana_enum.lana[0]);//对第一个网卡
//如果你有多张网卡
/*
for ( int i=0; i< lana_enum.length; ++i)
// getmac_one( lana_enum.lana[i]);
*/
}
return 0;
}

想挽留 2017-05-06 10:51:20

网卡的MAC地址是可以伪造的,但是魔高一尺,道高一丈,还是有办法获取网卡的真实MAC地址的。基本思想是DeviceIoControl函数和网卡驱动直接打交道,从驱动中获取真实的MAC地址。具体的实现可参见:通过WDK获取网卡原生MAC地址和当前MAC地址

虐人心 2017-03-20 17:14:09

之前项目中用到的代码:
// 网卡 MAC 地址,注意: MAC 地址是可以在注册表中修改的
通过API直接获取
BOOL GetMacAddress(std::wstring &strMacAddr)
{
PIP_ADAPTER_INFO pAdapterInfo;

DWORD AdapterInfoSize;

DWORD Err;

AdapterInfoSize = 0;

Err = GetAdaptersInfo(NULL, &AdapterInfoSize);

if((Err != 0) && (Err != ERROR_BUFFER_OVERFLOW))
{

ATLTRACE("获得网卡信息失败!");

return FALSE;

}

// 分配网卡信息内存

pAdapterInfo = (PIP_ADAPTER_INFO) GlobalAlloc(GPTR, AdapterInfoSize);

if(pAdapterInfo == NULL)
{
ATLTRACE("分配网卡信息内存失败");

return FALSE;

}

if(GetAdaptersInfo(pAdapterInfo, &AdapterInfoSize) != 0)
{

ATLTRACE(_T("获得网卡信息失败!n"));

GlobalFree(pAdapterInfo);

return FALSE;

}

wchar_t str[256]={0};
wsprintfW(str,L"%02X%02X%02X%02X%02X%02X",
pAdapterInfo->Address[0],

pAdapterInfo->Address[1],

pAdapterInfo->Address[2],

pAdapterInfo->Address[3],

pAdapterInfo->Address[4],

pAdapterInfo->Address[5]);

GlobalFree(pAdapterInfo);

strMacAddr = str;

return TRUE;
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文