https://git.reactos.org/?p=reactos.git;a=commitdiff;h=535e262b78f4ea3ea9c0de6e1cd1b6f2991b067e

commit 535e262b78f4ea3ea9c0de6e1cd1b6f2991b067e
Author:     Aidan Case <[email protected]>
AuthorDate: Sun Aug 2 23:06:49 2020 -0500
Commit:     Stanislav Motylkov <[email protected]>
CommitDate: Sun Aug 16 00:52:48 2020 +0300

    [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
---
 base/applications/taskmgr/perfdata.c | 43 ++++++++++++++++++++++++++++++++----
 base/applications/taskmgr/perfdata.h |  3 +++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/base/applications/taskmgr/perfdata.c 
b/base/applications/taskmgr/perfdata.c
index a19c0cb0d97..75c6c27fcd2 100644
--- a/base/applications/taskmgr/perfdata.c
+++ b/base/applications/taskmgr/perfdata.c
@@ -5,6 +5,7 @@
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer                <[email protected]>
  *  Copyright (C)        2014  Ismael Ferreras Morezuelas  
<[email protected]>
+ *  Copyright (C)        2020  Aidan Case                  
<[email protected]>
  *
  * 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;
diff --git a/base/applications/taskmgr/perfdata.h 
b/base/applications/taskmgr/perfdata.h
index 51e11f47b2e..8bd3d33ad57 100644
--- a/base/applications/taskmgr/perfdata.h
+++ b/base/applications/taskmgr/perfdata.h
@@ -4,6 +4,7 @@
  *  perfdata.h
  *
  *  Copyright (C) 1999 - 2001  Brian Palmer  <[email protected]>
+ *  Copyright (C)        2020  Aidan Case    <[email protected]>
  *
  * 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;

Reply via email to