{*******************************************************} { } { ThdNicMonitor } { } { Copyright (C) 2022 kku } { } {*******************************************************} unit ThdNicMonitor; interface uses Tocsg.Thread, System.SysUtils, Winapi.Windows, Winapi.Messages, System.Classes, System.Generics.Collections, ManagerNic, Tocsg.Network; const WM_NOTI_PREVENT_NIC = WM_USER + 4968; type TNicPrevent = record sDescPv, sWAlgo, sWifiName: String; bNewIpNic, bDHCP, bWireless, bWPublic: Boolean; nReviveSec, nWQuality: Integer; end; PNicReviveEnt = ^TNicReviveEnt; TNicReviveEnt = record nIdx: Integer; dwTick: DWORD; end; TNicReviveEntList = TList; TThdNicMonitor = class(TTgThread) protected hRcvHwnd_: HWND; NicPrevent_: TNicPrevent; PvDescList_, WifiNameList_: TStringList; NicReviveEntList_: TNicReviveEntList; procedure OnNicReviveNotify(Sender: TObject; const Item: PNicReviveEnt; Action: TCollectionNotification); procedure AddReviveInfo(nIdx: Integer); procedure SendLog(sLog: String); procedure ProcessNicPrevent(aEnt: PNicInfo; aWlanInfo: TWlanInfo = nil); procedure InitPreventNic; procedure OnChangeNicInfo(aState: TChangeNetAdapterState; aOldInfo, aNewInfo: PNicInfo); procedure Execute; override; public Constructor Create(hRcvHwnd: HWND; aNicPrevent: TNicPrevent); Destructor Destroy; override; end; implementation uses Tocsg.Exception, Tocsg.Safe, Tocsg.Strings, EM.nduWlanAPI; { TThdNicMonitor } Constructor TThdNicMonitor.Create(hRcvHwnd: HWND; aNicPrevent: TNicPrevent); begin Inherited Create; hRcvHwnd_ := hRcvHwnd; NicPrevent_ := aNicPrevent; NicReviveEntList_ := TNicReviveEntList.Create; NicReviveEntList_.OnNotify := OnNicReviveNotify; PvDescList_ := TStringList.Create; SplitString(UpperCase(NicPrevent_.sDescPv), '|', PvDescList_); WifiNameList_ := TStringList.Create; SplitString(UpperCase(NicPrevent_.sWifiName), '|', WifiNameList_); InitPreventNic; end; Destructor TThdNicMonitor.Destroy; var i: Integer; begin for i := 0 to NicReviveEntList_.Count - 1 do SetNicEnableByIndex(NicReviveEntList_[i].nIdx, true); FreeAndNil(WifiNameList_); FreeAndNil(PvDescList_); FreeAndNil(NicReviveEntList_); Inherited; end; procedure TThdNicMonitor.OnNicReviveNotify(Sender: TObject; const Item: PNicReviveEnt; Action: TCollectionNotification); begin if Action = cnRemoved then Dispose(Item); end; procedure TThdNicMonitor.AddReviveInfo(nIdx: Integer); var pInfo: PNicReviveEnt; begin if (NicPrevent_.nReviveSec > 0) and (nIdx <> -1) then begin New(pInfo); pInfo.nIdx := nIdx; pInfo.dwTick := GetTickCount; if NicReviveEntList_.Count > 0 then NicReviveEntList_.Insert(0, pInfo) else NicReviveEntList_.Add(pInfo); end; end; procedure TThdNicMonitor.SendLog(sLog: String); begin if hRcvHwnd_ <> 0 then begin sLog := Format('[%s] %s', [DateTimeToStr(Now), sLog]); SendMessage(hRcvHwnd_, WM_NOTI_PREVENT_NIC, 0, NativeInt(sLog)); end; end; procedure TThdNicMonitor.ProcessNicPrevent(aEnt: PNicInfo; aWlanInfo: TWlanInfo = nil); var i, c: Integer; sTemp: String; pWEnt: PWLanEnt; bBlock, bFreeWlan: Boolean; begin try bFreeWlan := false; if PvDescList_.Count > 0 then begin sTemp := UpperCase(aEnt.sDesc); for c := 0 to PvDescList_.Count - 1 do if Pos(PvDescList_[c], sTemp) > 0 then begin AddReviveInfo(SetNicEnable(aEnt.sDesc, false)); SendLog(Format('��Ʈ��ũ ���� ���� ���� (%s) : %s', [PvDescList_[c], aEnt.sDesc])); exit; end; end; if NicPrevent_.bDHCP and aEnt.bDhcp then begin AddReviveInfo(SetNicEnable(aEnt.sDesc, false)); SendLog(Format('DHCP ��Ʈ��ũ ���� : %s', [aEnt.sDesc])); exit; end; // if NicPrevent_.bWireless and // (aEnt.dwType = IF_TYPE_IEEE80211) and // (aEnt.sIpAddr <> '') and // (aEnt.sIpAddr <> IP_NULL) then if NicPrevent_.bWireless and (aEnt.dwType = IF_TYPE_IEEE80211) then begin if aWlanInfo = nil then begin bFreeWlan := true; aWlanInfo := TWlanInfo.Create; end; bBlock := not (NicPrevent_.bWPublic or (WifiNameList_.Count > 0) or (NicPrevent_.nWQuality > 0) or (NicPrevent_.sWAlgo <> '')); sTemp := Format('���� ��Ʈ��ũ ���� : %s', [aEnt.sDesc]); try pWEnt := aWlanInfo.GetWlanEntByName(aEnt.sDesc); if pWEnt <> nil then begin if not bBlock and NicPrevent_.bWPublic then begin bBlock := not pWEnt.bSecurety; if bBlock then sTemp := Format('���� ���� ��Ʈ��ũ ���� : %s', [aEnt.sDesc]); end; if not bBlock and (WifiNameList_.Count > 0) then begin var sChkName: String := pWEnt.sProfile; for i := 0 to WifiNameList_.Count - 1 do if sChkName.Contains(WifiNameList_[i]) then begin bBlock := true; sTemp := Format('���� ��Ʈ��ũ �̸� ���� : %s', [pWEnt.sProfile]); break; end; end; if not bBlock and (NicPrevent_.nWQuality > 0) and (NicPrevent_.nWQuality >= pWEnt.nQuality) then begin bBlock := true; sTemp := Format('���� ��Ʈ��ũ ǰ�� ���� : %s', [aEnt.sDesc]); end; if not bBlock and (NicPrevent_.sWAlgo <> '') and (Pos(DOT11_AUTH_ALGORITHM_To_String(pWEnt.dwAlgo1), NicPrevent_.sWAlgo) = 0) then begin bBlock := true; sTemp := Format('���� ��Ʈ��ũ ���� �˰���� ���� : %s (%s)', [aEnt.sDesc, DOT11_AUTH_ALGORITHM_To_String(pWEnt.dwAlgo1)]); end; if bBlock then begin DisconnectWIFI(pWEnt.InterfaceGuid); // AddReviveInfo(SetNicEnable(aEnt.sDesc, false)); SendLog(sTemp); end; end; finally if bFreeWlan and (aWlanInfo <> nil) then FreeAndNil(aWlanInfo); end; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. ProcessNicPrevent()'); end; end; procedure TThdNicMonitor.InitPreventNic; var MgNic: TManagerNic; WlanInfo: TWlanInfo; i: Integer; begin Guard(MgNic, TManagerNic.Create); Guard(WlanInfo, TWlanInfo.Create); for i := 0 to MgNic.NetList.Count - 1 do ProcessNicPrevent(MgNic.NetList[i], WlanInfo); end; procedure TThdNicMonitor.OnChangeNicInfo(aState: TChangeNetAdapterState; aOldInfo, aNewInfo: PNicInfo); begin case aState of cnasNewAdapter : begin SendLog(Format('���ο� ��Ʈ��ũ ��ġ �߰� : %s (IP=%s, MAC=%s, Type=%s)', [aNewInfo.sDesc, aNewInfo.sIpAddr, aNewInfo.sMac, GetNetAdapterTypeToStr(aNewInfo.dwType)])); if NicPrevent_.bNewIpNic then begin AddReviveInfo(SetNicEnable(aNewInfo.sDesc, false)); SendLog(Format('���ο� ��Ʈ��ũ ��ġ ���� : %s', [aNewInfo.sDesc])); end else ProcessNicPrevent(aNewInfo); end; cnasDelAdapter : begin if aOldInfo <> nil then begin SendLog(Format('��Ʈ��ũ ��ġ ���ŵ� : %s (IP=%s, MAC=%s, Type=%s)', [aOldInfo.sDesc, aOldInfo.sIpAddr, aOldInfo.sMac, GetNetAdapterTypeToStr(aOldInfo.dwType)])); end; end; cnasChangeIP : begin SendLog(Format('IP ����� : %s (Old IP=%s, New IP=%s)', [aNewInfo.sDesc, aOldInfo.sIpAddr, aNewInfo.sIpAddr])); if NicPrevent_.bNewIpNic then begin AddReviveInfo(SetNicEnable(aNewInfo.sDesc, false)); SendLog(Format('IP ���� ��Ʈ��ũ ��ġ ���� : %s', [aNewInfo.sDesc])); end else ProcessNicPrevent(aNewInfo); end; end; end; procedure TThdNicMonitor.Execute; var MgNic: TManagerNic; i: Integer; llCurTick: LONGLONG; begin Guard(MgNic, TManagerNic.Create); MgNic.OnChangeNetAdapterEvent := OnChangeNicInfo; while not Terminated and not GetWorkStop do begin try MgNic.GetChangeNetAdapterInfo; if (NicPrevent_.nReviveSec > 0) and (NicReviveEntList_.Count > 0) then begin llCurTick := GetTickCount; for i := NicReviveEntList_.Count - 1 downto 0 do if (llCurTick - NicReviveEntList_[i].dwTick) > (NicPrevent_.nReviveSec * 1000) then begin SetNicEnableByIndex(NicReviveEntList_[i].nIdx, true); NicReviveEntList_.Delete(i); end; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. Execute()'); end; Sleep(1000); end; end; end.