2010-07-17 3 views
3

Doublons possibles:
Getting Machine’s MAC Address — Good Solution?
How do I get the MAC address of a network card using Delphi?Comment obtenir l'adresse MAC dans Windows7?

J'utilise l'adresse MAC comme identifiant matériel pour la protection (ofcourse je crypté ces données) J'utilise ci-dessous code pour obtenir MAC adresse sur l'ordinateur de l'utilisateur

function MacAddress: string; 
var 
Lib: Cardinal; 
Func: function(GUID: PGUID): Longint; stdcall; 
GUID1, GUID2: TGUID; 
begin 
Result := ''; 
Lib := LoadLibrary('rpcrt4.dll'); 
if Lib <> 0 then 
begin 
    @Func := GetProcAddress(Lib, 'UuidCreateSequential'); 
    if Assigned(Func) then 
    begin 
    if (Func(@GUID1) = 0) and 
     (Func(@GUID2) = 0) and 
     (GUID1.D4[2] = GUID2.D4[2]) and 
     (GUID1.D4[3] = GUID2.D4[3]) and 
     (GUID1.D4[4] = GUID2.D4[4]) and 
     (GUID1.D4[5] = GUID2.D4[5]) and 
     (GUID1.D4[6] = GUID2.D4[6]) and 
     (GUID1.D4[7] = GUID2.D4[7]) then 
    begin 
     Result := 
     IntToHex(GUID1.D4[2], 2) + '-' + 
     IntToHex(GUID1.D4[3], 2) + '-' + 
     IntToHex(GUID1.D4[4], 2) + '-' + 
     IntToHex(GUID1.D4[5], 2) + '-' + 
     IntToHex(GUID1.D4[6], 2) + '-' + 
     IntToHex(GUID1.D4[7], 2); 
    end; 
    end; 
end; 
end; 

code ci-dessus fonctionne parfaitement sur Windows XP mais son donnant des valeurs différentes dans windows7, la valeur changeant chaque fois après ordinateur resratred :( est-il une chance d'obtenir une adresse MAC thats constante (sauf si l'utilisateur a changé son adresse MAC) ou y at-il tout bon code qui retrace les données constantes sur tous les systèmes d'exploitation?

merci à l'avance

+0

Qu'est-ce qui vous fait penser que [ce code] (http://msdn.microsoft.com/en-us/library/aa379322%28VS.85%29.aspx) récupère l'adresse MAC de votre ordinateur? –

+2

Ack! Cette fonction ne renvoie pas d'adresse MAC. Il renvoie une valeur qui arrive parfois à contenir une adresse MAC. – Gabe

Répondre

3

@ steve0, pour récupérer l'adresse MAC d'un adaptateur réseau vous pouvez utiliser la classe WMI et la Win32_NetworkAdapterConfiguration et vérifier la propriété MACAddress.

Vérifiez ce code:

program WMI_MAC; 

{$APPTYPE CONSOLE} 


uses 
    SysUtils 
    ,ActiveX 
    ,ComObj 
    ,Variants; 

function VarToStrNil(Value:Variant):string; //Dummy function to onvert an variant value to string 
begin 
    if VarIsNull(Value) then 
    Result:='' 
    else 
    Result:=VarToStr(Value); 
end; 


Procedure GetMacAddress; 
var 
    objWMIService : OLEVariant; 
    colItems  : OLEVariant; 
    colItem  : OLEVariant; 
    oEnum   : IEnumvariant; 
    iValue  : LongWord; 
    wmiHost, root, wmiClass: string; 

    function GetWMIObject(const objectName: String): IDispatch; 
    var 
    chEaten: Integer; 
    BindCtx: IBindCtx;//for access to a bind context 
    Moniker: IMoniker;//Enables you to use a moniker object 
    begin 
    OleCheck(CreateBindCtx(0, bindCtx)); 
    OleCheck(MkParseDisplayName(BindCtx, StringToOleStr(objectName), chEaten, Moniker));//Converts a string into a moniker that identifies the object named by the string 
    OleCheck(Moniker.BindToObject(BindCtx, nil, IDispatch, Result));//Binds to the specified object 
    end; 

begin 
    wmiHost  := '.'; 
    root   := 'root\CIMV2'; 
    wmiClass  := 'Win32_NetworkAdapterConfiguration'; 
    objWMIService := GetWMIObject(Format('winmgmts:\\%s\%s',[wmiHost,root])); 
    colItems  := objWMIService.ExecQuery(Format('SELECT * FROM %s',[wmiClass]),'WQL',0); 
    oEnum   := IUnknown(colItems._NewEnum) as IEnumVariant; 
    while oEnum.Next(1, colItem, iValue) = 0 do 
    //if VarToStrNil(colItem.MACAddress)<>'' then //uncomment if you only want list the interfaces with mac adress 
    //if colItem.IPEnabled then // uncomment if you only want list the active interfaces 
    begin 
    WriteLn('Card Description '+VarToStrNil(colItem.Caption)); 
    WriteLn('MACAddress  '+VarToStrNil(colItem.MACAddress)); 
    end; 
end; 

begin 
try 
    CoInitialize(nil); 
    try   
     GetMacAddress; 
     Readln; 
    finally 
    CoUninitialize; 
    end; 
except 
    on E:Exception do 
    Begin 
     Writeln(E.Classname, ': ', E.Message); 
     Readln; 
    End; 
    end; 
end. 
0

Voici un code fonctionne bien pour tout ordinateur sur votre réseau - peut essayer d'obtenir votre propre, en utilisant '127.0.0.1' comme IP:

function GetRemoteMacAddress(const IP: AnsiString): TSockData; 
// implements http://msdn.microsoft.com/en-us/library/aa366358(VS.85).aspx 
type 
    TSendARP = function(DestIp: DWORD; srcIP: DWORD; pMacAddr: pointer; PhyAddrLen: Pointer): DWORD; stdcall; 
const 
    HexChars: array[0..15] of AnsiChar = 'ABCDEF'; 
var dwRemoteIP: DWORD; 
    PhyAddrLen: Longword; 
    pMacAddr : array [0..7] of byte; 
    I: integer; 
    P: PAnsiChar; 
    SendARPLibHandle: THandle; 
    SendARP: TSendARP; 
begin 
    result := ''; 
    SendARPLibHandle := LoadLibrary('iphlpapi.dll'); 
    if SendARPLibHandle<>0 then 
    try 
    SendARP := GetProcAddress(SendARPLibHandle,'SendARP'); 
    if @SendARP=nil then 
     exit; // we are not under 2K or later 
    dwremoteIP := inet_addr(pointer(IP)); 
    if dwremoteIP<>0 then begin 
     PhyAddrLen := 8; 
     if SendARP(dwremoteIP, 0, @pMacAddr, @PhyAddrLen)=NO_ERROR then begin 
     if PhyAddrLen=6 then begin 
      SetLength(result,12); 
      P := pointer(result); 
      for i := 0 to 5 do begin 
      P[0] := HexChars[pMacAddr[i] shr 4]; 
      P[1] := HexChars[pMacAddr[i] and $F]; 
      inc(P,2); 
      end; 
     end; 
     end; 
    end; 
    finally 
    FreeLibrary(SendARPLibHandle); 
    end; 
end; 

Ce code est extrait de notre framework freeware et open source, unité SynCrtSock.pas. Voir http://synopse.info/fossil

Questions connexes