BSOne.SFC/eCrmHE/EXE_eCrmHomeEdition/Service/BsKwdSchKvCttSchClient.pas

399 lines
13 KiB
Plaintext

{*******************************************************}
{ }
{ 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 = '<eCrmFormat>%s</eCrmFormat><eCrmClass>%s</eCrmClass>';
{ 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<TCttSchOpt>(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<TAdDocInfo>(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('<eCrmPath>%s</eCrmPath>%s<eCrmBody>%s</eCrmBody>' +
// '<Found>%s</Found><Hits>%d</Hits>', [sPath, sHeader, sText, sFounds, nTotalHits]);
sResult := Format('<eCrmPath>[%s] %s</eCrmPath>%s<eCrmBody>%s</eCrmBody>' +
'<Found>%s</Found><Hits>%d</Hits>',
[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.