- Sync with trunk up to r46941.
[reactos.git] / base / applications / taskmgr / perfdata.c
index 015c499..a1095e5 100644 (file)
@@ -40,6 +40,15 @@ SYSTEM_HANDLE_INFORMATION                  SystemHandleInfo;
 PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION  SystemProcessorTimeInfo = NULL;
 PSID                                       SystemUserSid = NULL;
 
+typedef struct _SIDTOUSERNAME
+{
+    LIST_ENTRY List;
+    LPWSTR pszName;
+    BYTE Data[0];
+} SIDTOUSERNAME, *PSIDTOUSERNAME;
+
+static LIST_ENTRY SidToUserNameHead = {&SidToUserNameHead, &SidToUserNameHead};
+
 BOOL PerfDataInitialize(void)
 {
     SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
@@ -63,6 +72,8 @@ BOOL PerfDataInitialize(void)
 
 void PerfDataUninitialize(void)
 {
+    PLIST_ENTRY pCur;
+    PSIDTOUSERNAME pEntry;
 
     if (pPerfData != NULL)
         HeapFree(GetProcessHeap(), 0, pPerfData);
@@ -74,6 +85,15 @@ void PerfDataUninitialize(void)
         FreeSid(SystemUserSid);
         SystemUserSid = NULL;
     }
+
+    /* Free user names cache list */
+    pCur = SidToUserNameHead.Flink;
+    while (pCur != &SidToUserNameHead)
+    {
+        pEntry = CONTAINING_RECORD(pCur, SIDTOUSERNAME, List);
+        pCur = pCur->Flink;
+        HeapFree(GetProcessHeap(), 0, pEntry);
+    }
 }
 
 static void SidToUserName(PSID Sid, LPWSTR szBuffer, DWORD BufferSize)
@@ -86,6 +106,56 @@ static void SidToUserName(PSID Sid, LPWSTR szBuffer, DWORD BufferSize)
         LookupAccountSidW(NULL, Sid, szBuffer, &BufferSize, szDomainNameUnused, &DomainNameLen, &Use);
 }
 
+VOID
+WINAPI
+CachedGetUserFromSid(
+    PSID pSid,
+    LPWSTR pUserName,
+    PULONG pcwcUserName)
+{
+    PLIST_ENTRY pCur;
+    PSIDTOUSERNAME pEntry;
+    ULONG cbSid, cwcUserName;
+
+    cwcUserName = *pcwcUserName;
+
+    /* Walk through the list */
+    for(pCur = SidToUserNameHead.Flink;
+        pCur != &SidToUserNameHead;
+        pCur = pCur->Flink)
+    {
+        pEntry = CONTAINING_RECORD(pCur, SIDTOUSERNAME, List);
+        if (EqualSid((PSID)&pEntry->Data, pSid))
+        {
+            wcsncpy(pUserName, pEntry->pszName, cwcUserName);
+            *pcwcUserName = cwcUserName;
+            return;
+        }
+    }
+
+    /* We didn't find the SID in the list, get the name conventional */
+    SidToUserName(pSid, pUserName, cwcUserName);
+
+    /* Allocate a new entry */
+    *pcwcUserName = wcslen(pUserName);
+    cwcUserName = *pcwcUserName + 1;
+    cbSid = GetLengthSid(pSid);
+    pEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(SIDTOUSERNAME) + cbSid + cwcUserName * sizeof(WCHAR));
+
+    /* Copy the Sid and name to our entry */
+    CopySid(cbSid, (PSID)&pEntry->Data, pSid);
+    pEntry->pszName = (LPWSTR)(pEntry->Data + cbSid);
+    wcsncpy(pEntry->pszName, pUserName, cwcUserName);
+
+    /* Insert the new entry */
+    pEntry->List.Flink = &SidToUserNameHead;
+    pEntry->List.Blink = SidToUserNameHead.Blink;
+    SidToUserNameHead.Blink->Flink = &pEntry->List;
+    SidToUserNameHead.Blink = &pEntry->List;
+
+    return;
+}
+
 void PerfDataRefresh(void)
 {
     ULONG                                      ulSize;
@@ -106,6 +176,7 @@ void PerfDataRefresh(void)
     PSECURITY_DESCRIPTOR                       ProcessSD;
     PSID                                       ProcessUser;
     ULONG                                      Buffer[64]; /* must be 4 bytes aligned! */
+    ULONG                                      cwcUserName;
 
     /* Get new system time */
     status = NtQuerySystemInformation(SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
@@ -341,7 +412,8 @@ ClearInfo:
             ZeroMemory(&pPerfData[Idx].IOCounters, sizeof(IO_COUNTERS));
         }
 
-        SidToUserName(ProcessUser, pPerfData[Idx].UserName, sizeof(pPerfData[0].UserName) / sizeof(pPerfData[0].UserName[0]));
+        cwcUserName = sizeof(pPerfData[0].UserName) / sizeof(pPerfData[0].UserName[0]);
+        CachedGetUserFromSid(ProcessUser, pPerfData[Idx].UserName, &cwcUserName);
 
         if (ProcessSD != NULL)
         {
@@ -356,6 +428,29 @@ ClearInfo:
     LeaveCriticalSection(&PerfDataCriticalSection);
 }
 
+ULONG PerfDataGetProcessIndex(ULONG pid)
+{
+    ULONG idx;
+
+    EnterCriticalSection(&PerfDataCriticalSection);
+
+    for (idx = 0; idx < ProcessCount; idx++)
+    {
+        if (PtrToUlong(pPerfData[idx].ProcessId) == pid)
+        {
+            break;
+        }
+    }
+
+    LeaveCriticalSection(&PerfDataCriticalSection);
+
+    if (idx == ProcessCount)
+    {
+        return -1;
+    }
+    return idx;
+}
+
 ULONG PerfDataGetProcessCount(void)
 {
     return ProcessCount;
@@ -387,27 +482,6 @@ BOOL PerfDataGetImageName(ULONG Index, LPWSTR lpImageName, int nMaxCount)
     return bSuccessful;
 }
 
-int PerfGetIndexByProcessId(DWORD dwProcessId)
-{
-    int FoundIndex = -1;
-    ULONG Index;
-
-    EnterCriticalSection(&PerfDataCriticalSection);
-
-    for (Index = 0; Index < ProcessCount; Index++)
-    {
-        if (PtrToUlong(pPerfData[Index].ProcessId) == dwProcessId)
-        {
-            FoundIndex = Index;
-            break;
-        }
-    }
-
-    LeaveCriticalSection(&PerfDataCriticalSection);
-
-    return FoundIndex;
-}
-
 ULONG PerfDataGetProcessId(ULONG Index)
 {
     ULONG  ProcessId;