那有什么办法可以获取网卡的真实的物理地址呢?

原创 2013年12月04日 13:12:31

网卡MAC ID 可以通过.net提供的WMI类库来实现,如果用户通过第三方软件修改了mac地址,WMI就是无法获取真实的网卡地址了。

那有什么办法可以获取网卡的真实的物理地址呢?有,那就要用到Windows API函数DeviceIoControl了,代码如下:

public static string GetLocalMac()
        {
            List<string> netCardList = GetNetCardList();
            List<string>.Enumerator enumNetCard = netCardList.GetEnumerator();

            string macAddr = string.Empty;
            while (enumNetCard.MoveNext())
            {
                macAddr = GetPhysicalAddr(enumNetCard.Current);
                if (macAddr != string.Empty)
                {
                    break;
                }
            }
            return macAddr;
        }
        public static List<string> GetNetCardList()
        {
            List<string> cardList = new List<string>();
            try
            {
                //请求“System.Security.Permissions.RegistryPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”类型的权限已失败。
                RegistryKey regNetCards = Registry.LocalMachine.OpenSubKey(Win32Utils.REG_NET_CARDS_KEY);
                if (regNetCards != null)
                {
                    string[] names = regNetCards.GetSubKeyNames();
                    RegistryKey subKey = null;
                    foreach (string name in names)
                    {
                        subKey = regNetCards.OpenSubKey(name);
                        if (subKey != null)
                        {
                            object o = subKey.GetValue("ServiceName");
                            if (o != null)
                            {
                                cardList.Add(o.ToString());
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
            }

            return cardList;
        }
        private static string GetPhysicalAddr(string cardId)
        {
            string macAddress = string.Empty;
            uint device = 0;
            try
            {
                string driveName = "\\\\.\\" + cardId;
                device = Win32Utils.CreateFile(driveName,
                Win32Utils.GENERIC_READ | Win32Utils.GENERIC_WRITE,
                Win32Utils.FILE_SHARE_READ | Win32Utils.FILE_SHARE_WRITE,
                0, Win32Utils.OPEN_EXISTING, 0, 0);
                if (device != Win32Utils.INVALID_HANDLE_VALUE)
                {
                    byte[] outBuff = new byte[6];
                    uint bytRv = 0;
                    int intBuff = Win32Utils.PERMANENT_ADDRESS;

                    if (0 != Win32Utils.DeviceIoControl(device, Win32Utils.IOCTL_NDIS_QUERY_GLOBAL_STATS,
                    ref intBuff, 4, outBuff, 6, ref bytRv, 0))
                    {
                        string temp = string.Empty;
                        foreach (byte b in outBuff)
                        {
                            temp = Convert.ToString(b, 16).PadLeft(2, '0');
                            macAddress += temp;
                            temp = string.Empty;
                        }
                    }
                }
            }
            finally
            {
                if (device != 0)
                {
                    Win32Utils.CloseHandle(device);
                }
            }

            return macAddress;
        }
    }
    

 

  #region Win32Utils
    public class Win32Utils
    {
        public const string REG_NET_CARDS_KEY = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards";
        public const uint GENERIC_READ = 0x80000000;
        public const uint GENERIC_WRITE = 0x40000000;
        public const uint FILE_SHARE_READ = 0x00000001;
        public const uint FILE_SHARE_WRITE = 0x00000002;
        public const uint OPEN_EXISTING = 3;
        public const uint INVALID_HANDLE_VALUE = 0xffffffff;
        public const uint IOCTL_NDIS_QUERY_GLOBAL_STATS = 0x00170002;
        public const int PERMANENT_ADDRESS = 0x01010101;

        [DllImport("kernel32.dll")]
        public static extern int CloseHandle(uint hObject);

        [DllImport("kernel32.dll")]
        public static extern int DeviceIoControl(uint hDevice,
                                                  uint dwIoControlCode,
                                                  ref int lpInBuffer,
                                                  int nInBufferSize,
                                                  byte[] lpOutBuffer,
                                                  int nOutBufferSize,
                                                  ref uint lpbytesReturned,
                                                  int lpOverlapped);

        [DllImport("kernel32.dll")]
        public static extern uint CreateFile(string lpFileName,
                                              uint dwDesiredAccess,
                                              uint dwShareMode,
                                              int lpSecurityAttributes,
                                              uint dwCreationDisposition,
                                              uint dwFlagsAndAttributes,
                                              int hTemplateFile);

    }
    #endregion
}

 

相关文章推荐

delphi获取网卡物理地址

  • 2014年07月02日 15:10
  • 386KB
  • 下载

C++之获取网卡物理地址(MAC)

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include   //该头文件定义了Socket编程的功能  ...

新浪旧事-JAVA之获取网卡物理地址

在JAVA中有时候会需要定位到某台电脑,而通过IP定位显然是不行的,有一种解决方案是通过定位到电脑的物理地址来定位电脑,这是本文要介绍的内容。     1. PhysicalAddressUtil ...
  • geloin
  • geloin
  • 2012年04月13日 09:18
  • 618

macmakeup网卡物理地址修改

  • 2015年08月18日 11:20
  • 286KB
  • 下载

网卡物理地址

  • 2012年10月20日 12:07
  • 626B
  • 下载

安装VirtualBox虚拟网卡并任意修改其物理地址(MAC)

最近工作时需要使用虚拟的网卡,并且需要修改网卡地址(MAC),从网上查询一番(互联网真强大--!)结果如下: 可以生成虚拟网卡的方法有三种: 1、使用VMware的虚拟网卡。为什么先说这个方法因为...

整理在ubuntu重装之后配置过程(6G内存,修改网卡物理地址,修改hosts,codeblocks,eclipse,jdk,配置eclipse编译python)

1. 识别6G内存 由于现在电脑是6G内存,所以需要用apt内核来识别,在新立得软件包里搜索linux-image,找到linux-image-apt,安装即可。有命令行形式,第一次可以,第二次...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:那有什么办法可以获取网卡的真实的物理地址呢?
举报原因:
原因补充:

(最多只允许输入30个字)