tryhi 发表于 2011-10-28 22:29:33

请问如何检测到真实的物理地址MAC,是否有这个API

$mac = _API_Get_NetworkAdapterMAC (@IPAddress1)
MsgBox(0,0,$mac)

Func _API_Get_NetworkAdapterMAC($sIP)
        Local $MAC, $MACSize
        Local $i, $s, $r, $iIP

        $MAC = DllStructCreate("byte")
        $MACSize = DllStructCreate("int")

        DllStructSetData($MACSize, 1, 6)
        $r = DllCall("Ws2_32.dll", "int", "inet_addr", "str", $sIP)
        $iIP = $r
        $r = DllCall("iphlpapi.dll", "int", "SendARP", "int", $iIP, "int", 0, "ptr", DllStructGetPtr($MAC), "ptr", DllStructGetPtr($MACSize))
        $s = ""
        For $i = 0 To 5
                If $i Then $s = $s & ":"
                $s = $s & Hex(DllStructGetData($MAC, 1, $i + 1), 2)
        Next
        Return $s
EndFunc   ;==>_API_Get_NetworkAdapterMAC


上面段代码可以查到MCA,但如果用注册表改或者在本地连接里面将地址改成别的,查出来就不是原来那个了,请问有什么办法查出真实那个MAC

pusofalse 发表于 2011-10-28 22:29:34

本论坛搜索“怎么读取指定网卡名或连接名的原始mac?不是当前mac,是原始出厂mac”。

hzxymkb 发表于 2011-10-28 22:39:40

看P版的API应该有吧!

www378660084 发表于 2011-10-28 22:52:18

顶一下,要硬件通信,太困难了{:face (197):}

tsui 发表于 2011-10-28 23:11:33

用run执行ipconfig /all,再正则之。

gzh888666 发表于 2011-10-28 23:32:46

本帖最后由 gzh888666 于 2011-10-28 23:34 编辑

借用P版的#include <ACN_NET.au3>
#include <WinAPI.au3>
#include <GUIEdit.au3>
#include <GUIConstants.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

Global $_MACS_DELIMITER = ":"
Global $_MACC_MACADDRS = []
Global $_MACN_PRODURE
Global $_MACPP_WND_DEF_PROC = DllCallbackRegister("_MACADDRWNDPROC", "int", "hWnd;uint;wparam;lparam")
$sMac = _API_Get_NetworkAdapterMAC(@IPAddress1)
MsgBox(0, "", $sMac)

Func _GUICtrlMacAddr_Create($hWnd, $iLeft, $iTop, $sMac = "")
        Local $iPid, $hParent, $i_Parent, $i_Width, $i_Left, $h_Field, $aMac, $i_Pos = 0

        _WinAPI_GetWindowThreadProcessId($hWnd, $iPid)
        If $iPid <> @AutoItPID Then Return SetError(1, 0, 0)

        $i_Parent = GUICtrlCreateLabel("", $iLeft, $iTop, 140, 20, $SS_SUNKEN)
        $hParent = GUICtrlGetHandle(-1)
        GUICtrlSetBkColor(-1, 0xFFFFFF)
        $_MACC_MACADDRS += 1
        ReDim $_MACC_MACADDRS[$_MACC_MACADDRS + 1]
        $_MACC_MACADDRS[$_MACC_MACADDRS] = $i_Parent
        For $i = 1 To 6
                $_MACC_MACADDRS[$_MACC_MACADDRS][$i] = GUICtrlCreateInput("", $i_Pos, 3, 20, 17, 1, 4)
                GUICtrlSetLimit(-1, 2)
                $h_Field = GUICtrlGetHandle(-1)
                _WinAPI_SetParent($h_Field, $hParent)
                If $_MACC_MACADDRS = 1 And $i = 1 Then
                        GUIRegisterMsg($WM_COMMAND, "_CuiCtrlMacAddr_CmdProc")
                        $_MACN_PRODURE = _WinAPI_SetWindowLong($h_Field, -4, DllCallbackGetPtr($_MACPP_WND_DEF_PROC))
                Else
                        _WinAPI_SetWindowLong($h_Field, -4, DllCallbackGetPtr($_MACPP_WND_DEF_PROC))
                EndIf
                GUICtrlCreateLabel($_MACS_DELIMITER, $i_Pos + 41, $iTop + 10, 4, 2, $SS_SUNKEN)
                $i_Pos += 23
        Next
        GUICtrlDelete(-1)
        If $sMac <> "" Then
                $aMac = StringSplit($sMac, $_MACS_DELIMITER)
                If $aMac > 6 Then Return $_MACC_MACADDRS
                For $i = $aMac To 1 Step -1
                        If StringLen($aMac[$i]) = 2 And StringIsXDigit($aMac[$i]) Then
                                GUICtrlSetData($_MACC_MACADDRS[$_MACC_MACADDRS][$i], $aMac[$i])
                        EndIf
                Next
        EndIf
        Return $_MACC_MACADDRS
