网卡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
}