网卡相关的一些功能代码
获取网卡信息(支持多网卡)
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.
--------------------------------------------------------------------------------------------------
作者:黑暗煎饼果子
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
--------------------------------------------------------------------------------------------------