EndFunc   ;==>_GUICtrlMacAddr_Create


Func _GUICtrlMacAddr_GetAddress($iMacIndex)
        Local $sAddr

        If $iMacIndex < 1 Or $iMacIndex > $_MACC_MACADDRS Then Return ""
        For $i = 1 To 6
                $sAddr &= GUICtrlRead($_MACC_MACADDRS[$iMacIndex][$i]) & $_MACS_DELIMITER
        Next
        Return StringTrimRight($sAddr, StringLen($_MACS_DELIMITER))
EndFunc   ;==>_GUICtrlMacAddr_GetAddress

Func _CuiCtrlMacAddr_CmdProc($hWnd, $iMsg, $wparam, $lparam)
        Local $nID, $iNotifyCode

        $nID = BitAND($wparam, 0xFFFF)
        $iNotifyCode = BitShift($wparam, 0x10)
        If $iNotifyCode = $EN_CHANGE Then
                For $i = 1 To $_MACC_MACADDRS
                        For $f = 1 To 6
                                If $nID = $_MACC_MACADDRS[$i][$f] And StringLen(GUICtrlRead($nID)) >= 2 Then
                                        GUICtrlSetState($nID + 2, $GUI_FOCUS)
                                        _GUICtrlEdit_SetSel($nID + 2, 0, 2)
                                EndIf
                        Next
                Next
        EndIf
EndFunc   ;==>_CuiCtrlMacAddr_CmdProc





Func _GUICtrlMacAddr_SetAddress($iMacIndex, $sMac)
        Local $aMac
        If $iMacIndex < 1 Or $iMacIndex > $_MACC_MACADDRS Then Return 0
        $aMac = StringSplit($sMac, $_MACS_DELIMITER)
        For $i = $aMac To 1 Step -1
                If StringLen($aMac[$i]) = 2 And StringIsXDigit($aMac[$i]) Then
                        GUICtrlSetData($_MACC_MACADDRS[$iMacIndex][$i], $aMac[$i])
                EndIf
        Next
        Return 1
EndFunc   ;==>_GUICtrlMacAddr_SetAddress


Func _GUICtrlMacAddr_ShowHide($iMacIndex, $fHide = True)
        Local $iState = $GUI_SHOW
        If $fHide = True Then $iState = $GUI_HIDE
        If $iMacIndex < 1 Or $iMacIndex > $_MACC_MACADDRS Then Return 0
        For $i = 0 To 6
                GUICtrlSetState($_MACC_MACADDRS[$iMacIndex][$i], $iState)
                If $i = 6 Then ContinueLoop
                GUICtrlSetState($_MACC_MACADDRS[$iMacIndex][$i] + 1, $iState)
        Next
        Return 1
EndFunc   ;==>_GUICtrlMacAddr_ShowHide



Func _MACADDRWNDPROC($hWnd, $iMsg, $wparam, $lparam)
        If $iMsg = $WM_CHAR Then
                If StringIsXDigit(Chr($wparam)) = 0 And $wparam <> 8 Then Return 0
        EndIf
        Return _WinAPI_CallWindowProc($_MACN_PRODURE, $hWnd, $iMsg, $wparam, $lparam)
EndFunc   ;==>_MACADDRWNDPROC

tryhi 发表于 2011-10-28 23:44:18

借用P版的
gzh888666 发表于 2011-10-28 23:32 http://www.autoitx.com/images/common/back.gif

用run执行ipconfig /all,再正则之。
tsui 发表于 2011-10-28 23:11 http://www.autoitx.com/images/common/back.gif


不行呀,改了之后仍然获取不到

gzh888666 发表于 2011-10-29 00:25:50

