[TASKMGR] Fix display of process command-line string (#3016)

The CMD_LINE_CACHE index (idx) does not update when programs are closed.
Compare it with the process id (pid) in the cache and determine the pid
by the index in the same cache.

CORE-17115
This commit is contained in:
Aidan Case 2020-08-02 23:06:49 -05:00 committed by Stanislav Motylkov
parent 12186bec12
commit 535e262b78
No known key found for this signature in database
GPG key ID: AFE513258CBA9E92
2 changed files with 42 additions and 4 deletions

View file

@ -5,6 +5,7 @@
*
* Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
* Copyright (C) 2014 Ismael Ferreras Morezuelas <swyterzone+ros@gmail.com>
* Copyright (C) 2020 Aidan Case <aidanzcase@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -22,6 +23,8 @@
*/
#include "precomp.h"
#include "perfdata.h"
#include "winbase.h"
#define WIN32_LEAN_AND_MEAN
#include <aclapi.h>
@ -564,19 +567,50 @@ BOOL PerfDataGetCommandLine(ULONG Index, LPWSTR lpCommandLine, ULONG nMaxCount)
LPWSTR new_string;
PCMD_LINE_CACHE cache = global_cache;
PCMD_LINE_CACHE old_cache = NULL;
/* [A] Search for a string already in cache? If so, use it */
/* [A] Search for a string already in cache? If so, use it. If not, check if invalid and free it if so. */
while (cache && cache->pnext != NULL)
{
if (cache->idx == Index && cache->str != NULL)
if (cache->idx == Index && cache->pid == PerfDataGetProcessId(cache->idx) && cache->str != NULL)
{
/* Found it. Use it, and add some ellipsis at the very end to make it cute */
wcsncpy(lpCommandLine, cache->str, CMD_LINE_MIN(nMaxCount, cache->len));
wcscpy(lpCommandLine + CMD_LINE_MIN(nMaxCount, cache->len) - wcslen(ellipsis), ellipsis);
return TRUE;
}
cache = cache->pnext;
else if (cache->pid != PerfDataGetProcessId(cache->idx))
{
/* There has been a shift, and this node is no longer valid. Free it and recache it later. */
if (old_cache == NULL)
{
/* Unless, of course, its the global_cache. In that case, just shift global_cache to the next node and then free it. */
old_cache = global_cache;
if (global_cache->pnext == NULL)
{
/* And we are out of cache. Whoops. */
HeapFree(GetProcessHeap(), 0, old_cache);
global_cache = NULL;
break;
}
global_cache = global_cache->pnext;
cache = global_cache;
HeapFree(GetProcessHeap(), 0, old_cache);
}
else
{
/* We're in the middle of the cache, so we can safely shift nodes around. */
old_cache->pnext = cache->pnext;
HeapFree(GetProcessHeap(), 0, cache);
cache = old_cache->pnext;
}
}
else
{
/* This is not the cache you're looking for. */
old_cache = cache;
cache = cache->pnext;
}
}
/* [B] We don't; let's allocate and load a value from the process mem... and cache it */
@ -642,6 +676,7 @@ BOOL PerfDataGetCommandLine(ULONG Index, LPWSTR lpCommandLine, ULONG nMaxCount)
new_entry->idx = Index;
new_entry->str = new_string;
new_entry->len = CommandLineStr.Length;
new_entry->pid = ProcessId;
if (!global_cache)
global_cache = new_entry;

View file

@ -4,6 +4,7 @@
* perfdata.h
*
* Copyright (C) 1999 - 2001 Brian Palmer <brianp@reactos.org>
* Copyright (C) 2020 Aidan Case <aidanzcase@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -22,6 +23,7 @@
#pragma once
#include "windef.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -58,6 +60,7 @@ typedef struct _PERFDATA
typedef struct _CMD_LINE_CACHE
{
DWORD idx;
ULONG pid;
LPWSTR str;
ULONG len;
struct _CMD_LINE_CACHE* pnext;