网卡相关的一些功能代码

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

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 = ‘\SYSTEM\CurrentControlSet\Control\Class\{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. 
时间: 2024-10-13 09:26:53

网卡相关的一些功能代码的相关文章

jQuery实现的输入文本计数功能代码

jQuery实现的输入文本计数功能代码:在一些比较人性化的留言回复功能中,都有这样的设计,那就是当输入文本的时候,能够实现计数功能,可以提示用户还能能够输入多少文字,这样可以便于用户选择更合适的语言描述,下面就是一段能够实现此功能的代码,需要的朋友可以进行一下借鉴.代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="author&q

Java UDP实现聊天功能代码

我以前经常写的是基于TCP的网络编程,由于TCP建立连接鼻血要经过三次握手连接,服务器端需要阻塞式等待客户端的连接.而UDP则是可以直接向目的地址的目的端口上发送数据包,由于它只负责发送出去就好,不管对方是否正确接受到与否,所以当网络性能不好时它容易出现丢包的问题.(注意:UDP是基于数据报为单位进行传输的,而TCP是一种基于流进行传输的) 但是UDP很好的模拟了我们呢平时聊天的方式,可以很好的实现连续多次发送和接受,也就是简单的QQ聊天的功能. 现在来简要介绍Java中有关UDP编程相关的类:

DevExpress Grid控件经典常用功能代码收集

随着DevExpress 控件包越来越多的被中国用户使用,由于是英文版本,看英文版使用说明非常困难,慧都控件网在DevExpress 控件包使用方面有多年的研究,慧都控件网会不断的把DevExpress 使用经验分享给大家.»更多DevExpress开发资源与帮助文档 下面是我们平时收集最常用的DevExpress Winform 4个代码片段,比较常用,希望对广大DEV用户有帮助. 一 .GridControl的删除操作 private void rILinkEditInfoDel_Click

js常用功能代码

js常用功能代码(持续更新): 1,--折叠与展开 <input id="btnDisplay" type="button" class="baocun2" value="添加" onclick="changeDisplay()" /> <script type="text/javascript"> function changeDisplay() { var h

[转]计算机视觉、机器学习相关领域论文和源代码大集合

计算机视觉.机器学习相关领域论文和源代码大集合--持续更新…… [email protected] http://blog.csdn.net/zouxy09 注:下面有project网站的大部分都有paper和相应的code.Code一般是C/C++或者Matlab代码. 最近一次更新:2013-3-17 一.特征提取Feature Extraction: ·         SIFT [1] [Demo program][SIFT Library] [VLFeat] ·         PCA

IOS开发-OC学习-常用功能代码片段整理

IOS开发-OC学习-常用功能代码片段整理 IOS开发中会频繁用到一些代码段,用来实现一些固定的功能.比如在文本框中输入完后要让键盘收回,这个需要用一个简单的让文本框失去第一响应者的身份来完成.或者是在做与URL有关的功能时,需要在Info.plist中添加一段代码进而实现让网址完成从Http到Https的转换,以及其他的一些功能. 在从一个新手到逐渐学会各种功能.代码.控件.方法如何使用的过程中,也在逐渐积累一些知识,但是一次总不会把这些东西都深刻记住并完全理解.所以在这儿记录下这些东西,用来

通过javascript库JQuery实现页面跳转功能代码

通过javascript库JQuery实现页面跳转功能代码的四段代码实例如下. 实例1: 1 2 3 4 $(function(){ var pn = $("#gotopagenum").val();//#gotopagenum是文本框的id属性 location.href = "NewList.aspx?pagenum="+pn;//location.href实现客户端页面的跳转 }); 实例2: 实现跳转:window.location = 'user!add.

微网站中加入一键拨号功能代码

在做一个微信的微网站中的一个便民服务电话功能的应用,用到移动web页面中列出的电话号码,点击需要实现调用通讯录,网页一键拨号的拨打电话功能. 如果需要在移动浏览器中实现拨打电话,发送email,美国服务器,调用sns等功能,移动手机WEB页面(HTML5)Javascript提供的接口是一个好办法. 采用url链接的方式,实现在Safari ios,香港服务器,Android 浏览器,webos 浏览器,塞班浏览器,IE,Operamini等主流浏览器,进行拨打电话功能. 1.最常用WEB页面J

调用新浪微博接口,实现“分享”功能——代码实现

<!doctype html> <html> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <div> <p>点击下面的按钮可以将这段文字和图片分享到新浪微博哦!@独行冰海</p> <img src='http://t.cn/zRxMzZE' title='独