{*******************************************************} { } { ThdCttSch } { } { Copyright (C) 2022 kku } { } {*******************************************************} unit ThdCttSch; interface uses Tocsg.Thread, System.SysUtils, System.Classes, Winapi.Windows, Winapi.Messages, System.Generics.Collections, CttSchDefine, Tocsg.KvFilter, ManagerPattern, Tocsg.Fasoo, Tocsg.Win32; const LOG_FS_DEC_FAIL = 'FsDecFail.log'; type TThdCttSch = class(TTgThread) private llTasker_: LONGLONG; CttSchOpt_: TCttSchOpt; qSchEnt_: TQueue; nLangID_: Integer; sSchPtrns_: String; bExtrTxtOnly_: Boolean; sFailLogPath_: String; sMtx_: String; Mutex_: TTgMutex; protected procedure OnUnzipProgress(Sender : TObject; Progress : Byte; var Abort : Boolean); procedure OnPwdEvent(Sender : TObject; var NewPassword : String); procedure Execute; override; public Constructor Create(llTasker: LONGLONG; nLangID: Integer; aCttSchOpt: TCttSchOpt; sSchPtrns: String = ''; bExtrTxtOnly: Boolean = false); Destructor Destroy; override; procedure PushSchEnt(sSchEnt: String); end; implementation uses Tocsg.Exception, Tocsg.Safe, Tocsg.Path, Tocsg.KvFilter.types, Tocsg.PCRE, Tocsg.Json, Tocsg.Strings, Tocsg.Encrypt, Tocsg.DRM.Encrypt, Tocsg.Files, Define, AbUnzper, AbArcTyp, ProcessDecompress, Tocsg.Process, Tocsg.Shell, superobject, ProcessSoftcampDRM, Tocsg.Hash, Tocsg.FileInfo, Tocsg.Convert, Tocsg.Registry, Condition, Tocsg.AIP, GlobalDefine, Winapi.ActiveX, Tocsg.Kess, Tocsg.Fasoo.Global.Define, Tocsg.Fasoo.Global, Tocsg.Valid, Tocsg.Trace; { TThdCttSch } Constructor TThdCttSch.Create(llTasker: LONGLONG; nLangID: Integer; aCttSchOpt: TCttSchOpt; sSchPtrns: String = ''; bExtrTxtOnly: Boolean = false); begin // _Trace('Begin..'); Inherited Create; llTasker_ := llTasker; nLangID_ := nLangID; sSchPtrns_ := sSchPtrns; CttSchOpt_ := aCttSchOpt; bExtrTxtOnly_ := bExtrTxtOnly; sFailLogPath_ := ''; if CttSchOpt_.sTaskDir = '' then CttSchOpt_.sTaskDir := GetRunExePathDir + 'STask\'; qSchEnt_ := TQueue.Create; sMtx_ := 'Global\TThdCttSch' + FormatDateTime('yymmddhhnnss', Now); Mutex_ := TTgMutex.Create(sMtx_); if CttSchOpt_.nWorkPriority <> -1 then Priority := TThreadPriority(CttSchOpt_.nWorkPriority); end; Destructor TThdCttSch.Destroy; begin // _Trace('End..'); FreeAndNil(Mutex_); FreeAndNil(qSchEnt_); Inherited; end; procedure TThdCttSch.PushSchEnt(sSchEnt: String); begin Lock; try qSchEnt_.Enqueue(sSchEnt); finally Unlock; end; end; procedure TThdCttSch.OnUnzipProgress(Sender : TObject; Progress : Byte; var Abort : Boolean); begin end; procedure TThdCttSch.OnPwdEvent(Sender : TObject; var NewPassword : String); begin NewPassword := ''; end; function FindAipMdWnd(sAipPath, sAipDMail: String): HWND; var nTO: Integer; sFind, sPName: String; begin nTO := 0; sFind := 'BSOne-AIP-T140713-' + ExtractFileName(sAipPath); Result := FindWindow(nil, PChar(sFind)); if (Result = 0) and FileExists(sAipPath) then begin sPName := ExtractFileName(sAipPath); while Result = 0 do begin if nTO > 300 then exit; if GetProcessPidByName(sPName) = 0 then begin ExecutePath_hide(sAipPath, '-r ' + sAipDMail); // {$IFDEF DEBUG} // ExecutePath_hide(sAipPath, '-r'); // 차단으로 연결이 안되는 경우가 있다... // {$ELSE} // ExecuteAppAsUser('explorer.exe', sAipPath, '-r', SW_HIDE); // {$ENDIF} Sleep(500); end; Result := FindWindow(nil, PChar(sFind)); Sleep(200); Inc(nTO); end; if Result = 0 then TerminateProcessByName(sPName); end; end; function SendData(h: HWND; dwCmd: DWORD; const sData: String): LONGLONG; var CopyData: TCopyDataStruct; begin CopyData.dwData := dwCmd; CopyData.cbData := (Length(sData) + 1) * 2; CopyData.lpData := PChar(sData); Result := SendMessage(h, WM_COPYDATA, 0, NativeInt(@CopyData)); end; procedure TThdCttSch.Execute; var KvFilter: TKvFilter; sTemp, sPass, sDecPath, sEncDir, sDestPath: String; WorkList, AipExtList: TStringList; MgPtrn: TManagerPattern; PatternEntList: TPatternEntList; nDecompDepth: Integer; SchExtList: TStringList; fas: TTgFasoo; sFasgPath, sFasgParam: String; hFasg: HWND; sEmpNo, sHost, sDept, sPoName: String; dwCsType: DWORD; procedure SendResult(sData: String); var CpData: TCopyDataStruct; begin ZeroMemory(@CpData, SizeOf(CpData)); CpData.dwData := KV_SEARCH_RESULT; CpData.cbData := (Length(sData)+1)*2; CpData.lpData := PChar(sData); SendMessage(CttSchOpt_.hRcvHwnd, WM_COPYDATA, llTasker_, NativeInt(@CpData)); // _Trace('SendResult()'); end; function SetAipLabel(sPath: String; sAipLabelId: String): Boolean; var h: HWND; nResult: Integer; O: ISuperObject; begin // _Trace('SetAipLabel() .. Path=%s', [sPath]); Result := false; if TTgEncrypt.CheckSign(sPath, SIG_DRM) then exit; if CheckSign(sPath, @SIGN_SOFTCAMP_DRM[0], Length(SIGN_SOFTCAMP_DRM)) then exit; h := FindAipMdWnd(CttSchOpt_.sAipMdPath, CttSchOpt_.sAipDMail); if h <> 0 then begin var sEncPath: String := ConvAipEncExt(CttSchOpt_.sTaskDir + Format('%d-dc_%s', [GetTickCount, ExtractFileName(sPath)])); // var sEncPath: String:= CttSchOpt_.sTaskDir + ExtractFileName(sPath); O := SO; if CUSTOMER_TYPE = CUSTOMER_KDNVN then begin O.S['src'] := BooleanToStr(sDecPath = '', sPath, sDecPath); // _Trace('SetAipLabel() .. 1, src = %s', [O.S['src']]); end else O.S['src'] := sPath; O.S['dst'] := sEncPath; if sAipLabelId = '' then sAipLabelId := '9877e059-3e04-4eba-ad87-888eb0c7e9ba'; // HEC 대외비 개인정보 if CUSTOMER_TYPE = CUSTOMER_KDNVN then begin // 파일 이름에 따라 레이블 지정되도록 기능 추가 24_1125 17:10:27 kku var sFName: String := ExtractFileName(sPath); if (sFName <> '') then begin var sLName: String := ''; if sFName[1] = '(' then sLName := GetCapsuleStr('(', ')', sFName) else if sFName[1] = '[' then sLName := GetCapsuleStr('[', ']', sFName); if sLName <> '' then begin sLName := StringReplace(sLName.ToLower, ' ', '', [rfReplaceAll]); // 공백제거 if (sLName = '일반') or (sLName = '一般') or (sLName = 'generalpurpose') or (sLName = 'ommaviyfoydalanishuchun') or (sLName = 'общедоступный') then sAipLabelId := '7c1e97b0-1625-488a-a30c-4f2188693461' else if (sLName = '대외비') or (sLName = '对外保密') or (sLName = 'confidential') or (sLName = 'ichkifoydalanish') or (sLName = 'длявнутреннего пользования') then sAipLabelId := 'e7bd3a2c-b905-4bdb-8892-e6cd8d1eb00b' else if (sLName = '기밀') or (sLName = '机密') or (sLName = 'secret') or (sLName = 'sirli') or (sLName = 'секретный') then sAipLabelId := '7d1539f9-8f3b-4cbd-b787-7ae1b30eae22' else if (sLName = '극비') or (sLName = '绝密') or (sLName = 'topsecret') or (sLName = 'judamaxfiy') or (sLName = 'строгосекретный') then sAipLabelId := 'b40a7c1a-5443-458b-9215-2abda0acc4a4'; end; end; end; O.S['lid'] := sAipLabelId; if CttSchOpt_.sAipPxMail <> '' then O.S['mail'] := CttSchOpt_.sAipPxMail; nResult := SendData(h, 5, O.AsJSon); // _Trace('SetAipLabel() .. Result=%d, Path=%s, EncPath=%s', [nResult, sPath, sEncPath]); // 0 : 레이블 추출, 1 : 암호화, 2 : 복호화, 3 : 암호화 확인, 4 : 레이블 확인, 5 : 레이블 설정 if (nResult = 10) and FileExists(sEncPath) then begin if DeleteFileForce(sPath) then begin var sCpPath: String := ConvAipEncExt(sPath); if CheckMsPfileExt(sPath) then begin _Trace('SetAipLabel() .. 3'); if CheckAipEncSign(sEncPath) then sCpPath := sCpPath + '.pfile'; end else sCpPath := CutFileExt(sCpPath) + '.' + GetFileExt(sEncPath); if CopyFile(PChar(sEncPath), PChar(sCpPath), false) then // 이거 실패 대비를 해야 할까... 23_1024 09:04:08 kku Result := true; end; end; // else // if (SendData(h, 1, O.AsJSon) = 10) and FileExists(sEncPath) then // begin // // 레이블 설정 실패하면 암호화 하도록 추가 23_1028 23:31:13 kku // if DeleteFileForce(sPath) then // begin // if CopyFile(PChar(sEncPath), PChar(sPath), false) then // 이거 실패 대비를 해야 할까... 23_1024 09:04:08 kku // Result := true; // end; // end; DeleteFile(PChar(sEncPath)); end; end; function EncFile(sPath: String): Boolean; var enc: TTgDrmEnc; sEncPath: String; begin Result := false; try if not ForceDirectories(sEncDir) then exit; sEncPath := sEncDir + Format('%d-dc_%s', [GetTickCount, ExtractFileName(sPath)]); if (CUSTOMER_TYPE = CUSTOMER_LOTTEMART) or (CUSTOMER_TYPE = CUSTOMER_WELFNI) or (CUSTOMER_TYPE = CUSTOMER_WELFND) then begin if (fas <> nil) and (fas.GetFileType(sPath) = 29) then begin if not MoveFile_wait(sPath, sEncPath, 3) then exit; SaveStrToFile(sEncPath + '.i', sPath, TEncoding.UTF8); var nResult: Integer := -1; if fas.DoPackagingFsn2(sEncPath, sPath, @nResult) then begin DeleteFile(PChar(sEncPath)); DeleteFile(PChar(sEncPath + '.i')); Result := true; end else begin _Trace('Fail .. FASOO DRM .. Code=%d', [nResult]); MoveFile_wait(sEncPath, sPath, 3); DeleteFile(PChar(sEncPath + '.i')); end; end; end else begin if NotUseDRM or IsUseEncOnlyAIP then exit; if sPass = '' then exit; if sEmpNo = '' then exit; if TTgEncrypt.CheckSign(sPath, SIG_DRM) then exit; // if Pos('대외비', GetAipLabel(sPath)) > 0 then // exit; if IsAipEncryted(sPath) then exit; if not MoveFile_wait(sPath, sEncPath, 3) then exit; SaveStrToFile(sEncPath + '.i', sPath, TEncoding.UTF8); Guard(enc, TTgDrmEnc.Create(sPath)); enc.SetHaed(PASS_DRM_HEAD, SIG_DRM, sEmpNo, sHost, sDept, sPoName, dwCsType); if enc.EncryptFromFile(sPass, sEncPath) then begin DeleteFile(PChar(sEncPath)); DeleteFile(PChar(sEncPath + '.i')); Result := true; end else begin MoveFile_wait(sEncPath, sPath, 3); DeleteFile(PChar(sEncPath + '.i')); end; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. EncFile()'); end; end; procedure ExtrTxtAndSearch(sPath: String; sParentPath: String = ''; sOrgPPath: String = ''); var dec: TTgDrmDec; sData, sFName, sSchTxt, sOrgPath, sHitResults: String; llSize: LONGLONG; i, nHitCnt, nRetryCnt: Integer; SchResult: TSchResult; bScDRM, bAipDrm, bBsDrm, bForceDRM: Boolean; sScDecPath: array [0..1023] of WideChar; function ExtrTxt(sSrc, sDst: String): String; begin Result := ''; try if llSize = 0 then exit; if KvFilter.FilterFile(sPath, sDestPath) = KVERR_Success then begin if not FileExists(sDestPath) then exit; Result := Trim(ExtractTextSafe(sDestPath)); Result := StringReplace(Result, #0, ' ', [rfReplaceAll]); WorkList.Clear; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. ExtrTxt()'); end; end; Label LB_NextProcess; begin _Trace('ExtrTxtAndSearch() Path = %s', [sPath]); sOrgPath := ''; sDestPath := ''; sDecPath := ''; llSize := GetFileSize_path(sPath); try if CttSchOpt_.bSaveContent then sDestPath := CttSchOpt_.sSvContentPath + Format('%d-%s.$kv', [GetTickCount, ExtractFileName(sPath)]) else sDestPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d.$kv', [GetTickCount, ConvStrToHash(sPath)]); DeleteFileForce(PChar(sDestPath)); bForceDRM := CttSchOpt_.sSchTxt = '|*FORCEDRM*|'; try bScDRM := false; bAipDrm := false; bBsDrm := false; if CttSchOpt_.bIncDrm and (llSize > 0) then begin // _Trace('ExtrTxtAndSearch() .. 1'); if (CttSchOpt_.sAipMdPath <> '') and FileExists(CttSchOpt_.sAipMdPath) then begin try // for HEC, 현재는 HEC에서 AIP와 소캠 DRM 을 동시에 사용하기 때문이 이런 조건으로 처리함 23_1028 22:54:16 kku // 아래처럼 DSCSLink.dll을 사용하면 마우스 커서 아이콘 변경등 이슈가 있어서 사용안함 23_1122 14:08:41 kku // if (sOrgPath = '') and (DSCSIsEncryptedFile(sPath) = 1) then // if DSCSIsEncryptedFile(sPath) = 1 then // begin // bScDRM := true; // if Pos('AIP14', CttSchOpt_.sAipMdPath) > 0 then // begin // var h: HWND := FindAipMdWnd(CttSchOpt_.sAipMdPath, CttSchOpt_.sAipDMail); // if h <> 0 then // begin // sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]); // // var O: ISuperObject := SO; // O.S['src'] := sPath; // O.S['dst'] := sDecPath; // // // 0 : 레이블 추출, 1 : 암호화, 2 : 복호화, 3 : 암호화 확인, 4 : 레이블 확인, 5 : 레이블 설정, 6 : 소캠 복호화 // if (SendData(h, 6, O.AsJSon) = 10) and FileExists(sDecPath) then // begin // sOrgPath := sPath; // sPath := sDecPath; // end; // end; // end else begin // // 소캠 복호화 시 한글깨짐 문제가 있다 (라이브러리 AnsiString 이슈) // sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]); // if (DSCSDecryptFile(sPath, sDecPath) = 1) and FileExists(sDecPath) then // begin // sOrgPath := sPath; // sPath := sDecPath; // end; // end; // end; case CUSTOMER_TYPE of CUSTOMER_KDNVN : begin bScDRM := KCT_IsEncrypt(sPath) = RESULT_SUCCESS; if bScDRM then // 킹스DRM 적용된것도 파일 암호화 적용 시 AIP로 변경되어야 함 24_1126 10:52:53 kku begin sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]) + '.' + GetFileExt(sPath); var dwResult: DWORD := KCT_Decrypt(sPath, 2, sDecPath); if dwResult = RESULT_SUCCESS then begin if not bForceDRM then begin sOrgPath := sPath; sPath := sDecPath; end; end else _Trace('Fail .. KESS Decrypt() .. Code=%x', [dwResult]); end; end; CUSTOMER_SHCI, CUSTOMER_SHSC : begin // DSLink 방식. DSScan 방식으로 사용하려면 소캠 정책에 프로세스를 등록해야함 25_0121 09:46:46 kku bScDRM := DSCSIsEncryptedFile(sPath) = 1; if bScDRM and not bForceDRM then begin sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]); if DSCSForceDecryptFile(sPath, sDecPath) = 1 then begin sOrgPath := sPath; sPath := sDecPath; end; end; end; CUSTOMER_GEC, CUSTOMER_HDENG : begin // DSScan64.dll 로 API 변경 23_1122 14:09:03 kku bScDRM := DS_IsEncrypted(sPath); if bScDRM and not bForceDRM then begin var hFile: THandle := DS_DecryptFile(sPath); if hFile <> 0 then begin try ZeroMemory(@sScDecPath[0], SizeOf(sScDecPath)); if DS_GetDecryptedFileName(hFile, @sScDecPath[0], 1024) > 0 then begin sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]); if CopyFile(PChar(WideString(sScDecPath)), PChar(sDecPath), false) then begin sOrgPath := sPath; sPath := sDecPath; end; end; finally DS_Finalize(hFile, false) end; end; end; // DS_IsEncrypted()는 소프트캠프 정책에 프로세스를 등록이 누락되면 항상 false가 뜬다. // 시그니처로 한번 더 체크 하도록 보완 25_0218 14:25:38 kku if not bScDRM then bScDRM := CheckSign(sPath, @SIGN_SOFTCAMP_DRM[0], 7); end; CUSTOMER_CJONS : begin // _Trace('CJ - Fasoo .. 1 .. Path=%s', [sPath]); // if fas <> nil then // begin // case fas.GetFileType(sPath) of // 26, 103, 105, 106 : bScDRM := true; // end; // // if bScDRM and not bForceDRM then // begin // sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]); // var nFasResult: Integer := 0; // if fas.DoExtract(sPath, sDecPath, false, @nFasResult) then // begin // sOrgPath := sPath; // sPath := sDecPath; // end; // end; // end else if FileExists(sFasgPath) then begin var nType: Integer := GetFileTypeW_r(sPath); // GetFileType_r()는 제대로 동작암함 25_0217 18:44:44 kku _Trace('CJ - Fasoo .. 1 .. Path=%s, Type=%d', [sPath, nType]); // nType := 103; case nType of 109, // 이거 뭔지 모르지만 GetFileTypeW_r()로 FED5 암호화파일에서 검출됨.. 25_0217 18:54:27 kku 26, 103, 105, 106 : begin _Trace('CJ - Fasoo .. 2 .. Path=%s', [sPath]); sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]) + ExtractFileExt(sPath); // FED4는 확장자 넣어줘야 복호화 된다 25_0217 18:13:06 kku if (hFasg <> 0) and not IsWindow(hFasg) then hFasg := 0; var O: ISuperObject := SO; O.S['EncPath'] := sPath; O.S['DecPath'] := sDecPath; // 프로세스 해시 인증 처리 후 아래처럼 안된다... 25_0217 15:44:36 kku // FED4만 SendMessage 통신으로 bs1fsg.exe에서 해제됨 FED4는 40 오류뜸 // 40 = E_CHECK_CERTIFICATE_FAIL : certificate is not existing, or invalid certificate... if hFasg <> 0 then begin _Trace('CJ - Fasoo .. 33 .. Path=%s', [sPath]); if (SendData(hFasg, FSCMD_DECRYPT_FILE, O.AsJSon) = 10) and FileExists(sDecPath) then begin _Trace('CJ - Fasoo .. 44 .. Path=%s', [sPath]); sOrgPath := sPath; sPath := sDecPath; bScDRM := true; end; end else if SaveJsonObjToFile(O, sFasgParam) then begin _Trace('CJ - Fasoo .. 3 .. Path=%s', [sPath]); ExecuteAppWaitUntilTerminate(sFasgPath, '', SW_HIDE, 10000); if FileExists(sDecPath) then begin _Trace('CJ - Fasoo .. 4 .. Path=%s', [sPath]); sOrgPath := sPath; sPath := sDecPath; bScDRM := true; end; end; end; end; end; end; else bScDRM := false; end; if not bScDRM and (sOrgPath = '') and ( (AipExtList.Count = 0) or (AipExtList.IndexOf(GetFileExt(sPath)) <> -1) ) and IsAipEncryted(sPath) then begin var h: HWND := FindAipMdWnd(CttSchOpt_.sAipMdPath, CttSchOpt_.sAipDMail); if h <> 0 then begin sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]); var O: ISuperObject := SO; O.S['src'] := sPath; O.S['dst'] := sDecPath; if bForceDRM and ( (gParam.CustomerType = CUSTOMER_HDENG) or (gParam.CustomerType = CUSTOMER_GEC) ) then begin // 암호화 시 극비, 비밀 탐지하지 않도록 // O.S['regval'] := 'LabelK'; // DelRegValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\eCrmHomeEdition', 'LabelK'); // if SendData(h, 4, O.AsJSon) = 10 then // begin // sData := UpperCase(GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SOFTWARE\eCrmHomeEdition', 'LabelK')); // if sData <> '' then // DelRegValue(HKEY_LOCAL_MACHINE, 'SOFTWARE\eCrmHomeEdition', 'LabelK'); // // bAipDrm := sData.Contains('RESTRICTED') or // sData.Contains('RESTRICTED-P') or // sData.Contains('SECRET') or // sData.Contains('TOP-SECRET'); // end; // 암호화 유무만 확인... // 타인 비밀, 극비의 경우 레이블 가져오는거 조차 실패한다. 그래서 아래처럼 처리 24_0723 13:37:15 kku // 음.. 타인 비밀, 극비는 암호화 여부도 가져올 수 없다 24_0723 15:40:08 kku bAipDrm := SendData(h, 3, O.AsJSon) = 10; end else begin // 0 : 레이블 추출, 1 : 암호화, 2 : 복호화, 3 : 암호화 확인, 4 : 레이블 확인, 5 : 레이블 설정 if (SendData(h, 2, O.AsJSon) = 10) and FileExists(sDecPath) then begin sOrgPath := sPath; sPath := sDecPath; bAipDrm := true; end; end; end; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. ExtrTxtAndSearch() .. AIP or SC'); end; end else if TTgEncrypt.CheckSign(sPath, SIG_DRM) then begin bBsDrm := true; if sPass = '' then exit; if not bForceDRM then begin dec := TTgDrmDec.Create(sPath); try dec.CheckSig(SIG_DRM); // 헤더 오프셋 설정을 위해 추가 if not dec.ExtrHead(PASS_DRM_HEAD) then exit; sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d', [GetTickCount, ConvStrToHash(sPath)]); if not dec.DecryptToFile(sPass, sDecPath) then exit; sOrgPath := sPath; sPath := sDecPath; finally dec.Free; end; end; end else begin _Trace('ExtrTxtAndSearch() .. 2'); case CUSTOMER_TYPE of CUSTOMER_WELFND, CUSTOMER_WELFNI, CUSTOMER_GIORDANO, CUSTOMER_LOTTEMART : begin // 롯데마트 파수 복호화 처리 24_1104 14:58:00 kku if fas <> nil then begin _Trace('ExtrTxtAndSearch() .. 3'); var nEncType: Integer := fas.GetFileType(sPath); bScDRM := (nEncType = 103) {FSN}; // or (nEncType = 106) {NX}; if bScDRM and not bForceDRM then begin _Trace('ExtrTxtAndSearch() .. 4'); // 파수는 확장자 안넣어주면 암/복호화 동작안하는 버전이 있어서 넣어줌 25_0414 14:49:21 kku sDecPath := CttSchOpt_.sTaskDir + Format('%d-dc_%d.%s', [GetTickCount, ConvStrToHash(sPath), GetFileExt(sPath)]); var nRst: Integer := 0; if fas.DoExtract(sPath, sDecPath, true, @nRst) then begin _Trace('ExtrTxtAndSearch() .. 5'); sOrgPath := sPath; sPath := sDecPath; end else begin if sFailLogPath_ <> '' then WriteLnFileEndUTF8(sFailLogPath_, Format('[%s] %d : %s', [FormatDateTime('yyyy-mm-dd hh:nn:ss', Now), nRst, sPath])); end; if not FileExists(sDecPath) then begin if sFailLogPath_ <> '' then WriteLnFileEndUTF8(sFailLogPath_, Format('[%s] NF : %s', [FormatDateTime('yyyy-mm-dd hh:nn:ss', Now), nRst, sPath])); end; end; end; end; end; end; end; except // .. end; if bForceDRM and (llSize > 0) then begin if not bAipDrm and ( not bScDRM or (CUSTOMER_TYPE = CUSTOMER_KDNVN) ) then begin if sParentPath <> '' then sFName := sParentPath + ' > ' + ExtractFileName(sPath) else sFName := ExtractFileName(sPath); ZeroMemory(@SchResult, SizeOf(SchResult)); SchResult.sFName := sFName; SchResult.sPath := sPath; if (CttSchOpt_.sAipMdPath <> '') and (AipExtList.Count > 0) and (AipExtList.IndexOf(GetFileExt(sPath)) <> -1) then begin SchResult.bMakeDrm := SetAipLabel(sPath, CttSchOpt_.sAipLabelId); SendResult(TTgJson.ValueToJsonAsString(SchResult)); end else if not bBsDrm then begin SchResult.bMakeDrm := EncFile(sPath); SendResult(TTgJson.ValueToJsonAsString(SchResult)); end; Finalize(SchResult); end; if FileExists(sDecPath) then DeleteFile(PChar(sDecPath)); end else begin sData := ExtrTxt(sPath, sDestPath); if CttSchOpt_.bIncFName then sData := 'FileName : ' + ExtractFileName(sPath) + #13#10#13#10 + sData; if sData <> '' then begin if sOrgPath <> '' then begin // 복호화 흔적이 있으면 원본파일 정보 채워주고 sPath := sOrgPath; // 복호화 흔적 파일 삭제 해줌 // 아래에서 삭제해주는걸로 변경 24_1126 14:10:53 kku // DeleteFile(PChar(sDecPath)); end; if sParentPath <> '' then begin if sOrgPath <> '' then sFName := '*' + sParentPath + ' > ' + ExtractFileName(sPath) // 압축파일내 암호화 파일은 *로 표시 25_0530 13:04:36 kku else sFName := sParentPath + ' > ' + ExtractFileName(sPath); end else sFName := ExtractFileName(sPath); if sOrgPPath <> '' then begin // 부모 파일 경로가 있다면 (압축파일), 해당 경로로 강제 지정 sPath := sOrgPPath; end; nHitCnt := 0; sHitResults := ''; ZeroMemory(@SchResult, SizeOf(SchResult)); SchResult.sFName := sFName; SchResult.sPath := sPath; SchResult.bDrm := sOrgPath <> ''; SchResult.bOtherDrm := bScDRM; if bExtrTxtOnly_ then begin // 텍스트만 출력 기능 추가 23_0111 15:33:45 kku SchResult.nHitCnt := -100; SchResult.sResultStr := sData; SendResult(TTgJson.ValueToJsonAsString(SchResult)); end else begin sSchTxt := CttSchOpt_.sSchTxt; if sSchTxt <> '' then begin try nHitCnt := TTgPcre.GetMatchValues(sData, sSchTxt, sHitResults); if nHitCnt > 0 then begin Inc(SchResult.nHitCnt, nHitCnt); SchResult.sSchName := '*KWD*'; SchResult.sResultStr := GetCountOverlapWords(sHitResults); end; except // ... end; end; var nOrCnt: Integer := 0; var nAndCnt: Integer := 0; var nHighCnt: Integer := 0; var nTotalHitCnt: Integer := 0; var sSchName: String := ''; var sResultStr: String := ''; var sValidStr: String := ''; if PatternEntList.Count > 0 then begin for i := 0 to PatternEntList.Count - 1 do begin sSchTxt := PatternEntList[i].GetSearchText; if sSchTxt <> '' then begin try nHitCnt := TTgPcre.GetMatchValues(sData, sSchTxt, sHitResults); if nHitCnt > 0 then begin sValidStr := ''; if nHitCnt < PatternEntList[i].IfCount then continue; if sSchTxt.StartsWith('(? '' then SumString(sResultStr, sValidStr, RESULT_SEPARATOR) else SumString(sResultStr, GetCountOverlapWords(sHitResults), RESULT_SEPARATOR); end; except {$IFDEF DEBUG} on E: Exception do begin ETgException.TraceException(E, Format('PName=%s, SchTxt=%s', [PatternEntList[i].Name, sSchTxt])) end; {$ENDIF} end; end; end; end; if nTotalHitCnt > 0 then begin var bFoundOk: Boolean := true; if (nHighCnt = 0) and (PatternEntList.AndCount > 0) then begin // AND 갯수가 다르다면 X if nAndCnt <> PatternEntList.AndCount then bFoundOk := false; // OR가 조건으로 있는데 검출된 OR가 없다면 X if (PatternEntList.AndCount <> PatternEntList.Count) and (nOrCnt = 0) then bFoundOk := false; end; if bFoundOk then begin SchResult.nHitCnt := nTotalHitCnt; SchResult.sSchName := sSchName; SchResult.sResultStr := sResultStr; end; end; // _Trace('ExtrTxtAndSearch() .. 11'); if (SchResult.nHitCnt = 0) and CttSchOpt_.bNoMatchNoti then begin // 증분검사 대상에서 검출이 안되었다면 24_0611 10:01:47 kku SchResult.sResultStr := '*NoMatch*'; SendResult(TTgJson.ValueToJsonAsString(SchResult)); end else  if SchResult.nHitCnt > 0 then begin // _Trace('ExtrTxtAndSearch() .. 22, ScDRM=%s, SchResult.DRM=%s, CttSchOpt.MakeDrm=%s', [BooleanToStr(bScDRM, 'Y', 'N'), BooleanToStr(SchResult.bDrm, 'Y', 'N'), BooleanToStr(CttSchOpt_.bMakeDrm, 'Y', 'N')]); // if not SchResult.bDrm and CttSchOpt_.bMakeDrm and case CUSTOMER_TYPE of CUSTOMER_KDNVN : begin // 경동나비엔 DRM 변환 조건 추가 24_1126 13:59:34 kku if not bAipDrm and CttSchOpt_.bMakeDrm and (CttSchOpt_.sAipMdPath <> '') then begin if (CttSchOpt_.sAipMdPath <> '') and (AipExtList.Count > 0) and (AipExtList.IndexOf(GetFileExt(sPath)) <> -1) then begin SchResult.bMakeDrm := SetAipLabel(sPath, CttSchOpt_.sAipLabelId); end; end; end; CUSTOMER_WELFND, CUSTOMER_WELFNI : begin if CttSchOpt_.bMakeDrm and not bBsDrm and (fas <> nil) then begin if bScDRM then begin try sTemp := fas.GetFileHeader(sPath); if sTemp <> '' then begin SplitString(sTemp, ';', WorkList, true); if WorkList.Count > 11 then begin // 보안코드 12번째 있음 // 개인보안 등급이 아니면 다시 암호화 25_0408 10:21:32 kku if WorkList[11] <> _sSecurityLevel then begin SchResult.bMakeDrm := EncFile(sDecPath); if SchResult.bMakeDrm and FileExists(sDecPath) then begin if DeleteFile(PChar(sPath)) then MoveFile_wait(sDecPath, sPath); end; end; end; end; except // .. end; end else SchResult.bMakeDrm := EncFile(sPath); end; end; else begin if (not bScDRM and not SchResult.bDrm and CttSchOpt_.bMakeDrm) or (bAipDrm and CttSchOpt_.bMakeDrm and (CttSchOpt_.sAipMdPath <> '')) then // 대외비 된것도 대외비 개인정보로 변경되기 위한 조건 24_0306 11:09:36 kku begin // _Trace('ExtrTxtAndSearch() .. 33'); if (CttSchOpt_.sAipMdPath <> '') and (AipExtList.Count > 0) and (AipExtList.IndexOf(GetFileExt(sPath)) <> -1) then begin SchResult.bMakeDrm := SetAipLabel(sPath, CttSchOpt_.sAipLabelId); end else if not bBsDrm then begin // _Trace('ExtrTxtAndSearch() .. 44'); SchResult.bMakeDrm := EncFile(sPath); end; end; end; end; if CttSchOpt_.bExtrTxt then SchResult.sExtrTxt := sData; SendResult(TTgJson.ValueToJsonAsString(SchResult)); end else if CUSTOMER_TYPE = CUSTOMER_KDNVN then begin if not bAipDrm and CttSchOpt_.bMakeDrm and CttSchOpt_.bMakeDrmN then begin if (CttSchOpt_.sAipMdPath <> '') and (AipExtList.Count > 0) and (AipExtList.IndexOf(GetFileExt(sPath)) <> -1) then begin SchResult.bMakeDrm := SetAipLabel(sPath, CttSchOpt_.sAipLabelId); SendResult(TTgJson.ValueToJsonAsString(SchResult)); end; end; end else if not bScDRM and not SchResult.bDrm and CttSchOpt_.bMakeDrm and CttSchOpt_.bMakeDrmN then // 미검출 파일 대외비 암호화 begin // 이거 3번 중복됨.. 개선 필요... 24_0105 15:09:14 kku if (CttSchOpt_.sAipMdPath <> '') and (AipExtList.Count > 0) and (AipExtList.IndexOf(GetFileExt(sPath)) <> -1) then begin SchResult.bMakeDrm := SetAipLabel(sPath, BooleanToStr(IsHD, 'cdcaf456-5176-400c-b0e6-6301b2c47597', CttSchOpt_.sAipLabelId)); SendResult(TTgJson.ValueToJsonAsString(SchResult)); end; end; end; Finalize(SchResult); sData := ''; if not CttSchOpt_.bSaveContent then DeleteFileForce(PChar(sDestPath)); end else begin DeleteFileForce(PChar(sDestPath)); var bSendRst: Boolean := false; if (sOrgPath = '') and not bScDRM and CttSchOpt_.bMakeDrm and CttSchOpt_.bMakeDrmN then begin // 이거 3번 중복됨.. 개선 필요... 24_0105 15:09:14 kku if sParentPath <> '' then sFName := sParentPath + ' > ' + ExtractFileName(sPath) else sFName := ExtractFileName(sPath); ZeroMemory(@SchResult, SizeOf(SchResult)); SchResult.sFName := sFName; SchResult.sPath := sPath; if (CttSchOpt_.sAipMdPath <> '') and (AipExtList.Count > 0) and (AipExtList.IndexOf(GetFileExt(sPath)) <> -1) then begin SchResult.bMakeDrm := SetAipLabel(sPath, BooleanToStr(IsHD, 'cdcaf456-5176-400c-b0e6-6301b2c47597', CttSchOpt_.sAipLabelId)); SendResult(TTgJson.ValueToJsonAsString(SchResult)); bSendRst := true; end; end; if not bSendRst and CttSchOpt_.bNoMatchNoti then begin if sParentPath <> '' then begin if sOrgPath <> '' then sFName := '*' + sParentPath + ' > ' + ExtractFileName(sPath) // 압축파일내 암호화 파일은 *로 표시 25_0530 13:04:36 kku else sFName := sParentPath + ' > ' + ExtractFileName(sPath) end else sFName := ExtractFileName(sPath); ZeroMemory(@SchResult, SizeOf(SchResult)); SchResult.sFName := sFName; SchResult.sPath := sPath; SchResult.bDrm := sOrgPath <> ''; SchResult.bOtherDrm := bScDRM; // 증분검사 대상에서 검출이 안되었다면 24_0611 10:01:47 kku SchResult.sResultStr := '*NoMatch*'; SendResult(TTgJson.ValueToJsonAsString(SchResult)); end; end; if FileExists(sDecPath) then DeleteFile(PChar(sDecPath)); end; except on E: Exception do begin ETgException.TraceException(Self, E, 'Fail .. ExtrTxtAndSearch()'); if FileExists(sDestPath) then DeleteFileForce(PChar(sDestPath)); end; end; end; procedure ProcessDecompFile(sPath, sExportDir: String; sOrgCompPath: String; sParentFile: String = ''); var i: Integer; sExt, sUpDirName: String; begin try // 압축파일 처리 22_1201 14:54:18 kku DeleteDir(sExportDir, true, true); if ForceDirectories(sExportDir) then begin Inc(nDecompDepth); try if (CttSchOpt_.nUnzipDepth > 0) and (CttSchOpt_.nUnzipDepth < nDecompDepth) then exit; var FList: TStringList; Guard(FList, TStringList.Create); try DecompressFile(sPath, sExportDir, OnUnzipProgress, OnPwdEvent); ExtrFilesPathFromDir(sExportDir, FList, true); for i := 0 to FList.Count - 1 do begin sExt := GetFileExt(FList[i]).ToUpper; sUpDirName := StringReplace(ExtractFilePath(FList[i]), sExportDir, '', [rfReplaceAll]); if sUpDirName <> '' then sUpDirName := sParentFile + ' > ' + sUpDirName else sUpDirName := sParentFile; if SchExtList.IndexOf(sExt) <> -1 then ExtrTxtAndSearch(FList[i], sUpDirName, sOrgCompPath) else if CttSchOpt_.bIncZip and (Pos(sExt, COMPRESS_EXTS) > 0) then ProcessDecompFile(FList[i], Format('%s%d\', [sExportDir, nDecompDepth]), sOrgCompPath, sUpDirName + ' > ' + ExtractFileName(FList[i])); end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. Unzip'); end; finally DeleteDir(sExportDir, true, true); Dec(nDecompDepth); end; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. ProcessDecompFile()'); end; end; var sPath, sExtrDir, sExt: String; i: Integer; begin sEncDir := 'C:\ProgramData\HE\EncTask\'; sEmpNo := ''; sHost := ''; sDept := ''; sPoName := ''; dwCsType := 0; if (CttSchOpt_.sAipMdPath = '') and (CttSchOpt_.sAipDMail <> '') then begin var StrList: TStringList; Guard(StrList, TStringList.Create); SplitString(CttSchOpt_.sAipDMail, '|', StrList, true); if StrList.Count >= 5 then begin sEmpNo := StrList[0]; sHost := StrList[1]; sDept := StrList[2]; sPoName := StrList[3]; dwCsType := StrToIntDef(StrList[4], 0); end; end; case CUSTOMER_TYPE of CUSTOMER_WELFNI, CUSTOMER_WELFND : begin sFailLogPath_ := GetRunExePathDir + 'Log\'; ForceDirectories(sFailLogPath_); sFailLogPath_ := sFailLogPath_ + LOG_FS_DEC_FAIL; // 파수 복호화 로그 초기화 25_1111 14:51:17 kku if FileExists(sFailLogPath_) then DeleteFile(PChar(sFailLogPath_)); end; end; fas := nil; sFasgPath := ''; hFasg := 0; if UseFasooDecrypt then begin if CUSTOMER_TYPE = CUSTOMER_CJONS then begin // 파수 클라이언트가 없는 환경에서 복호화 준비 sFasgPath := GetRunExePathDir + DIR_CONF + EXE_FASOO_GLOBAL; sFasgParam := GetRunExePathDir + DIR_CONF + DAT_PARAM; // _Trace('Init Fasoo .. 1'); if FileExists(sFasgPath) then begin var O: ISuperObject := SO; O.S['OwnerX'] := sMtx_; {$IFDEF DEBUG} O.B['Trace'] := true; O.S['TracePath'] := GetRunExePath + '.log'; {$ENDIF} O.I['Type'] := 1; if SaveJsonObjToFile(O, sFasgParam) then begin // _Trace('Init Fasoo .. 2'); var nTO: Integer := 0; while hFasg = 0 do begin if nTO > 10 then break; if GetProcessPidByName(EXE_FASOO_GLOBAL) = 0 then begin if not FileExists(sFasgPath) then break; ExecutePath_hide(sFasgPath); // _Trace('Init Fasoo .. 3'); Sleep(1000); end; hFasg := FindWindow(PChar('TDlgbs1fsgMain'), PChar('Dlgbs1fsgMain')); if hFasg = 0 then hFasg := FindWindow(PChar('TDlgbs1fsgMain'), PChar('Dlgbs1fsgMain')); Sleep(200); Inc(nTO); end end; // _Trace('Init Fasoo .. 4, hFasg=%d', [hFasg]); end else sFasgPath := ''; end else begin case CUSTOMER_TYPE of CUSTOMER_LOTTEMART : SetDSD_CODE(DSD_CODE_LOTTEMART); // CUSTOMER_CJONS : SetDSD_CODE(DSD_CODE_CJ); CUSTOMER_WELFNI : SetDSD_CODE(DSD_CODE_WFNI); CUSTOMER_WELFND : SetDSD_CODE(DSD_CODE_WFND); CUSTOMER_GIORDANO : SetDSD_CODE(DSD_CODE_GIORDANO); end; var sFsDir: String := GetRunExePathDir + 'fsdinit'; if not DirectoryExists(sFsDir) then sFsDir := GetRunExePathDir + DIR_CONF + 'fsdinit'; if DirectoryExists(sFsDir) then begin CoInitializeEx(nil, COINIT_APARTMENTTHREADED); fas := TTgFasoo.Create(sFsDir); end; end; end; Guard(KvFilter, TKvFilter.Create(CttSchOpt_.sKvMdPath, CttSchOpt_.nKvTimeoutSec)); Guard(WorkList, TStringList.Create); Guard(SchExtList, TStringList.Create); // 이미지 확장자 추가 24_0516 10:32:21 kku, todo : 옵션별 처리? // SplitString(UpperCase(DOC_EXTS) + '|' + UpperCase(OCR_IMG_EXTS), '|', SchExtList); SplitString(UpperCase(CttSchOpt_.sZipExts), '|', SchExtList); Guard(AipExtList, TStringList.Create); SplitString(CttSchOpt_.sAipExt, '|', AipExtList, false, true); AipExtList.CaseSensitive := false; Guard(MgPtrn, TManagerPattern.Create); if nLangID_ <> 0 then MgPtrn.LangId := nLangID_; Guard(PatternEntList, TPatternEntList.Create(false)); if (sSchPtrns_ <> '') or (CttSchOpt_.sCustomKwdPtrn <> '') then begin var StrList: TStringList; Guard(StrList, TStringList.Create); var PtrnEnt: TPatternEnt; SplitString(sSchPtrns_, '|', StrList); if CttSchOpt_.sCustomKwdPtrn <> '' then begin var CusList: TStringList; Guard(CusList, TStringList.Create); SplitString(CttSchOpt_.sCustomKwdPtrn, '**', CusList); var InfoList: TStringList; Guard(InfoList, TStringList.Create); for i := 0 to CusList.Count - 1 do begin SplitString(CusList[i], '::', InfoList); if InfoList.Count > 4 then begin PtrnEnt := MgPtrn.GetPatternEntByName(InfoList[0]); if PtrnEnt = nil then begin PtrnEnt := TPatternEnt.Create(MgPtrn, nil, nil, StrToIntDef(InfoList[2], 1)); PtrnEnt.AddName(MgPtrn.LangId, InfoList[0]); MgPtrn.EntList.Add(PtrnEnt); StrList.Add(InfoList[0]); end; PtrnEnt.RType := ManagerPattern.TRuleType(StrToIntDef(InfoList[3], 0)); if InfoList.Count > 5 then PtrnEnt.RSeverity := ManagerPattern.TRuleSeverity(StrToIntDef(InfoList[5], 0)); PtrnEnt.IsAnd := InfoList[4] = 'T'; PtrnEnt.PatternList.Add(InfoList[1]); end; end; // for i := 0 to CusList.Count - 1 do // begin // sPtrnEnt := CusList[i]; // nPos := Pos('::', sPtrnEnt); // if nPos > 0 then // begin // sPtrnName := Copy(sPtrnEnt, 1, nPos - 1); // Delete(sPtrnEnt, 1, nPos + 1); // nPos := Pos('|*|', sPtrnEnt); // if nPos > 0 then // begin // sPtrnVal := Copy(sPtrnEnt, 1, nPos - 1); // Delete(sPtrnEnt, 1, nPos + 2); // nCnt := StrToIntDef(sPtrnEnt, 1); // end else begin // sPtrnVal := sPtrnEnt; // nCnt := 1; // end; // // PtrnEnt := MgPtrn.GetPatternEntByName(sPtrnName); // if PtrnEnt = nil then // begin // PtrnEnt := TPatternEnt.Create(MgPtrn, nil, nil, nCnt); // PtrnEnt.AddName(MgPtrn.LangId, sPtrnName); // MgPtrn.EntList.Add(PtrnEnt); // StrList.Add(sPtrnName); // end; // PtrnEnt.PatternList.Add(sPtrnVal); // end; // end; end; for i := 0 to StrList.Count - 1 do begin PtrnEnt := MgPtrn.GetPatternEntByName(StrList[i]); if PtrnEnt <> nil then PatternEntList.Add(PtrnEnt); end; end else MgPtrn.GetUsePatternEnt(PatternEntList); if CttSchOpt_.sMK <> '' then sPass := DecText(CttSchOpt_.sMK) else sPass := ''; sExtrDir := CttSchOpt_.sTaskDir + '@etr\'; while not Terminated and not GetWorkStop do begin try DeleteFile(PChar(sDecPath)); sDecPath := ''; Lock; try if qSchEnt_.Count > 0 then sPath := qSchEnt_.Dequeue else sPath := ''; finally Unlock; end; if (sPath = '') or not FileExists(sPath) then begin SendMessage(CttSchOpt_.hRcvHwnd, WM_CTTSCH_REQUEST, KV_REQUEST_SEARCH_PATH, llTasker_); Sleep(250); continue; end; if not ForceDirectories(CttSchOpt_.sTaskDir) then begin _Trace('Fail .. CreateTaskDir()'); exit; end; sExt := UpperCase(GetFileExt(sPath)); if CttSchOpt_.bIncZip and (Pos(sExt, COMPRESS_EXTS) > 0) then begin nDecompDepth := 0; ProcessDecompFile(sPath, sExtrDir, sPath, ExtractFileName(sPath)); DeleteDir(sExtrDir, true, true); end else ExtrTxtAndSearch(sPath); SendMessage(CttSchOpt_.hRcvHwnd, WM_CTTSCH_REQUEST, KV_REQUEST_SEARCH_PATH, llTasker_); except on E: Exception do begin Sleep(500); ETgException.TraceException(Self, E, 'Fail .. Execute()'); end; end; end; end; end.