{*******************************************************} { } { ThdProcStoredPacket } { } { Copyright (C) 2022 kku } { } {*******************************************************} unit ThdProcStoredPacket; interface uses Tocsg.Thread, Tocsg.StoredPacket, System.SysUtils, Winapi.Windows, System.Classes, System.Generics.Collections; const MAX_THREAD_COUNT = 2; type TThdProcStoredPacket = class(TTgThread) private ullNextDelaySec_: ULONGLONG; dwTaskType_: DWORD; sAgentDataDir_, sStoredPath_: String; dtCreate_, dtLastProc_: TDateTime; nLastCmd_: Integer; sLastProcPath_: String; procedure SetLastProcInfo(dtVal: TDateTime; nCmd: Integer; sPath: String); function GetLastProcDT: TDateTime; function GetLastCmd: Integer; function GetLastProcPath: String; protected procedure Execute; override; public Constructor Create(const sAgentDataDir, sStoredPath: String; ullNextDelaySec: ULONGLONG); property StoredPath: String read sStoredPath_; property WorkState: TTgThreadState read GetWorkState; property CreateDT: TDateTime read dtCreate_; property LastProcDT: TDateTime read GetLastProcDT; property LastCmd: Integer read GetLastCmd; property LastProcPath: String read GetLastProcPath; end; TThdProcStoredPacketFile = class(TTgThread) private ullNextDelaySec_: ULONGLONG; sAgentInfoDir_, sStoredDir_: String; ProcThreadList_: TList; procedure OnProcThreadNotify(Sender: TObject; const Item: TThdProcStoredPacket; Action: TCollectionNotification); protected procedure Execute; override; public Constructor Create(const sAgentInfoDir, sStoredDir: String; ullNextDelaySec: ULONGLONG); Destructor Destroy; override; end; implementation uses Tocsg.Packet, Tocsg.Exception, Tocsg.Safe, Tocsg.Files, System.DateUtils, RSecuServer; { TThdProcStoredPacket } Constructor TThdProcStoredPacket.Create(const sAgentDataDir, sStoredPath: String; ullNextDelaySec: ULONGLONG); begin Inherited Create; dtCreate_ := Now; dtLastProc_ := dtCreate_; dwTaskType_ := 0; sAgentDataDir_ := sAgentDataDir; sStoredPath_ := sStoredPath; ullNextDelaySec_ := ullNextDelaySec; StartThread; end; procedure TThdProcStoredPacket.SetLastProcInfo(dtVal: TDateTime; nCmd: Integer; sPath: String); begin Lock; try dtLastProc_ := dtVal; nLastCmd_ := nCmd; sLastProcPath_ := sPath; finally Unlock; end; end; function TThdProcStoredPacket.GetLastProcDT: TDateTime; begin Lock; try Result := dtLastProc_; finally Unlock; end; end; function TThdProcStoredPacket.GetLastCmd: Integer; begin Lock; try Result := nLastCmd_; finally Unlock; end; end; function TThdProcStoredPacket.GetLastProcPath: String; begin Lock; try Result := sLastProcPath_; finally Unlock; end; end; procedure TThdProcStoredPacket.Execute; var LoadPacket: TLoadPacket; pBuf: TBytes; Rcv: IRcvPacket; nCmd: Integer; sProcPath: String; begin SetLastProcInfo(Now, 0, ''); SetWorkState(tsWorking); LoadPacket := TLoadPacket.Create(sStoredPath_, false); if LoadPacket.LastError = ERROR_SUCCESS then begin try try dwTaskType_ := LoadPacket.TaskType; if dwTaskType_ <> TASK_DESTROY then begin LoadPacket.InitLoadHeader; pBuf := LoadPacket.PopPacketBuf; while not Terminated and not WorkStop and (pBuf <> nil) do begin try // if (pBuf[4] = 123) and // ((pBuf[3] <> 58) and // : // (pBuf[3] <> 123) and // { // (pBuf[3] <> 91) and // [ // (pBuf[3] <> 44)) and // , // ((pBuf[5] = 34)) then // " // begin // Rcv := TTgPacket..Create(pBuf, true); // end else Rcv := TTgPacket.Create(pBuf, false); nCmd := Rcv.Command; sProcPath := sAgentDataDir_ + Rcv.S['P0'] + '\'; SetLastProcInfo(Now, nCmd, sProcPath); case nCmd of 0 : ; // QTC_AGENT_LOG : process_QTC_CLIENT_LOG_forAgent(sProcPath + DIR_COLLECT_AGENTLOG, Rcv); end; except on E: Exception do ETgException.TraceException(Self, E); end; pBuf := LoadPacket.PopPacketBuf; end; end; except on E: Exception do ETgException.TraceException(Self, E); end; finally FreeAndNil(LoadPacket); if not Terminated and not WorkStop then DeleteFile(PChar(sStoredPath_)); end; end else begin FreeAndNil(LoadPacket); DeleteFile(PChar(sStoredPath_)); end; if ullNextDelaySec_ > 0 then begin // ÇÊ¿ä ½Ã ´ÙÀ½ ÆÐŶ 󸮸¦ Áö¿¬ Sleep(ullNextDelaySec_ * 1000); end; SetWorkState(tsCompleted); end; { TThdProcStoredPacketFile } Constructor TThdProcStoredPacketFile.Create(const sAgentInfoDir, sStoredDir: String; ullNextDelaySec: ULONGLONG); begin Inherited Create; sAgentInfoDir_ := sAgentInfoDir; sStoredDir_ := sStoredDir; ullNextDelaySec_ := ullNextDelaySec; ProcThreadList_ := TList.Create; ProcThreadList_.OnNotify := OnProcThreadNotify; StartThread; end; Destructor TThdProcStoredPacketFile.Destroy; begin FreeAndNil(ProcThreadList_); Inherited; end; procedure TThdProcStoredPacketFile.OnProcThreadNotify(Sender: TObject; const Item: TThdProcStoredPacket; Action: TCollectionNotification); begin case Action of cnAdded: ; cnRemoved: begin Item.StopThread; Item.Free; end; cnExtracted: ; end; end; function StringListCompareFileCreateDate(List: TStringList; Index1, Index2: Integer): Integer; var ftCreate1, ftCreate2, ftModify, ftAccess: TFileTime; begin if (Index1 >= 0) and (Index1 < List.Count) and (Index2 >= 0) and (Index2 < List.Count) then begin GetFileDateTime(List[Index1], ftCreate1, ftModify, ftAccess); GetFileDateTime(List[Index2], ftCreate2, ftModify, ftAccess); Result := CompareFileTime(ftCreate2, ftCreate1); end else Result := 0; end; procedure TThdProcStoredPacketFile.Execute; var i: Integer; wfd: TWin32FindData; hSc: THandle; sDir, sPath: String; PkFileList: TStringList; bTimeout, bTimeout2: Boolean; dtNow: TDateTime; function CheckUse: Boolean; var n: Integer; begin Result := false; if ProcThreadList_.Count > 0 then begin for n := 0 to ProcThreadList_.Count - 1 do if ProcThreadList_[n].StoredPath = sPath then begin Result := true; exit; end; end; if (gServer <> nil) and gServer.Active then gServer.SafeFreeUseSaveStored(sPath); end; begin Guard(PkFileList, TStringList.Create); PkFileList.CaseSensitive := false; sDir := ExtractFilePath(sStoredDir_); while not Terminated and not WorkStop do begin try if ProcThreadList_.Count < MAX_THREAD_COUNT then begin sDir := IncludeTrailingPathDelimiter(sDir); sPath := sDir + '*.*'; hSc := FindFirstFile(PChar(sPath), wfd); if hSc = INVALID_HANDLE_VALUE then exit; if PkFileList.Count = 0 then begin try Repeat if (String(wfd.cFileName) <> '.') and (String(wfd.cFileName) <> '..') then if ((wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) <> 0) then begin if Terminated or WorkStop then exit; end else begin if Terminated or WorkStop then exit; if Pos('collectdata.', wfd.cFileName) > 0 then PkFileList.Add(sDir + wfd.cFileName); end; Until not FindNextFile(hSc, wfd); finally FindClose(hSc); PkFileList.CustomSort(StringListCompareFileCreateDate); end; end; for i := PkFileList.Count - 1 downto 0 do begin sPath := PkFileList[i]; PkFileList.Delete(i); if FileExists(sPath) and not CheckUse then begin ProcThreadList_.Add(TThdProcStoredPacket.Create(sAgentInfoDir_, sPath, ullNextDelaySec_)); if ProcThreadList_.Count >= MAX_THREAD_COUNT then begin break; end; end; end; end; for i := ProcThreadList_.Count - 1 downto 0 do begin dtNow := Now; bTimeout := MinutesBetween(ProcThreadList_[i].LastProcDT, dtNow) >= 3; bTimeout2 := MinutesBetween(ProcThreadList_[i].CreateDT, dtNow) >= 60; if bTimeout or bTimeout2 or (ProcThreadList_[i].WorkState = tsCompleted) then // ŸÀӾƿô begin if bTimeout then _Trace('WorkThread Timeout .. PacketFile = %s, LastCmd = %d, LastProcPath = %s', [ProcThreadList_[i].StoredPath, ProcThreadList_[i].LastCmd, ProcThreadList_[i].LastProcPath]); if bTimeout2 then _Trace('WorkThread Timeout2 .. PacketFile = %s, LastCmd = %d, LastProcPath = %s, CreateDT = %s', [ProcThreadList_[i].StoredPath, ProcThreadList_[i].LastCmd, ProcThreadList_[i].LastProcPath, DateTimeToStr(ProcThreadList_[i].CreateDT)]); ProcThreadList_.Delete(i); end; end; Sleep(100); except // end; end; end; end.