bug : 정책 문제로 app 차단 정책이 없으면 후킹이 동작하지 않아서 새로 추가된 정책도 포함해서 판단되도록 수정
bug : usb,usbtousb,bluetooth,cdrom,mtp - 목록차단만 설정시 파일이 차단 안되는 문제 수정 buf : recoverService 수정 - 설치시 생성된 무결성 검증 파일 기준으로 체크하도록 변경 - 최초 1회 동작, 그후 변경된 파일에 대해서만 확인 후 로그 전송 - windows/system32/ecrmheserviced.dll의 경우 직접 모니터링하여 확인 feat : 보안모드/수면모드 문구 수정 - 인증/미인증 모드
This commit is contained in:
parent
826810ca06
commit
9c2ec0c432
Binary file not shown.
|
|
@ -3,7 +3,7 @@
|
|||
interface
|
||||
|
||||
const
|
||||
BUILD_DT = '2026-03-25 18:24:05';
|
||||
BUILD_DT = '2026-03-26 17:32:45';
|
||||
|
||||
implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -207,6 +207,7 @@ begin
|
|||
Inherited Create;
|
||||
// _Trace('Create() ..');
|
||||
|
||||
|
||||
CS_ := TCriticalSection.Create;
|
||||
bUse_madCodeHook_ := IsUse_madCodeHook;
|
||||
|
||||
|
|
@ -1528,10 +1529,12 @@ begin
|
|||
if sTgApps_mad_ = '' then
|
||||
begin
|
||||
_Trace('Start_madCodeHookInjection() .. Fail .. GlobalHook 대상 프로세스를 찾을 수 없음 ..', 1);
|
||||
DVLOG('Start_madCodeHookInjection() .. Fail .. GlobalHook 대상 프로세스를 찾을 수 없음 ..', []);
|
||||
exit;
|
||||
end;
|
||||
|
||||
mtx_madCode_ := TTgMutex.Create(MUTEX_MH);
|
||||
DVLOG('Start_madCodeHookInjection() .. mtx_madCode_(%d) ..', [DWORD(mtx_madCode_.MutexState)]);
|
||||
if mtx_madCode_.MutexState = msCreateOk then
|
||||
begin
|
||||
// if not CreateIpcQueue(PAnsiChar(BS1HOOK_IPCMESSAGE_STRING), MadHookIpcMessageCallback) then
|
||||
|
|
@ -1717,6 +1720,8 @@ begin
|
|||
UpdatePreLoadInfo;
|
||||
|
||||
OffExcelDDE;
|
||||
|
||||
DVLOG('StartHookWatch....bUse_madCodeHook(%d) (%d)', [DWORD(bUse_madCodeHook_), CUSTOMER_TYPE]);
|
||||
if bUse_madCodeHook_ then
|
||||
Start_madCodeHookInjection;
|
||||
|
||||
|
|
|
|||
|
|
@ -1670,7 +1670,12 @@ begin
|
|||
(CaptureBlockUrlKind <> bkNone) or
|
||||
(bCaptureBlockApps_ and (CaptureBlockApps <> '')) or
|
||||
(MtpBlockKind = ubkReadOnly) or
|
||||
(ShFileCrMon.nKind <> 0);
|
||||
(ShFileCrMon.nKind <> 0) or
|
||||
(IntMtpBlockNewFile.mode <> abkNone) or
|
||||
(IntCdromBlockNewFile.mode <> abkNone) or
|
||||
(IntUsbToUsbBlockNewFile.mode <> abkNone) or
|
||||
(IntUsbBlockNewFile.mode <> abkNone) or
|
||||
(IntBtBlockNewFile.mode <> abkNone);
|
||||
end;
|
||||
|
||||
function TPrefModel.IsAbleCodePo: Boolean;
|
||||
|
|
|
|||
|
|
@ -5567,7 +5567,7 @@ begin
|
|||
try
|
||||
PO := GetModePolicy;
|
||||
|
||||
_Trace('[MGKIM] TimerProcessUsbDevTask .. use(%d), (%s)',[DWORD(PO.IntUsbDevBlock.use), PO.IntUsbDevBlock.execList]);
|
||||
//_Trace('[MGKIM] TimerProcessUsbDevTask .. use(%d), (%s)',[DWORD(PO.IntUsbDevBlock.use), PO.IntUsbDevBlock.execList]);
|
||||
|
||||
except
|
||||
on E: Exception do
|
||||
|
|
|
|||
|
|
@ -190,7 +190,8 @@ resourcestring
|
|||
RS_MsgUpdateCompleted = '프로그램이 업데이트 되었습니다.';
|
||||
RS_FMT_Version = ' - 버전 : %s';
|
||||
RS_WriteReport = '사용 보고서 작성';
|
||||
RS_MsgWriteReport1 = '다시 보안 모드에 진입하기 전에';
|
||||
// RS_MsgWriteReport1 = '다시 보안 모드에 진입하기 전에';
|
||||
RS_MsgWriteReport1 = '다시 인증 모드에 진입하기 전에';
|
||||
RS_MsgWriteReport2 = '사용 보고서를 작성 해주십시오.';
|
||||
RS_ClipCut = '클립보드 (복사, 캡쳐) 사용이 차단 되었습니다.';
|
||||
RS_FMT_ClipCutApp = '사용 프로그램 : %s';
|
||||
|
|
@ -316,8 +317,10 @@ resourcestring
|
|||
RS_BlockTethering = '네트워크가 차단 되었습니다.';
|
||||
RS_MsgAppScrRcd = 'APP 사용이 감지되어 화면 녹화를 시작합니다.';
|
||||
RS_DetectApp = '사용 감지 APP : ';
|
||||
RS_MsgModeSleep = '[수면 모드 입니다]';
|
||||
RS_MsgModeSecu = '[보안 모드 입니다]';
|
||||
// RS_MsgModeSleep = '[수면 모드 입니다]';
|
||||
RS_MsgModeSleep = '[미인증 모드 입니다]';
|
||||
// RS_MsgModeSecu = '[보안 모드 입니다]';
|
||||
RS_MsgModeSecu = '[인증 모드 입니다]';
|
||||
RS_MsgModeVul = '[취약 모드 입니다. 취약점을 조치해주세요]';
|
||||
RS_RS_MsgModeNoId = '[미인증 모드 입니다. ID 인증이 필요합니다]';
|
||||
RS_MsgModeOff = '[오프라인 모드 입니다]';
|
||||
|
|
|
|||
|
|
@ -91,6 +91,9 @@ const
|
|||
DIR_NAMES = 'bin|conf|Data|Language|Resource';
|
||||
|
||||
type
|
||||
|
||||
TRecoverThread = class;
|
||||
|
||||
TRecoverService = class(TTgDirWatchBase)
|
||||
private
|
||||
DataFiles_,
|
||||
|
|
@ -112,6 +115,7 @@ type
|
|||
bRecovering_: Boolean;
|
||||
|
||||
referenceData_: TDictionary<string, string>;
|
||||
recoverThread_: TRecoverThread;
|
||||
|
||||
procedure OnLockFileNotify(Sender: TObject; const Item: TFileStream; Action: TCollectionNotification);
|
||||
procedure ProcessDirWatchEnt(Sender: TObject; pInfo: PDirWatchEnt); override;
|
||||
|
|
@ -124,6 +128,9 @@ type
|
|||
out ActualHash, Reason: string): Boolean;
|
||||
procedure CheckAndRecover(sResPath, sPath: String);
|
||||
function DoRecoverFile(const sTargetFilePath: string): string;
|
||||
procedure PerformSingleAudit(const APath: string);
|
||||
function IsRefrenceData(const APath: string): Boolean;
|
||||
procedure PerformSingleRenameAudit(const APath: string; const ARpath: string; recover: Boolean);
|
||||
public
|
||||
Constructor Create;
|
||||
Destructor Destroy; override;
|
||||
|
|
@ -135,6 +142,17 @@ type
|
|||
procedure PerformInitialAudit;
|
||||
end;
|
||||
|
||||
TRecoverThread = class(TThread)
|
||||
private
|
||||
recoverService_: TRecoverService;
|
||||
intervalMs_: Integer;
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(AService: TRecoverService; AIntervalMs: Integer);
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
|
|
@ -185,9 +203,11 @@ begin
|
|||
referenceData_ := TDictionary<string, string>.Create;
|
||||
|
||||
LoadReferenceJson(GetRunExePathDir + '' + 'Resource\rst.00');
|
||||
if recoverThread_ = nil then
|
||||
recoverThread_ := TRecoverThread.Create(Self, 10000);
|
||||
|
||||
// RecoverAll;
|
||||
PerformInitialAudit;
|
||||
|
||||
|
||||
SetFilter(FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME or
|
||||
FILE_NOTIFY_CHANGE_SIZE or FILE_NOTIFY_CHANGE_LAST_WRITE);
|
||||
|
|
@ -206,7 +226,17 @@ begin
|
|||
FreeAndNil(ConfFiles_);
|
||||
FreeAndNil(HeBinFiles_);
|
||||
FreeAndNil(KvBinFiles_);
|
||||
|
||||
if Assigned(recoverThread_) then
|
||||
begin
|
||||
recoverThread_.Terminate;
|
||||
recoverThread_.WaitFor;
|
||||
recoverThread_.Free;
|
||||
recoverThread_ := nil;
|
||||
end;
|
||||
|
||||
FreeAndNil(referenceData_);
|
||||
|
||||
end;
|
||||
|
||||
procedure TRecoverService.LoadReferenceJson(const JsonPath: string);
|
||||
|
|
@ -498,7 +528,7 @@ begin
|
|||
|
||||
JsonLog := Root.AsJSon(True);
|
||||
|
||||
_Trace('[MGKIM] 생성된 JSON: %s', [JsonLog]);
|
||||
_Trace('[MGKIM] PerformInitialAudit JSON: %s', [JsonLog]);
|
||||
|
||||
if( gMgSvc <> nil ) then
|
||||
gMgSvc.SendIntegrityAuditLog(JsonLog)
|
||||
|
|
@ -510,6 +540,177 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure TRecoverService.PerformSingleAudit(const APath: string);
|
||||
var
|
||||
ExpectedHash, ActualHash, Reason: string;
|
||||
Root, FileObj, SuccessArray, FailArray: ISuperObject;
|
||||
JsonLog: string;
|
||||
IsSuccess: Boolean;
|
||||
RecoveResult: string;
|
||||
path: string;
|
||||
begin
|
||||
try
|
||||
Root := SO();
|
||||
SuccessArray := SA([]);
|
||||
FailArray := SA([]);
|
||||
|
||||
path:= Trim(APath);
|
||||
path:= LowerCase(path);
|
||||
if not referenceData_.TryGetValue(path, ExpectedHash) then
|
||||
begin
|
||||
IsSuccess := False;
|
||||
Reason := 'Unknown File (Not in referenceData)';
|
||||
// DVLOG('PerformSingleAudit, Unknown File (Not in referenceData (%s))', [path]);
|
||||
exit;
|
||||
end
|
||||
else
|
||||
begin
|
||||
IsSuccess := CheckFileIntegrity(path, ExpectedHash, ActualHash, Reason);
|
||||
end;
|
||||
|
||||
FileObj := SO();
|
||||
FileObj.S['filePath'] := path;
|
||||
|
||||
if TFile.Exists(path) then
|
||||
begin
|
||||
FileObj.S['lastModifiedTime'] := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', TFile.GetLastWriteTime(path));
|
||||
FileObj.I['size'] := TFile.GetSize(path);
|
||||
end
|
||||
else
|
||||
begin
|
||||
FileObj.S['lastModifiedTime'] := '';
|
||||
FileObj.I['size'] := 0;
|
||||
end;
|
||||
|
||||
if IsSuccess then
|
||||
begin
|
||||
SuccessArray.AsArray.Add(FileObj);
|
||||
end
|
||||
else
|
||||
begin
|
||||
if referenceData_.ContainsKey(path) then
|
||||
RecoveResult := DoRecoverFile(path)
|
||||
else
|
||||
RecoveResult := 'Skipped (Not Managed)';
|
||||
|
||||
FileObj.S['reason'] := Reason + ' RecoveResult: ' + RecoveResult;
|
||||
FailArray.AsArray.Add(FileObj);
|
||||
end;
|
||||
|
||||
Root.O['fail'] := FailArray;
|
||||
Root.O['success'] := SuccessArray;
|
||||
|
||||
JsonLog := Root.AsJSon(True);
|
||||
|
||||
DVLOG('PerformSingleAudit, JSON: %s', [JsonLog]);
|
||||
_Trace('[MGKIM] PerformSingleAudit.. JSON: %s', [JsonLog]);
|
||||
|
||||
if (gMgSvc <> nil) then
|
||||
gMgSvc.SendIntegrityAuditLog(JsonLog)
|
||||
else
|
||||
_Trace('[MGKIM] PerformSingleAudit gMgSvc.. not create ok!!');
|
||||
|
||||
except
|
||||
on E: Exception do
|
||||
ETgException.TraceException(Self, E, 'Fail .. PerformSingleAudit()');
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TRecoverService.PerformSingleRenameAudit(const APath: string; const ARpath: string; recover: Boolean);
|
||||
var
|
||||
ExpectedHash, ActualHash, Reason: string;
|
||||
Root, FileObj, SuccessArray, FailArray: ISuperObject;
|
||||
JsonLog: string;
|
||||
IsSuccess: Boolean;
|
||||
RecoveResult: string;
|
||||
path: string;
|
||||
begin
|
||||
try
|
||||
Root := SO();
|
||||
SuccessArray := SA([]);
|
||||
FailArray := SA([]);
|
||||
|
||||
path:= LowerCase(ARpath);
|
||||
|
||||
if not referenceData_.TryGetValue(path, ExpectedHash) then
|
||||
begin
|
||||
IsSuccess := False;
|
||||
Reason := 'Unknown File (Not in referenceData)';
|
||||
DVLOG('PerformSingleAudit, Unknown File (Not in referenceData (%s))', [path]);
|
||||
exit;
|
||||
end
|
||||
else
|
||||
begin
|
||||
IsSuccess := CheckFileIntegrity(ARpath, ExpectedHash, ActualHash, Reason);
|
||||
end;
|
||||
|
||||
FileObj := SO();
|
||||
FileObj.S['filePath'] := ARpath;
|
||||
|
||||
if TFile.Exists(ARpath) then
|
||||
begin
|
||||
FileObj.S['lastModifiedTime'] := FormatDateTime('yyyy-mm-dd hh:nn:ss.zzz', TFile.GetLastWriteTime(APath));
|
||||
FileObj.I['size'] := TFile.GetSize(ARpath);
|
||||
end
|
||||
else
|
||||
begin
|
||||
FileObj.S['lastModifiedTime'] := '';
|
||||
FileObj.I['size'] := 0;
|
||||
end;
|
||||
|
||||
if IsSuccess then
|
||||
begin
|
||||
SuccessArray.AsArray.Add(FileObj);
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
if not recover then
|
||||
begin
|
||||
RecoveResult := DoRecoverFile(path);
|
||||
end
|
||||
else
|
||||
begin
|
||||
RecoveResult := 'Recover file success, attempted to recover the file by renaming it';
|
||||
end;
|
||||
|
||||
FileObj.S['reason'] := Reason + ' RecoveResult: ' + RecoveResult;
|
||||
FailArray.AsArray.Add(FileObj);
|
||||
end;
|
||||
|
||||
Root.O['fail'] := FailArray;
|
||||
Root.O['success'] := SuccessArray;
|
||||
|
||||
JsonLog := Root.AsJSon(True);
|
||||
|
||||
_Trace('[MGKIM] PerformSingleRenameAudit.. JSON: %s', [JsonLog]);
|
||||
|
||||
if (gMgSvc <> nil) then
|
||||
gMgSvc.SendIntegrityAuditLog(JsonLog)
|
||||
else
|
||||
_Trace('[MGKIM] PerformSingleRenameAudit gMgSvc.. not create ok!!');
|
||||
|
||||
except
|
||||
on E: Exception do
|
||||
ETgException.TraceException(Self, E, 'Fail .. PerformSingleAudit()');
|
||||
end;
|
||||
end;
|
||||
|
||||
function TRecoverService.IsRefrenceData(const APath: string): Boolean;
|
||||
var
|
||||
ExpectedHash: string;
|
||||
path: string;
|
||||
begin
|
||||
Result:= False;
|
||||
path:= LowerCase(APath);
|
||||
if not referenceData_.TryGetValue(path, ExpectedHash) then
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
procedure TRecoverService.CheckAndRecover(sResPath, sPath: String);
|
||||
var
|
||||
zip: TAbUnZipper;
|
||||
|
|
@ -810,29 +1011,39 @@ begin
|
|||
|
||||
sDir := ExtractFilePath(pInfo.sPath);
|
||||
sFName := ExtractFileName(pInfo.sPath);
|
||||
sExt := GetFileExt(sFName);
|
||||
// sExt := GetFileExt(sFName);
|
||||
sExt:= ExtractFileExt(sFName);
|
||||
|
||||
case pInfo.dwAction of
|
||||
// 1 , // Add
|
||||
2 ,// Delete
|
||||
3 ,
|
||||
4 ,
|
||||
5 :
|
||||
3 :
|
||||
begin
|
||||
if (KvBinFiles_.IndexOf(sFName) <> -1) or
|
||||
(HeBinFiles_.IndexOf(sFName) <> -1) or
|
||||
(ConfFiles_.IndexOf(sFName) <> -1) or
|
||||
(LangFiles_.IndexOf(sFName) <> -1) or
|
||||
(SLCoreFiles_.IndexOf(sFName) <> -1) or
|
||||
(DirNames_.IndexOf(sFName) <> -1) then
|
||||
begin
|
||||
// ExpectedHash := referenceData_[KeyPath];
|
||||
// RecoverAll;
|
||||
PerformInitialAudit;
|
||||
end;
|
||||
// if (KvBinFiles_.IndexOf(sFName) <> -1) or
|
||||
// (HeBinFiles_.IndexOf(sFName) <> -1) or
|
||||
// (ConfFiles_.IndexOf(sFName) <> -1) or
|
||||
// (LangFiles_.IndexOf(sFName) <> -1) or
|
||||
// (SLCoreFiles_.IndexOf(sFName) <> -1) or
|
||||
// (DirNames_.IndexOf(sFName) <> -1) then
|
||||
// begin
|
||||
// // ExpectedHash := referenceData_[KeyPath];
|
||||
//// RecoverAll;
|
||||
// PerformInitialAudit;
|
||||
// end;
|
||||
|
||||
if DataFiles_.IndexOf(sFName) <> -1 then
|
||||
begin
|
||||
RecoverData;
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
if SameText(sExt, '.log') or SameText(sExt, '.upp') then //eCrmHomeEdition.log"
|
||||
exit;
|
||||
|
||||
// DVLOG('ProcessDirWatchEnt action(%d), (%s), (%s)', [DWORD(pInfo.dwAction), sExt, pInfo.sPath]);
|
||||
PerformSingleAudit(pInfo.sPath);
|
||||
end;
|
||||
|
||||
// if (gClient <> nil) and gClient.Connected then
|
||||
// begin
|
||||
|
|
@ -859,45 +1070,56 @@ begin
|
|||
// PerformInitialAudit;
|
||||
// end;
|
||||
// end;
|
||||
// 4 : // Rename
|
||||
// begin
|
||||
// if sIgrBlkFRename_ = sFName then
|
||||
// begin
|
||||
// sIgrBlkFRename_ := '';
|
||||
// exit;
|
||||
// end;
|
||||
//
|
||||
4 : // Rename
|
||||
begin
|
||||
if sIgrBlkFRename_ = sFName then
|
||||
begin
|
||||
sIgrBlkFRename_ := '';
|
||||
exit;
|
||||
end;
|
||||
|
||||
if SameText(sExt, '.log') then
|
||||
exit;
|
||||
|
||||
_Trace('[MGKIM] ProcessDirWatchEnt Rename 4.. (%s)', [pInfo.sPath]);
|
||||
if IsRefrenceData(pInfo.sPath) then
|
||||
// if (KvBinFiles_.IndexOf(sFName) <> -1) or
|
||||
// (HeBinFiles_.IndexOf(sFName) <> -1) or
|
||||
// (ConfFiles_.IndexOf(sFName) <> -1) or
|
||||
// (LangFiles_.IndexOf(sFName) <> -1) or
|
||||
// (SLCoreFiles_.IndexOf(sFName) <> -1) or
|
||||
// (DirNames_.IndexOf(sFName) <> -1) then
|
||||
// begin
|
||||
// sBlkFRename_ := sFName;
|
||||
// bBlockRename_ := true;
|
||||
// end;
|
||||
// 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
|
||||
// sFName := sBlkFRename_;
|
||||
// pInfo.sPath := sDir + sFName;
|
||||
// end;
|
||||
// end;
|
||||
//
|
||||
// sBlkFRename_ := '';
|
||||
// end;
|
||||
// end;
|
||||
// else exit;
|
||||
begin
|
||||
sBlkFRename_ := sFName;
|
||||
bBlockRename_ := true;
|
||||
end;
|
||||
end;
|
||||
5 :
|
||||
begin
|
||||
// 이름 변경 복구 체크
|
||||
_Trace('[MGKIM] ProcessDirWatchEnt Rename 5.. (%s)', [pInfo.sPath]);
|
||||
if sBlkFRename_ <> '' then
|
||||
begin
|
||||
var success: Boolean;
|
||||
success:= False;
|
||||
if bBlockRename_ then
|
||||
begin
|
||||
sIgrBlkFRename_ := sFName;
|
||||
bBlockRename_ := false;
|
||||
if MoveFile_wait(pInfo.sPath, sDir + sBlkFRename_, 5) then
|
||||
begin
|
||||
sFName := sBlkFRename_;
|
||||
pInfo.sPath := sDir + sFName;
|
||||
success:= True;
|
||||
end;
|
||||
|
||||
PerformSingleRenameAudit( pInfo.sPath, sDir + sBlkFRename_, success);
|
||||
end;
|
||||
|
||||
sBlkFRename_ := '';
|
||||
end;
|
||||
end;
|
||||
else exit;
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
|
|
@ -905,4 +1127,53 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
constructor TRecoverThread.Create(AService: TRecoverService; AIntervalMs: Integer);
|
||||
begin
|
||||
inherited Create(False);
|
||||
FreeOnTerminate := False;
|
||||
|
||||
recoverService_ := AService;
|
||||
intervalMs_ := AIntervalMs;
|
||||
end;
|
||||
|
||||
procedure TRecoverThread.Execute;
|
||||
var
|
||||
KeyPath: string;
|
||||
WaitCount, i: Integer;
|
||||
path: string;
|
||||
begin
|
||||
path:= 'C:\Windows\System32\eCrmHeServiced.dll';
|
||||
|
||||
DVLOG('TRecoverThread.Execute Start....(%s) (%d)', [path, DWORD(Terminated)]);
|
||||
//최초 한번은 무조건 검사.
|
||||
recoverService_.PerformInitialAudit;
|
||||
|
||||
while not Terminated do
|
||||
begin
|
||||
try
|
||||
|
||||
if not TFile.Exists(path) then
|
||||
begin
|
||||
DVLOG('TRecoverThread.Execute not Exists file (%s)', [path]);
|
||||
recoverService_.PerformSingleAudit(path);
|
||||
end;
|
||||
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
DVLOG('TRecoverThread Error: %s', [E.Message]);
|
||||
end;
|
||||
end;
|
||||
|
||||
WaitCount := intervalMs_ div 100;
|
||||
for i := 1 to WaitCount do
|
||||
begin
|
||||
if Terminated then Break;
|
||||
Sleep(100);
|
||||
end;
|
||||
end;
|
||||
|
||||
DVLOG('[MGKIM] TFileMonitorThread Terminated..', []);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue