979 lines
27 KiB
Plaintext
979 lines
27 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ ThdSchFileScan }
|
|
{ }
|
|
{ Copyright (C) 2022 Sunk }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit ThdSchFileScan;
|
|
|
|
interface
|
|
|
|
uses
|
|
{$IFDEF _HE_}
|
|
ManagerModel,
|
|
{$ENDIF}
|
|
Define,
|
|
System.SysUtils, System.Classes, Winapi.Windows, System.SyncObjs,
|
|
System.Generics.Collections, Winapi.Messages, Tocsg.Thread,
|
|
Tocsg.Files, CttSchDefine, Tocsg.Win32;
|
|
|
|
const
|
|
// ProcessSoftcampDRM.pas로 이동 25_0218 14:24:19 kku
|
|
// SIGN_SOFTCAMP_DRM: array [0..13] of Byte =
|
|
// ($53, $43, $44, $53, $41, $30, $30, $34, $00, $00, $52, $00, $20, $88); // SCDSA00 시작됨 // 수정 23_1221 11:02:43 kku
|
|
// ($53, $43, $44, $53, $41, $30, $30, $34, $00, $00, $52, $00, $20, $88, $F1, $53); // SCDSA004 시작됨
|
|
|
|
SIGN_FASOO_DRM: array [0..7] of Byte = ($9B, $20, $44, $52, $4D, $4F, $4E, $45); // > DRMONE 로 시작됨
|
|
|
|
type
|
|
TThdSchFileScan = class(TTgThread)
|
|
protected
|
|
sProcDir_,
|
|
sProcSchFile_: String;
|
|
FileScanOpt_: TFileScanOpt;
|
|
llTotalTgFile_,
|
|
llProcTgFile_,
|
|
llFound_,
|
|
llFoundFile_,
|
|
llTotalDir_,
|
|
llTotalFile_: LONGLONG;
|
|
TgDirList_,
|
|
TgNetDirList_,
|
|
ScanExtList_,
|
|
SvFileList_,
|
|
SvDirList_,
|
|
SvScanList_,
|
|
TestCompList_: TStringList;
|
|
|
|
sWorkDir_: String;
|
|
|
|
dtBegin_: TDateTime;
|
|
|
|
evScanSearchEnd_,
|
|
evScanSearchBegin_: TNotifyEvent;
|
|
|
|
sMtx_: String;
|
|
TaskMutex_: TTgMutex;
|
|
CttSchOpt_: TCttSchOpt;
|
|
hKvCttSch_: HWND;
|
|
KvProcInfo_,
|
|
NtProcInfo_: TProcessInformation;
|
|
dtRecentSch_: TDateTime;
|
|
qSchEnt_,
|
|
qSchNetEnt_: TQueue<String>;
|
|
bSendEvent_: Boolean;
|
|
|
|
bDoNetSch_, // 네트워크 위치 검색 확인
|
|
bIgrFasDrm_, // 파수 DRM 적용된 파일 무시 24_1023 15:28:49 kku
|
|
bIgrScDrm_, // 소캠 DRM 적용된 파일 무시 23_1206 16:53:12 kku
|
|
bIgrAipDrm_, // AIP DRM 적용된 파일 무시 24_0215 10:16:53 kku
|
|
bIgrSizeZero_: Boolean;// 사이즈 0인 파일 무시
|
|
{$IFDEF _HE_}
|
|
CttSchProg_: TCttSchProg;
|
|
dwProgTick_: DWORD;
|
|
sSchTitle_: String;
|
|
bIgrExcept_: Boolean;
|
|
MgCampExcept_: TManagerCampExcept;
|
|
{$ENDIF}
|
|
dtScan_: TDateTime;
|
|
|
|
bProcContinue_: Boolean;
|
|
|
|
procedure ScanSchFiles;
|
|
procedure ScanSchNetFiles;
|
|
procedure Execute; override;
|
|
public
|
|
Constructor Create(sTgDirs: String; aOpt: TFileScanOpt; dtScan: TDateTime; bSendEvent: Boolean = true);
|
|
Destructor Destroy; override;
|
|
|
|
procedure UpdateProgress(sStatus: String; bForce: Boolean = false; sResult: String = 'none');
|
|
|
|
procedure SetKvCttSchHandle(h: HWND);
|
|
function NextSchPath: String;
|
|
procedure AddNetFileEnt(sPath: String);
|
|
procedure IncFoundCount(nHits: Integer);
|
|
procedure IncFoundFileCount;
|
|
procedure IncEncFileCount;
|
|
procedure IncEncFailFileCount;
|
|
procedure IncDelFileCount;
|
|
procedure IncTotalDir(ll: LONGLONG);
|
|
procedure IncTotalFile(ll: LONGLONG);
|
|
|
|
property WorkState: TTgThreadState read GetWorkState;
|
|
property TotalDirCount: LONGLONG read llTotalDir_;
|
|
property TotalFileCount: LONGLONG read llTotalFile_;
|
|
property TotalTgFileCount: LONGLONG read llTotalTgFile_;
|
|
property TotalEncCount: LONGLONG read CttSchProg_.llEncFileCnt;
|
|
property TotalEncFailCount: LONGLONG read CttSchProg_.llEncFailFileCnt;
|
|
property TotalDelCount: LONGLONG read CttSchProg_.llDelFileCnt;
|
|
property ProcTgFileCount: LONGLONG read llProcTgFile_;
|
|
property FoundCount: LONGLONG read llFound_;
|
|
property FoundFileCount: LONGLONG read llFoundFile_;
|
|
property ProcDir: String read sProcDir_;
|
|
property ProcSchFile: String read sProcSchFile_;
|
|
property BeginDT: TDateTime read dtBegin_;
|
|
property OnScanSearchBegin: TNotifyEvent write evScanSearchBegin_;
|
|
property OnScanSearchEnd: TNotifyEvent write evScanSearchEnd_;
|
|
property KvCttSchWnd: HWND read hKvCttSch_;
|
|
property IsSendEvent: Boolean read bSendEvent_;
|
|
property ScanDate: TDateTime read dtScan_;
|
|
property IgrScDrm: Boolean write bIgrScDrm_;
|
|
property IgrFasDrm: Boolean write bIgrFasDrm_;
|
|
property IgrAipDrm: Boolean write bIgrAipDrm_;
|
|
property IgrSizeZero: Boolean write bIgrSizeZero_;
|
|
{$IFDEF _HE_}
|
|
property CttSchProg: TCttSchProg read CttSchProg_;
|
|
property SchTitle: String read sSchTitle_;
|
|
property IgrExcept: Boolean write bIgrExcept_;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF _HE_}
|
|
ManagerService, GlobalDefine, Condition,
|
|
{$ENDIF}
|
|
Tocsg.PCRE, Tocsg.Trace, Tocsg.Exception,
|
|
Tocsg.Strings, Tocsg.Safe, Tocsg.Path, Tocsg.Process, System.DateUtils,
|
|
superobject, Tocsg.Json, Tocsg.WinInfo, Tocsg.DateTime, Tocsg.Convert, Tocsg.FileInfo, DefineHelper, Tocsg.AIP,
|
|
ProcessSoftcampDRM, Tocsg.Registry, Tocsg.Delete;
|
|
|
|
{ TThdSchFileScan }
|
|
|
|
Constructor TThdSchFileScan.Create(sTgDirs: String; aOpt: TFileScanOpt; dtScan: TDateTime; bSendEvent: Boolean = true);
|
|
var
|
|
i: Integer;
|
|
sTemp: String;
|
|
ThdDirWatchEnt: TThdDirWatchEnt;
|
|
begin
|
|
Inherited Create;
|
|
bSendEvent_ := bSendEvent;
|
|
hKvCttSch_ := 0;
|
|
bDoNetSch_ := false;
|
|
bIgrScDrm_ := false;
|
|
bIgrFasDrm_ := false;
|
|
bIgrAipDrm_ := false;
|
|
bIgrSizeZero_ := true;
|
|
WorkState_ := tsInit;
|
|
{$IFDEF _HE_}
|
|
bIgrExcept_ := false;
|
|
ZeroMemory(@CttSchProg_, SizeOf(CttSchProg_));
|
|
dwProgTick_ := 0;
|
|
if aOpt.bShowSchTitle then
|
|
sSchTitle_ := aOpt.sSchTitle
|
|
else
|
|
sSchTitle_ := '';
|
|
MgCampExcept_ := nil;
|
|
{$ENDIF}
|
|
if dtScan <> 0 then
|
|
dtScan_ := dtScan
|
|
else
|
|
dtScan_ := Now;
|
|
|
|
bProcContinue_ := false;
|
|
|
|
TgDirList_ := TStringList.Create;
|
|
SplitString(sTgDirs, '|', TgDirList_);
|
|
|
|
TgNetDirList_ := TStringList.Create;
|
|
for i := TgDirList_.Count - 1 downto 0 do
|
|
begin
|
|
sTemp := TgDirList_[i];
|
|
if TgDirList_[i].StartsWith('@') or TgDirList_[i].StartsWith('\\') then
|
|
begin
|
|
TgDirList_.Delete(i);
|
|
if sTemp[1] = '@' then
|
|
Delete(sTemp, 1, 1);
|
|
TgNetDirList_.Add(sTemp);
|
|
end;
|
|
end;
|
|
|
|
FileScanOpt_ := aOpt;
|
|
case FileScanOpt_.CttSchOpt.nWorkPriority of
|
|
0 : Priority := tpHighest;
|
|
1 : Priority := tpHigher;
|
|
// 2 : Priority := tpNormal;
|
|
3 : Priority := tpLower;
|
|
4 : Priority := tpLowest;
|
|
else Priority := tpNormal;
|
|
end;
|
|
|
|
llFound_ := 0;
|
|
llFoundFile_ := 0;
|
|
llTotalTgFile_ := 0;
|
|
llProcTgFile_ := 0;
|
|
llTotalDir_ := 0;
|
|
llTotalFile_ := 0;
|
|
sProcSchFile_ := '';
|
|
|
|
ScanExtList_ := TStringList.Create;
|
|
ScanExtList_.CaseSensitive := false;
|
|
SplitString(FileScanOpt_.sScanExt, '|', ScanExtList_);
|
|
|
|
@evScanSearchEnd_ := nil;
|
|
@evScanSearchBegin_ := nil;
|
|
|
|
SvFileList_ := nil;
|
|
SvDirList_ := nil;
|
|
SvScanList_ := nil;
|
|
if FileScanOpt_.bSaveFileList then
|
|
SvFileList_ := TStringList.Create;
|
|
if FileScanOpt_.bSaveDirList then
|
|
SvDirList_ := TStringList.Create;
|
|
if FileScanOpt_.bSaveScanList then
|
|
SvScanList_ := TStringList.Create;
|
|
TestCompList_ := TStringList.Create;
|
|
|
|
sMtx_ := 'Global\TaskKvCttSch@' + FormatDateTime('yyyymmddhhnnss', Now);
|
|
TaskMutex_ := TTgMutex.Create(sMtx_);
|
|
|
|
CttSchOpt_ := FileScanOpt_.CttSchOpt;
|
|
hKvCttSch_ := 0;
|
|
dtRecentSch_ := 0;
|
|
qSchEnt_ := TQueue<String>.Create;
|
|
qSchNetEnt_ := TQueue<String>.Create;
|
|
ZeroMemory(@KvProcInfo_, SizeOf(KvProcInfo_));
|
|
ZeroMemory(@NtProcInfo_, SizeOf(NtProcInfo_));
|
|
|
|
dtBegin_ := Now;
|
|
StartThread;
|
|
end;
|
|
|
|
Destructor TThdSchFileScan.Destroy;
|
|
begin
|
|
if KvProcInfo_.dwProcessId <> 0 then
|
|
begin
|
|
TerminateProcessByPid(KvProcInfo_.dwProcessId);
|
|
KvProcInfo_.dwProcessId := 0;
|
|
end;
|
|
|
|
if NtProcInfo_.dwProcessId <> 0 then
|
|
begin
|
|
TerminateProcessByPid(NtProcInfo_.dwProcessId);
|
|
NtProcInfo_.dwProcessId := 0;
|
|
end;
|
|
|
|
{$IFDEF _HE_}
|
|
if MgCampExcept_ <> nil then
|
|
FreeAndNil(MgCampExcept_);
|
|
{$ENDIF}
|
|
|
|
FreeAndNil(qSchNetEnt_);
|
|
FreeAndNIl(qSchEnt_);
|
|
FreeAndNil(ScanExtList_);
|
|
if SvFileList_ <> nil then
|
|
FreeAndNil(SvFileList_);
|
|
if SvDirList_ <> nil then
|
|
FreeAndNil(SvDirList_);
|
|
if SvScanList_ <> nil then
|
|
FreeAndNil(SvScanList_);
|
|
FreeAndNil(TestCompList_);
|
|
FreeAndNil(TgNetDirList_);
|
|
FreeAndNil(TgDirList_);
|
|
FreeAndNil(TaskMutex_);
|
|
Inherited;
|
|
end;
|
|
|
|
procedure TThdSchFileScan.ScanSchFiles;
|
|
var
|
|
sTgDir: String;
|
|
IgrWordPaths: TStringList;
|
|
i: Integer;
|
|
llLimitSize: LONGLONG;
|
|
|
|
procedure ExtractFiles(sDir: String);
|
|
var
|
|
wfd: TWin32FindData;
|
|
hSc: THandle;
|
|
sExt,
|
|
sFName,
|
|
sPath: String;
|
|
dtCreate,
|
|
dtModify: TDateTime;
|
|
llSize: LONGLONG;
|
|
begin
|
|
try
|
|
if not DirectoryExists(sDir) then
|
|
exit;
|
|
|
|
sDir := IncludeTrailingPathDelimiter(sDir);
|
|
|
|
if IgrWordPaths.Count > 0 then
|
|
begin
|
|
var i: Integer;
|
|
sPath := UpperCase(sDir);
|
|
for i := 0 to IgrWordPaths.Count - 1 do
|
|
begin
|
|
if Pos(IgrWordPaths[i], sPath) > 0 then
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
if SvDirList_ <> nil then
|
|
SvDirList_.Add(sDir);
|
|
|
|
sPath := sDir + '*.*';
|
|
hSc := FindFirstFile(PChar(sPath), wfd);
|
|
if hSc = INVALID_HANDLE_VALUE then
|
|
exit;
|
|
|
|
try
|
|
Repeat
|
|
if GetWorkStop or Terminated then
|
|
begin
|
|
SetWorkState(tsStop);
|
|
exit;
|
|
end;
|
|
|
|
if (String(wfd.cFileName) <> '.') and (String(wfd.cFileName) <> '..') then
|
|
begin
|
|
sFName := UpperCase(wfd.cFileName);
|
|
sPath := sDir + wfd.cFileName;
|
|
if ((wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) then
|
|
begin
|
|
Inc(llTotalDir_);
|
|
|
|
// \application data\ 등 junction 속성 경로가 있으면 무시해야함..
|
|
// 시스템 권한으로 돌리면 해당 경로로 정크된 경로까지 따라 들어감 24_0226 14:32:14 kku
|
|
if (wfd.dwFileAttributes and FILE_ATTRIBUTE_REPARSE_POINT) = 0 then
|
|
ExtractFiles(sPath);
|
|
end else begin
|
|
Inc(llTotalFile_);
|
|
|
|
if SvFileList_ <> nil then
|
|
SvFileList_.Add(sPath);
|
|
|
|
if Pos('~$', sFName) = 1 then
|
|
continue;
|
|
|
|
if Pos('POWERSHELL_TRANSCRIPT', sFName) = 1 then
|
|
continue;
|
|
|
|
sExt := GetFileExt(sPath).ToLower;
|
|
if (sExt <> '$KV') and (ScanExtList_.IndexOf(sExt) <> -1) then
|
|
begin
|
|
if FileScanOpt_.bPartScan and (FileScanOpt_.dtRecent <> 0) then
|
|
begin
|
|
dtCreate := ConvFileTimeToDateTime_Local(wfd.ftCreationTime);
|
|
dtModify := ConvFileTimeToDateTime_Local(wfd.ftLastWriteTime);
|
|
|
|
if (CompareDateTime(FileScanOpt_.dtRecent, dtCreate) <> -1) and
|
|
(CompareDateTime(FileScanOpt_.dtRecent, dtModify) <> -1) then
|
|
continue;
|
|
end;
|
|
|
|
llSize := GetFileSizeHiLow(wfd.nFileSizeHigh, wfd.nFileSizeLow);
|
|
if (llSize = 0) and bIgrSizeZero_ then
|
|
continue;
|
|
|
|
if (llLimitSize > 0) and (llSize >= llLimitSize) then
|
|
continue;
|
|
|
|
// 소캠 파일 거르기 23_1031 12:30:45 kku
|
|
if bIgrScDrm_ then
|
|
begin
|
|
if CheckSign(sPath, @SIGN_SOFTCAMP_DRM[0], Length(SIGN_SOFTCAMP_DRM)) then
|
|
begin
|
|
// Inc(CttSchProg_.llEncFileCnt);
|
|
continue;
|
|
end;
|
|
end;
|
|
|
|
// 파수 파일 거르기 24_1023 15:29:22 kku
|
|
if bIgrFasDrm_ then
|
|
begin
|
|
if CheckSign(sPath, @SIGN_FASOO_DRM[0], 8) then
|
|
begin
|
|
// Inc(CttSchProg_.llEncFileCnt);
|
|
continue;
|
|
end;
|
|
end;
|
|
|
|
if bIgrAipDrm_ then
|
|
begin
|
|
// if Pos('대외비', GetAipLabel(sPath)) > 0 then
|
|
if IsAipEncryted(sPath) then
|
|
continue;
|
|
end;
|
|
|
|
// 예외 거르기 23_1227 12:58:55 kku
|
|
if (MgCampExcept_ <> nil) and MgCampExcept_.IsExceptFile(sPath) then
|
|
continue;
|
|
|
|
qSchEnt_.Enqueue(sPath);
|
|
Inc(llTotalTgFile_);
|
|
|
|
if SvScanList_ <> nil then
|
|
SvScanList_.Add(sPath);
|
|
end;
|
|
end;
|
|
end;
|
|
Until not FindNextFile(hSc, wfd);
|
|
finally
|
|
WinApi.Windows.FindClose(hSc);
|
|
end;
|
|
except
|
|
// ..
|
|
end;
|
|
end;
|
|
|
|
begin
|
|
llLimitSize := LONGLONG(FileScanOpt_.nLimitSizeMB) * 1048576;
|
|
Guard(IgrWordPaths, TStringList.Create);
|
|
SplitString(UpperCase(FileScanOpt_.sIgrWordPath), '|', IgrWordPaths);
|
|
try
|
|
SetWorkState(tsWorking);
|
|
for i := 0 to TgDirList_.Count - 1 do
|
|
begin
|
|
if GetWorkStop or Terminated then
|
|
begin
|
|
SetWorkState(tsStop);
|
|
exit;
|
|
end;
|
|
|
|
sProcDir_ := '?:\';
|
|
sTgDir := TgDirList_[i];
|
|
if not DirectoryExists(sTgDir) then
|
|
continue;
|
|
sProcDir_ := sTgDir;
|
|
|
|
// 대상 파일 스캔
|
|
ExtractFiles(sTgDir);
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
ETgException.TraceException(Self, E, 'Fail .. ScanSchFiles()');
|
|
SetWorkState(tsFail);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TThdSchFileScan.ScanSchNetFiles;
|
|
var
|
|
sHpExe, sParam: String;
|
|
|
|
procedure CreateProcessNetScan;
|
|
var
|
|
hProcess: THandle;
|
|
O: ISuperObject;
|
|
begin
|
|
{$IFDEF _HE_}
|
|
if MutexExists(MUTEX_KILL) then
|
|
begin
|
|
SetWorkStop(true);
|
|
exit;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
if not FileExists(sHpExe) then
|
|
exit;
|
|
|
|
try
|
|
if NtProcInfo_.dwProcessId <> 0 then
|
|
TerminateProcessByPid(NtProcInfo_.dwProcessId);
|
|
ZeroMemory(@NtProcInfo_, SizeOf(NtProcInfo_));
|
|
|
|
O := SO;
|
|
O.I['Cmd'] := HPCMD_REQ_NETDIR_SCAN;
|
|
O.S['Mtx'] := sMtx_;
|
|
O.I['Tasker'] := ULONGLONG(Self);
|
|
O.O['FOpt'] := TTgJson.ValueToJsonObject<TFileScanOpt>(FileScanOpt_);
|
|
O.I['CT'] := CUSTOMER_TYPE;
|
|
O.S['TgNDir'] := sProcDir_;
|
|
|
|
if SaveJsonObjToFile(O, sParam) then
|
|
begin
|
|
{$IFDEF DEBUG}
|
|
NtProcInfo_ := ExecuteApp(sHpExe, Format('/p "%s"', [sParam]), SW_SHOWNORMAL);
|
|
{$ELSE}
|
|
NtProcInfo_ := ExecuteAppAsUser('explorer.exe', sHpExe, Format('/p "%s"', [sParam]), SW_SHOWNORMAL);
|
|
{$ENDIF}
|
|
if NtProcInfo_.dwProcessId = 0 then
|
|
begin
|
|
{$IFDEF DEBUG}
|
|
ASSERT(false);
|
|
{$ELSE}
|
|
_Trace('Fail .. CreateProcessNetScan() .. ExecuteApp()');
|
|
{$ENDIF}
|
|
end;
|
|
end else
|
|
_Trace('Fail .. CreateProcessNetScan() .. SaveJsonObjToFile()');
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. CreateProcessNetScan()');
|
|
end;
|
|
end;
|
|
|
|
var
|
|
i: Integer;
|
|
dwRst: DWORD;
|
|
begin
|
|
if GetWorkState <> tsWorking then
|
|
exit;
|
|
|
|
try
|
|
sHpExe := GetRunExePathDir + DIR_CONF + EXE_HP;
|
|
if not FileExists(sHpExe) then
|
|
exit;
|
|
|
|
sParam := GetRunExePathDir + '$NetSchOpt.dat';
|
|
for i := TgNetDirList_.Count - 1 downto 0 do
|
|
begin
|
|
sProcDir_ := TgNetDirList_[i];
|
|
|
|
CreateProcessNetScan;
|
|
while not Terminated and not GetWorkStop do
|
|
begin
|
|
dwRst := WaitForSingleObject(NtProcInfo_.hProcess, 50);
|
|
if dwRst <> WAIT_TIMEOUT then
|
|
break;
|
|
|
|
// 타임아웃
|
|
// if (nTimeOutMilSec > 0) and ((GetTickCount - dwExecuteTick) > nTimeOutMilSec) then
|
|
// begin
|
|
// TerminateProcess(PI.hProcess, 999);
|
|
// exit;
|
|
// end;
|
|
end;
|
|
|
|
if Terminated or GetWorkStop then
|
|
begin
|
|
if NtProcInfo_.hProcess <> 0 then
|
|
TerminateProcess(NtProcInfo_.hProcess, 999);
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
DeleteFile(PChar(sParam));
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
ETgException.TraceException(Self, E, 'Fail .. ScanSchNetFiles()');
|
|
SetWorkState(tsFail);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TThdSchFileScan.SetKvCttSchHandle(h: HWND);
|
|
begin
|
|
hKvCttSch_ := h;
|
|
end;
|
|
|
|
function TThdSchFileScan.NextSchPath: String;
|
|
begin
|
|
Lock;
|
|
try
|
|
if qSchEnt_.Count > 0 then
|
|
begin
|
|
if not bProcContinue_ then
|
|
begin
|
|
bProcContinue_ := true;
|
|
var sInfo: String := GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'cppn');
|
|
if sInfo <> '' then
|
|
begin
|
|
var InfoList: TStringList;
|
|
Guard(InfoList, TStringList.Create);
|
|
SplitString(sInfo, ':', InfoList, true);
|
|
|
|
if InfoList.Count > 4 then
|
|
begin
|
|
var nIdx: Integer := StrToIntDef(InfoList[0], 0);
|
|
llFoundFile_ := StrToIntDef(InfoList[1], 0);
|
|
CttSchProg_.llFound := llFoundFile_;
|
|
CttSchProg_.llEncFileCnt := StrToIntDef(InfoList[2], 0);
|
|
CttSchProg_.llEncFailFileCnt := StrToIntDef(InfoList[3], 0);
|
|
CttSchProg_.llDelFileCnt := StrToIntDef(InfoList[4], 0);
|
|
|
|
var nCnt: Integer := qSchEnt_.Count;
|
|
if nCnt > nIdx then
|
|
begin
|
|
while llProcTgFile_ < nIdx do
|
|
begin
|
|
Result := qSchEnt_.Dequeue;
|
|
sProcSchFile_ := Result;
|
|
dtRecentSch_ := Now;
|
|
Inc(llProcTgFile_);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
Result := qSchEnt_.Dequeue;
|
|
sProcSchFile_ := Result;
|
|
dtRecentSch_ := Now;
|
|
Inc(llProcTgFile_);
|
|
end else
|
|
if qSchNetEnt_.Count > 0 then
|
|
begin
|
|
if not bProcContinue_ then
|
|
begin
|
|
bProcContinue_ := true;
|
|
var sInfo: String := GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'cppn');
|
|
if sInfo <> '' then
|
|
begin
|
|
var InfoList: TStringList;
|
|
Guard(InfoList, TStringList.Create);
|
|
SplitString(sInfo, ':', InfoList, true);
|
|
|
|
if InfoList.Count > 4 then
|
|
begin
|
|
var nIdx: Integer := StrToIntDef(InfoList[0], 0);
|
|
llFoundFile_ := StrToIntDef(InfoList[1], 0);
|
|
CttSchProg_.llFound := llFoundFile_;
|
|
CttSchProg_.llEncFileCnt := StrToIntDef(InfoList[2], 0);
|
|
CttSchProg_.llEncFailFileCnt := StrToIntDef(InfoList[3], 0);
|
|
CttSchProg_.llDelFileCnt := StrToIntDef(InfoList[4], 0);
|
|
|
|
var nCnt: Integer := qSchNetEnt_.Count;
|
|
if nCnt > nIdx then
|
|
begin
|
|
while llProcTgFile_ < nIdx do
|
|
begin
|
|
Result := qSchNetEnt_.Dequeue;
|
|
sProcSchFile_ := Result;
|
|
dtRecentSch_ := Now;
|
|
Inc(llProcTgFile_);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if not bDoNetSch_ then
|
|
begin
|
|
bDoNetSch_ := true;
|
|
if KvProcInfo_.dwProcessId <> 0 then
|
|
TerminateProcessByPid(KvProcInfo_.dwProcessId);
|
|
ZeroMemory(@KvProcInfo_, SizeOf(KvProcInfo_));
|
|
exit;
|
|
end;
|
|
|
|
Result := qSchNetEnt_.Dequeue;
|
|
sProcSchFile_ := Result;
|
|
dtRecentSch_ := Now;
|
|
Inc(llProcTgFile_);
|
|
|
|
// _Trace('NextSchPath - NetPath = %s', [Result], 1);
|
|
end else
|
|
Result := '';
|
|
finally
|
|
Unlock;
|
|
end;
|
|
|
|
{$IFDEF _HE_}
|
|
// 부하 때문에 전송하지 않도록 함 (HEC에서 부하 확인) 24_0919 14:39:34 kku
|
|
// if gMgSvc.IsNewApi then
|
|
// UpdateProgress('PROGRESS')
|
|
// else
|
|
// UpdateProgress('progress');
|
|
{$ENDIF}
|
|
|
|
if Result = '' then
|
|
begin
|
|
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cppn');
|
|
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cptd');
|
|
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cpid');
|
|
|
|
SetWorkState(tsCompleted);
|
|
SetWorkStop(true);
|
|
end else
|
|
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'cppn', Format('%d:%d:%d:%d:%d',
|
|
[llProcTgFile_, llFoundFile_, CttSchProg_.llEncFileCnt, CttSchProg_.llEncFailFileCnt, CttSchProg_.llDelFileCnt]), true);
|
|
end;
|
|
|
|
procedure TThdSchFileScan.AddNetFileEnt(sPath: String);
|
|
begin
|
|
if (MgCampExcept_ <> nil) and MgCampExcept_.IsExceptFile(sPath) then
|
|
exit;
|
|
|
|
qSchNetEnt_.Enqueue(sPath);
|
|
Inc(llTotalTgFile_);
|
|
end;
|
|
|
|
procedure TThdSchFileScan.IncFoundCount(nHits: Integer);
|
|
begin
|
|
Inc(llFound_, nHits);
|
|
end;
|
|
|
|
procedure TThdSchFileScan.IncFoundFileCount;
|
|
begin
|
|
Inc(llFoundFile_);
|
|
end;
|
|
|
|
procedure TThdSchFileScan.IncEncFileCount;
|
|
begin
|
|
{$IFDEF _HE_}
|
|
Inc(CttSchProg_.llEncFileCnt);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TThdSchFileScan.IncEncFailFileCount;
|
|
begin
|
|
{$IFDEF _HE_}
|
|
Inc(CttSchProg_.llEncFailFileCnt);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TThdSchFileScan.IncDelFileCount;
|
|
begin
|
|
{$IFDEF _HE_}
|
|
Inc(CttSchProg_.llDelFileCnt);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TThdSchFileScan.IncTotalDir(ll: LONGLONG);
|
|
begin
|
|
Inc(llTotalDir_, ll);
|
|
end;
|
|
|
|
procedure TThdSchFileScan.IncTotalFile(ll: LONGLONG);
|
|
begin
|
|
Inc(llTotalFile_, ll);
|
|
end;
|
|
|
|
procedure TThdSchFileScan.UpdateProgress(sStatus: String; bForce: Boolean = false; sResult: String = 'none');
|
|
begin
|
|
{$IFDEF _HE_}
|
|
if CttSchProg_.sScanId <> '' then
|
|
begin
|
|
var dwTick: DWORD := GetTickCount;
|
|
if bForce or ((dwTick - dwProgTick_) > 10000) then
|
|
begin
|
|
dwProgTick_ := dwTick;
|
|
|
|
CttSchProg_.llProc := llProcTgFile_;
|
|
CttSchProg_.llTotal := llTotalTgFile_;
|
|
CttSchProg_.llFound := llFoundFile_;
|
|
CttSchProg_.sResult := sResult;
|
|
CttSchProg_.sStatus := sStatus;
|
|
if bSendEvent_ then
|
|
begin
|
|
if gMgSvc.IsNewApi then
|
|
gMgSvc.SendCampnProgInfo(CttSchProg_)
|
|
else
|
|
gMgSvc.SendCttSchProgInfo(CttSchProg_);
|
|
end;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
end;
|
|
|
|
procedure TThdSchFileScan.Execute;
|
|
var
|
|
sComName,
|
|
sKvCsPath: String;
|
|
|
|
procedure CreateProcessKV;
|
|
var
|
|
hProcess: THandle;
|
|
O: ISuperObject;
|
|
sParam: String;
|
|
begin
|
|
{$IFDEF _HE_}
|
|
if MutexExists(MUTEX_KILL) then
|
|
begin
|
|
SetWorkStop(true);
|
|
exit;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
if not FileExists(sKvCsPath) then
|
|
exit;
|
|
|
|
try
|
|
if KvProcInfo_.dwProcessId <> 0 then
|
|
begin
|
|
TerminateProcessByPid(KvProcInfo_.dwProcessId);
|
|
DeleteDir(sWorkDir_);
|
|
end;
|
|
|
|
if not ForceDirectories(sWorkDir_) then
|
|
begin
|
|
_Trace('Fail .. CreateWorkDir()');
|
|
SetWorkState(tsFail);
|
|
exit;
|
|
end;
|
|
|
|
ZeroMemory(@KvProcInfo_, SizeOf(KvProcInfo_));
|
|
hKvCttSch_ := 0;
|
|
dtRecentSch_ := 0;
|
|
|
|
O := SO;
|
|
O.I['CSTT'] := Integer(csttSchMulti);
|
|
O.S['Mtx'] := sMtx_;
|
|
O.I['Tasker'] := ULONGLONG(Self);
|
|
if FileScanOpt_.nLangId <> 0 then
|
|
O.I['LangID'] := FileScanOpt_.nLangId;
|
|
if FileScanOpt_.sSchPtrns <> '' then
|
|
O.S['SchPtrns'] := FileScanOpt_.sSchPtrns;
|
|
if bDoNetSch_ then
|
|
CttSchOpt_.sTaskDir := sKvCsPath[1] + ':\ProgramData\HE\STask\';
|
|
O.O['Opt'] := TTgJson.ValueToJsonObject<TCttSchOpt>(CttSchOpt_);
|
|
O.I['CT'] := CUSTOMER_TYPE;
|
|
sParam := GetRunExePathDir + '$KvCttSchOpt.dat';
|
|
if SaveJsonObjToFile(O, sParam) then
|
|
begin
|
|
if bDoNetSch_ then
|
|
begin
|
|
{$IFDEF DEBUG}
|
|
KvProcInfo_ := ExecuteApp(sKvCsPath, Format('-p "%s"', [sParam]), SW_SHOWNORMAL);
|
|
{$ELSE}
|
|
KvProcInfo_ := ExecuteAppAsUser('explorer.exe', sKvCsPath, Format('-p "%s"', [sParam]), SW_SHOWNORMAL);
|
|
{$ENDIF}
|
|
end else
|
|
KvProcInfo_ := ExecuteApp(sKvCsPath, Format('-p "%s"', [sParam]), SW_SHOWNORMAL);
|
|
|
|
if KvProcInfo_.dwProcessId = 0 then
|
|
begin
|
|
{$IFDEF DEBUG}
|
|
ASSERT(false);
|
|
{$ELSE}
|
|
_Trace('Fail .. CreateProcessKV() .. ExecuteApp()');
|
|
{$ENDIF}
|
|
end;
|
|
end else
|
|
_Trace('Fail .. CreateProcessKV() .. SaveJsonObjToFile()');
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. CreateProcessKV()');
|
|
end;
|
|
end;
|
|
|
|
var
|
|
nTmSec,
|
|
nTaskLenMax: Integer;
|
|
bNewStart: Boolean;
|
|
begin
|
|
sWorkDir_ := GetRunExePathDir + 'STask\';
|
|
DeleteDir(sWorkDir_);
|
|
if not ForceDirectories(sWorkDir_) then
|
|
begin
|
|
_Trace('Fail .. CreateWorkDir()');
|
|
SetWorkState(tsFail);
|
|
exit;
|
|
end;
|
|
CttSchOpt_.sTaskDir := sWorkDir_;
|
|
|
|
nTmSec := FileScanOpt_.nSchTimeoutSec;
|
|
if nTmSec <= 0 then
|
|
nTmSec := DEF_TIMEOUT_SEC;
|
|
_Trace('TThdSchFileScan .. Init .. TmSec=%d', [nTmSec], 5);
|
|
|
|
{$IFDEF _HE_}
|
|
if gMgSvc.IsNewApi then
|
|
begin
|
|
if IsCampaignTaskIdLong then
|
|
nTaskLenMax := 64
|
|
else
|
|
nTaskLenMax := 32;
|
|
end else
|
|
nTaskLenMax := 24;
|
|
|
|
CttSchProg_.dtStart := dtBegin_;
|
|
CttSchProg_.sScanId := FileScanOpt_.sScanId;
|
|
sComName := GetComName;
|
|
|
|
bNewStart := GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'cpid') <> CttSchProg_.sScanId;
|
|
if bNewStart then
|
|
begin
|
|
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cppn');
|
|
DelRegValue(HKEY_LOCAL_MACHINE, REG_HE, 'cptd');
|
|
end;
|
|
|
|
if not bNewStart then
|
|
CttSchProg_.sTaskId := GetRegValueAsString(HKEY_LOCAL_MACHINE, REG_HE, 'cptd');
|
|
|
|
if CttSchProg_.sTaskId = '' then
|
|
begin
|
|
if IsCampaignTaskIdLong then
|
|
CttSchProg_.sTaskId := sComName + '\' + FormatDateTime('yymmddhhnnss', dtBegin_)
|
|
else
|
|
CttSchProg_.sTaskId := sComName + '\' + FormatDateTime('hhnnss', dtBegin_);
|
|
|
|
if Length(CttSchProg_.sTaskId) > nTaskLenMax then
|
|
begin
|
|
SetLength(sComName, Length(sComName) - (Length(CttSchProg_.sTaskId) - nTaskLenMax));
|
|
if IsCampaignTaskIdLong then
|
|
CttSchProg_.sTaskId := sComName + '\' + FormatDateTime('yymmddhhnnss', dtBegin_)
|
|
else
|
|
CttSchProg_.sTaskId := sComName + '\' + FormatDateTime('hhnnss', dtBegin_);
|
|
end;
|
|
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'cptd', CttSchProg_.sTaskId, true);
|
|
SetRegValueString(HKEY_LOCAL_MACHINE, REG_HE, 'cpid', CttSchProg_.sScanId, true);
|
|
end;
|
|
|
|
if bIgrExcept_ then
|
|
MgCampExcept_ := TManagerCampExcept.Create;
|
|
{$ENDIF}
|
|
|
|
if Assigned(evScanSearchBegin_) then
|
|
evScanSearchBegin_(Self);
|
|
|
|
{$IFDEF _HE_}
|
|
if bNewStart then
|
|
begin
|
|
if gMgSvc.IsNewApi then
|
|
UpdateProgress('PENDING')
|
|
else
|
|
UpdateProgress('scan');
|
|
end;
|
|
{$ENDIF}
|
|
|
|
// 로컬 드라이브 스캔
|
|
ScanSchFiles;
|
|
|
|
// 공유폴더, 네트워크 드라이브 스캔
|
|
ScanSchNetFiles;
|
|
|
|
if SvFileList_ <> nil then
|
|
SvFileList_.SaveToFile(FileScanOpt_.sSvFilePath, TEncoding.UTF8);
|
|
if SvDirList_ <> nil then
|
|
SvDirList_.SaveToFile(FileScanOpt_.sSvDirPath, TEncoding.UTF8);
|
|
if SvScanList_ <> nil then
|
|
SvScanList_.SaveToFile(FileScanOpt_.sSvScanPath, TEncoding.UTF8);
|
|
|
|
sKvCsPath := GetRunExePathDir + EXE_KVCTTSCH;
|
|
while not Terminated and not GetWorkStop do
|
|
begin
|
|
try
|
|
if (KvProcInfo_.dwProcessId = 0) or
|
|
(GetProcessNameByPid(KvProcInfo_.dwProcessId) = '') or
|
|
( (dtRecentSch_ > 0) and
|
|
(SecondsBetween(dtRecentSch_, Now) >
|
|
(nTmSec + BooleanToInt(Pos(GetFileExt(sProcSchFile_).ToUpper, COMPRESS_EXTS) > 0, 60, 0))) ) then // 압축파일은 시간을 더 준다
|
|
CreateProcessKV;
|
|
|
|
Sleep(1000);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. Execute()');
|
|
end;
|
|
end;
|
|
|
|
if KvProcInfo_.dwProcessId <> 0 then
|
|
begin
|
|
TerminateProcessByPid(KvProcInfo_.dwProcessId);
|
|
KvProcInfo_.dwProcessId := 0;
|
|
end;
|
|
|
|
{$IFDEF _HE_}
|
|
if gMgSvc.IsNewApi then
|
|
UpdateProgress('DONE', true);
|
|
|
|
// kv에서 임시 파일을 사용하고 비정상 종료 시 삭제를 못하는 경우가 있다.
|
|
// 사용자 임시 폴더 초기화 25_0903 09:11:59 kku
|
|
ClearUserTempFolder;
|
|
{$ENDIF}
|
|
|
|
// DeleteDir(sWorkDir_);
|
|
if Assigned(evScanSearchEnd_) then
|
|
evScanSearchEnd_(Self);
|
|
end;
|
|
|
|
end.
|