• 网卡相关的一些功能代码


    获取网卡信息(支持多网卡)

    uses
      Registry;
    
    
    function GetAdapterInformation: AnsiString;
    //{$DEFINE PHY_NETWORKCARD_ONLY} {是否只获取物理网卡}
    
      function _GetSystem32Dir: AnsiString;
      var
        nBuf: array[0..MAX_PATH] of AnsiChar;
      begin
        GetSystemDirectoryA(nBuf, MAX_PATH);
        Result := nBuf;
        if Result[Length(Result)] <> '' then
          Result := Result + '';
      end;
    
      const
        MAX_ADAPTER_NAME_LENGTH = 256;
        MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
        MAX_ADAPTER_ADDRESS_LENGTH = 8;
    
      type
        time_t = Longint;
        PIP_MASK_STRING = ^IP_MASK_STRING;
        IP_ADDRESS_STRING = record
          S: array [0..15] of AnsiChar;
        end;
        PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
        IP_MASK_STRING = IP_ADDRESS_STRING;
        TIpAddressString = IP_ADDRESS_STRING;
        PIpAddressString = PIP_MASK_STRING;
    
        PIP_ADDR_STRING = ^IP_ADDR_STRING;
        _IP_ADDR_STRING = record
          Next: PIP_ADDR_STRING;
          IpAddress: IP_ADDRESS_STRING;
          IpMask: IP_MASK_STRING;
          Context: DWORD;
        end;
        IP_ADDR_STRING = _IP_ADDR_STRING;
        TIpAddrString = IP_ADDR_STRING;
        PIpAddrString = PIP_ADDR_STRING;
    
        PIPAdapterInfo = ^TIPAdapterInfo;
        TIPAdapterInfo = record {IP_ADAPTER_INFO}
          Next: PIPAdapterInfo;
          ComboIndex: Cardinal;
          AdapterName: Array[0..MAX_ADAPTER_NAME_LENGTH + 3] of AnsiChar;
          Description: Array[0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of AnsiChar;
          AddressLength: Integer; {MAC}
          Address: Array[1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
          Index: Cardinal;
          _Type: Longint;
          DhcpEnabled: Longint;
          CurrentIpAddress: PIP_ADDR_STRING; {IP}
          IpAddressList: IP_ADDR_STRING;
          GatewayList: IP_ADDR_STRING; {网关}
          DhcpServer: IP_ADDR_STRING; {DHCP服务器}
          HaveWins: Boolean;
          PrimaryWinsServer: IP_ADDR_STRING;
          SecondaryWinsServer: IP_ADDR_STRING;
          LeaseObtained: time_t;
          LeaseExpires: time_t;
        end;
    
        _GetAdaptersInfo = function(AI: PIPAdapterInfo; var BufLen: Integer): Integer; stdcall;
    
      function _MACToStr(AByteArr: PByte; ALen: Integer): AnsiString;
      Begin
        Result := '';
        while (ALen > 0) do
        begin
          Result := Result + IntToHex(AByteArr^, 2) + '-';
          AByteArr := Pointer(Integer(AByteArr) + SizeOf(Byte));
          Dec(ALen);
        end;
        SetLength(Result, Length(Result) - 1);
      End;
    
      function _IsNetWorkCard(AAdapterID: string): Boolean;
      var
        i: Integer;
        nStrs: TStringList;
      const
        {虚拟适配器}
        NCF_VIRTUAL = $001;
        {软件模拟的适配器}
        NCF_SOFTWARE_ENUMERATED = $002;
        {物理适配器}
        NCF_PHYSICAL = $004;
        {不显示用户接口}
        NCF_HIDDEN = $008;
        {没有相关的服务(设备驱动程序)}
        NCF_NO_SERVICE = $010;
        {不能被用户删除(例如通过控制面板或设备管理器)}
        NCF_NOT_USER_REMOVABLE = $020;
        {组件有多个端口,每个端口作为单独的设备安装。每个端口有自己的hw_id(组件ID)并可被单独安装,这只适合于EISA适配器}
        NCF_MULTIPORT_INSTANCED_ADAPTER = $040;
        {支持用户接口(例如,Advanced Page或Customer Properties Sheet}
        NCF_HAS_UI = $080;
        {是一个过滤器}
        NCF_FILTER = $400;
    
        __CST_BASKKEY = 'SYSTEMCurrentControlSetControlClass{4D36E972-E325-11CE-BFC1-08002BE10318}';
        __CST_INSTANCEID = 'NetCfgInstanceId';
        __CST_CCT = 'Characteristics';
      begin
        Result := False;
        with TRegistry.Create do
        try
          RootKey := HKEY_LOCAL_MACHINE;
          if not OpenKey(__CST_BASKKEY, False) then
            Exit;
    
          nStrs := TStringList.Create;
          try
            GetKeyNames(nStrs);
            CloseKey;
            for i := 0 to nStrs.Count - 1 do
            begin
              if not OpenKey(__CST_BASKKEY + '' + nStrs[i], False) then
                Exit;
              if not ValueExists(__CST_INSTANCEID) then
                Exit;
              if not (ReadString(__CST_INSTANCEID) = AAdapterID) then
                Continue;
              if not ValueExists(__CST_CCT) then
                Exit;
              {只过滤物理网卡}
              if ReadInteger(__CST_CCT) and NCF_PHYSICAL = NCF_PHYSICAL then
              begin
                Result := True;
                Break;
              end;
            end;
          finally
            nStrs.Free;
          end;
        finally
          Free;
        end;
        Result := True;
      end;
    
    var
      nHWND: THandle;
      nGetAdaptersInfo: _GetAdaptersInfo;
      nAI, nWork: PIPAdapterInfo;
      nSize, nRes, nLH, nLO, x: Integer;
      nStr, nHPY, nOther: AnsiString;
    begin
      Result := '';
      nHWND := LoadLibraryA(PAnsiChar(_GetSystem32Dir + 'iphlpapi.dll'));
      if nHWND = 0 then
        Exit;
      nGetAdaptersInfo := GetProcAddress(nHWND, PAnsiChar('GetAdaptersInfo'));
      if not Assigned(nGetAdaptersInfo) then
        Exit;
      nSize := 5120;
      GetMem(nAI, nSize);
      try
        nRes := nGetAdaptersInfo(nAI, nSize);
        if (nRes <> ERROR_SUCCESS) then
        begin
          SetLastError(nRes);
          RaiseLastWin32Error;
        end
        else
        begin
          nWork := nAI;
          nLH := 0;
          nLO := 0;
          SetLength(nHPY, nSize);
          SetLength(nOther, nSize);
          Repeat
            try
              {返回 名称 + MAC}
              nStr := Trim(nWork^.Description) + '&'
                + Trim(_MACToStr(@nWork^.Address, nWork^.AddressLength)) + #13#10{网卡MAC};
    (*
              {返回 名称+ID+MAC}
              nStr := Trim(nWork^.Description) + '&' {网卡名称(描述)}
                + Trim(nWork^.AdapterName) + '&' {网卡ID}
                + Trim(_MACToStr(@nWork^.Address, nWork^.AddressLength)) + '&'#13#10{网卡MAC};
    *)
              x := Length(nStr);
              if _IsNetWorkCard(nWork^.AdapterName) then
              begin
                Move(nStr[1], nHPY[nLH + 1], x);
                Inc(nLH, x);
              end
              else
              begin
                Move(nStr[1], nOther[nLO + 1], x);
                Inc(nLO, x);
              end;
              nWork := nWork^.Next;
            except
            end;
          Until (nWork = nil);
          Result := Trim(Copy(nHPY, 1, nLH) + Copy(nOther, 1, nLO));
        end;
      finally
        FreeMem(nAI);
        Freelibrary(nHWND);
      end;
    end;

    获取网卡连接状态

    const  
      MAX_INTERFACE_NAME_LEN = 256;
      MAXLEN_PHYSADDR = 8;
      MAXLEN_IFDESCR = 256;
      MIB_IF_TYPE_OTHER = 1;
      MIB_IF_TYPE_ETHERNET = 6;
      MIB_IF_TYPE_TOKENRING = 9;
      MIB_IF_TYPE_FDDI = 15;
      MIB_IF_TYPE_PPP = 23;
      MIB_IF_TYPE_LOOPBACK = 24;
      MIB_IF_TYPE_SLIP = 28;
      MIB_IF_ADMIN_STATUS_UP = 1;
      MIB_IF_ADMIN_STATUS_DOWN = 2;
      MIB_IF_ADMIN_STATUS_TESTING = 3;
      MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0;
      MIB_IF_OPER_STATUS_UNREACHABLE = 1;
      MIB_IF_OPER_STATUS_DISCONNECTED = 2;
      MIB_IF_OPER_STATUS_CONNECTING = 3;
      MIB_IF_OPER_STATUS_CONNECTED = 4;
      MIB_IF_OPER_STATUS_OPERATIONAL = 5;
    type  
      MIB_PHYSADDR = array[0..MAXLEN_PHYSADDR - 1] of Byte;
      MIB_IFDESCR = array[0..MAXLEN_IFDESCR - 1] of Char;
      
      PMIB_IFROW = ^MIB_IFROW;
      MIB_IFROW = packed record  
        wszName: array[0..MAX_INTERFACE_NAME_LEN - 1] of WCHAR;
        dwIndex,   
        dwType,   
        dwMtu,   
        dwSpeed,   
        dwPhysAddrLen: DWORD;
        bPhysAddr: MIB_PHYSADDR;
        dwAdminStatus,   
        dwOperStatus,   
        dwLastChange,   
        dwInOctets,   
        dwInUcastPkts,   
        dwInNUcastPkts,   
        dwInDiscards,   
        dwInErrors,   
        dwInUnknownProtos,   
        dwOutOctets,   
        dwOutUcastPkts,   
        dwOutNUcastPkts,   
        dwOutDiscards,   
        dwOutErrors,   
        dwOutQLen,   
        dwDescrLen: DWORD;
        bDescr: MIB_IFDESCR;
      end;
      
      PMIB_IFTABLE = ^MIB_IFTABLE;
      MIB_IFTABLE = packed record  
        dwNumEntries: DWORD;
        table: array[0..0] of MIB_IFROW;
      end;
      
      TAdapterStatus = record  
        dwType,   
        dwOperStatus: DWORD;
        bDescr: MIB_IFDESCR;
      end;
      TAdapterStatuses = array of TAdapterStatus;
      
    function GetIfTable(pIfTable: PMIB_IFTABLE; pdwSize: PULONG; bOrder: BOOL): DWORD;
      stdcall; external 'iphlpapi.dll'; 
      
    procedure ScanAdapters(var AdapterStatuses: TAdapterStatuses); {先调用, 获取适配器信息}
    function GetAdapterTypeString(const dwType: DWORD): string; {获取适配器类型中文描述}
    function GetAdapterStatusString(const dwOperStatus: DWORD): string; {获取适配器状态中文描述}
    
      
    implementation  
    
    var  
      dwSize: DWORD;
      pMibIfTable: PMIB_IFTABLE;
      
    function GetAdapterTypeString(const dwType: DWORD): string;
    begin  
      case dwType of  
        MIB_IF_TYPE_OTHER: Result := '其他';
        MIB_IF_TYPE_ETHERNET: Result := '以太网';
        MIB_IF_TYPE_TOKENRING: Result := '令牌环';
        MIB_IF_TYPE_FDDI: Result := 'FDDI';
        MIB_IF_TYPE_PPP: Result := 'PPP';
        MIB_IF_TYPE_LOOPBACK: Result := '回路';
        MIB_IF_TYPE_SLIP: Result := 'SLIP';
      end;
    end;
    
    function GetAdapterStatusString(const dwOperStatus: DWORD): string;
    begin  
      case dwOperStatus of  
        MIB_IF_OPER_STATUS_NON_OPERATIONAL: Result := '掉线';
        MIB_IF_OPER_STATUS_UNREACHABLE: Result := '不可达';
        MIB_IF_OPER_STATUS_DISCONNECTED: Result := '断开';
        MIB_IF_OPER_STATUS_CONNECTING: Result := '连接中';
        MIB_IF_OPER_STATUS_CONNECTED: Result := '已连接';
        MIB_IF_OPER_STATUS_OPERATIONAL: Result := '连通';
      end;
    end;
    
    procedure ScanAdapters(var AdapterStatuses: TAdapterStatuses);
    var  
      dwRetVal: DWORD;
      num, i: Longint;
    begin  
      dwRetVal := GetIfTable(pMibIfTable, @dwSize, False);
      if dwRetVal = NO_ERROR then  
      begin  
        num := pMibIfTable^.dwNumEntries;
        if Length(AdapterStatuses) <> num then  
          SetLength(AdapterStatuses, num);
        for i := Low(AdapterStatuses) to High(AdapterStatuses) do  
        begin  
          AdapterStatuses[i].dwType := pMibIfTable^.table[i].dwType;
          AdapterStatuses[i].dwOperStatus := pMibIfTable^.table[i].dwOperStatus;
          AdapterStatuses[i].bDescr := pMibIfTable^.table[i].bDescr;
        end;
      end;
    end;
    
    initialization  
      GetIfTable(nil, @dwSize, False);
      GetMem(pMibIfTable, dwSize);
         
    finalization  
      FreeMem(pMibIfTable);
    end. 
  • 相关阅读:
    [USACO07JAN]平衡的阵容Balanced Lineup
    洛谷 P4389 付公主的背包 解题报告
    多项式Ⅱ
    半平面交 板子
    Problem C Dist 解题报告
    二维凸包的板子
    洛谷 P4841 城市规划 解题报告
    广二模拟赛 Problem A: 青春野狼不做理性小魔女的梦 解题报告
    CF 997E 解题报告
    洛谷 P4244 [SHOI2008]仙人掌图 II 解题报告
  • 原文地址:https://www.cnblogs.com/lzl_17948876/p/5282611.html
Copyright © 2020-2023  润新知