Skip to content

Commit 44fa1da

Browse files
perf: enhance process time retrieval with optional pidMap parameter
1 parent f9a07b3 commit 44fa1da

1 file changed

Lines changed: 55 additions & 17 deletions

File tree

main.cpp

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
314340
void 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

17181748
void 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 << "\nWhy 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 << "\nStarted: " << GetReadableFileTime(pid) << std::endl;
1965+
std::cout << "\nStarted: " << GetReadableFileTime(pid, pidMap) << std::endl;
19281966
}
19291967

19301968
if (pids.size() > 1) {

0 commit comments

Comments
 (0)