@@ -275,6 +275,11 @@ ULONGLONG GetProcessCreationTime(DWORD pid) {
275275 CloseHandle (hProcess);
276276 return 0 ;
277277}
278+
279+ ULONGLONG GetProcessCreationTime (DWORD pid, const std::unordered_map<DWORD , PROCESSENTRY32 >& pidMap) {
280+ if (!pidMap.empty () && pidMap.find (pid) == pidMap.end ()) return 0 ;
281+ return GetProcessCreationTime (pid);
282+ }
278283// Process uptime helper
279284// Reference: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes
280285// While this does indeed give you the time since the process was created,
@@ -311,6 +316,27 @@ std::string GetReadableFileTime(DWORD pid) {
311316 return oss.str ();
312317}
313318
319+ std::string GetReadableFileTime (DWORD pid, const std::unordered_map<DWORD , PROCESSENTRY32 >& pidMap) {
320+ ULONGLONG creationTime = GetProcessCreationTime (pid, pidMap);
321+ if (creationTime == 0 ) return " N/A" ;
322+ time_t unixTime = windows_time_to_unix_epoch (creationTime);
323+ time_t now = std::time (nullptr );
324+ double diffSeconds = std::difftime (now, unixTime);
325+
326+ std::string ago;
327+ if (diffSeconds < 60 ) ago = std::to_string ((int )diffSeconds) + " seconds ago" ;
328+ else if (diffSeconds < 3600 ) ago = std::to_string ((int )diffSeconds / 60 ) + " minutes ago" ;
329+ else if (diffSeconds < 86400 ) ago = std::to_string ((int )diffSeconds / 3600 ) + " hours ago" ;
330+ else ago = std::to_string ((int )diffSeconds / 86400 ) + " days ago" ;
331+
332+ std::tm bt{};
333+ localtime_s (&bt, &unixTime);
334+
335+ std::ostringstream oss;
336+ oss << ago << " (" << std::put_time (&bt, " %a %Y-%m-%d %H:%M:%S %z" ) << " )" ;
337+ return oss.str ();
338+ }
339+
314340void PrintErrorHints (int errorCode, HANDLE hshot) {
315341 EnsureCurrentParentExe (hshot);
316342 // Use our little lookup table to give hints for specific errors
@@ -1487,7 +1513,7 @@ return WideToString(stringBuffer);
14871513#endif
14881514}
14891515
1490- void PrintAncestry (DWORD pid, HANDLE hSnapshot) {
1516+ void PrintAncestry (DWORD pid, HANDLE hSnapshot, const std::unordered_map< DWORD , PROCESSENTRY32 >& pidMap ) {
14911517 // now we're geting the name
14921518// we're making it slower by adding a bunch of snapshots
14931519// but again, we'll optimize and refactor later, i need this to work first
@@ -1506,14 +1532,18 @@ UPDATE: This is done now!!
15061532
15071533
15081534 // Build a PID→process map ONCE instead of walking 3 times
1509- std::unordered_map<DWORD , PROCESSENTRY32 > pidMap;
1535+ std::unordered_map<DWORD , PROCESSENTRY32 > localPidMap;
1536+ const std::unordered_map<DWORD , PROCESSENTRY32 >* pidMapPtr = &pidMap;
15101537 PROCESSENTRY32 pe32{};
15111538 pe32.dwSize = sizeof (PROCESSENTRY32 );
1512-
1513- if (Process32First (hSnapshot, &pe32)) {
1514- do {
1515- pidMap.emplace (pe32.th32ProcessID , pe32);
1516- } while (Process32Next (hSnapshot, &pe32));
1539+
1540+ if (pidMapPtr->empty ()) {
1541+ if (Process32First (hSnapshot, &pe32)) {
1542+ do {
1543+ localPidMap.emplace (pe32.th32ProcessID , pe32);
1544+ } while (Process32Next (hSnapshot, &pe32));
1545+ }
1546+ pidMapPtr = &localPidMap;
15171547 }
15181548
15191549 DWORD parentPid = 0 ;
@@ -1526,8 +1556,8 @@ UPDATE: This is done now!!
15261556 // here, we're gonna use the existing snapshot so it doesn't use another
15271557 // it shouldn't harm performance, but even if it does, I want to get
15281558 // the features done first before optimizing anything
1529- auto currentIt = pidMap. find (currentProcessId);
1530- if (currentIt != pidMap. end ()) {
1559+ auto currentIt = pidMapPtr-> find (currentProcessId);
1560+ if (currentIt != pidMapPtr-> end ()) {
15311561 pe32 = currentIt->second ;
15321562 }
15331563
@@ -1537,12 +1567,12 @@ UPDATE: This is done now!!
15371567 std::vector<std::string> exeNames; // sorry for the crap code but idk how to make multidimensional arrays yet 😭😭😭
15381568 std::vector<DWORD > pidNames; // hopefully the compiler can fix it
15391569 std::vector<DWORD > parentPids;
1540- ULONGLONG creationTime = GetProcessCreationTime (pid);
1570+ ULONGLONG creationTime = GetProcessCreationTime (pid, *pidMapPtr );
15411571 bool found = false ;
15421572 while (pid != 0 && pid != 4 ) {
15431573 found = false ;
1544- auto it = pidMap. find (pid);
1545- if (it != pidMap. end ()) {
1574+ auto it = pidMapPtr-> find (pid);
1575+ if (it != pidMapPtr-> end ()) {
15461576 const PROCESSENTRY32 & entry = it->second ;
15471577 // Without comments, this literally looks like alien gibberish so lemme explain
15481578
@@ -1552,7 +1582,7 @@ UPDATE: This is done now!!
15521582
15531583 parentPid = entry.th32ParentProcessID ; // this gets the pid of the PARENT pid (if there hopefully is one)
15541584 parentPids.emplace_back (entry.th32ParentProcessID ); // adds above to list
1555- ULONGLONG parentTime = GetProcessCreationTime (entry.th32ParentProcessID );
1585+ ULONGLONG parentTime = GetProcessCreationTime (entry.th32ParentProcessID , *pidMapPtr );
15561586
15571587 if (parentPid == 0 || parentPid == 4 || parentTime == 0 || parentTime >= creationTime) {
15581588 // we can't be sure if the parent actually exists and windows isn't lying to us,
@@ -1579,7 +1609,7 @@ UPDATE: This is done now!!
15791609 std::reverse (pidNames.begin (), pidNames.end ());
15801610 std::reverse (parentPids.begin (), parentPids.end ());
15811611 int children = 0 ; // i wonder what would happen if you could set an emoji as var name
1582- for (const auto & pair : pidMap ) {
1612+ for (const auto & pair : *pidMapPtr ) {
15831613 const PROCESSENTRY32 & entry = pair.second ;
15841614
15851615 // this time, our target pid is already stored at the very top of our list.
@@ -1717,6 +1747,14 @@ void FindProcessPorts(DWORD targetPid) {
17171747
17181748void PIDinspect (const std::vector<DWORD >& pids, const std::vector<std::string>& names, HANDLE hshot) { // ooh guys look i'm in the void
17191749 DWORD pid = pids[0 ];
1750+ std::unordered_map<DWORD , PROCESSENTRY32 > pidMap;
1751+ PROCESSENTRY32 pe32{};
1752+ pe32.dwSize = sizeof (PROCESSENTRY32 );
1753+ if (Process32First (hshot, &pe32)) {
1754+ do {
1755+ pidMap.emplace (pe32.th32ProcessID , pe32);
1756+ } while (Process32Next (hshot, &pe32));
1757+ }
17201758 std::string procName = GetProcessNameFromPid (pid, hshot);
17211759 if (virtualTerminalEnabled) {
17221760 if (procName == " " ){
@@ -1913,7 +1951,7 @@ std::string FRAM = ""; // fram means formatted ram, i'm so creative at var namin
19131951 } else {
19141952 std::cout << " \n Why It Exists:\n " ;
19151953 }
1916- PrintAncestry (pid, hshot);
1954+ PrintAncestry (pid, hshot, pidMap );
19171955
19181956 FindProcessPorts (pid);
19191957
@@ -1922,9 +1960,9 @@ std::string FRAM = ""; // fram means formatted ram, i'm so creative at var namin
19221960
19231961
19241962 if (virtualTerminalEnabled) {
1925- std::cout << " \n\033 [1;35mStarted:\033 [0m " << GetReadableFileTime (pid) << std::endl;
1963+ std::cout << " \n\033 [1;35mStarted:\033 [0m " << GetReadableFileTime (pid, pidMap ) << std::endl;
19261964 } else {
1927- std::cout << " \n Started: " << GetReadableFileTime (pid) << std::endl;
1965+ std::cout << " \n Started: " << GetReadableFileTime (pid, pidMap ) << std::endl;
19281966 }
19291967
19301968 if (pids.size () > 1 ) {
0 commit comments