{*******************************************************} { } { ManagerNic } { } { Copyright (C) 2022 kku } { } {*******************************************************} unit ManagerNic; interface uses Tocsg.Obj, System.SysUtils, System.Classes, Winapi.Windows, System.Generics.Collections; const // 네트워크 어댑터 Type 식별 MIB_IF_TYPE_OTHER = 1; // Some other type of network interface. 기타 등등 MIB_IF_TYPE_ETHERNET = 6; // An Ethernet network interface. 이더넷(무선 포함) IF_TYPE_ISO88025_TOKENRING = 9; // MIB_IF_TYPE_TOKENRING 토큰링 MIB_IF_TYPE_FDDI = 15; // 광 MIB_IF_TYPE_PPP = 23; // A PPP network interface. PPP MIB_IF_TYPE_LOOPBACK = 24; // A software loopback network interface. 루프백 (localloop) MIB_IF_TYPE_SLIP = 28; // An ATM network interface. SLIP IF_TYPE_IEEE80211 = 71; // An IEEE 802.11 wireless network interface. type PNicInfo = ^TNicInfo; TNicInfo = record sName, sDesc, sIpAddr, sMac: AnsiString; dwType, dwIndex: DWORD; bDhcp: Boolean; nNcType: Integer; end; TNicInfoList = class(TList) protected bFreeItem_: Boolean; procedure Notify(const Item: PNicInfo; Action: TCollectionNotification); override; public Constructor Create; property FreeItem: Boolean write bFreeItem_; end; TChangeNetAdapterState = (cnasNewAdapter, cnasDelAdapter, cnasChangeIP); TChangeNetAdapterEvent = procedure(aState: TChangeNetAdapterState; aOldInfo, aNewInfo: PNicInfo) of object; TManagerNic = class(TTgObject) private ChkNetList_: TNicInfoList; ChangeNetAdapterEvent_: TChangeNetAdapterEvent; public Constructor Create; Destructor Destroy; override; function GetNetAdapters(var aNetList: TNicInfoList): Integer; function GetChangeNetAdapterInfo: Integer; property OnChangeNetAdapterEvent: TChangeNetAdapterEvent write ChangeNetAdapterEvent_; property NetList: TNicInfoList read ChkNetList_; end; implementation uses Tocsg.Network, Tocsg.Strings, Tocsg.Exception, Tocsg.Safe; { TNicInfoList } constructor TNicInfoList.Create; begin Inherited Create; bFreeItem_ := true; end; procedure TNicInfoList.Notify(const Item: PNicInfo; Action: TCollectionNotification); begin if bFreeItem_ and (Action = cnRemoved) then Dispose(Item); end; { TManagerNic } Constructor TManagerNic.Create; begin Inherited Create; ChangeNetAdapterEvent_ := nil; ChkNetList_ := TNicInfoList.Create; GetNetAdapters(ChkNetList_); end; Destructor TManagerNic.Destroy; begin if ChkNetList_ <> nil then FreeAndNil(ChkNetList_); Inherited; end; function TManagerNic.GetNetAdapters(var aNetList: TNicInfoList): Integer; var NetAdapterInfo: TNetAdapterInfo; pInfo: PNicInfo; i: Integer; begin Result := 0; try aNetList.Clear; Guard(NetAdapterInfo, TNetAdapterInfo.Create); for i := 0 to NetAdapterInfo.Count - 1 do begin New(pInfo); ZeroMemory(pInfo, SizeOf(TNicInfo)); with NetAdapterInfo.Items[i]^ do begin pInfo.sName := sName; pInfo.sDesc := sDesc; pInfo.sIpAddr := sIpAddrs; pInfo.sMac := sMacAddr; pInfo.dwType := dwType; pInfo.dwIndex := dwIndex; pInfo.bDhcp := bDHCP; pInfo.nNcType := -1; // for HE, 선언만 해주고 다른데서 처리함 22_0622 11:24:07 kku end; aNetList.Add(pInfo); end; Result := aNetList.Count; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. GetNetAdapters()'); end; end; // 네트워크 어댑터 제거된건 sDetectIps에 포함되지 않음 22_0117 16:37:04 sunk function TManagerNic.GetChangeNetAdapterInfo: Integer; var NetList, AddNetList: TNicInfoList; i, c: Integer; bAdd: Boolean; begin Result := 0; // sDetectIps := ''; try if ChkNetList_ = nil then begin ChkNetList_ := TNicInfoList.Create; GetNetAdapters(ChkNetList_); exit; end; AddNetList := TNicInfoList.Create; AddNetList.bFreeItem_ := false; try NetList := TNicInfoList.Create; if GetNetAdapters(NetList) > 0 then begin // IP 변경 감지 for i := 0 to NetList.Count - 1 do begin bAdd := true; for c := ChkNetList_.Count - 1 downto 0 do begin if (NetList[i].dwIndex = ChkNetList_[c].dwIndex) and (NetList[i].dwType = ChkNetList_[c].dwType) and (CompareText(NetList[i].sName, ChkNetList_[c].sName) = 0) then begin bAdd := false; if NetList[i].sIpAddr <> ChkNetList_[c].sIpAddr then begin Inc(Result); // 이전 IP가 널이거나 유효한지 판단 추가 22_0125 09:28:57 sunk // 네트워크 장치가 새로 추가될때 IP가 안잡히는 경우 대상이 되지 않기때문에 다시 되돌림 22_0126 09:03:47 sunk // if IsValidIP(ChkNetList_[c].sIpAddr) then // SumString(sDetectIps, NetList[i].sIpAddr, '|'); if Assigned(ChangeNetAdapterEvent_) then ChangeNetAdapterEvent_(cnasChangeIP, ChkNetList_[c], NetList[i]); end; ChkNetList_.Delete(c); end; end; if bAdd then AddNetList.Add(NetList[i]); end; // 추가된 네트워크 어댑터 확인 for i := 0 to AddNetList.Count - 1 do begin Inc(Result); // SumString(sDetectIps, AddNetList[i].sIpAddr, '|'); if Assigned(ChangeNetAdapterEvent_) then ChangeNetAdapterEvent_(cnasNewAdapter, AddNetList[i], AddNetList[i]); end; // 제거된 네트워크 어댑터 확인 for i := 0 to ChkNetList_.Count - 1 do begin Inc(Result); if Assigned(ChangeNetAdapterEvent_) then ChangeNetAdapterEvent_(cnasDelAdapter, ChkNetList_[i], ChkNetList_[i]); end; end; finally FreeAndNil(AddNetList); FreeAndNil(ChkNetList_); ChkNetList_ := NetList; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. GetChangeNetAdapterInfo()'); end; end; end.