不行呀,改了之后仍然获取不到
tryhi 发表于 2011-10-28 23:44 http://www.autoitx.com/images/common/back.gif
刚写了一个回显的,再试试!#include <Constants.au3>
Opt("MustDeclareVars",1)
MsgBox(0,"",_test())
Func _test()
Local $foo,$line,$lines,$Test
$foo = Run(@ComSpec & " /c ipconfig /all", @SystemDir, @SW_HIDE, $STDOUT_CHILD)
$lines = ""
While 1
    $line = StdoutRead($foo)
    If @error Then ExitLoop
   $lines &= $line
Wend
;MsgBox(0,"test",$lines)
$Test = StringRegExp($lines, '(?s)本地连接.+?Physical Address.+?:(.+?)\r', 3)
Return $Test
EndFunc

gzh888666 发表于 2011-10-29 00:45:56

WMI接口的试试看!#Include <Array.au3>
$NetworkAdapterInfo=_NetworkAdapterInfo()
MsgBox(0,"",$NetworkAdapterInfo)
Func _NetworkAdapterInfo()
      Local $colItem
      Local $objItem
      Local $colItems
      Local $objItems
      Local $objWMIService
      Local $Adapters
      $Adapters = 0
      $objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")
      $colItem= $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionStatus >0", "WQL", 0x30)
      If IsObj($colItem) Then
                For $objItem In $colItem
                        If $objItem.MACAddress = "00:00:00:00:00:00" Then ContinueLoop
                        $Adapters += 1
                        ReDim $Adapters
                        $Adapters[$Adapters] += $Adapters
                        $Adapters[$Adapters] = $objItem.NetConnectionStatus
                        $Adapters[$Adapters] = $objItem.Description
                        $Adapters[$Adapters] = $objItem.NetConnectionID
                        $Adapters[$Adapters] = $objItem.MACAddress   
                        $colItems= $objWMIService.ExecQuery('SELECT * FROM Win32_NetworkAdapterConfiguration WHERE MACAddress = "'&$Adapters[$Adapters]&'" And IPEnabled = True ' , "WQL", 0x30)                                             
                        If IsObj($colItems) Then
                              For $objItems In $colItems
                                        ;if $objItem1.IPAddress(0) = "0.0.0.0" Then ContinueLoop
                                        $Adapters[$Adapters] = $objItems.IPAddress(0)
                                        $Adapters[$Adapters] = $objItems.DefaultIPGateway(0)
                                        $Adapters[$Adapters] = $objItems.IPSubnet(0)
                                        $Adapters[$Adapters] = $objItems.DNSServerSearchOrder(0)
                                        $Adapters[$Adapters] = $objItems.DNSServerSearchOrder(1)
                              Next   
                        EndIf
                Next
      EndIf
      
Return $Adapters

EndFunc

tryhi 发表于 2011-10-29 00:52:08

本帖最后由 tryhi 于 2011-10-29 00:53 编辑

#include "stdafx.h"
#include <windows.h>
//#include <iptypes.h>
#include <iphlpapi.h>
#include <NtDDNdis.h>

#pragma comment ( lib, "iphlpapi.lib" )

