频道分类

Delphi 获取网卡Mac为软件注册机器码

作者:admin 来源: 日期:2020/2/8 0:10:35 人气: 标签:

 
unit uRegCode;

interface

uses
  Winapi.Windows, System.SysUtils, System.Classes, ActiveX, ComObj, System.Variants,
  System.StrUtils, Registry, Winapi.IpTypes, Winapi.IpHlpApi,
  IdHashMessageDigest, IdGlobal;

function GetRegCode(): string;

function GetGUID(): string;

function GetMacAddress(): string;

    { Public declarations }
function strToMD5(S: string): string;

implementation

const
  NCF_VIRTUAL = $01; //  说明组件是个虚拟适配器
  NCF_SOFTWARE_ENUMERATED = $02; //  说明组件是一个软件模拟的适配器
  NCF_PHYSICAL = $04; //  说明组件是一个物理适配器
  NCF_HIDDEN = $08;  //说明组件不显示用户接口
  NCF_NO_SERVICE = $10; //  说明组件没有相关的服务(设备驱动程序)
  NCF_NOT_USER_REMOVABLE = $20;  // 说明不能被用户删除(例如,通过控制面板或设备管理器)
  NCF_MULTIPORT_INSTANCED_ADAPTER = $40; //  说明组件有多个端口,每个端 口作为单独的设备安装。
                                          //  每个 端口有自己的hw_id(组件ID) 并可被单独安装,
                                          //  这只适合于 EISA适配器
  NCF_HAS_UI = $80; // 说明组件支持用户接口(例如,Advanced Page或Customer  Properties Sheet)
  NCF_FILTER = $400; //  说明组件是一个过滤器

function IsPhysicalAdapter(sAdapterGUID: string; bOnlyPCI: Boolean = False): Boolean;
const
  NET_CARD_KEY_PATH = 'SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}';
var
  Reg: TRegistry;
  sList: TStrings;
  vCharacteristics: DWORD;
  I: Integer;
begin
  Result := False;
  sList := TStringList.Create;
  Reg := TRegistry.Create;
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if not Reg.OpenKey(NET_CARD_KEY_PATH, False) then
      Exit;
    Reg.GetKeyNames(sList);
    Reg.CloseKey;
    if sList.Count > 0 then
      for I := 0 to Pred(sList.Count) do
        if Reg.OpenKey(NET_CARD_KEY_PATH + '\' + sList.Strings[I], False) then
        begin
          try
            if (Trim(UpperCase(sAdapterGUID)) = Trim(UpperCase(Reg.ReadString('NetCfgInstanceId')))) then
            begin
              vCharacteristics := DWORD(Reg.ReadInteger('Characteristics'));
              Result := (NCF_PHYSICAL and vCharacteristics) = NCF_PHYSICAL;
              Break;
            end;
          finally
            Reg.CloseKey;
          end;
        end;
  finally
    Reg.Free;
    sList.Free;
  end;
end;

function GetMacAddress(): string;
var
  dwRet: DWORD;
  AI, Work: PIpAdapterInfo;
  sGUID, sTmp, sLastMAC, sFirstMAC: string;
  I: Integer;
  uSize: ULONG;
begin
  Result := '';
  sLastMAC := '';
  sFirstMAC := '';
  uSize := SizeOf(TIpAdapterInfo);
  GetMem(AI, uSize);
  dwRet := GetAdaptersInfo(AI, uSize);
  if (dwRet = ERROR_BUFFER_OVERFLOW) then
  begin
    FreeMem(AI);
    GetMem(AI, uSize);
    dwRet := GetAdaptersInfo(AI, uSize);
  end;
  try
    if (dwRet <> ERROR_SUCCESS) then
      Exit;
    Work := AI;
    while Work <> nil do
    begin
      try
        sGUID := string(AnsiString(Work.AdapterName));
        sTmp := string(AnsiString(Work.Description));
        // 名称描述出现VMWare,直接忽略
        if Pos('VMWare', sTmp) > 0 then
          Continue;

        // 名称描述出现adapter,直接忽略
        //if Pos(' ADAPTER',UpperCase(sTmp)) > 0 then
        //  Continue;

        // 配置的ID地址不正常,忽略
        if Work.AddressLength = 0 then
          Continue;

        // 将网卡MAC地址转成字符串
        sLastMAC := '';
        for I := 0 to Work.AddressLength - 1 do
        begin
          sLastMAC := sLastMAC + Format('%.2x', [Work.Address[I]]);
        end;

        if sFirstMAC = '' then
          sFirstMAC := sLastMAC;

        // 不是物理网卡,忽略
        if not IsPhysicalAdapter(sGUID) then
          Continue;

        Result := sLastMAC;

        //找到第一个物理网卡后退出
        Break;
      finally
        Work := Work.Next;
      end;
    end;
    // 找不到物理网卡MAC,返回第一个即可
    if Result = '' then
      Result := sFirstMAC;
  finally
    FreeMem(AI);
  end;
end;

function GetRegCode(): string;
var
  sMac_Addr:string;
begin
  sMac_Addr := GetMacAddress;
  //Result := GetGUID + GetMacAddress;
  Result := strToMD5(sMac_Addr);
end;

function GetGUID(): string;
var
  LTep: TGUID;
  sGUID: string;
begin
  CreateGUID(LTep);
  sGUID := GUIDToString(LTep);
  sGUID := StringReplace(sGUID, '-', '', [rfReplaceAll]);
  sGUID := Copy(sGUID, 2, Length(sGUID) - 2);
  Result := sGUID;
end;

function strToMD5(S: string): string;
var
  Md5Encode: TIdHashMessageDigest5;
begin
  Md5Encode := TIdHashMessageDigest5.Create;
  result := Md5Encode.HashStringAsHex(S);
  Md5Encode.Free;
end;

end.