415 lines
13 KiB
Plaintext
415 lines
13 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ CrmUtil }
|
|
{ }
|
|
{ Copyright (C) 2022 kku }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit CrmUtil;
|
|
|
|
interface
|
|
|
|
uses
|
|
IdHTTP, System.Classes, Winapi.Windows;
|
|
|
|
function GetRandomString(nLen: Integer): String;
|
|
function GetADUserName: String;
|
|
function GetUserNameFromExplorer: String;
|
|
|
|
function VerifyEmpNo(sSvrUrl: String; aHTTP: TIdHTTP; sEmpNo: String): Boolean;
|
|
function GetEmpNoInfo(sSvrUrl: String; aHTTP: TIdHTTP; sEmpNo: String): String;
|
|
|
|
function GetQuarantineInfo(sSvrUrl: String; aHTTP: TIdHTTP; sHostInfo: String): String;
|
|
|
|
function ExtrTextFromImage(sImgPath: String; aAngle: Extended = 0): String;
|
|
|
|
function SendData(h: HWND; dwCmd: DWORD; const sData: String): LONGLONG;
|
|
|
|
// KBIZ에서 엑셀이 한번에 재대로 실행 안되는 현상이 있어서 작성
|
|
procedure ExcelCheckAndHideRun(sUserSid: String);
|
|
|
|
implementation
|
|
|
|
uses
|
|
Tocsg.Registry, System.SysUtils, Tocsg.Exception,
|
|
Tocsg.Process, Condition, Tocsg.Trace, Tocsg.WTS, Tocsg.Safe, Tocsg.Path,
|
|
GlobalDefine, Tocsg.WinInfo, IdMultipartFormData, superobject, Tocsg.Files,
|
|
Tocsg.Shell, Tocsg.Graphic, Winapi.Messages,
|
|
DefineHelper, Tocsg.Strings;
|
|
|
|
var
|
|
_DoGetInfoCount: Integer = 0;
|
|
|
|
function GetRandomString(nLen: Integer): String;
|
|
const
|
|
arrRanChar: array [0..13] of Char =
|
|
('a', 'b', 'c', 'd', 'e', 'f', 'g',
|
|
'h', 'x', 't', 'z', 'u', 'l', 'k');
|
|
var
|
|
i: Integer;
|
|
begin
|
|
Result := '';
|
|
if nLen = 0 then
|
|
|
|
Randomize;
|
|
for i := 1 to nLen do
|
|
Result := Result + arrRanChar[Random(13)];
|
|
end;
|
|
|
|
function GetADUserName: String;
|
|
var
|
|
sAdHostName: String;
|
|
begin
|
|
Result := '';
|
|
|
|
// AD 환경에서 호스트명(컴퓨터 이름)을 다르게 가져오도록 보완 (김경덕프로 요청, 다이이찌산쿄) 22_0629 09:37:23 kku
|
|
// 주의 : 비밀번호 취약상태 점검때는 사용하면 안된다. 이렇게 하면 로그온정보 제대로 가져올 수 없음
|
|
sAdHostName := GetRegValueAsString(HKEY_LOCAL_MACHINE,
|
|
'SOFTWARE\Microsoft\Windows\CurrentVersion\Group Policy\DataStore\Machine\0', 'szTargetName');
|
|
|
|
// 보완 24_0108 12:57:40 kku
|
|
if sAdHostName = '' then
|
|
sAdHostName := GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName', 'ComputerName');
|
|
|
|
if sAdHostName <> '' then
|
|
begin
|
|
var sUser: String := '';
|
|
var sRegKey: String := GetRegRecentUserSid;
|
|
|
|
if sRegKey <> '' then
|
|
begin
|
|
sUser := Trim(GetRegValueAsString(HKEY_USERS, sRegKey + '\Volatile Environment', 'USERNAME'));
|
|
if sUser = '' then
|
|
sUser := GetUserNameFromReg(sRegKey);
|
|
if sUser = '' then
|
|
TTgTrace.T('RecentUserSid = %s', [sRegKey]);
|
|
end else
|
|
TTgTrace.T('Fail .. GetADUserName()');
|
|
|
|
if sUser = '' then
|
|
begin
|
|
sUser := WTS_GetCurrentUserName; // 패스워드 취약점검 안하면 사용자 계정 상관없어서 이렇게 처리 22_0705 14:38:37 kku
|
|
if sUser = '' then
|
|
TTgTrace.T('Fail?? WTS_GetCurrentUserName()'); // AD 환경에서 실패하는것을 확인함. 다시 실행하면 되는 경우 있음 22_0721 15:43:52 kku
|
|
end;
|
|
|
|
Result := sAdHostName + '\' + sUser;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
function GetUserNameFromExplorer: String;
|
|
var
|
|
PList: TProcessEntList;
|
|
pEnt: PProcessEntInfo;
|
|
PidList: TProcessIdList;
|
|
i: Integer;
|
|
begin
|
|
if IsUseLocalHostName then
|
|
begin
|
|
// 로컬 호스트네임으로 가져오도록 고정 24_0321 10:04:54 kku
|
|
var sCom: String := GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Control\ComputerName\ComputerName', 'ComputerName');
|
|
var sUser: String := GetRegValueAsString(HKEY_USERS, GetRegRecentUserSid + '\Volatile Environment', 'USERNAME');
|
|
|
|
// 카스퍼스키 계정 프록시? 기능 때문에 제대로 계정 정보를 가져올수 없다...
|
|
// GetUserNameFromReg() 로도 계정 권한이 "%SystemRoot%\ServiceProfiles\ksnproxy" 로 확인됨 24_0327 15:47:43 kku
|
|
if sUser = '' then
|
|
sUser := WTS_GetCurrentUserName;
|
|
|
|
if (sCom <> '') and (sUser <> '') then
|
|
begin
|
|
Result := sCom + '\' + sUser;
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
if IsUseActiveDirectory then // and IsSkipPwd then
|
|
begin
|
|
Result := GetADUserName;
|
|
if Result <> '' then
|
|
exit;
|
|
end;
|
|
|
|
Result := GetDomainUserNameFromReg;
|
|
if Result <> '' then
|
|
exit;
|
|
|
|
try
|
|
Guard(PidList, TProcessIdList.Create);
|
|
if GetProcessPidsByName('explorer.exe', PidList) > 0 then
|
|
begin
|
|
Guard(PList, TProcessEntList.Create);
|
|
PList.UpdateProcessList;
|
|
|
|
for i := 0 to PidList.Count - 1 do
|
|
begin
|
|
pEnt := PList.GetProcInfoByPid(PidList[i]);
|
|
if pEnt <> nil then
|
|
begin
|
|
Result := Trim(pEnt.sOwner);
|
|
if Result = '\\\' then
|
|
Result := '';
|
|
|
|
if Result <> '' then
|
|
begin
|
|
DeleteFile(PChar(GetRunExePathDir + LOG_RESTART));
|
|
exit;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
if Result = '' then
|
|
begin
|
|
var sPath: String := GetRunExePathDir + LOG_RESTART;
|
|
if FileExists(sPath) then
|
|
begin
|
|
// 다시 시작했는데도 안되면.. 그냥 일반적으로 구해준다. 22_0613 08:16:07 kku
|
|
DeleteFile(PChar(sPath));
|
|
Result := GetComName + '\' + WTS_GetCurrentUserName;
|
|
TTgTrace.T('Fail .. GetUserNameFromExplorer(), Restart.. UserName="%s"', [Result]);
|
|
end else begin
|
|
Inc(_DoGetInfoCount);
|
|
TTgTrace.T('Fail .. GetUserNameFromExplorer(), TryCount=%d', [_DoGetInfoCount]);
|
|
if _DoGetInfoCount > 5 then
|
|
begin
|
|
var sName: String := GetUserNameFromReg;
|
|
if sName = '' then
|
|
begin
|
|
TTgTrace.T('Fail .. GetUserNameFromExplorer(), Terminate..');
|
|
WriteLnFileEndUTF8(sPath, Format('[%s] Fail .. GetUserNameFromExplorer()', [DateTimeToStr(Now)]));
|
|
TerminateProcess(GetCurrentProcess, 900);
|
|
end else
|
|
Result := GetComName + '\' + sName;
|
|
end;
|
|
end;
|
|
end;
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
Result := GetComName + '\' + WTS_GetCurrentUserName;
|
|
ETgException.TraceException(E, 'Fail .. GetUserNameFromExplorer()');
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function VerifyEmpNo(sSvrUrl: String; aHTTP: TIdHTTP; sEmpNo: String): Boolean;
|
|
var
|
|
ss: TStringStream;
|
|
nOldTM1,
|
|
nOldTM2: Integer;
|
|
O: ISuperObject;
|
|
begin
|
|
Result := false;
|
|
try
|
|
if CUSTOMER_TYPE = CUSTOMER_CNSCERT then
|
|
begin
|
|
// CNSCERT는 인사연동을 하지 않기 때문에 사번 패턴만 검증함 22_0711 16:14:43 kku
|
|
Result := IsCheckEmpNoCNSCERT(sEmpNo);
|
|
exit;
|
|
end;
|
|
|
|
nOldTM1 := aHTTP.ReadTimeout;
|
|
nOldTM2 := aHTTP.ConnectTimeout;
|
|
try
|
|
// sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequests.do', 'agentEmpNoChecks.do', [rfReplaceAll]);
|
|
// sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequest.do', 'agentEmpNoCheck.do', [rfReplaceAll]);
|
|
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequests.do', 'agentEmpInfo.do', [rfReplaceAll]);
|
|
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequest.do', 'agentEmpInfos.do', [rfReplaceAll]);
|
|
|
|
Guard(ss, TStringStream.Create('{\"Request : HeartBeat\"}', TEncoding.UTF8));
|
|
aHTTP.Request.ContentType := 'application/json; charset=utf-8';
|
|
aHTTP.Request.CustomHeaders.Clear; // 메인에서 DRM 처리도 같이 해주고 있기 때문에 초기화 해줘야 한다 22_0602 08:25:35 kku
|
|
aHTTP.Request.CustomHeaders.Values['requestType'] := sEmpNo;
|
|
|
|
// Result := aHTTP.Post(sSvrUrl, ss) = 'true';
|
|
O := SO(aHTTP.Post(sSvrUrl, ss));
|
|
Result := O.S['result'] = 'true';
|
|
finally
|
|
aHTTP.ReadTimeout := nOldTM1;
|
|
aHTTP.ConnectTimeout := nOldTM2;
|
|
end;
|
|
except
|
|
{$IFDEF TRACE1}
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, Format('Fail .. VerifyEmpNo(), RqType=%s', [sRqType]));
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
function GetEmpNoInfo(sSvrUrl: String; aHTTP: TIdHTTP; sEmpNo: String): String;
|
|
var
|
|
ss: TStringStream;
|
|
nOldTM1,
|
|
nOldTM2: Integer;
|
|
begin
|
|
Result := '';
|
|
try
|
|
nOldTM1 := aHTTP.ReadTimeout;
|
|
nOldTM2 := aHTTP.ConnectTimeout;
|
|
try
|
|
if CUSTOMER_TYPE = CUSTOMER_CNSCERT then
|
|
begin
|
|
// CNSCERT는 인사연동을 하지 않기 때문에 사번 패턴만 검증함 22_0711 16:14:43 kku
|
|
if IsCheckEmpNoCNSCERT(sEmpNo) then
|
|
Result := 'true';
|
|
exit;
|
|
end;
|
|
|
|
if Pos('agentLogRequests.do', sSvrUrl) = 0 then
|
|
begin
|
|
sSvrUrl := sSvrUrl + 'agentEmpInfo.do';
|
|
end else begin
|
|
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequests.do', 'agentEmpInfo.do', [rfReplaceAll]);
|
|
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequest.do', 'agentEmpInfos.do', [rfReplaceAll]);
|
|
end;
|
|
|
|
Guard(ss, TStringStream.Create('{\"Request : HeartBeat\"}', TEncoding.UTF8));
|
|
aHTTP.Request.ContentType := 'application/json; charset=utf-8';
|
|
aHTTP.Request.CustomHeaders.Clear; // 메인에서 DRM 처리도 같이 해주고 있기 때문에 초기화 해줘야 한다 22_0602 08:25:35 kku
|
|
aHTTP.Request.CustomHeaders.Values['requestType'] := sEmpNo;
|
|
|
|
Result := aHTTP.Post(sSvrUrl, ss);
|
|
finally
|
|
aHTTP.ReadTimeout := nOldTM1;
|
|
aHTTP.ConnectTimeout := nOldTM2;
|
|
end;
|
|
except
|
|
// on E: Exception do
|
|
// raise Exception.Create(E.Message);
|
|
{$IFDEF TRACE1}
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, Format('Fail .. GetEmpNoInfo(), RqType=%s', [sRqType]));
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
function GetQuarantineInfo(sSvrUrl: String; aHTTP: TIdHTTP; sHostInfo: String): String;
|
|
var
|
|
ss: TStringStream;
|
|
nOldTM1,
|
|
nOldTM2: Integer;
|
|
begin
|
|
Result := '';
|
|
try
|
|
nOldTM1 := aHTTP.ReadTimeout;
|
|
nOldTM2 := aHTTP.ConnectTimeout;
|
|
try
|
|
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequests.do', 'getQuarantineFileInfo.do', [rfReplaceAll]);
|
|
sSvrUrl := StringReplace(sSvrUrl, 'agentLogRequest.do', 'getQuarantineFileInfo.do', [rfReplaceAll]);
|
|
|
|
Guard(ss, TStringStream.Create('{\"Request : HeartBeat\"}', TEncoding.UTF8));
|
|
// Guard(ss, TStringStream.Create(sEmpNo, TEncoding.UTF8));
|
|
aHTTP.Request.ContentType := 'application/json; charset=utf-8';
|
|
aHTTP.Request.CustomHeaders.Clear; // 메인에서 DRM 처리도 같이 해주고 있기 때문에 초기화 해줘야 한다 22_0602 08:25:35 kku
|
|
aHTTP.Request.CustomHeaders.Values['requestType'] := sHostInfo; // gMgSvc.AgentModel.AgentId;
|
|
|
|
Result := aHTTP.Post(sSvrUrl, ss);
|
|
finally
|
|
aHTTP.ReadTimeout := nOldTM1;
|
|
aHTTP.ConnectTimeout := nOldTM2;
|
|
end;
|
|
except
|
|
// on E: Exception do
|
|
// raise Exception.Create(E.Message);
|
|
{$IFDEF TRACE1}
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, Format('Fail .. GetQuarantineInfo(), RqType=%s', [sRqType]));
|
|
{$ENDIF}
|
|
end;
|
|
end;
|
|
|
|
function ExtrTextFromImage(sImgPath: String; aAngle: Extended = 0): String;
|
|
var
|
|
sOcr,
|
|
sOutPath,
|
|
sTempPath: String;
|
|
StrList: TStringList;
|
|
begin
|
|
Result := '';
|
|
sTempPath := '';
|
|
sOcr := GetRunExePathDir + DIR_CONF + EXE_OCR;
|
|
if not FileExists(sOcr) then
|
|
sOcr := GetRunExePathDir + EXE_OCR;
|
|
|
|
if FileExists(sOcr) then
|
|
begin
|
|
sOutPath := sOcr[1] + ':\ProgramData\HE\Task\' + ExtractFileName(sImgPath) + '.$xt';
|
|
if ForceDirectories(ExtractFilePath(sOutPath)) then
|
|
begin
|
|
if aAngle <> 0 then
|
|
begin
|
|
sTempPath := CutFileExt(sImgPath) + 'R18.png';
|
|
if RotatePngFile(sImgPath, sTempPath, aAngle) then
|
|
sImgPath := sTempPath;
|
|
end;
|
|
|
|
try
|
|
ExecuteAppWaitUntilTerminate(sOcr, Format('"%s" "%s"', [sImgPath, sOutPath]), SW_HIDE);
|
|
finally
|
|
if sTempPath <> '' then
|
|
DeleteFile(sTempPath);
|
|
end;
|
|
|
|
if FileExists(sOutPath) then
|
|
begin
|
|
Result := ExtractTextSafe(sOutPath);
|
|
DeleteFile(sOutPath);
|
|
end;
|
|
end;
|
|
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 ExcelCheckAndHideRun(sUserSid: String);
|
|
var
|
|
sPath: String;
|
|
begin
|
|
if GetProcessPidByName('excel.exe') <> 0 then
|
|
exit;
|
|
|
|
sPath := '';//GetRegValueAsString(HKEY_USERS, sUserSid + '\Software\Microsoft\Windows\CurrentVersion\Extensions', 'xlsx');
|
|
|
|
if (sPath = '') or not FileExists(sPath) then
|
|
begin
|
|
sPath := GetRegValueAsString(HKEY_CLASSES_ROOT, 'dqyfile\DefaultIcon', '');
|
|
if sPath <> '' then
|
|
begin
|
|
var nPos: Integer := Pos(',', sPath);
|
|
if nPos > 0 then
|
|
Delete(sPath, nPos, Length(sPath) - nPos + 1);
|
|
|
|
if not FileExists(sPath) then
|
|
exit;
|
|
end;
|
|
end;
|
|
|
|
{$IFDEF DEBUG}
|
|
ExecutePath_hide(sPath);
|
|
{$ELSE}
|
|
var O: ISuperObject := SO;
|
|
O.I['Cmd'] := HPCMD_EXECUTE_FILE;
|
|
O.S['Path'] := sPath;
|
|
O.B['Hide'] := true;
|
|
SaveJsonObjToFile(O, GetRunExePathDir + DIR_CONF + DAT_PARAM);
|
|
|
|
var sHlpExe: String := GetRunExePathDir + DIR_CONF + EXE_HLP;
|
|
|
|
ExecuteAppAsUser('explorer.exe', sHlpExe, '', SW_HIDE);
|
|
{$ENDIF}
|
|
end;
|
|
|
|
end.
|