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

2216 lines
68 KiB
Plaintext

{*******************************************************}
{ }
{ FileService }
{ }
{ Copyright (C) 2022 kku }
{ }
{*******************************************************}
unit FileService;
interface
uses
Tocsg.Files, System.SysUtils, System.Classes, System.Generics.Collections,
Vcl.Graphics, Tocsg.Thread, ManagerPattern, GlobalDefine, Winapi.Windows,
ManagerModel;
const
IGNORE_MONITOR_EXT = 'inf|cat|db|AMS|dll|trm|xml|trc|DBF|tmp|igpi|$kv|' +
'crdownload|cab|uro|cach|sys';
IGNORE_PATH = '_marked.|_mask.|.rbs|.log|.uro|~$|pdmsa.prop|admsa.prop|uprism\cache|\$RECYCLE.BIN\|' +
// IGNORE_PATH = '_marked.|_mask.|.rbs|.log|.uro|pdmsa.prop|admsa.prop|uprism\cache|\$RECYCLE.BIN\|' +
':\Windows\|:\ProgramData\HE\|:\ProgramData\Tocsg\|:\CubeLog\|\Windows\WER\Temp\|\AppData\Local\Microsoft\Office\Features\|' +
'ks_folder_watcher.txt|\Bs1Backup\'{AdobeReader 실행 시 탐지 발생};
// '\Windows\SoftwareDistribution\Download\';
IGNORE_DEL_PATH = '\Drivers\|\Chrome|\Bs1Backup\|' +
'$WINDOWS|Program Files\|Program Files (x86)\|' + // Tocsg\|_TOCSG|' +
'\Microsoft\Outlook\|ntuser.dat|.cach|.timestamp|\.oracle|' +
'desktop.ini|Visual Studio|.vssettings|\BSD2\|bootmgr.exe|' +
'\Boot\|cisco\|\HDMessenger|\CTILog|ncky.bin|n5tmp.bin|\.eclipse|' +
'\eclipse|org.eclipse|\Rsupport\|\Exosphere|\System Volume|' +
'\KESS\|\MarkAny\|eCrmHome|WinSxS|ProgramData\|store.bin|' +
'Workspace\|AppData\|\Windows\INetCache\';
type
TThdDelFiles = class(TTgThread)
private
qFiles_: TQueue<String>;
protected
procedure Execute; override;
public
Constructor Create;
Destructor Destroy; override;
procedure Clear;
procedure Push(sPath: String);
end;
TWaitEntTask = (wetExtrTxt, wetDoDRM, wetSendFile, wetPopup);
TWaitEntTasks = set of TWaitEntTask;
PWaitEnt = ^TWaitEnt;
TWaitEnt = record
sPath: String;
Tasks: TWaitEntTasks;
LogInfo: TLogInfo;
bBlock,
bIgrDrmBlock: Boolean;
nMinMB,
nLimitMB: Integer;
dwAction: DWORD;
end;
TThdWaitProc = class(TTgThread)
private
qEnts_: TQueue<PWaitEnt>;
FList_: TStringList;
procedure OnNotifyEnt(Sender: TObject; const Item: PWaitEnt; Action: TCollectionNotification);
protected
procedure Execute; override;
public
Constructor Create;
Destructor Destroy; override;
procedure Clear;
function HashPath(sPath: String): Boolean;
procedure Push(pEnt: PWaitEnt; bForce: Boolean = false);
end;
TThdEncFiles = class(TTgThread)
private
qFiles_: TQueue<String>;
sPass_: String;
protected
procedure Execute; override;
public
Constructor Create;
Destructor Destroy; override;
procedure Clear;
procedure Push(sPath: String);
end;
PIgr1PInfo = ^TIgr1PInfo;
TIgr1PInfo = record
dwTick,
dwMilSec: DWORD;
end;
TFileService = class(TTgDirWatchBase)
private
BlkRenameF_,
BlkRenameDF_,
MaskedList_, // 이미 마스킹 처리된 파일들을 일정 시간 반복 처리 하지 않기 위해 사용 22_0511 10:26:12 kku
IgPathList_,
ImgExtList_,
DrmExtList_,
MaskExtList_,
IgMonExtList_,
IgMonDirList_,
IgBlockDirList_,
MonExtList_,
BlockExtList_,
IgDelPathList_: TStringList;
bIsWorking_: Boolean;
MgPtn_: TManagerPattern;
PatternEntList_: TPatternEntList;
dwLangID_: WORD;
ThdDelFiles_: TThdDelFiles;
// ThdEncFiles_: TThdEncFiles;
ThdWaitProc_: TThdWaitProc;
// 수정 로그 2초에 한번 남게 23_1106 14:41:15 kku
dwLastModTick_: DWORD;
sLastModPath_: String;
bBlockRename_,
bPopupRename_: Boolean;
sOldName_,
sIgMonDirs_,
sIgBlockDirs_,
sMonExts_,
sBlockExts_,
sBlkRenameF_,
sBlkRenameDF_,
sBlkFRename_,
sIgrBlkFRename_: String;
UsbList_,
ExpUsbList_,
Igr1PathList_: TStringList;
function IsIgrExt(sPath: String): Boolean;
function IsIgrPath(sPath: String): Boolean;
function IsIgrMonDir(sPath: String): Boolean;
function IsIgrDelPath(sPath: String): Boolean;
procedure ProcessDirWatchEnt(Sender: TObject; pInfo: PDirWatchEnt); override;
public
Constructor Create;
Destructor Destroy; override;
procedure StartService;
procedure StopService;
procedure AddDriveWatch(sDrive: String; bIsUsb: Boolean = false; bExpUsb: Boolean = false);
procedure AddIgr1Path(sPath: String; wAliveSec: WORD = 0);
procedure DelDriveWatch(sDrive: String);
function HasIgr1Path(sPath: String): Boolean;
property IsWorking: Boolean read bIsWorking_;
end;
implementation
uses
Tocsg.Safe, Tocsg.Strings, Tocsg.Path, ManagerService,
superobject, Tocsg.Exception, Condition,
Tocsg.Disk, Tocsg.PCRE, Tocsg.Network, Tocsg.Process,
CttSchDefine, Tocsg.Json, Tocsg.KvFilter.adinfo, Tocsg.DRM.Encrypt,
Tocsg.Encrypt, KDL.Localizer, Tocsg.Packet, BsKwdSchKvCttSchClient,
ManagerCampaign, Tocsg.Trace, Tocsg.Driver, Tocsg.Convert, Tocsg.WTS;
resourcestring
RS_WARNING_MSG = '중요문서 무단 반출 시 법적 제재를 받을수 있으며 모든 출력물은 모니터링 됩니다';
var
PATTERNLIST: array [0..13] of String = (
'\d{2}[01]\d[0123]\d-\d{7}', '\d{2}[01]\d[0123]\d{8}', '\d\d[01]\d[0123]\d-\d{7}',
'\d{2}[01]\d[0123]\d[ ]\d{7}', '\d{2}[01]\d[0123]\d-\d{7}', '\d{2}[01]\d[0123]\d{8}', '\d\d[01]\d[0123]\d-\d{7}',
'\d{2}[01]\d[0123]\d[ ]\d{7}', '[0][1][016789][-) ]\d{3,4}[- ]\d{4}', '\d{2,4}[-) ][0-9]{3,4}[- ][0-9]{4}',
'[a-zA-Z]{1}[0-9a-zA-Z]{1}[0-9]{7}', '([가-힣]{2}(\s|-)?|[가-힣]{2}-?)(\s|-)?\d{2}(\s|-)?\d{6}(\s|-)?\d{2}',
'(?<=[^0-9a-zA-Z])([M|S|R|O|D|m|s|r|o|d][0-9]{8})(?=[^0-9a-zA-Z])',
'(?<=[^0-9a-zA-Z])([a-zA-Z]{2}[0-9]{7})(?=[^0-9a-zA-Z])');
PATTERN_NAME_LIST: array [0..13] of String = ('&SSN&', '&SSN&', '&SSN&', '&SSN&', '&SSN&',
'&SSN&', '&SSN&', '&SSN&', '&mobile&', '&mobile&', '&passport&', '&licenseNumber&',
'&passport&', '&passport&');
KEYWORDLIST: array [0..64] of String = (
'confident', 'confidence', 'disclose', 'secret', 'Antitrust Laws',
'legal', 'unpublish', 'financial', 'trade', 'patent',
'price','pricing', 'authorise', 'insecure','uncontroll'
,'Code of Ethics' ,'Prices', 'Costs','Profits','Offerings of products and services'
,'Terms of sale conditions','sales volume','Production capacity','Market share','Quote decisions'
,'Distribution methodology','Violations','Unauthorized', 'Complaint','Harassment'
,'audit','agency','assembly','industrial', '신뢰',
'공개','비밀', '독점 금지법','반트러스트법', '범죄',
'민감한', '기밀에 관련된', '법률상의', '철회', '금융',
'재정상의', '거래', '특허', '가격', '가격 책정',
'윤리강령', '판매 약관', '시장 점유율', '고객 선택', '판매 영역',
'위반', '무단', '권한이 없는', '희롱', '감사',
'회계감사', 'crime', 'sensitive', 'authorize', 'uncontrol'
);
{ TThdDelFiles }
Constructor TThdDelFiles.Create;
begin
Inherited Create;
qFiles_ := TQueue<String>.Create;
end;
Destructor TThdDelFiles.Destroy;
begin
FreeAndNil(qFiles_);
Inherited;
end;
procedure TThdDelFiles.Push(sPath: String);
begin
Lock;
try
qFiles_.Enqueue(sPath);
finally
Unlock;
end;
end;
procedure TThdDelFiles.Clear;
begin
Lock;
try
qFiles_.Clear;
finally
Unlock;
end;
end;
procedure TThdDelFiles.Execute;
var
sPath: String;
bChkDrm: Boolean;
fs: TFileStream;
LogInfo: TLogInfo;
begin
while not Terminated and not GetWorkStop do
begin
try
if qFiles_.Count = 0 then
begin
Sleep(500);
continue;
end;
Lock;
try
sPath := qFiles_.Dequeue;
finally
Unlock;
end;
if sPath.Length > 0 then
begin
bChkDrm := sPath[1] = '*';
if bChkDrm then
begin
// DRM 적용된거 예외는 로그도 별도 처리해준다... 24_0528 14:56:58 kku
var bBlock: Boolean := true;
var bOpenFail: Boolean := false;
Delete(sPath, 1, 1);
if not FileExists(sPath) then
continue;
try
// DRM 적용된거면 삭제안함 24_0528 14:08:46 kku
Guard(fs, TFileStream.Create(sPath, fmOpenRead));
if TTgEncrypt.CheckSign(fs, SIG_DRM) then
bBlock := false;
except
// 사용중등의 이유로 실패하면 다시 시도하게
Push('*' + sPath);
Sleep(500);
bOpenFail := true;
end;
if bOpenFail then
continue;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
if bBlock then
LogInfo.sCode := LOGCODE_PREVENT_FILEIO
else
LogInfo.sCode := LOGCODE_PREVENT_FILEMONITOR;
LogInfo.sPath := sPath;
LogInfo.sSummary := Format('[Create] %s', [sPath]);
gMgSvc.SendEventLogEx(@LogInfo, bBlock);
if gMgSvc.ModePolicy.FileBlock.IsNoti then
begin
if bBlock then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, LogInfo.sSummary)
else if CUSTOMER_TYPE <> CUSTOMER_SERVE1 then // 서브원은 팝업 안함 24_0711 08:45:55 kku
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, LogInfo.sSummary);
end;
if not bBlock then
continue;
end;
if FileExists(sPath) then
begin
if not DeleteFile(PChar(sPath)) then
begin
Push(sPath);
Sleep(500);
end;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. Execute()')
end;
end;
end;
{ TThdWaitProc }
Constructor TThdWaitProc.Create;
begin
Inherited Create;
FList_ := TStringList.Create;
FList_.CaseSensitive := false;
qEnts_ := TQueue<PWaitEnt>.Create;
end;
Destructor TThdWaitProc.Destroy;
begin
Clear;
FreeAndNil(qEnts_);
FreeAndNil(FList_);
Inherited;
end;
procedure TThdWaitProc.OnNotifyEnt(Sender: TObject; const Item: PWaitEnt; Action: TCollectionNotification);
begin
if Action = cnRemoved then
Dispose(Item);
end;
procedure TThdWaitProc.Clear;
begin
Lock;
try
qEnts_.OnNotify := OnNotifyEnt;
qEnts_.Clear;
FList_.Clear;
finally
qEnts_.OnNotify := nil;
Unlock;
end;
end;
function TThdWaitProc.HashPath(sPath: String): Boolean;
begin
Lock;
try
Result := FList_.IndexOf(sPath) <> -1;
finally
Unlock;
end;
end;
procedure TThdWaitProc.Push(pEnt: PWaitEnt; bForce: Boolean = false);
begin
Lock;
try
if bForce or (FList_.IndexOf(pEnt.sPath) = -1) then
begin
if bForce then
begin
if FList_.IndexOf(pEnt.sPath) = -1 then
FList_.Add(pEnt.sPath);
end;
qEnts_.Enqueue(pEnt);
end;
finally
Unlock;
end;
end;
procedure TThdWaitProc.Execute;
var
pEnt: PWaitEnt;
fs: TFileStream;
n: Integer;
bIsDrm: Boolean;
llSize: LONGLONG;
begin
while not Terminated and not GetWorkStop do
begin
bIsDrm := false;
pEnt := nil;
try
Lock;
try
if qEnts_.Count > 0 then
pEnt := qEnts_.Dequeue;
finally
Unlock;
end;
if pEnt = nil then
begin
Sleep(100);
continue;
end;
if FileExists(pEnt.sPath) then
begin
// if GetFileSize_path(pEnt.sPath) > 5242880 then
// begin
// // 5MB 이상은 원문, 원본 수집 안되도록 보완 24_0725 15:50:15 kku
// Exclude(pEnt.Tasks, wetSendFile);
// Exclude(pEnt.Tasks, wetExtrTxt);
// end;
if (wetExtrTxt in pEnt.Tasks) or
(pEnt.bBlock and pEnt.bIgrDrmBlock) then
begin
try
Guard(fs, TFileStream.Create(pEnt.sPath, fmOpenRead));
bIsDrm := TTgEncrypt.CheckSign(fs, SIG_DRM);
except
Push(pEnt, true);
Sleep(500);
continue;
end;
if not bIsDrm and (wetExtrTxt in pEnt.Tasks) then
pEnt.LogInfo.sBody := ExtrTextFromFile(pEnt.sPath);
Exclude(pEnt.Tasks, wetExtrTxt);
end;
if pEnt.bBlock then
begin
if wetSendFile in pEnt.Tasks then
begin
if bIsDrm then
begin
if pEnt.bIgrDrmBlock then
pEnt.bBlock := false;
end;
end else
if bIsDrm and pEnt.bIgrDrmBlock then
begin
// 삭제 안함
end else
if not DeleteFile(PChar(pEnt.sPath)) then
begin
// 삭제 실패 ?
_Trace('파일 생성 차단 : 삭제 실패 .. Path = "%s"', [pEnt.sPath], 4);
Push(pEnt, true);
continue;
end;
end;
if wetSendFile in pEnt.Tasks then
begin
try
Guard(fs, TFileStream.Create(pEnt.sPath, fmOpenRead));
except
// 사용중 등의 이유로 읽기 실패하면 재시도
_Trace('Fail .. Execute() .. wetSendFile .. 파일을 읽을 수 없습니다, Path=%s', [pEnt.sPath], 1);
Push(pEnt, true);
Sleep(1000);
continue;
end;
llSize := GetFileSize_path(pEnt.sPath);
if (llSize >= (LONGLONG(pEnt.nMinMB) * 1048576)) and (llSize <= (LONGLONG(pEnt.nLimitMB) * 1048576)) then
begin
pEnt.LogInfo.sFileCompId := gMgSvc.MakeComponentId(pEnt.sPath);
if wetDoDRM in pEnt.Tasks then
begin
if IsUseEncOnlyAIP or gMgSvc.FirstAip then
begin
if CUSTOMER_TYPE = CUSTOMER_KDNVN then
gMgSvc.SendFile(pEnt.LogInfo, 'quarantineLogCollect.do', pEnt.sPath, pEnt.nMinMB, pEnt.nLimitMB, crtAIP, BooleanToInt(pEnt.dwAction = 1, 30, 0))
else
gMgSvc.SendFile(pEnt.LogInfo, 'quarantineLogCollect.do', pEnt.sPath, pEnt.nMinMB, pEnt.nLimitMB, crtAIP);
end else
gMgSvc.SendFile(pEnt.LogInfo, 'quarantineLogCollect.do', pEnt.sPath, pEnt.nMinMB, pEnt.nLimitMB, crtDRM);
Exclude(pEnt.Tasks, wetDoDRM);
end else
if pEnt.bBlock then
gMgSvc.SendFile(pEnt.LogInfo, 'quarantineLogCollect.do', pEnt.sPath, pEnt.nMinMB, pEnt.nLimitMB, crtDelete)
else
gMgSvc.SendFile(pEnt.LogInfo, 'quarantineLogCollect.do', pEnt.sPath, pEnt.nMinMB, pEnt.nLimitMB);
end else
if pEnt.bBlock and not DeleteFile(PChar(pEnt.sPath)) then // 크기제한에 걸린거면 바로 삭제 추가 24_0919 15:33:42 kku
begin
// 삭제 실패 ?
_Trace('파일 생성 차단 : 삭제 실패2 .. Path = "%s"', [pEnt.sPath], 4);
Push(pEnt, true);
continue;
end;
Exclude(pEnt.Tasks, wetSendFile);
end;
if wetDoDRM in pEnt.Tasks then
begin
if IsUseEncOnlyAIP or gMgSvc.FirstAip then
gMgSvc.ThdReact.AddEnt(crtAIP, pEnt.sPath, gMgSvc.ModePolicy.FileMonEncDelaySec)
else
gMgSvc.ThdReact.AddEnt(crtDRM, pEnt.sPath, gMgSvc.ModePolicy.FileMonEncDelaySec);
Exclude(pEnt.Tasks, wetDoDRM);
end;
end;
if wetPopup in pEnt.Tasks then
begin
if pEnt.bBlock then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, pEnt.LogInfo.sSummary)
else
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, pEnt.LogInfo.sSummary);
Exclude(pEnt.Tasks, wetPopup);
end;
gMgSvc.SendEventLogEx(@pEnt.LogInfo, pEnt.bBlock);
Lock;
try
n := FList_.IndexOf(pEnt.sPath);
if n <> -1 then
FList_.Delete(n);
finally
Unlock;
end;
Dispose(pEnt);
except
// ..
Sleep(200);
if pEnt <> nil then
Push(pEnt, true);
end;
end;
end;
{ TThdEncFiles }
Constructor TThdEncFiles.Create;
begin
Inherited Create;
qFiles_ := TQueue<String>.Create;
sPass_ := GetMK;
end;
Destructor TThdEncFiles.Destroy;
begin
FreeAndNil(qFiles_);
Inherited;
end;
procedure TThdEncFiles.Push(sPath: String);
begin
Lock;
try
qFiles_.Enqueue(sPath);
finally
Unlock;
end;
end;
procedure TThdEncFiles.Clear;
begin
Lock;
try
qFiles_.Clear;
finally
Unlock;
end;
end;
procedure TThdEncFiles.Execute;
var
sPath,
sTaskDir, sTgEncPath: String;
enc: TTgDrmEnc;
bResult: Boolean;
begin
sTaskDir := 'C:\ProgramData\HE\EncTask\';
while not Terminated and not GetWorkStop do
begin
try
if qFiles_.Count = 0 then
begin
Sleep(500);
continue;
end;
Lock;
try
sPath := qFiles_.Dequeue;
finally
Unlock;
end;
if FileExists(sPath) and ForceDirectories(sTaskDir) then
begin
if TTgEncrypt.CheckSign(sPath, SIG_DRM) then
continue;
sTgEncPath := GetSameFileNameInc(sTaskDir + '$Tmp' + ExtractFileName(sPath));
// if not MoveFile_wait(sPath, sTgEncPath, 3) then
if not CopyFile(PChar(sPath), PChar(sTgEncPath), false) then
begin
Push(sPath);
Sleep(500);
continue;
end;
DeleteFile(PChar(sPath));
SaveStrToFile(sTgEncPath + '.i', sPath, TEncoding.UTF8);
bResult := false;
enc := TTgDrmEnc.Create(sPath);
try
enc.SetHaed(PASS_DRM_HEAD, SIG_DRM, gMgSvc.EmpNo, gMgSvc.UserName, 'none', 'none', CUSTOMER_TYPE);
bResult := enc.EncryptFromFile(sPass_, sTgEncPath);
finally
FreeAndNil(enc);
end;
if bResult then
begin
DeleteFile(PChar(sTgEncPath));
DeleteFile(PChar(sTgEncPath + '.i'));
end else begin
// MoveFile_wait(sTgEncPath, sPath, 3);
if CopyFile(PChar(sTgEncPath), PChar(sPath), false) then
DeleteFile(PChar(sTgEncPath));
DeleteFile(PChar(sTgEncPath + '.i'));
TTgTrace.T('Fail .. TThdEncFiles.EncFile(), Path=%s', [sPath]);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. Execute()')
end;
end;
end;
{ TFileService }
Constructor TFileService.Create;
procedure InitFilter;
var
sTemp: String;
begin
SetFilter(FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_SIZE or FILE_NOTIFY_CHANGE_LAST_WRITE);
SplitString(DOC_EXTS, '|', MaskExtList_);
SplitString(IMAGE_EXTS, '|', ImgExtList_);
sTemp := IGNORE_PATH + '|' + GetRunExePathDir;
case CUSTOMER_TYPE of
CUSTOMER_SANKYO : sTemp := sTemp + '|C:\HIWARE\|C:\HIWARE 6\';
CUSTOMER_CNSCERT : sTemp := sTemp + '|C:\WWNTUSER\';
CUSTOMER_ALADIN : sTemp := sTemp + '|\APPDATA\LOCAL\|\APPDATA\ROAMING\';
end;
SplitString(UpperCase(sTemp), '|', IgPathList_);
SplitString(UpperCase(IGNORE_DEL_PATH), '|', IgDelPathList_);
sTemp := IGNORE_MONITOR_EXT;
case CUSTOMER_TYPE of
CUSTOMER_SANKYO : sTemp := sTemp + '|rbf|rtf|chm';
CUSTOMER_NHL : sTemp := sTemp + '|bmp|xsd|ico|exe';
end;
SplitString(sTemp, '|', IgMonExtList_);
end;
begin
Inherited Create(true, false, true);
bIsWorking_ := false;
sOldName_ := '';
sIgMonDirs_ := '';
sIgBlockDirs_ := '';
sMonExts_ := '';
sBlockExts_ := '';
sBlkRenameF_ := '';
sBlkRenameDF_ := '';
sBlkFRename_ := '';
sIgrBlkFRename_ := '';
bBlockRename_ := false;
bPopupRename_ := false;
DrmExtList_ := TStringList.Create;
DrmExtList_.CaseSensitive := false;
SplitString(DRM_EXTS, '|', DrmExtList_);
MaskExtList_ := TStringList.Create;
MaskExtList_.CaseSensitive := false;
ImgExtList_ := TStringList.Create;
ImgExtList_.CaseSensitive := false;
IgPathList_ := TStringList.Create;
IgPathList_.CaseSensitive := false;
IgDelPathList_ := TStringList.Create;
IgDelPathList_.CaseSensitive := false;
IgMonExtList_ := TStringList.Create;
IgMonExtList_.CaseSensitive := false;
IgMonDirList_ := TStringList.Create;
IgMonDirList_.CaseSensitive := false;
IgBlockDirList_ := TStringList.Create;
IgBlockDirList_.CaseSensitive := false;
MaskedList_ := TStringList.Create;
MaskedList_.CaseSensitive := false;
BlkRenameF_ := TStringList.Create;
BlkRenameDF_ := TStringList.Create;
MonExtList_ := TStringList.Create;
MonExtList_.CaseSensitive := false;
BlockExtList_ := TStringList.Create;
BlockExtList_.CaseSensitive := false;
UsbList_ := TStringList.Create;
UsbList_.CaseSensitive := false;
ExpUsbList_ := TStringList.Create;
ExpUsbList_.CaseSensitive := false;
Igr1PathList_ := TStringList.Create;
Igr1PathList_.CaseSensitive := false;
sLastModPath_ := '';
dwLastModTick_ := 0;
MgPtn_ := TManagerPattern.Create;
PatternEntList_ := TPatternEntList.Create(false);
MgPtn_.GetUsePatternEnt(PatternEntList_);
dwLangID_ := GetSystemDefaultLangID; // todo : 설정된 LangID 가져오기 추가 22_0713 16:18:41 kku
ThdDelFiles_ := TThdDelFiles.Create;
// ThdEncFiles_ := TThdEncFiles.Create;
ThdWaitProc_ := TThdWaitProc.Create;
InitFilter;
end;
Destructor TFileService.Destroy;
begin
StopService;
Inherited;
FreeAndNil(Igr1PathList_);
FreeAndNil(ExpUsbList_);
FreeAndNil(UsbList_);
FreeAndNil(BlkRenameDF_);
FreeAndNil(BlkRenameF_);
FreeAndNil(MaskedList_);
FreeAndNil(BlockExtList_);
FreeAndNil(MonExtList_);
FreeAndNil(IgBlockDirList_);
FreeAndNil(IgMonDirList_);
FreeandNil(IgMonExtList_);
FreeAndNil(IgDelPathList_);
FreeAndNil(IgPathList_);
FreeAndNil(ImgExtList_);
FreeAndNil(MaskExtList_);
FreeAndNil(DrmExtList_);
FreeAndNil(ThdWaitProc_);
// FreeAndNil(ThdEncFiles_);
FreeAndNil(ThdDelFiles_);
FreeAndNil(PatternEntList_);
FreeAndNil(MgPtn_);
end;
procedure TFileService.StartService;
var
dwLogicalDrv: DWORD;
i: Integer;
sDrive: String;
DriveInfo: TDriveInfo;
begin
if not bIsWorking_ then
begin
bIsWorking_ := true;
dwLogicalDrv := GetLogicalDrives;
for i := 0 to 31 do
if (dwLogicalDrv and (1 shl i)) > 0 then
begin
sDrive := Format('%s:\', [Char(Integer('A')+i)]);
if CUSTOMER_TYPE <> CUSTOMER_NHL then
begin
// 불량(?) 디스크 걸러내기
// NHL에서는 이렇게 하면 인식하지 못한다.. 내부 보안모듈 때문인듯 22_0923 11:16:27 kku
// if GetDriveExtent(sDrive).liExtentLength.QuadPart = 0 then
if not DirectoryExists(sDrive) then
continue;
end;
GetDriveDetail(sDrive, @DriveInfo);
AddDriveWatch(sDrive, Pos('USB', UpperCase(DriveInfo.sSerial)) = 1);
// AddDriveWatch(sDrive, GetDriveType(PChar(sDrive)) = DRIVE_REMOVABLE); // 외장 디스크는 "DRIVE_FIXED"로 인식됨 24_0829 11:12:27 kku
end;
ThdDelFiles_.StartThread;
// ThdEncFiles_.StartThread;
ThdWaitProc_.StartThread;
Processor_.StartThread;
end;
end;
procedure TFileService.StopService;
begin
if bIsWorking_ then
begin
bIsWorking_ := false;
ThdDelFiles_.Clear;
ThdDelFiles_.PauseThread;
// ThdEncFiles_.Clear;
// ThdEncFiles_.PauseThread;
ThdWaitProc_.Clear;
ThdWaitProc_.PauseThread;
Processor_.Clear;
Processor_.PauseThread;
ExpUsbList_.Clear;
UsbList_.Clear;
Igr1PathList_.Clear;
sLastModPath_ := '';
dwLastModTick_ := 0;
try
ClearDirWatch;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. StopService()');
end;
end;
end;
procedure TFileService.AddDriveWatch(sDrive: String; bIsUsb: Boolean = false; bExpUsb: Boolean = false);
begin
if sDrive = '' then
exit;
if bIsUsb and (UsbList_.IndexOf(sDrive[1]) = -1) then
UsbList_.Add(sDrive[1]);
if bExpUsb and (ExpUsbList_.IndexOf(sDrive[1]) = -1) then
ExpUsbList_.Add(sDrive[1]);
AddDirWatch(sDrive);
end;
// 1회 감시 무시, DRM 임시 파일등 처리 23_1215 10:12:36 kku
procedure TFileService.AddIgr1Path(sPath: String; wAliveSec: WORD = 0);
var
i: Integer;
pEnt: PIgr1PInfo;
begin
try
Lock;
try
i := Igr1PathList_.IndexOf(sPath);
if i = -1 then
begin
if wAliveSec > 0 then
begin
New(pEnt);
pEnt.dwTick := GetTickCount;
pEnt.dwMilSec := wAliveSec * 1000;
Igr1PathList_.AddObject(sPath, TObject(pEnt));
end else
Igr1PathList_.Add(sPath);
end else begin
if wAliveSec > 0 then
begin
pEnt := PIgr1PInfo(Igr1PathList_.Objects[i]);
if pEnt = nil then
begin
New(pEnt);
Igr1PathList_.Objects[i] := TObject(pEnt);
end;
pEnt.dwTick := GetTickCount;
pEnt.dwMilSec := wAliveSec * 1000;
end;
end;
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. AddIgr1Path()');
end;
end;
procedure TFileService.DelDriveWatch(sDrive: String);
var
n: Integer;
begin
if sDrive = '' then
exit;
n := UsbList_.IndexOf(sDrive[1]);
if n <> -1 then
UsbList_.Delete(n);
n := ExpUsbList_.IndexOf(sDrive[1]);
if n <> -1 then
ExpUsbList_.Delete(n);
DelDirWatch(sDrive);
end;
function TFileService.HasIgr1Path(sPath: String): Boolean;
var
i: Integer;
pEnt: PIgr1PInfo;
dwTick: DWORD;
begin
Result := false;
try
Lock;
try
if Igr1PathList_.Count = 0 then
exit;
dwTick := GetTickCount;
for i := Igr1PathList_.Count - 1 downto 0 do
begin
pEnt := PIgr1PInfo(Igr1PathList_.Objects[i]);
if pEnt <> nil then
begin
if (dwTick - pEnt.dwTick) > pEnt.dwMilSec then
begin
Dispose(pEnt);
Igr1PathList_.Delete(i);
end;
end;
end;
i := Igr1PathList_.IndexOf(sPath);
if i <> -1 then
begin
if Igr1PathList_.Objects[i] = nil then
Igr1PathList_.Delete(i);
Result := true;
end;
finally
Unlock;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. HasIgr1Path()');
end;
end;
function TFileService.IsIgrExt(sPath: String): Boolean;
begin
Result := false;
try
if sPath = '' then
exit;
// USB라면 확장자 예외 무시 24_0722 09:56:01 kku
if (UsbList_.Count > 0) and (UsbList_.IndexOf(sPath[1]) <> -1) then
exit;
Result := IgMonExtList_.IndexOf(GetFileExt(sPath)) <> -1;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsIgrExt()');
end;
end;
function TFileService.IsIgrPath(sPath: String): Boolean;
var
i: Integer;
begin
Result := false;
try
if sPath = '' then
exit;
// USB라면 확장자 예외 무시 24_0722 09:56:01 kku
if (UsbList_.Count > 0) and (UsbList_.IndexOf(sPath[1]) <> -1) then
exit;
sPath := UpperCase(sPath);
for i := 0 to IgPathList_.Count - 1 do
begin
if sPath.Contains(IgPathList_[i]) then
begin
Result := true;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsIgrPath()');
end;
end;
function TFileService.IsIgrMonDir(sPath: String): Boolean;
var
i: Integer;
begin
Result := false;
try
if sPath = '' then
exit;
sPath := UpperCase(sPath);
for i := 0 to IgMonDirList_.Count - 1 do
begin
if sPath.Contains(IgMonDirList_[i].ToUpper) then
begin
Result := true;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsIgrPath()');
end;
end;
function TFileService.IsIgrDelPath(sPath: String): Boolean;
var
i: Integer;
begin
Result := false;
try
if sPath = '' then
exit;
// USB라면 확장자 예외 무시 24_0722 09:56:01 kku
if (UsbList_.Count > 0) and (UsbList_.IndexOf(sPath[1]) <> -1) then
exit;
sPath := UpperCase(sPath);
for i := 0 to IgDelPathList_.Count - 1 do
begin
if sPath.Contains(IgDelPathList_[i]) then
begin
Result := true;
exit;
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. IsIgrDelPath()');
end;
end;
procedure TFileService.ProcessDirWatchEnt(Sender: TObject; pInfo: PDirWatchEnt);
var
PO: TPrefModel;
bFileMonPO,
bFileBlockPO,
bIsCollectTxt,
bIsCollectFile: Boolean;
function CheckIgrFile(sPath: String): Boolean;
var
i: Integer;
begin
Result := true;
sPath := UpperCase(sPath);
if CUSTOMER_TYPE <> CUSTOMER_GEC then
begin
{
if (sExt = 'DOC') or (sExt = 'XLS') or (sExt = 'PPT') or
(sExt = 'DOT') or (sExt = 'PPS') or (sExt = 'POT') then
begin
Result := IsAipEncrytedOldOfficeDoc(sPath, sTempDir);
if not Result then
Result := IsAipEncrytedOfficeDoc(sPath, sTempDir);
end else
if (sExt = 'DOCX') or (sExt = 'XLSX') or (sExt = 'PPTX') or
(sExt = 'DOCM') or (sExt = 'DOTX') or (sExt = 'XLSM') or
(sExt = 'XLSB') then
begin
}
// 별도 처리 추가 (NH 요청) 22_0809 13:58:28 kku
if sPath.Contains('MICROSOFT') then
begin
var sExt: String := GetFileExt(sPath);
if (sExt = 'DOC') or (sExt = 'DOCX') or (sExt = 'RTF') or
(sExt = 'XLS') or (sExt = 'XLSX') or (sExt = 'PPT') or
// 추가 25_0106 13:19:44 kku
(sExt = 'DOT') or (sExt = 'PPS') or (sExt = 'POT') or
(sExt = 'DOCM') or (sExt = 'DOTX') or (sExt = 'XLSM') or
(sExt = 'XLSB') or (sExt = 'PDF') or
(sExt = 'PPTX') or (sExt = 'TXT') then
Exit(true)
else
Exit(false);
end;
end;
if IsIgrDelPath(sPath) then
begin
Result := false;
exit;
end;
end;
function ExtrTxtData(aType: TCttSchTaskType; sSrcPath, sDestPath: String; sAssocInfo: String = ''): Boolean;
var
sExe,
sParam: String;
O: ISuperObject;
Opt: TCttSimpleOpt;
begin
Result := false;
sExe := GetRunExePathDir + EXE_KVCTTSCH;
if not FileExists(sExe) then
exit;
Opt.sSrcPath := sSrcPath;
Opt.sDestPath := sDestPath;
Opt.sAssocInfo := sAssocInfo;
sParam := GetRunExePathDir + '$kvcs.dat';
O := SO;
O.I['CSTT'] := Integer(aType);
O.O['SOpt'] := TTgJson.ValueToJsonObject<TCttSimpleOpt>(Opt);
if SaveJsonObjToFile(O, sParam) then
begin
if ExecuteAppWaitUntilTerminate(sExe, Format('-p "%s"', [sParam]), SW_HIDE, 20000) then
Result := FileExists(sDestPath);
end;
end;
// yhkim 251203 파일 변경 감시/파일 생성 차단 예외 폴더 지정시 예약어 추가
procedure SetReplaceDir(DirList: TStringList);
var
i: Integer;
sCfgDir,
sProfileDir: string;
begin
// sProfileDir := GetEnvironmentVariable('USERPROFILE'); // C:\Users\<계정명>
sProfileDir := WTS_GetActiveUserProfilePath;
if sProfileDir = '' then
sProfileDir := 'C:\Users\' + ExtractFileName(gMgSvc.Domain);
_Trace('SetReplaceDir() .. UserDir=%s', [sProfileDir], 1);
for i := 0 to DirList.Count - 1 do
begin
if (Length(DirList[i]) > 2) and
(DirList[i][1] = '%') and
(DirList[i][Length(DirList[i])] = '%') then
begin
sCfgDir := DirList[i];
if SameText(sCfgDir, '%USERPROFILE%') then
DirList[i] := sProfileDir
else if SameText(sCfgDir, '%Desktop%') then
DirList[i] := sProfileDir + '\Desktop'
else if SameText(sCfgDir, '%Documents%') then
DirList[i] := sProfileDir + '\Documents'
else if SameText(sCfgDir, '%APPDATA%') then
DirList[i] := sProfileDir + '\AppData'
else if SameText(sCfgDir, '%LOCALAPPDATA%') then
DirList[i] := sProfileDir + '\AppData\Local'
else if SameText(sCfgDir, '%TEMP%') then
DirList[i] := sProfileDir + '\AppData\Local\Temp'
else if SameText(sCfgDir, '%Downloads%') then
DirList[i] := sProfileDir + '\Downloads'
else if SameText(sCfgDir, '%Windows%') then
DirList[i] := 'C:\Windows'
else if SameText(sCfgDir, '%ProgramData%') then
DirList[i] := 'C:\ProgramData';
_Trace('SetReplaceDir() .. ChangeDir .. CfgDir=%s, SetDir=%s', [sCfgDir, DirList[i]], 1);
end;
end;
end;
procedure UpdateExtInfo;
begin
if PO.IsOldPolicy then
begin
if sMonExts_ <> PO.FileMonExt then
begin
sMonExts_ := PO.FileMonExt;
SplitString(StringReplace(sMonExts_, '.', '', [rfReplaceAll]), '|', MonExtList_);
SplitString(StringReplace(sMonExts_, '.', '', [rfReplaceAll]), '|', BlockExtList_);
end;
end else begin
if sMonExts_ <> PO.FileMon.sExts then
begin
sMonExts_ := PO.FileMon.sExts;
SplitString(StringReplace(sMonExts_, '.', '', [rfReplaceAll]), '|', MonExtList_);
end;
if sBlockExts_ <> PO.FileBlock.sExts then
begin
sBlockExts_ := PO.FileBlock.sExts;
SplitString(StringReplace(sBlockExts_, '.', '', [rfReplaceAll]), '|', BlockExtList_);
end;
if sIgMonDirs_ <> PO.FileMon.sExceptPath then
begin
sIgMonDirs_ := PO.FileMon.sExceptPath;
SplitString(sIgMonDirs_, '|', IgMonDirList_);
SetReplaceDir(IgMonDirList_);
end;
if sIgBlockDirs_ <> PO.FileBlock.sExceptPath then
begin
sIgBlockDirs_ := PO.FileBlock.sExceptPath;
SplitString(sIgBlockDirs_, '|', IgBlockDirList_);
SetReplaceDir(IgBlockDirList_);
end;
end;
end;
function GetEventToStr: String;
begin
case pInfo.dwAction of
1 : Result := 'Create';
3 : Result := 'Modify';
5 :
begin
// 오피스 파일의 경우 파일 수정 시 "~WND2391.tmp"의 임시 파일을 이름 변경으로 저장한다.. 이를 보정 23_1204 19:41:55 kku
if (sOldName_ <> '') and (sOldName_[1] = '~') and (GetFileExt(sOldName_).ToUpper = 'TMP') then
Result := 'Modify'
else
Result := 'Rename';
end
else Result := Format('Unknown-%d', [pInfo.dwAction]);
end;
end;
{$IFDEF WIN64}
procedure MaskingFromFile(nType: Integer; sSrcPath, sOrgPath: String);
const
DOC_HEADER_FMT = '<eCrmFormat>%s</eCrmFormat><eCrmClass>%s</eCrmClass>';
var
StrList: TStringList;
sData,
sClass, sFormat,
sHeader,
sResult,
sDestPath: String;
i, c: Integer;
DocInfo: TAdDocInfo;
O: ISuperObject;
llSize: LONGLONG;
begin
try
Guard(StrList, TStringList.Create);
sData := ExtractTextSafe(sSrcPath);
if PO.IsOldPolicy then
begin
// 키뷰로 아래한글등 문서내용을 추출 못하는 경우가 있다.
if sData <> '' then
begin
for i := 0 to PatternEntList_.Count - 1 do
begin
if TTgPcre.GetMatchValues(sData, PatternEntList_[i].GetSearchText, sResult) > 0 then
begin
SplitString(sResult, ',', StrList, false, true);
for c := 0 to StrList.Count - 1 do
sData := StringReplace(sData, StrList[c], '&' + PatternEntList_[i].Name + '&', [rfReplaceAll]);
end;
end;
if GetUserDefaultLangID = $412 then
sFormat := '&키워드&'
else
sFormat := '&Keyword&';
for i := Low(KEYWORDLIST) to High(KEYWORDLIST) do
sData := StringReplace(sData, KEYWORDLIST[i], sFormat, [rfReplaceAll]);
StrList.Text := sData;
StrList.SaveToFile(sSrcPath, TEncoding.UTF8);
if sData.Length > 1500 then
SetLength(sData, 1500);
end;
gMgSvc.PopupMessage(nType, sOrgPath);
sDestPath := GetRunExePathDir + 'Task\';
if not ForceDirectories(sDestPath) then
exit;
sDestPath := sDestPath + ExtractFileName(pInfo.sPath) + '.tmp';
try
if not ExtrTxtData(csttExtrDocInfo, sOrgPath, sDestPath) then
exit;
if not LoadJsonObjFromFile(O, sDestPath) then
exit;
if O.O['Info'] = nil then
exit;
finally
if FileExists(sDestPath) then
DeleteFile(PChar(sDestPath));
end;
DocInfo := TTgJson.GetDataAsType<TAdDocInfo>(O.O['Info']);
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] %s</eCrmPath>%s<eCrmBody>%s</eCrmBody>', [GetEventToStr, sOrgPath, sHeader, sData]);
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;
gMgSvc.SendEventLog(URI_USER_ACTION, sHeader, sResult);
end else begin
sDestPath := GetRunExePathDir + 'Task\';
if ForceDirectories(sDestPath) then
begin
sDestPath := sDestPath + ExtractFileName(pInfo.sPath) + '.tmp';
if ExtrTxtData(csttExtrDocInfo, sOrgPath, sDestPath) then
begin
try
if LoadJsonObjFromFile(O, sDestPath) then
begin
DocInfo := TTgJson.GetDataAsType<TAdDocInfo>(O.O['Info']);
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]);
end;
finally
DeleteFile(PChar(sDestPath));
end;
end;
end;
var LogInfo: TLogInfo;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
case nType of
TYPE_MSG_PREVENT_FILECHANGE : LogInfo.sCode := LOGCODE_PREVENT_FILEMONITOR;
TYPE_MSG_PREVENT_FILEMASK : LogInfo.sCode := LOGCODE_PREVENT_FILEMASK;
TYPE_MSG_PREVENT_FILEWRITE : LogInfo.sCode := LOGCODE_PREVENT_FILEIO;
TYPE_MSG_PREVENT_FILEDRMENC : LogInfo.sCode := PREVENT_DRM_ENCRYPT;
end;
if (bFileMonPO and bIsCollectTxt) or
(bFileBlockPO and PO.FileBlock.IsCollectTxt) then
LogInfo.sBody := sData;
if (bFileMonPO and bIsCollectFile) or
(bFileBlockPO and PO.FileBlock.IsCollectFile) then
begin
llSize := GetFileSize_path(sOrgPath);
if (llSize >= (LONGLONG(PO.FileMonMinMB) * 1048576)) and (llSize <= (LONGLONG(PO.FileMonLimitMB) * 1048576)) then
begin
LogInfo.sFileCompId := gMgSvc.MakeComponentId(sOrgPath);
if bFileMonPO and bIsCollectFile and PO.FileMon.DoEnc then
begin
if IsUseEncOnlyAIP or gMgSvc.FirstAip then
gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sOrgPath, PO.FileMonMinMB, PO.FileMonLimitMB, crtAIP, PO.FileMonEncDelaySec)
else
gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sOrgPath, PO.FileMonMinMB, PO.FileMonLimitMB, crtDRM, PO.FileMonEncDelaySec);
end else
if bFileBlockPO and PO.FileBlock.IsCollectFile then
gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sOrgPath, PO.FileMonMinMB, PO.FileBlkLimitMB, crtDelete)
else
gMgSvc.SendFile(LogInfo, 'quarantineLogCollect.do', sOrgPath, PO.FileMonMinMB, PO.FileBlkLimitMB);
end;
end;
LogInfo.sPath := sOrgPath;
// Action : 1 = Add, 2 = Delete, 3 = Modify, 4 = Rename, 5 = NewName
if pInfo.dwAction = 5 then
begin
if (sOldName_ <> '') and (sOldName_[1] = '~') and (GetFileExt(sOldName_).ToUpper = 'TMP') then
LogInfo.sSummary := Format('[Modify] %s', [sOrgPath])
else
LogInfo.sSummary := Format('[Rename] %s', [sOrgPath + ' < Old : ' + sOldName_]);
end else
LogInfo.sSummary := Format('[%s] %s', [GetEventToStr, sOrgPath]);
if bFileMonPO and PO.FileMon.DoEnc and not bIsCollectFile then
begin
if IsUseEncOnlyAIP or gMgSvc.FirstAip then
gMgSvc.ThdReact.AddEnt(crtAIP, sOrgPath, PO.FileMonEncDelaySec)
else
gMgSvc.ThdReact.AddEnt(crtDRM, sOrgPath, PO.FileMonEncDelaySec);
end;
gMgSvc.SendEventLogEx(@LogInfo, LogInfo.sCode = LOGCODE_PREVENT_FILEIO);
if PO.FileMon.IsNoti then
gMgSvc.PopupMessage(nType, LogInfo.sSummary);
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. MaskingFromFile()')
end;
end;
procedure RefineRecentMask;
var
i: Integer;
begin
for i := MaskedList_.Count - 1 downto 0 do
begin
if (GetTickCount - DWORD(MaskedList_.Objects[i])) >= 5000 then
MaskedList_.Delete(i)
end;
end;
function CheckRecentMask(sPath: String): Boolean;
var
i: Integer;
begin
Result := false;
i := MaskedList_.IndexOf(sPath);
if i = -1 then
exit;
Result := (GetTickCount - DWORD(MaskedList_.Objects[i])) < 5000;
end;
{$ENDIF}
var
sExt,
sDir,
sFName,
sIgCheck,
sDestPath: String;
bLoadFail: Boolean;
i, nRetryCnt: Integer;
LogInfo: TLogInfo;
llSize: LONGLONG;
// 파일이 사용중일 수 있다. 1초 간격으로 5번까지 시도해본다.
Label
LB_Retry1, LB_Retry2;
begin
try
sDir := ExtractFilePath(pInfo.sPath);
sFName := ExtractFileName(pInfo.sPath);
sExt := GetFileExt(sFName);
PO := gMgSvc.ModePolicy;
// DRM 임시파일 무시 23_1215 09:55:23 kku
sIgCheck := GetCapsuleStr('#', '_', pInfo.sPath);
if (sIgCheck <> '') and (StrToIntDef(sIgCheck, 0) <> 0) then
exit;
if HasIgr1Path(pInfo.sPath) then
exit;
case pInfo.dwAction of
1, 3 : ; // 추가, 수정, 새이름 아니면 무시
2 : // 삭제
begin
if (PO.FileMon.Kind <> fmkNone) and PO.FileMon.DeleteEvt then
begin
if PO.FileMon.OnlyUSB and
(Length(sDir) > 0) and
(UsbList_.IndexOf(sDir[1]) = -1) then exit;
UpdateExtInfo;
case PO.FileMon.Kind of
fmkNone : bFileMonPO := false;
fmkAll : bFileMonPO := true;
fmkIncExt : bFileMonPO := (MonExtList_.IndexOf(sExt) <> -1) or ((sExt = '') and (MonExtList_.IndexOf('!EXT') <> -1));
fmkIgrExt :
begin
bFileMonPO := MonExtList_.IndexOf(sExt) = -1;
if bFileMonPO and (sExt = '') then
bFileMonPO := MonExtList_.IndexOf('!EXT') = -1;
end;
end;
if bFileMonPO then
begin
if IsIgrPath(pInfo.sPath) then
exit;
// if IsIgrExt(pInfo.sPath) then
// exit;
if IsIgrMonDir(pInfo.sPath) then
exit;
if PO.IsOldPolicy then
begin
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEMONITOR, Format('<eCrmPath>[Delete] %s</eCrmPath>', [pInfo.sPath]));
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, pInfo.sPath);
end else begin
if PO.FileMon.DoEnc and gMgSvc.HasEncIgr(pInfo.sPath) then
exit;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := LOGCODE_PREVENT_FILEMONITOR;
LogInfo.sPath := pInfo.sPath;
LogInfo.sSummary := Format('[Delete] %s', [pInfo.sPath]);
gMgSvc.SendEventLogEx(@LogInfo, false);
if PO.FileMon.IsNoti then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, LogInfo.sSummary);
end;
end;
end;
exit;
end;
4 :
begin
sOldName_ := sFName;
if sIgrBlkFRename_ = sFName then
begin
sIgrBlkFRename_ := '';
exit;
end;
case PO.BlockFRename of
bfrExe : if (sExt = '') or (sExt.ToUpper <> 'EXE') then exit;
bfrNoExe : if (sExt = '') or (sExt.ToUpper = 'EXE') then exit;
end;
var sChkPath: String := UpperCase(sFName);
if PO.BlockFRename <> bfrFalse then
begin
if PO.BlockFRenames <> sBlkRenameF_ then
begin
sBlkRenameF_ := PO.BlockFRenames;
SplitString(UpperCase(sBlkRenameF_), '|', BlkRenameF_);
end;
for i := 0 to BlkRenameF_.Count - 1 do
begin
if Pos(BlkRenameF_[i], sChkPath) > 0 then
begin
sBlkFRename_ := sFName;
case PO.BlockFRename of
bfrAll,
bfrExe,
bfrNoExe : bBlockRename_ := true;
bfrPopup : bPopupRename_ := true;
end;
exit;
end;
end;
end;
sChkPath := UpperCase(pInfo.sPath);
if PO.BlockFdRename <> bdrFalse then
begin
if PO.BlockDirFileRenames <> sBlkRenameDF_ then
begin
sBlkRenameDF_ := PO.BlockDirFileRenames;
SplitString(UpperCase(sBlkRenameDF_), '|', BlkRenameDF_);
end;
for i := 0 to BlkRenameDF_.Count - 1 do
begin
case Pos(BlkRenameDF_[i], sChkPath) of
1, 2:
begin
case PO.BlockFdRename of
bdrAll,
bdrLog : sBlkFRename_ := sFName;
bdrPopup :
begin
sBlkFRename_ := sFName;
bPopupRename_ := true;
end;
bdrThis :
begin
var sChkDir1: String := IncludeTrailingPathDelimiter(BlkRenameDF_[i]);
var sChkDir2: String := ExtractFilePath(sChkPath);
// :\Temp\ 비교를 위해 앞을 하나 잘라줌
if sChkDir1[1] = ':' then
Delete(sChkDir2, 1, 1);
if sChkDir1 = sChkDir2 then
sBlkFRename_ := sFName;
end;
end;
break;
end;
end;
end;
if not bPopupRename_ then
bBlockRename_ := (sBlkFRename_ <> '') and (PO.BlockFdRename <> bdrLog);
end;
exit;
end;
5 :
begin
// 이름 변경 복구 체크
if sBlkFRename_ <> '' then
begin
if bBlockRename_ then
begin
sIgrBlkFRename_ := sFName;
bBlockRename_ := false;
if MoveFile_wait(pInfo.sPath, sDir + sBlkFRename_, 5) then
begin
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILERENAME, sBlkFRename_ + '|' + sFName + '|' + sDir);
gMgSvc.SendEventLog(URI_USER_ACTION, PREVENT_FILERENAME,
Format('[Rename] OrgName : %s, NewName : %s, Path : %s', [sBlkFRename_, sFName, sDir]));
sFName := sBlkFRename_;
pInfo.sPath := sDir + sFName;
end;
end else begin
if bPopupRename_ then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILERENAME, sBlkFRename_ + '|' + sFName + '|' + sDir + '|M');
gMgSvc.SendEventLog(URI_USER_ACTION, MONITOR_FILERENAME,
Format('[Rename] OrgName : %s, NewName : %s, Path : %s', [sBlkFRename_, sFName, sDir]), false);
end;
sBlkFRename_ := '';
bPopupRename_ := false;
end;
end;
else exit;
end;
// 존재하는 파일만 처리
if not FileExists(pInfo.sPath) then
exit;
// 처리 무시 체크
if IsIgrPath(pInfo.sPath) then
exit;
// 원래 삭제 무시 체크 해서 삭제 작업만 구분 하려고 했지만...
// 모든 파일 대상으로 처리 함 22_0504 16:06:35 kku
if not CheckIgrFile(pInfo.sPath) then
exit;
{$IFDEF WIN64}
RefineRecentMask;
{$ENDIF}
UpdateExtInfo;
if PO.IsPreventDownloads then
begin
// 다운로드 폴더 차단 추가
sDestPath := UpperCase(sDir);
if Pos('\DOWNLOADS\', sDestPath) > 0 then
begin
ThdDelFiles_.Push(pInfo.sPath);
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, pInfo.sPath);
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEIO, Format('<eCrmPath>%s</eCrmPath>', [pInfo.sPath]));
exit; // 파일 쓰기 차단 처리 후 탈출
end;
end else
if CUSTOMER_TYPE = CUSTOMER_ALADIN then
begin
sDestPath := UpperCase(sDir);
if Pos('\DOWNLOADS\', sDestPath) > 0 then
exit;
end;
if PO.IsWaterMark then
begin
if ImgExtList_.IndexOf(sExt) <> -1 then
begin
// var sToday: String := FormatDateTime('yyyy-mm-dd hh:nn:ss', Now);
var sWaterTxt: String;
// var sAppend: String := sToday;// + '/' + gMgSvc.EmpNo +'/' + gMgSvc.HandleConfig.UserName;
if IsWatermarkNH then
sWaterTxt := RS_WARNING_MSG
else if IsWatermarkKFTC then
sWaterTxt := gMgSvc.EmpNo + '/' + gMgSvc.HandleConfig.UserName + '/' +
gMgSvc.NicService.GetIP + '/'
else
sWaterTxt := gMgSvc.HandleConfig.UserName + '/' + gMgSvc.NicService.GetIP + '/';
sDestPath := CutFileExt(pInfo.sPath) + '_marked.' + sExt;
if ExtrTxtData(csttWaterMarkImg, pInfo.sPath, sDestPath, sWaterTxt) then
begin
DeleteFile(PChar(pInfo.sPath));
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_WARTERMARK, pInfo.sPath);
if not PO.IsOldPolicy then
begin
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := LOGCODE_PREVENT_WATERMARK;
LogInfo.sPath := pInfo.sPath;
LogInfo.sSummary := 'Water marked : ' + ExtractFileName(pInfo.sPath);
gMgSvc.SendEventLogEx(@LogInfo);
end else
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_WATERMARK, 'Water marked : ' + pInfo.sPath);
end;
exit; // 워터마크 처리 후 탈출
end;
end;
case PO.FileMon.Kind of
fmkNone : bFileMonPO := false;
fmkAll : bFileMonPO := true;
fmkIncExt :
begin
bFileMonPO := (MonExtList_.IndexOf(sExt) <> -1) or ((sExt = '') and (MonExtList_.IndexOf('!EXT') <> -1));
if pInfo.dwAction = 5 then
begin
if not bFileMonPO and PO.FileMon.RenameEvt and (sOldName_ <> '') then
begin
var sOldExt: String := GetFileExt(sOldName_);
bFileMonPO := (MonExtList_.IndexOf(sOldExt) <> -1) or ((sOldExt = '') and (MonExtList_.IndexOf('!EXT') <> -1));
end;
end;
end;
fmkIgrExt :
begin
bFileMonPO := MonExtList_.IndexOf(sExt) = -1;
if bFileMonPO and (sExt = '') then
bFileMonPO := MonExtList_.IndexOf('!EXT') = -1;
if pInfo.dwAction = 5 then
begin
if not bFileMonPO and PO.FileMon.RenameEvt and (sOldName_ <> '') then
begin
var sOldExt: String := GetFileExt(sOldName_);
bFileMonPO := MonExtList_.IndexOf(sOldExt) = -1;
if bFileMonPO and (sOldExt = '') then
bFileMonPO := MonExtList_.IndexOf('!EXT') = -1;
end;
end;
end;
end;
// 파일 변경 감시 - USB 사용시에만 체크
if bFileMonPO and PO.FileMon.OnlyUSB and
(Length(sDir) > 0) and
(UsbList_.IndexOf(sDir[1]) = -1) then bFileMonPO := false;
if bFileMonPO then
begin
if gMgSvc.IsNewApi then
begin
// Action : 1 = Add, 2 = Delete, 3 = Modify, 4 = Rename, 5 = NewName
case pInfo.dwAction of
1 :
begin
bFileMonPO := PO.FileMon.CreateEvt;
if bFileMonPO and PO.FileMon.DoEnc and gMgSvc.HasEncIgr(pInfo.sPath) then
exit;
end;
2 : bFileMonPO := PO.FileMon.DeleteEvt;
3 :
begin
if (sLastModPath_ = pInfo.sPath) and
((GetTickCount - dwLastModTick_) < 1200) then exit;
sLastModPath_ := pInfo.sPath;
dwLastModTick_ := GetTickCount;
bFileMonPO := PO.FileMon.ModifyEvt;
if bFileMonPO and PO.FileMon.DoEnc and gMgSvc.HasEncIgr(pInfo.sPath, true) then
exit;
end;
5 : bFileMonPO := PO.FileMon.RenameEvt;
end;
end;
if bFileMonPO then
begin
if IsIgrMonDir(pInfo.sPath) then
bFileMonPO := false;
if bFileMonPO and (PO.FileMon.Kind = fmkAll) and IsIgrExt(pInfo.sPath) then
bFileMonPO := false;
end;
end;
case PO.FileBlock.Kind of
fmkNone : bFileBlockPO := false;
fmkAll : bFileBlockPO := true;
fmkIncExt : bFileBlockPO := (BlockExtList_.IndexOf(sExt) <> -1) or ((sExt = '') and (BlockExtList_.IndexOf('!EXT') <> -1));
fmkIgrExt :
begin
bFileBlockPO := BlockExtList_.IndexOf(sExt) = -1;
if bFileBlockPO and (sExt = '') then
bFileBlockPO := BlockExtList_.IndexOf('!EXT') = -1;
end;
end;
// 파일 생성 차단 - USB 사용시에만 체크
if bFileBlockPO and PO.FileBlock.OnlyUSB and
(Length(sDir) > 0) and
(UsbList_.IndexOf(sDir[1]) = -1) then bFileBlockPO := false;
bFileBlockPO := bFileBlockPO and (pInfo.dwAction = 1); // 파일 생성 차단으로 기능 변경 23_0811 08:32:06 kku
if bFileBlockPO and (IgBlockDirList_.Count > 0) then
begin
for i := 0 to IgBlockDirList_.Count - 1 do
begin
sIgCheck := UpperCase(pInfo.sPath);
if sIgCheck.Contains(IgBlockDirList_[i].ToUpper) then
begin
bFileBlockPO := false;
break;
end;
end;
end;
// 파일 생성 차단 - 컨텐츠 필터, 파일 변경 감시보다 우선 순위 위
if bFileBlockPO and
PO.FileBlock.ContentFilter.bActive and
(PO.FileBlock.ContentFilter.sPatterns <> '') then
begin
bFileBlockPO := false;
if CheckRecentMask('FileMon:' + pInfo.sPath) then
exit;
MaskedList_.AddObject('FileMon:' + pInfo.sPath, TObject(GetTickCount));
try
if gKvKwdSch <> nil then
begin
var Send: ISendPacket := TTgPacket.Create(KVC_REQUEST_KEYWORD_SEARCH);
Send.S['Path'] := pInfo.sPath;
if gMgSvc.IsNewApi then
Send.S['Ptrn'] := gMgSvc.MgRule.GetRuleSearchStrFromIds(PO.FileBlock.ContentFilter.sPatterns)
else
Send.S['Ptrn'] := PO.FileBlock.ContentFilter.sPatterns;
Send.I['Action'] := FILEMON_WRITEBLOCK;
Send.I['Event'] := pInfo.dwAction;
Send.S['OldName'] := sOldName_;
Send.I['LimitHit'] := PO.FileBlock.ContentFilter.nHitLimit;
gKvKwdSch.SendPacket(Send);
end;
except
// ...
end;
end;
// 파일 변경 감시 - 컨텐츠 필터, 파일 생성 차단보다 우선 순위 아래
if bFileMonPO and
PO.FileMon.ContentFilter.bActive and
(PO.FileMon.ContentFilter.sPatterns <> '') then
begin
bFileMonPO := false;
if CheckRecentMask('FileMon:' + pInfo.sPath) then
exit;
MaskedList_.AddObject('FileMon:' + pInfo.sPath, TObject(GetTickCount));
try
if gKvKwdSch <> nil then
begin
var Send: ISendPacket := TTgPacket.Create(KVC_REQUEST_KEYWORD_SEARCH);
Send.S['Path'] := pInfo.sPath;
if gMgSvc.IsNewApi then
Send.S['Ptrn'] := gMgSvc.MgRule.GetRuleSearchStrFromIds(PO.FileMon.ContentFilter.sPatterns)
else
Send.S['Ptrn'] := PO.FileMon.ContentFilter.sPatterns;
Send.I['Action'] := FILEMON_WRITEMON;
Send.I['Event'] := pInfo.dwAction;
Send.S['OldName'] := sOldName_;
Send.I['LimitHit'] := PO.FileMon.ContentFilter.nHitLimit;
// 사용하지 않음. 나중에 삭제 필요 25_0623 15:52:05 kku
// Send.B['DoEnc'] := ((CUSTOMER_TYPE = CUSTOMER_WELFNI) or (CUSTOMER_TYPE = CUSTOMER_WELFND)) and PO.FileMon.DoEnc;
gKvKwdSch.SendPacket(Send);
end;
except
// ...
end;
end;
// DRM 컨텐츠 필터 적용 추가 23_0424 13:01:52 kku
if PO.DrmCF.bActive and (DrmExtList_.IndexOf(sExt) <> -1) then
begin
if bFileBlockPO then
bFileBlockPO := false; // 쓰기 차단 무시 23_0424 13:04:02 kku
// DRM 열람 시 생성되는 파일 체크해서 거름 23_0424 14:04:33 kku
if (sFName <> '') and (sFName[1] = '#') and (Pos('_', sFName) > 3) then
exit;
if CheckRecentMask('DoDrm:' + pInfo.sPath) then
exit;
MaskedList_.AddObject('DoDrm:' + pInfo.sPath, TObject(GetTickCount));
try
if gKvKwdSch <> nil then
begin
var Send: ISendPacket := TTgPacket.Create(KVC_REQUEST_KEYWORD_SEARCH);
Send.S['Path'] := pInfo.sPath;
Send.S['Ptrn'] := PO.DrmCF.sPatterns;
Send.I['Action'] := FILEMON_DRM;
Send.I['LimitHit'] := PO.DrmCF.nHitLimit;
gKvKwdSch.SendPacket(Send);
end;
except
// ...
end;
end;
if bFileBlockPO and
PO.FileBlock.ContentFilter.bActive and
(PO.FileBlock.ContentFilter.sPatterns <> '') then
begin
bFileBlockPO := false;
if CheckRecentMask('FileBlock:' + pInfo.sPath) then
exit;
MaskedList_.AddObject('FileBlock:' + pInfo.sPath, TObject(GetTickCount));
try
if gKvKwdSch <> nil then
begin
var Send: ISendPacket := TTgPacket.Create(KVC_REQUEST_KEYWORD_SEARCH);
Send.S['Path'] := pInfo.sPath;
Send.S['Ptrn'] := PO.FileBlock.ContentFilter.sPatterns;
Send.I['Action'] := FILEMON_WRITEBLOCK;
Send.I['LimitHit'] := PO.FileBlock.ContentFilter.nHitLimit;
gKvKwdSch.SendPacket(Send);
end;
except
// ...
end;
end;
bIsCollectTxt := PO.FileMon.IsCollectTxt;
if not bIsCollectTxt then
begin
case pInfo.dwAction of
1 : bIsCollectTxt := PO.FmCreateCol.bTxt; // Add
3 : bIsCollectTxt := PO.FmModifyCol.bTxt; // Modify
5 : bIsCollectTxt := PO.fmRenameCol.bTxt; // Rename
end;
end;
bIsCollectFile := PO.FileMon.IsCollectFile;
if not bIsCollectFile then
begin
case pInfo.dwAction of
1 : bIsCollectFile := PO.FmCreateCol.bFile; // Add
3 : bIsCollectFile := PO.FmModifyCol.bFile; // Modify
5 : bIsCollectFile := PO.fmRenameCol.bFile; // Rename
end;
end;
if PO.IsOldPolicy then
begin
// 2.7 이하 서버 대응 처리
if (MaskExtList_.IndexOf(sExt) <> -1) then // 저장 차단 정책 있으면 마스킹 하지 않음 22_0725 12:57:54 kku
begin
try
if CheckRecentMask(pInfo.sPath) then
exit;
MaskedList_.AddObject(pInfo.sPath, TObject(GetTickCount));
// if not PrefModel.IsMasking or (PrefModel.DrmEncKind <> dekNone) then
if not PO.IsMasking then
begin
sDestPath := GetRunExePathDir + 'Task\';
ForceDirectories(sDestPath);
sDestPath := sDestPath + sFName + '.tmp';
end else
sDestPath := CutFileExt(pInfo.sPath) + '_mask.txt';
try
if bFileBlockPO then
begin
// MaskingFromFile(TYPE_MSG_PREVENT_FILEWRITE, sDestPath, pInfo.sPath);
var bBlock: Boolean := true;
// 예외 등록된 USB 장치면 로그만 남도록 24_0528 14:34:14 kku
if PO.FileBlock.OnlyUSB and (pInfo.sPath.Length > 0) and
(ExpUsbList_.IndexOf(pInfo.sPath[1]) <> -1) then
begin
bBlock := false;
end else
if PO.IsDrmAttAbleFB then
begin
// DRM 적용된건 허용할 경우 24_0528 14:05:46 kku
ThdDelFiles_.Push('*' + pInfo.sPath);
exit;
end else
ThdDelFiles_.Push(pInfo.sPath);
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEIO, Format('<eCrmPath>[%s] %s</eCrmPath>', [GetEventToStr, pInfo.sPath]));
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, pInfo.sPath);
end else
if PO.IsMasking then
begin
// ExtrTxtData() 이게 실패해도 아래 암호화등의 처리가 필요 하다 22_1025 15:49:11 kku
ExtrTxtData(csttExtrSimple, pInfo.sPath, sDestPath);
MaskingFromFile(TYPE_MSG_PREVENT_FILEMASK, sDestPath, pInfo.sPath);
ThdDelFiles_.Push(pInfo.sPath);
end else
if bFileMonPO then
begin
if (PO.FileMon.Kind <> fmkAll) or not IsIgrExt(pInfo.sPath) then
begin
// ExtrTxtData() 이게 실패해도 아래 암호화등의 처리가 필요 하다 22_1025 15:49:11 kku
ExtrTxtData(csttExtrSimple, pInfo.sPath, sDestPath);
MaskingFromFile(TYPE_MSG_PREVENT_FILECHANGE, sDestPath, pInfo.sPath);
end;
end;
finally
if FileExists(sDestPath) then
DeleteFile(PChar(sDestPath));
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessMasking..');
end;
end else begin
if bFileBlockPO then
begin
var bBlock: Boolean := true;
// 예외 등록된 USB 장치면 로그만 남도록 24_0528 14:34:14 kku
if PO.FileBlock.OnlyUSB and (pInfo.sPath.Length > 0) and
(ExpUsbList_.IndexOf(pInfo.sPath[1]) <> -1) then
begin
bBlock := false;
end else
if PO.IsDrmAttAbleFB then
begin
// DRM 적용된건 허용할 경우 24_0528 14:05:46 kku
ThdDelFiles_.Push('*' + pInfo.sPath);
exit;
end else
ThdDelFiles_.Push(pInfo.sPath);
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEIO, Format('<eCrmPath>[%s] %s</eCrmPath>', [GetEventToStr, pInfo.sPath]));
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, pInfo.sPath);
end else
if bFileMonPO and ((PO.FileMon.Kind <> fmkAll) or not IsIgrExt(pInfo.sPath)) then
begin
gMgSvc.SendEventLog(URI_USER_ACTION, LOGCODE_PREVENT_FILEMONITOR, Format('<eCrmPath>[%s] %s</eCrmPath>', [GetEventToStr, pInfo.sPath]));
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, pInfo.sPath);
end;
end;
end else begin
////////////////////////////////////////////////////////////////////////////
///
// 2.7 이상 서버 대응 처리
if bFileBlockPO then
begin
var bBlock: Boolean := true;
// 예외 등록된 USB 장치면 로그만 남도록 24_0528 14:34:14 kku
if PO.FileBlock.OnlyUSB and (pInfo.sPath.Length > 0) and
(ExpUsbList_.IndexOf(pInfo.sPath[1]) <> -1) then
begin
bBlock := false;
end;
ZeroMemory(@LogInfo, SizeOf(LogInfo));
if bBlock then
LogInfo.sCode := LOGCODE_PREVENT_FILEIO
else
LogInfo.sCode := LOGCODE_PREVENT_FILEMONITOR;
LogInfo.sPath := pInfo.sPath;
LogInfo.sSummary := Format('[%s] %s', [GetEventToStr, pInfo.sPath]);
if PO.FileBlock.IsCollectTxt or
PO.FileBlock.IsCollectFile then
begin
// 차단 전 수집을 위해 지연 처리 추가 24_0725 15:14:47 kku
var pEnt: PWaitEnt;
New(pEnt);
ZeroMemory(pEnt, SizeOf(TWaitEnt));
pEnt.sPath := pInfo.sPath;
pEnt.LogInfo := LogInfo;
pEnt.bBlock := bBlock;
pEnt.bIgrDrmBlock := PO.IsDrmAttAbleFB;
pEnt.nMinMB := PO.FileBlkMinMB;
pEnt.nLimitMB := PO.FileBlkLimitMB;
pEnt.dwAction := pInfo.dwAction;
if PO.FileBlock.IsCollectTxt then
Include(pEnt.Tasks, wetExtrTxt);
if PO.FileBlock.IsCollectFile then
Include(pEnt.Tasks, wetSendFile);
if PO.FileBlock.IsNoti then
Include(pEnt.Tasks, wetPopup);
ThdWaitProc_.Push(pEnt);
exit;
end else
if bBlock then
begin
if PO.IsDrmAttAbleFB then
begin
// DRM 적용된건 허용할 경우 24_0528 14:05:46 kku
ThdDelFiles_.Push('*' + pInfo.sPath);
exit;
end else
ThdDelFiles_.Push(pInfo.sPath);
end;
gMgSvc.SendEventLogEx(@LogInfo, bBlock);
if PO.FileBlock.IsNoti then
begin
if bBlock then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILEWRITE, LogInfo.sSummary)
else
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, LogInfo.sSummary);
end;
end else
if bFileMonPO then
begin
if CheckRecentMask('FileMon:' + pInfo.sPath) then
exit;
MaskedList_.AddObject('FileMon:' + pInfo.sPath, TObject(GetTickCount));
ZeroMemory(@LogInfo, SizeOf(LogInfo));
LogInfo.sCode := LOGCODE_PREVENT_FILEMONITOR;
LogInfo.sPath := pInfo.sPath;
if pInfo.dwAction = 5 then
LogInfo.sSummary := Format('[Rename] %s', [pInfo.sPath + ' < Old : ' + sOldName_])
else
LogInfo.sSummary := Format('[%s] %s', [GetEventToStr, pInfo.sPath]);
if bIsCollectTxt or bIsCollectFile then
begin
// LogInfo.sBody := ExtrTextFromFile(pInfo.sPath);
// 큰용량 파일의 경우 지연 처리를 위해 추가 24_0725 15:06:13 kku
var pEnt: PWaitEnt;
New(pEnt);
ZeroMemory(pEnt, SizeOf(TWaitEnt));
pEnt.sPath := pInfo.sPath;
pEnt.LogInfo := LogInfo;
pEnt.nMinMB := PO.FileMonMinMB;
pEnt.nLimitMB := PO.FileMonLimitMB;
pEnt.dwAction := pInfo.dwAction;
if bIsCollectTxt then
Include(pEnt.Tasks, wetExtrTxt);
if bIsCollectFile then
Include(pEnt.Tasks, wetSendFile);
if Po.FileMon.DoEnc then
Include(pEnt.Tasks, wetDoDRM);
if PO.FileMon.IsNoti then
Include(pEnt.Tasks, wetPopup);
ThdWaitProc_.Push(pEnt);
exit;
end else
// if bIsCollectFile then // 대용량 파일 생성중 업로드가 안되는 현상 때문에 위 조건으로 합침 25_1126 16:23:52 kku
// begin
// llSize := GetFileSize_path(pInfo.sPath);
// if (llSize >= (LONGLONG(PO.FileMonMinMB) * 1048576)) and (llSize <= (LONGLONG(PO.FileMonLimitMB) * 1048576)) then
// begin
// // 원본 파일 수집
// LogInfo.sFileCompId := gMgSvc.MakeComponentId(pInfo.sPath);
// if PO.FileMon.DoEnc then
// begin
// if IsUseEncOnlyAIP or gMgSvc.FirstAip then
// gMgSvc.SendFile(LogInfo.sFileCompId, 'quarantineLogCollect.do', pInfo.sPath, PO.FileMonMinMB, PO.FileMonLimitMB, crtAIP, PO.FileMonEncDelaySec)
// else
// gMgSvc.SendFile(LogInfo.sFileCompId, 'quarantineLogCollect.do', pInfo.sPath, PO.FileMonMinMB, PO.FileMonLimitMB, crtDRM, PO.FileMonEncDelaySec);
// end else
// gMgSvc.SendFile(LogInfo.sFileCompId, 'quarantineLogCollect.do', pInfo.sPath, PO.FileMonMinMB, PO.FileMonLimitMB);
// end;
// end else
if PO.FileMon.DoEnc then
begin
// [대응] 암호화
if IsUseEncOnlyAIP or gMgSvc.FirstAip then
gMgSvc.ThdReact.AddEnt(crtAIP, pInfo.sPath, PO.FileMonEncDelaySec)
else
gMgSvc.ThdReact.AddEnt(crtDRM, pInfo.sPath, PO.FileMonEncDelaySec);
end;
gMgSvc.SendEventLogEx(@LogInfo, false);
if PO.FileMon.IsNoti then
gMgSvc.PopupMessage(TYPE_MSG_PREVENT_FILECHANGE, LogInfo.sSummary);
end;
end;
except
on E: Exception do
ETgException.TraceException(Self, E, 'Fail .. ProcessDirWatchEntry()')
end;
end;
end.