BOOL WINAPI GetPhyMacAddress(char* strServiceName)
{
BOOLbRet      = FALSE;
charpstrBuf;
sprintf(pstrBuf, "//./%s", strServiceName);

HANDLEhDev= CreateFile(pstrBuf, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
if ( hDev != INVALID_HANDLE_VALUE )
{
    int    inBuf;
    BYTEoutBuf= { 0 };
    DWORDBytesReturned;
    inBuf= OID_802_3_PERMANENT_ADDRESS;

    if ( DeviceIoControl(hDev, IOCTL_NDIS_QUERY_GLOBAL_STATS, (LPVOID)&inBuf, 4, outBuf, 256, &BytesReturned, NULL) )
    if ( DeviceIoControl(hDev, IOCTL_NDIS_QUERY_GLOBAL_STATS, (LPVOID)&inBuf, 4, outBuf, 256, &BytesReturned, NULL) )
    {
      sprintf(pstrBuf, "物理mac:%02X-%02X-%02X-%02X-%02X-%02X\n",
      outBuf, outBuf, outBuf, outBuf, outBuf, outBuf);
      printf(pstrBuf);
      bRet= TRUE;
    }

    inBuf= OID_802_3_CURRENT_ADDRESS;

    {
      sprintf(pstrBuf, "当前mac:%02X-%02X-%02X-%02X-%02X-%02X\n",
      outBuf, outBuf, outBuf, outBuf, outBuf, outBuf);
      printf(pstrBuf);
      bRet= TRUE;
    }
    CloseHandle(hDev);
}
return bRet;
}

//网卡 MAC 地址
BOOL GetMacAddress()
{
UINT      uErrorCode= 0;
IP_ADAPTER_INFOiai;
ULONG      uSize    = 0;
DWORD      dwResult= GetAdaptersInfo(&iai, &uSize);

if ( dwResult == ERROR_BUFFER_OVERFLOW )
{
    PIP_ADAPTER_INFOpiai= (PIP_ADAPTER_INFO)new BYTE;
    dwResult= GetAdaptersInfo(piai, &uSize);
    if ( ERROR_SUCCESS == dwResult )
    {
      while ( piai )
      {
      printf("名称:%s\n", piai->AdapterName);
      printf("描述:%s\n", piai->Description);
      printf("类型:%d\n", piai->Type);
      GetPhyMacAddress(piai->AdapterName);
      printf("\n");
      piai = piai->Next;
      }
    }
    delete[] piai;
}
return TRUE;
}
据说这段VC代码可以获取到,用了DeviceIoControl函数,不过没看懂。。。。。。

hzxymkb 发表于 2011-10-29 06:43:56

回复 9# tryhi


    等P版来转成AU3吧!

happytc 发表于 2011-10-29 11:27:39

MAC地址有两个:

①OID_CURRENT_ADDRESS   这个就是可以通过修改注册表等等多种方法改变
②OID_PERMANENT_ADDRESS   这个就只能通过修改驱动改变了

第一个就是目前正在使用的Mac地址,第二个就是网卡硬件地址
要想得到第②个的地址,就必须直接跟网卡通信,所以就容易想到以下方法了:网卡设备发送一个   OID   请求,网卡就会返回硬件MAC地址的,于是:
用_WinAPI_CreateFileEx来打开硬件设备,也就是网卡了。
再用_WinAPI_DeviceIoControl()向网卡发送控制信息,也就是OIDs
就可以得到硬件(网卡)的mac地址了。

到这,以楼主的能力,应该就可以写出代码来了,若真的还不能,我可以试着帮你写写。
不知道楼上P版说的是不是这个原理。

happytc 发表于 2011-10-29 12:34:56

忍不住手贱,试写了个,机子开启了太多运行的程序,就不重启机子测试了,希望没有问题


#Include <Memory.au3>
#include <WinAPIEx.au3>

Local $NicID, $iMac
$NicID = _GetAdapterID()
$iMac = _GetAdapterMac($NicID)
$iMac = StringTrimRight(StringRegExpReplace($iMac, "(..)", "\1-"), 1)
MsgBox(0, "Mac Address", $iMac)


Func _GetAdapterMac($NicID)
        Local $hDevice, $hBuffer, $pBuffer, $tMem, $iMac
       
        $hDevice = _WinAPI_CreateFileEx("\\.\" & $NicId, $OPEN_EXISTING, 0, 0, 3, 4, 0)
        If @error Then
                Return SetError(1, 0, 0)
        EndIf
       
        $iLength =6
        $hBuffer = _MemGlobalAlloc($iLength)
        $pBuffer = _MemGlobalLock($hBuffer)
        $tMem =DllStructCreate( "byte[" & $iLength & "]", $pBuffer)
        DllStructSetData($tMem, 1, 0x01010101)
        _MemGlobalUnlock($hBuffer)       
        _WinAPI_DeviceIoControl($hDevice, 0x170002, DllStructGetPtr($tMem), 4, DllStructGetPtr($tMem), $iLength)
        $iMac = DllStructGetData($tMem, 1)
        Return StringTrimLeft($iMac, 2)
EndFunc

Func _GetAdapterID()
        Local $objWMIService, $colItems, $AdapterID
       
        $objWMIService = ObjGet("winmgmts:\\localhost\root\cimv2")
        $colItems = $objWMIService.ExecQuery("Select * from Win32_TSNetworkAdapterListSetting")
        For $Item In $colItems
                $AdapterID = $Item.NetworkAdapterID
        Next
        Return $AdapterID
EndFunc

user3000 发表于 2011-10-29 16:53:29

"忍不住手贱,试写了个..."

要是每个大牛都这样...嘿嘿, 世界就太美妙了!

tryhi 发表于 2011-10-30 04:34:26

非常感谢楼上的各位朋友,问题终于解决了。
页: [1] 2 3
查看完整版本: 请问如何检测到真实的物理地址MAC,是否有这个API