{*******************************************************} { } { BsKwdSchKvCttSchClient } { } { Copyright (C) 2023 kku } { } {*******************************************************} unit BsKwdSchKvCttSchClient; interface uses Tocsg.ClientBase, System.SysUtils, System.Classes, Tocsg.Packet, Winapi.Windows, Tocsg.Win32, CttSchDefine, FileService; const FILEMON_WRITEMON = 1; FILEMON_WRITEBLOCK = 2; FILEMON_DRM = 3; type TBsKwdSchKvCttSchClient = class(TTgClientBase) private dwExecuteTick_: DWORD; bTerminated_: Boolean; sKvPath_: String; Mtx_: TTgMutex; FileScanOpt_: TFileScanOpt; ThdDelFiles_: TThdDelFiles; ThdEncFiles_: TThdEncFiles; protected function GetConnected: Boolean; override; procedure ConnectedEvent; override; procedure DisconnectedEvent; override; procedure ProcessRcvPacket(aRcv: IRcvPacket); override; public Constructor Create(aFileScanOpt: TFileScanOpt); Destructor Destroy; override; end; var gKvKwdSch: TBsKwdSchKvCttSchClient = nil; implementation uses Tocsg.Exception, Tocsg.Strings, Tocsg.WndUtil, Tocsg.Path, superobject, Tocsg.Json, Tocsg.Shell, Tocsg.KvFilter.adinfo, ManagerService, GlobalDefine, ManagerModel, Tocsg.Safe, Tocsg.PCRE, ManagerCampaign, Condition, Tocsg.Files; const DOC_HEADER_FMT = '%s%s'; { TBsKwdSchKvCttSchClient } Constructor TBsKwdSchKvCttSchClient.Create(aFileScanOpt: TFileScanOpt); begin Inherited Create('', 0); ASSERT(gKvKwdSch = nil); gKvKwdSch := Self; dwExecuteTick_ := 0; bTerminated_ := false; FileScanOpt_ := aFileScanOpt; sKvPath_ := GetRunExePathDir + EXE_KVCTTSCH; Mtx_ := TTgMutex.Create('Global\BsFileMonKv' + IntToStr(GetTickCount)); ThdDelFiles_ := TThdDelFiles.Create; ThdEncFiles_ := TThdEncFiles.Create; ThdDelFiles_.StartThread; ThdEncFiles_.StartThread; end; Destructor TBsKwdSchKvCttSchClient.Destroy; begin gKvKwdSch := nil; FreeAndNil(Mtx_); bTerminated_ := true; Inherited; FreeAndNil(ThdEncFiles_); FreeAndNil(ThdDelFiles_); end; function TBsKwdSchKvCttSchClient.GetConnected: Boolean; {$IFDEF DEBUG} procedure ConnectDebugCore; var hFind, hIpc: HWND; begin hFind := FindWindow('TDlgKvCttSchMain', nil); if hFind <> 0 then begin hIpc := StrToInt64Def(ExtrNumStr(GetWindowCaption(hFind)), 0); if hIpc <> 0 then ConnectWnd(hIpc); end; end; {$ENDIF} var sParam: String; O: ISuperObject; begin Result := Inherited; if not Result and not bTerminated_ and (W2W_ <> nil) then begin if (GetTickCount - dwExecuteTick_) > 10000 then // 최소 10초에 한번만 실행 되도록함 begin dwExecuteTick_ := GetTickCount; {$IFDEF 1DEBUG} if DebugHook <> 0 then begin ConnectDebugCore; exit; end; {$ELSE} if not FileExists(sKvPath_) then begin _Trace('Fail .. GetConnected() .. Not found "kv-exe"'); exit; end; if GetSelfWnd = 0 then begin _Trace('Fail .. GetConnected() .. GetSelfWnd()'); exit; end; O := SO; O.I['CSTT'] := Integer(csttSchConnect); O.S['Mtx'] := Mtx_.MutexName; O.I['Tasker'] := GetSelfWnd; O.O['Opt'] := TTgJson.ValueToJsonObject(FileScanOpt_.CttSchOpt); O.I['CT'] := CUSTOMER_TYPE; sParam := GetRunExePathDir + '$bfkso.dat'; if SaveJsonObjToFile(O, sParam) then begin ExecutePath(sKvPath_, Format('-p "%s"', [sParam])); end; {$ENDIF} end; end; end; procedure TBsKwdSchKvCttSchClient.ConnectedEvent; begin try Inherited; SetSendPauseState(false); _Trace('Connected.', 3); except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. ConnectedEvent()'); end; end; procedure TBsKwdSchKvCttSchClient.DisconnectedEvent; begin try Inherited; QSendPacket_.Clear; _Trace('Disconnected', 3); except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. DisconnectedEvent()'); end; end; procedure TBsKwdSchKvCttSchClient.ProcessRcvPacket(aRcv: IRcvPacket); function GetEventToStr(nAction: Integer): String; begin case nAction of 1 : Result := 'Create'; 3 : Result := 'Modify'; 5 : Result := 'Rename'; else Result := Format('Unknown-%d', [nAction]); end; end; procedure process_KVC_RESPONSE_KEYWORD_SEARCH; var sPath, sText, sFounds, sClass, sFormat, sHeader, sResult: String; nTotalHits: Integer; DocInfo: TAdDocInfo; PO: TPrefModel; begin // _Trace('Found Path="%s"', [aRcv.S['Path']]); PO := gMgSvc.ModePolicy; sPath := aRcv.S['Path']; sText := aRcv.S['Text']; if gMgSvc.IsNewApi then sFounds := gMgSvc.MgRule.GetRuleNamesFromIds(aRcv.S['Founds']) else sFounds := aRcv.S['Founds']; nTotalHits := aRcv.I['TotalHits']; if aRcv.O['Info'] <> nil then DocInfo := TTgJson.GetDataAsType(aRcv.O['Info']) else ZeroMemory(@DocInfo, SizeOf(DocInfo)); if (DocInfo.eClass > -1) and (DocInfo.eClass < 22) then sClass := ENdocClassDescStrs[DocInfo.eClass] else sClass := 'Unknown format'; if (DocInfo.eFormat > -1) and (DocInfo.eFormat < 437) then sFormat := ENdocFmtDescStrs[DocInfo.eFormat] else sFormat := 'No Format Found'; sHeader := Format(DOC_HEADER_FMT, [sClass, sFormat]); // sResult := Format('%s%s%s' + // '%s%d', [sPath, sHeader, sText, sFounds, nTotalHits]); sResult := Format('[%s] %s%s%s' + '%s%d', [GetEventToStr(aRcv.I['Event']), sPath, sHeader, sText, sFounds, nTotalHits]); case aRcv.I['Action'] of FILEMON_WRITEMON : begin // case nType of // TYPE_MSG_PREVENT_FILECHANGE : sHeader := LOGCODE_PREVENT_FILEMONITOR; // TYPE_MSG_PREVENT_FILEMASK : sHeader := LOGCODE_PREVENT_FILEMASK; // TYPE_MSG_PREVENT_FILEWRITE : sHeader := LOGCODE_PREVENT_FILEIO; // TYPE_MSG_PREVENT_FILEDRMENC : sHeader := PREVENT_DRM_ENCRYPT; // end; if PO.IsOldPolicy then begin gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEMONITOR, sResult); if PO.IsOldPolicy or Po.FileMon.IsNoti then gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, Format('%s|%s|%d', [sPath, sFounds, nTotalHits])); end else begin var LogInfo: TLogInfo; ZeroMemory(@LogInfo, SizeOf(LogInfo)); LogInfo.sCode := LOGCODE_PREVENT_FILEMONITOR; if (aRcv.S['SchName'] <> '') and (aRcv.S['FoundSum'] <> '') then begin var OA: ISuperObject := TSuperObject.Create(stArray); var OTemp: ISuperObject; var StrList: TStringList; var RstList: TStringList; var i: Integer; Guard(StrList, TStringList.Create); SplitString(aRcv.S['SchName'], RESULT_SEPARATOR, StrList); Guard(RstList, TStringList.Create); SplitString(aRcv.S['FoundSum'], RESULT_SEPARATOR, RstList); for i := 0 to StrList.Count - 1 do begin OTemp := SO; OTemp.S['RULE_ID'] := StrList[i]; OTemp.S['TEXT'] := RemoveOverlapWords(RstList[i], ';'); OTemp.S['CNT'] := IntToStr(GetCountOverlapWordsCount(GetCountOverlapWords(RstList[i], ';'))); OA.AsArray.Add(OTemp); end; LogInfo.OVio := OA; end; if PO.FileMon.IsCollectTxt then LogInfo.sBody := sText; if PO.FileMon.IsCollectFile then begin if GetFileSize_path(sPath) <= (LONGLONG(Po.FileMonLimitMB) * 1048576) then begin LogInfo.sFileCompId := gMgSvc.MakeComponentId(sPath); if Po.FileMon.DoEnc then begin if IsUseEncOnlyAIP or gMgSvc.FirstAip then gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sPath, PO.FileMonMinMB, Po.FileMonLimitMB, crtAIP) else gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sPath, PO.FileMonMinMB, Po.FileMonLimitMB, crtDRM); end else gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sPath, PO.FileMonMinMB, Po.FileMonLimitMB); end; end else if Po.FileMon.DoEnc then begin if IsUseEncOnlyAIP or gMgSvc.FirstAip then gMgSvc.ThdReact.AddEnt(crtAIP, sPath, Po.FileMonEncDelaySec) else if not NotUseDRM or UseFasooEncrypt then gMgSvc.ThdReact.AddEnt(crtDRM, sPath, Po.FileMonEncDelaySec); end; LogInfo.sPath := sPath; // Action : 1 = Add, 2 = Delete, 3 = Modify, 4 = Rename, 5 = NewName case aRcv.I['Event'] of 5 : LogInfo.sSummary := Format('[Rename] %s', [sPath + ' < Old : ' + aRcv.S['OldName']]); else LogInfo.sSummary := Format('[%s] %s', [GetEventToStr(aRcv.I['Event']), sPath]); end; if aRcv.B['MakeDrm'] then LogInfo.sResInfo := 'DRM'; gMgSvc.SendEventLogEx(@LogInfo, false); if PO.FileMon.IsNoti then gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, Format('%s|%s|%d', [LogInfo.sSummary, sFounds, nTotalHits])); end; end; FILEMON_WRITEBLOCK : begin if PO.IsOldPolicy then begin gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEIO, sResult); if PO.IsOldPolicy or Po.FileBlock.IsNoti then gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, Format('%s|%s|%d', [sPath, sFounds, nTotalHits])); ThdDelFiles_.Push(sPath); end else begin var LogInfo: TLogInfo; ZeroMemory(@LogInfo, SizeOf(LogInfo)); LogInfo.sCode := LOGCODE_PREVENT_FILEIO; if (aRcv.S['SchName'] <> '') and (aRcv.S['FoundSum'] <> '') then begin var OA: ISuperObject := TSuperObject.Create(stArray); var OTemp: ISuperObject; var StrList: TStringList; var RstList: TStringList; var i: Integer; Guard(StrList, TStringList.Create); SplitString(aRcv.S['SchName'], RESULT_SEPARATOR, StrList); Guard(RstList, TStringList.Create); SplitString(aRcv.S['FoundSum'], RESULT_SEPARATOR, RstList); for i := 0 to StrList.Count - 1 do begin OTemp := SO; OTemp.S['RULE_ID'] := StrList[i]; OTemp.S['TEXT'] := RemoveOverlapWords(RstList[i], ';'); OTemp.S['CNT'] := IntToStr(GetCountOverlapWordsCount(GetCountOverlapWords(RstList[i], ';'))); OA.AsArray.Add(OTemp); end; LogInfo.OVio := OA; end; if PO.FileBlock.IsCollectTxt then LogInfo.sBody := sText; if PO.FileBlock.IsCollectFile then begin if GetFileSize_path(sPath) <= (LONGLONG(PO.FileBlkLimitMB) * 1048576) then begin LogInfo.sFileCompId := gMgSvc.MakeComponentId(sPath); gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sPath, PO.FileBlkMinMB, PO.FileBlkLimitMB, crtDelete); end; end else ThdDelFiles_.Push(sPath); LogInfo.sPath := sPath; LogInfo.sSummary := Format('[Create] %s', [sPath]); gMgSvc.SendEventLogEx(@LogInfo); if PO.FileBlock.IsNoti then gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, Format('%s|%s|%d', [LogInfo.sSummary, sFounds, nTotalHits])); end; end; FILEMON_DRM : begin if gMgSvc.IsNewApi then begin var LogInfo: TLogInfo; ZeroMemory(@LogInfo, SizeOf(LogInfo)); LogInfo.sCode := PREVENT_DRM_ENCRYPT; LogInfo.sPath := sPath; LogInfo.sSummary := '[DRM] ' + ExtractFileName(sPath); gMgSvc.SendEventLogEx(@LogInfo, false); end else gMgSvc.SendEventLog(URI_USER_ACTION, PREVENT_DRM_ENCRYPT, sResult); gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEDRMENC, Format('%s|%s|%d', [sPath, sFounds, nTotalHits])); ThdEncFiles_.Push(sPath); end; end; end; begin try case aRcv.Command of KVC_RESPONSE_KEYWORD_SEARCH : process_KVC_RESPONSE_KEYWORD_SEARCH; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. ProcessRcvPacket()'); end; end; end.