百度空间 | 百度首页 
               
 
查看文章
 
Windows中获取MAC地址的几种方法
2007-07-09 14:44

mac.reg

___________________________开始拷贝___________________________
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
{4D36E972-E325-11CE-BFC1-08002bE10318}\0001]
"NetworkAddress"="0001E80022AD"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
{4D36E972-E325-11CE-BFC1-08002bE10318}\0001\Ndi\Params\NetworkAddress]
@="0001E80022AD"
"ParamDesc"="MAC Address"
____________________________结束________________________________

手动修改注册表

WIN2K/XP/2003
在注册表项 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
4D36E972-E325-11CE-BFC1-08002BE10318 (WinXP SP2 English Version中验证)
中的0000,0001,0002中的DriverDesc找到你的网卡描述,然后在相应的 项目中
添加字符串变量"NetworkAddress",值就是你要
设置的MAC地址,重启网卡。

为了方便起见,可在 NDI\params中加一项名为NetworkAddress的子键,在该子键下
添加名为default的字符串,其值就是你要修改成什么样的,这个值用来改变  
上面 注册表项 的值,而不必要每次都用注册表编辑器

在NetworkAddress的主键下继续添加命名为ParamDesc的字符串,其作用是制定
NetworkAddress主键的描述

ps:win9x中则对应于HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Service\Class\Net\

1.NDIS(DDK)通过驱动程序获取MAC地址

ndis规范中说明,网卡驱动程序支持ioctl_ndis_query_stats接口
参数如下:
OID_802_3_PERMANENT_ADDRESS :物理地址
OID_802_3_CURRENT_ADDRESS    :mac地址
于是我们的方法就得到了。

首先,看看注册表,找一找网卡有几块,分别是什么设备名。
具体位置和os有关,2000下在hlm\software\microsoft\windows nt\current version\networkcards。

然后createfile(devicename,...)注意,要用linkname,因此
还要加上"////.//device//".

接着
deviceiocontrol(hmac,IOCTL_NDIS_QUERY_STATS,
OID_802_3_PERMANENT_ADDRESS/OID_802_3_CURRENT_ADDRESS...)


具体的情况可以参看ddk下的
OID_802_3_CURRENT_ADDRESS条目


2.NetAPI-2得到MAC (MSDN推荐方法)

#include <windows.h>
//#include <wincon.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

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

ASTAT Adapter;

int main (void)
{
       NCB Ncb;
       UCHAR uRetCode;
       char NetName[50];
       LANA_ENUM    lenum;
       int       i;

       memset( &Ncb, 0, sizeof(Ncb) );
       Ncb.ncb_command = NCBENUM;
       Ncb.ncb_buffer = (UCHAR *)&lenum;
       Ncb.ncb_length = sizeof(lenum);
       uRetCode = Netbios( &Ncb );
       printf( "The NCBENUM return code is: 0x%x \n", uRetCode );

       for(i=0; i < lenum.length ;i++)
        {
           memset( &Ncb, 0, sizeof(Ncb) );
           Ncb.ncb_command = NCBRESET;
           Ncb.ncb_lana_num = lenum.lana;

           uRetCode = Netbios( &Ncb );
           printf( "The NCBRESET on LANA %d return code is: 0x%x \n",
                   lenum.lana, uRetCode );

           memset( &Ncb, 0, sizeof (Ncb) );
           Ncb.ncb_command = NCBASTAT;
           Ncb.ncb_lana_num = lenum.lana;

           strcpy( Ncb.ncb_callname,   "*                " );
           Ncb.ncb_buffer = (char *) &Adapter;
           Ncb.ncb_length = sizeof(Adapter);

           uRetCode = Netbios( &Ncb );
           printf( "The NCBASTAT on LANA %d return code is: 0x%x \n",
                   lenum.lana, uRetCode );
           if ( uRetCode == 0 )
             {
              printf( "The Ethernet Number on LANA %d is:%02x%02x%02x%02x%02x%02x\n",
                   lenum.lana,
                   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] );
              }
          }

}

3.用COM API获取网卡MAC地址
      这种方法使用COM API创建一个GUID(全局唯一标识符)并从那里继承MAC地址。
GUID通常用来标识COM组件以及系统中的其他对象。它们是由MAC地址(结合其他东西)计算得来的,表面上MAC地址就包含在其中。
我说表面上是因为事实上并没有包含。我提供这种方法更多的是为了作为反面教材。您也许用这种方法能够得到MAC地址,但
有时候您只会得到随机的十六进制数值。下面的例子十分简单,无需多讲。我们使用CoCreateGuid创建GUID,并将最后六个字节
放入字符串中。它们可能是MAC地址,但并不是必然的。

uuid.cpp
#include <windows.h>
#include <iostream>
#include <conio.h>

using namespace std;

int main()
{
    cout << "MAC address is: ";
    
    // 向COM要求一个UUID。如果机器中有以太网卡,
    // UUID最后的六个字节(Data4的2-7字节)应该是本地以太网卡的MAC地址。
    GUID uuid;
    CoCreateGuid(&uuid);
    // Spit the address out
    char mac_addr[18];
    sprintf(mac_addr,"%02X:%02X:%02X:%02X:%02X:%02X",
    uuid.Data4[2],uuid.Data4[3],uuid.Data4[4],
    uuid.Data4[5],uuid.Data4[6],uuid.Data4[7]);
    cout << mac_addr << endl;
    getch();
    return 0;
}


4.用NetAPI来获取网卡MAC地址

首先在头文件定义中加入#include "nb30.h"

#pragma comment(lib,"netapi32.lib")
typedef struct _ASTAT_
{
   ADAPTER_STATUS adapt;
   NAME_BUFFER     NameBuff[30];
} ASTAT, * PASTAT;


就可以这样调用来获取远程网卡MAC地址了:

CString GetMacAddress(CString sNetBiosName)
{
     ASTAT Adapter;

     NCB ncb;
     UCHAR uRetCode;

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

     uRetCode = Netbios(&ncb);

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

     sNetBiosName.MakeUpper();

     FillMemory(ncb.ncb_callname, NCBNAMSZ - 1, 0x20);

     strcpy((char *)ncb.ncb_callname, (LPCTSTR) sNetBiosName);

     ncb.ncb_callname[sNetBiosName.GetLength()] = 0x20;
     ncb.ncb_callname[NCBNAMSZ] = 0x0;

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

     uRetCode = Netbios(&ncb);
   
     CString sMacAddress;

     if (uRetCode == 0)
     {
         sMacAddress.Format(_T("%02x%02x%02x%02x%02x%02x"),
          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]);
     }
     return sMacAddress;
}


类别:网络相关 | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu