PVIEWDAT.C
/******************************************************************************\ 
*       This is a part of the Microsoft Source Code Samples.  
*       Copyright 1993 - 1998 Microsoft Corporation. 
*       All rights reserved.  
*       This source code is only intended as a supplement to  
*       Microsoft Development Tools and/or WinHelp documentation. 
*       See these sources for detailed information regarding the  
*       Microsoft samples programs. 
\******************************************************************************/ 
 
 
/****************************************************************************** 
 
                            P V I E W   D A T A 
 
    Name:       pviewdat.c 
 
    Description: 
        This module collects the data to be displayed in pview. 
 
******************************************************************************/ 
 
#include    <windows.h> 
#include    <winperf.h> 
#include    "perfdata.h" 
#include    "pviewdat.h" 
#include    "pviewdlg.h" 
#include    <stdio.h> 
#include    <stdlib.h> 
#include    <string.h> 
#include    <tchar.h> 
 
 
#define NODATA  TEXT("--------") 
 
 
 
 
 
void    FormatTimeFields 
               (double      fTime, 
                PTIME_FIELD pTimeFld); 
 
DWORD   PutCounterDWKB 
               (HWND            hWnd, 
                DWORD           dwItemID, 
                PPERF_INSTANCE  pInst, 
                PPERF_OBJECT    pObj, 
                DWORD           dwCounterIdx); 
 
DWORD   PutCounterHEX 
               (HWND            hWnd, 
                DWORD           dwItemID, 
                PPERF_INSTANCE  pInst, 
                PPERF_OBJECT    pObj, 
                DWORD           dwCounterIdx); 
 
DWORD   PutCounterDW 
               (HWND            hWnd, 
                DWORD           dwItemID, 
                PPERF_INSTANCE  pInst, 
                PPERF_OBJECT    pObj, 
                DWORD           dwCounterIdx); 
 
void    PaintAddressSpace 
               (HWND            hMemDlg, 
                PPERF_INSTANCE  pInst, 
                PPERF_OBJECT    pObj, 
                DWORD           TotalID, 
                DWORD           NoAccessID, 
                DWORD           NoAccessIndex, 
                DWORD           ReadOnlyID, 
                DWORD           ReadOnlyIndex, 
                DWORD           ReadWriteID, 
                DWORD           ReadWriteIndex, 
                DWORD           WriteCopyID, 
                DWORD           WriteCopyIndex, 
                DWORD           ExecuteID, 
                DWORD           ExecuteIndex1, 
                DWORD           ExecuteIndex2, 
                DWORD           ExecuteIndex3, 
                DWORD           ExecuteIndex4); 
 
void    PaintMemDlgAddrData 
               (HWND            hMemDlg, 
                PPERF_INSTANCE  pInst, 
                PPERF_OBJECT    pObj); 
 
void    PaintMemDlgVMData 
               (HWND            hMemDlg, 
                PPERF_INSTANCE  pInst, 
                PPERF_OBJECT    pObj); 
 
void    PaintPviewDlgMemoryData 
               (HWND            hPviewDlg, 
                PPERF_INSTANCE  pInst, 
                PPERF_OBJECT    pObj); 
 
void    RefreshMemoryDlgImageList 
               (HWND            hImageList, 
                DWORD           ParentIndex, 
                PPERF_OBJECT    pImageObj); 
 
WORD    ProcessPriority 
               (PPERF_OBJECT    pObject, 
                PPERF_INSTANCE  pInstance); 
 
void    SetProcessListText 
               (PPERF_INSTANCE pInst, 
                PPERF_COUNTER  pCPU, 
                PPERF_COUNTER  pPRIV, 
                PPERF_COUNTER  pProcID, 
                double         fTime, 
                LPTSTR         str); 
 
void    SetThreadListText 
               (PPERF_INSTANCE  pInst, 
                PPERF_COUNTER   pCPU, 
                PPERF_COUNTER   pPRIV, 
                double          fTime, 
                LPTSTR          str); 
 
 
 
 
//********************************************************************* 
// 
//      FormatTimeFields 
// 
//  Formats a double value to time fields. 
// 
void FormatTimeFields   (double      fTime, 
                         PTIME_FIELD pTimeFld) 
{ 
INT     i; 
double   f; 
 
    f = fTime/3600; 
 
    pTimeFld->Hours = i = (int)f; 
 
    f = f - i; 
    pTimeFld->Mins = i = (int)(f = f * 60); 
 
    f = f - i; 
    pTimeFld->Secs = i = (int)(f = f * 60); 
 
    f = f - i; 
    pTimeFld->mSecs = (int)(f * 1000); 
} 
 
 
 
 
//********************************************************************* 
// 
//      PutCounterDWKB 
// 
//  Display a DWORD counter's data in KB units. 
// 
DWORD   PutCounterDWKB (HWND            hWnd, 
                        DWORD           dwItemID, 
                        PPERF_INSTANCE  pInst, 
                        PPERF_OBJECT    pObj, 
                        DWORD           dwCounterIdx) 
{ 
PPERF_COUNTER   pCounter; 
DWORD           *pdwData; 
TCHAR           szTemp[20]; 
 
    if (pCounter = FindCounter (pObj, dwCounterIdx)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        wsprintf (szTemp, TEXT("%ld KB"), *pdwData/1024); 
        SetDlgItemText (hWnd, dwItemID, szTemp); 
 
        return *pdwData; 
        } 
    else 
        { 
        SetDlgItemText (hWnd, dwItemID, NODATA); 
        return 0; 
        } 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      PutCounterHEX 
// 
//  Display a DWORD counter's data in hex. 
// 
DWORD   PutCounterHEX  (HWND            hWnd, 
                        DWORD           dwItemID, 
                        PPERF_INSTANCE  pInst, 
                        PPERF_OBJECT    pObj, 
                        DWORD           dwCounterIdx) 
{ 
PPERF_COUNTER   pCounter; 
DWORD           *pdwData; 
TCHAR           szTemp[20]; 
 
    if (pCounter = FindCounter (pObj, dwCounterIdx)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        wsprintf (szTemp, TEXT("0x%08x"), *pdwData); 
        SetDlgItemText (hWnd, dwItemID, szTemp); 
 
        return *pdwData; 
        } 
    else 
        { 
        SetDlgItemText (hWnd, dwItemID, NODATA); 
        return 0; 
        } 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      PutCounterDWKB 
// 
//  Display a DWORD counter's data. 
// 
DWORD   PutCounterDW   (HWND            hWnd, 
                        DWORD           dwItemID, 
                        PPERF_INSTANCE  pInst, 
                        PPERF_OBJECT    pObj, 
                        DWORD           dwCounterIdx) 
{ 
PPERF_COUNTER   pCounter; 
DWORD           *pdwData; 
 
    if (pCounter = FindCounter (pObj, dwCounterIdx)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        SetDlgItemInt (hWnd, dwItemID, *pdwData, FALSE); 
 
        return *pdwData; 
        } 
    else 
        { 
        SetDlgItemText (hWnd, dwItemID, NODATA); 
        return 0; 
        } 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      PaintAddressSpace 
// 
// 
void    PaintAddressSpace  (HWND            hMemDlg, 
                            PPERF_INSTANCE  pInst, 
                            PPERF_OBJECT    pObj, 
                            DWORD           TotalID, 
                            DWORD           NoAccessID, 
                            DWORD           NoAccessIndex, 
                            DWORD           ReadOnlyID, 
                            DWORD           ReadOnlyIndex, 
                            DWORD           ReadWriteID, 
                            DWORD           ReadWriteIndex, 
                            DWORD           WriteCopyID, 
                            DWORD           WriteCopyIndex, 
                            DWORD           ExecuteID, 
                            DWORD           ExecuteIndex1, 
                            DWORD           ExecuteIndex2, 
                            DWORD           ExecuteIndex3, 
                            DWORD           ExecuteIndex4) 
{ 
PPERF_COUNTER   pCounter; 
DWORD           *pdwData; 
TCHAR           szTemp[20]; 
 
DWORD           dwTotal = 0; 
DWORD           dwExecute = 0; 
BOOL            bCounter = FALSE; 
 
 
    dwTotal += PutCounterDWKB (hMemDlg, NoAccessID,  pInst, pObj, NoAccessIndex); 
    dwTotal += PutCounterDWKB (hMemDlg, ReadOnlyID,  pInst, pObj, ReadOnlyIndex); 
    dwTotal += PutCounterDWKB (hMemDlg, ReadWriteID, pInst, pObj, ReadWriteIndex); 
    dwTotal += PutCounterDWKB (hMemDlg, WriteCopyID, pInst, pObj, WriteCopyIndex); 
 
 
    // execute is the sum of the following 
    // 
    if (pCounter = FindCounter (pObj, ExecuteIndex1)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwTotal += *pdwData; 
        dwExecute += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, ExecuteIndex2)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwTotal += *pdwData; 
        dwExecute += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, ExecuteIndex3)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwTotal += *pdwData; 
        dwExecute += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, ExecuteIndex4)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwTotal += *pdwData; 
        dwExecute += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (bCounter) 
        { 
        wsprintf (szTemp, TEXT("%ld KB"), dwExecute/1024); 
        SetDlgItemText (hMemDlg, ExecuteID, szTemp); 
        } 
    else 
        SetDlgItemText (hMemDlg, ExecuteID, NODATA); 
 
    wsprintf (szTemp, TEXT("%ld KB"), dwTotal/1024); 
    SetDlgItemText (hMemDlg, TotalID, szTemp); 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      PaintMemDlgAddrData 
// 
//  Paint the memory dialog address space data. 
// 
void    PaintMemDlgAddrData(HWND            hMemDlg, 
                            PPERF_INSTANCE  pInst, 
                            PPERF_OBJECT    pObj) 
{ 
    PaintAddressSpace (hMemDlg, pInst, pObj, 
                       MEMORY_TOTALPRIVATE_COMMIT, 
                       MEMORY_PRIVATE_NOACCESS,  PX_PROCESS_PRIVATE_NOACCESS, 
                       MEMORY_PRIVATE_READONLY,  PX_PROCESS_PRIVATE_READONLY, 
                       MEMORY_PRIVATE_READWRITE, PX_PROCESS_PRIVATE_READWRITE, 
                       MEMORY_PRIVATE_WRITECOPY, PX_PROCESS_PRIVATE_WRITECOPY, 
                       MEMORY_PRIVATE_EXECUTE,   PX_PROCESS_PRIVATE_EXECUTABLE, 
                                                 PX_PROCESS_PRIVATE_EXE_READONLY, 
                                                 PX_PROCESS_PRIVATE_EXE_READWRITE, 
                                                 PX_PROCESS_PRIVATE_EXE_WRITECOPY); 
 
    PaintAddressSpace (hMemDlg, pInst, pObj, 
                       MEMORY_TOTALMAPPED_COMMIT, 
                       MEMORY_MAPPED_NOACCESS,  PX_PROCESS_MAPPED_NOACCESS, 
                       MEMORY_MAPPED_READONLY,  PX_PROCESS_MAPPED_READONLY, 
                       MEMORY_MAPPED_READWRITE, PX_PROCESS_MAPPED_READWRITE, 
                       MEMORY_MAPPED_WRITECOPY, PX_PROCESS_MAPPED_WRITECOPY, 
                       MEMORY_MAPPED_EXECUTE,   PX_PROCESS_MAPPED_EXECUTABLE, 
                                                PX_PROCESS_MAPPED_EXE_READONLY, 
                                                PX_PROCESS_MAPPED_EXE_READWRITE, 
                                                PX_PROCESS_MAPPED_EXE_WRITECOPY); 
 
    PaintAddressSpace (hMemDlg, pInst, pObj, 
                       MEMORY_TOTALIMAGE_COMMIT, 
                       MEMORY_IMAGE_NOACCESS,   PX_PROCESS_IMAGE_NOACCESS, 
                       MEMORY_IMAGE_READONLY,   PX_PROCESS_IMAGE_READONLY, 
                       MEMORY_IMAGE_READWRITE,  PX_PROCESS_IMAGE_READWRITE, 
                       MEMORY_IMAGE_WRITECOPY,  PX_PROCESS_IMAGE_WRITECOPY, 
                       MEMORY_IMAGE_EXECUTE,    PX_PROCESS_IMAGE_EXECUTABLE, 
                                                PX_PROCESS_IMAGE_EXE_READONLY, 
                                                PX_PROCESS_IMAGE_EXE_READWRITE, 
                                                PX_PROCESS_IMAGE_EXE_WRITECOPY); 
} 
 
 
 
 
//********************************************************************* 
// 
//      PaintMemDlgVMData 
// 
//  Paint the memory dialog Virtual Memory data. 
// 
void    PaintMemDlgVMData  (HWND            hMemDlg, 
                            PPERF_INSTANCE  pInst, 
                            PPERF_OBJECT    pObj) 
{ 
 
    PutCounterDWKB (hMemDlg, MEMORY_WS,           pInst, pObj, PX_PROCESS_WORKING_SET); 
    PutCounterDWKB (hMemDlg, MEMORY_PEAK_WS,      pInst, pObj, PX_PROCESS_PEAK_WS); 
    PutCounterDWKB (hMemDlg, MEMORY_PRIVATE_PAGE, pInst, pObj, PX_PROCESS_PRIVATE_PAGE); 
    PutCounterDWKB (hMemDlg, MEMORY_VSIZE,        pInst, pObj, PX_PROCESS_VIRTUAL_SIZE); 
    PutCounterDWKB (hMemDlg, MEMORY_PEAK_VSIZE,   pInst, pObj, PX_PROCESS_PEAK_VS); 
    PutCounterDWKB (hMemDlg, MEMORY_PFCOUNT,      pInst, pObj, PX_PROCESS_FAULT_COUNT); 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      PaintPviewDlgMemoryData 
// 
//  Paint the memory data for pview dialog. 
// 
void    PaintPviewDlgMemoryData    (HWND            hPviewDlg, 
                                    PPERF_INSTANCE  pInst, 
                                    PPERF_OBJECT    pObj) 
{ 
PPERF_COUNTER   pCounter; 
TCHAR           str[20]; 
DWORD           *pdwData; 
DWORD           dwData = 0; 
BOOL            bCounter = FALSE; 
 
 
    if (pCounter = FindCounter (pObj, PX_PROCESS_PRIVATE_NOACCESS)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwData += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, PX_PROCESS_PRIVATE_READONLY)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwData += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, PX_PROCESS_PRIVATE_READWRITE)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwData += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, PX_PROCESS_PRIVATE_WRITECOPY)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwData += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, PX_PROCESS_PRIVATE_EXECUTABLE)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwData += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, PX_PROCESS_PRIVATE_EXE_READONLY)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwData += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, PX_PROCESS_PRIVATE_EXE_READWRITE)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwData += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (pCounter = FindCounter (pObj, PX_PROCESS_PRIVATE_EXE_WRITECOPY)) 
        { 
        pdwData = (DWORD *) CounterData (pInst, pCounter); 
        dwData += *pdwData; 
        bCounter = TRUE; 
        } 
 
    if (bCounter) 
        { 
        wsprintf (str, TEXT("%ld KB"), dwData/1024); 
        SetDlgItemText (hPviewDlg, PVIEW_TOTALPRIVATE_COMMIT, str); 
        } 
    else 
        SetDlgItemText (hPviewDlg, PVIEW_TOTALPRIVATE_COMMIT, NODATA); 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshMemoryDlg 
// 
//  Refresh the memory detail dialog. 
// 
BOOL    RefreshMemoryDlg   (HWND            hMemDlg, 
                            PPERF_INSTANCE  pProcessInstance, 
                            PPERF_OBJECT    pProcessObject, 
                            PPERF_OBJECT    pAddressObject, 
                            PPERF_OBJECT    pImageObject) 
{ 
DWORD           *pProcessID1; 
DWORD           *pProcessID2; 
PPERF_COUNTER   pCounter1; 
PPERF_COUNTER   pCounter2; 
PPERF_INSTANCE  pAddressInstance; 
HWND            hImageList; 
TCHAR           szTemp[40]; 
BOOL            bStat = FALSE; 
INT             InstIndex = 0; 
 
 
    if ((pCounter1 = FindCounter (pProcessObject, PX_PROCESS_ID)) && 
        (pCounter2 = FindCounter (pAddressObject, PX_PROCESS_ID))) 
        { 
        pProcessID1 = (DWORD *) CounterData (pProcessInstance, pCounter1); 
 
        wsprintf (szTemp, TEXT("%s (%#x)"), InstanceName (pProcessInstance), *pProcessID1); 
        SetDlgItemText (hMemDlg, MEMORY_PROCESS_ID, szTemp); 
 
        pAddressInstance = FirstInstance (pAddressObject); 
 
        while (pAddressInstance && InstIndex < pAddressObject->NumInstances) 
            { 
            pProcessID2 = (DWORD *) CounterData (pAddressInstance, pCounter2); 
 
            if (*pProcessID1 == *pProcessID2) 
                { 
                PaintMemDlgAddrData (hMemDlg, pAddressInstance, pAddressObject); 
                PaintMemDlgVMData (hMemDlg, pProcessInstance, pProcessObject); 
 
                hImageList = GetDlgItem (hMemDlg, MEMORY_IMAGE); 
                RefreshMemoryDlgImageList (hImageList, InstIndex, pImageObject); 
 
                bStat = TRUE; 
                break; 
                } 
 
            pAddressInstance = NextInstance (pAddressInstance); 
            InstIndex++; 
            } 
        } 
 
    return bStat; 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshMemoryDlgImageList 
// 
//  Refresh the image list for memory dialog. 
// 
void    RefreshMemoryDlgImageList  (HWND            hImageList, 
                                    DWORD           ParentIndex, 
                                    PPERF_OBJECT    pImageObj) 
{ 
PPERF_INSTANCE  pImageInst; 
INT             ListIndex; 
INT             InstIndex = 0; 
 
 
    ListIndex = SendMessage (hImageList, CB_ADDSTRING, 0, (DWORD)TEXT(" Total Commit")); 
    SendMessage (hImageList, CB_SETITEMDATA, ListIndex, 0xFFFFFFFF); 
 
    if (pImageObj) 
        { 
        pImageInst = FirstInstance (pImageObj); 
 
        while (pImageInst && InstIndex < pImageObj->NumInstances) 
            { 
            if (ParentIndex == pImageInst->ParentObjectInstance) 
                { 
                ListIndex = SendMessage (hImageList, 
                                         CB_ADDSTRING, 
                                         0, 
                                         (DWORD)InstanceName(pImageInst)); 
                SendMessage (hImageList, CB_SETITEMDATA, ListIndex, InstIndex); 
                } 
 
            pImageInst = NextInstance (pImageInst); 
            InstIndex++; 
            } 
        } 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshMemoryDlgImage 
// 
// 
void RefreshMemoryDlgImage (HWND            hMemDlg, 
                            DWORD           dwIndex, 
                            PPERF_OBJECT    pImageObject) 
{ 
PPERF_INSTANCE  pInst; 
 
    if (pInst = FindInstanceN (pImageObject, dwIndex)) 
        PaintAddressSpace (hMemDlg, pInst, pImageObject, 
                           MEMORY_TOTALIMAGE_COMMIT, 
                           MEMORY_IMAGE_NOACCESS,   PX_IMAGE_NOACCESS, 
                           MEMORY_IMAGE_READONLY,   PX_IMAGE_READONLY, 
                           MEMORY_IMAGE_READWRITE,  PX_IMAGE_READWRITE, 
                           MEMORY_IMAGE_WRITECOPY,  PX_IMAGE_WRITECOPY, 
                           MEMORY_IMAGE_EXECUTE,    PX_IMAGE_EXECUTABLE, 
                                                    PX_IMAGE_EXE_READONLY, 
                                                    PX_IMAGE_EXE_READWRITE, 
                                                    PX_IMAGE_EXE_WRITECOPY); 
} 
 
 
//********************************************************************* 
// 
//      RefreshPviewDlgMemoryData 
// 
//  Update the memory data for pview dialog.  This should be done 
//  after the ghCostlyData is collected and is not refreshing. 
// 
void RefreshPviewDlgMemoryData (HWND            hPviewDlg, 
                                PPERF_INSTANCE  pProcessInstance, 
                                PPERF_OBJECT    pProcessObject, 
                                PPERF_OBJECT    pAddressObject) 
{ 
DWORD           *pProcessID1; 
DWORD           *pProcessID2; 
PPERF_COUNTER   pCounter1; 
PPERF_COUNTER   pCounter2; 
PPERF_INSTANCE  pAddressInstance; 
INT             i = 0; 
 
 
    if ((pCounter1 = FindCounter (pProcessObject, PX_PROCESS_ID)) && 
        (pCounter2 = FindCounter (pAddressObject, PX_PROCESS_ID))) 
        { 
        pProcessID1 = (DWORD *) CounterData (pProcessInstance, pCounter1); 
 
        pAddressInstance = FirstInstance (pAddressObject); 
 
        while (pAddressInstance && i < pAddressObject->NumInstances) 
            { 
            pProcessID2 = (DWORD *) CounterData (pAddressInstance, pCounter2); 
 
            if (*pProcessID1 == *pProcessID2) 
                { 
                PaintPviewDlgMemoryData (hPviewDlg, pAddressInstance, pAddressObject); 
                break; 
                } 
 
            pAddressInstance = NextInstance (pAddressInstance); 
            i++; 
            } 
        } 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshPviewDlgThreadPC 
// 
//  Update the thread PC value.  This should be done after the ghCostlyData 
//  is collected and is no refreshing. 
// 
void RefreshPviewDlgThreadPC   (HWND            hPviewDlg, 
                                LPTSTR          szProcessName, 
                                LPTSTR          szThreadName, 
                                PPERF_OBJECT    pThreadDetailsObject, 
                                PPERF_DATA      pCostlyData) 
{ 
PPERF_COUNTER   pCounter; 
PPERF_INSTANCE  pInstance; 
PPERF_INSTANCE  pParent; 
LPTSTR          szInstanceName; 
LPTSTR          szParentName; 
TCHAR           str[20]; 
DWORD           *pdwData; 
INT             i = 0; 
 
 
    if (pCounter = FindCounter (pThreadDetailsObject, PX_THREAD_PC)) 
        { 
        pInstance = FirstInstance (pThreadDetailsObject); 
 
        while (pInstance && i < pThreadDetailsObject->NumInstances) 
            { 
            if (!(szInstanceName = InstanceName (pInstance))) 
                // can't find name 
                ; 
            else if (lstrcmp (szThreadName, szInstanceName)) 
                // the thread name is different 
                ; 
            else if (!(pParent = FindInstanceParent (pInstance, pCostlyData))) 
                // can't find parent 
                ; 
            else if (!(szParentName = InstanceName (pParent))) 
                // can't find parent's name 
                ; 
            else if (!lstrcmp (szProcessName, szParentName)) 
                { 
                // Parent's name matches, this is the right one. 
                // 
 
                pdwData = CounterData (pInstance, pCounter); 
                wsprintf (str, TEXT("0x%08x"), *pdwData); 
                SetDlgItemText (hPviewDlg, PVIEW_THREAD_PC, str); 
 
                return; 
                } 
 
            pInstance = NextInstance (pInstance); 
            i++; 
            } 
        } 
 
 
    // We are here only because we can't find the data to display. 
    // 
 
    SetDlgItemText (hPviewDlg, PVIEW_THREAD_PC, NODATA); 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      ProcessPriority 
// 
//  Returns the process priority dialog item id. 
// 
WORD    ProcessPriority    (PPERF_OBJECT    pObject, 
                            PPERF_INSTANCE  pInstance) 
{ 
PPERF_COUNTER   pCounter; 
DWORD           *pdwData; 
 
 
    if (pCounter = FindCounter (pObject, PX_PROCESS_PRIO)) 
        { 
        pdwData = (DWORD *) CounterData (pInstance, pCounter); 
 
        if (*pdwData < 7) 
            return PVIEW_PRIORITY_IDL; 
        else if (*pdwData < 10) 
            return PVIEW_PRIORITY_NORMAL; 
        else 
            return PVIEW_PRIORITY_HIGH; 
        } 
    else 
        return PVIEW_PRIORITY_NORMAL; 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshPerfData 
// 
//  Get a new set of performance data.  pData should be NULL initially. 
// 
PPERF_DATA RefreshPerfData (HKEY        hPerfKey, 
                            LPTSTR      szObjectIndex, 
                            PPERF_DATA  pData, 
                            DWORD       *pDataSize) 
{ 
    if (GetPerfData (hPerfKey, szObjectIndex, &pData, pDataSize) == ERROR_SUCCESS) 
        return pData; 
    else 
        return NULL; 
} 
 
 
 
 
//********************************************************************* 
// 
//      SetProcessListText 
// 
//  Format the process list text. 
// 
void SetProcessListText (PPERF_INSTANCE pInst, 
                         PPERF_COUNTER  pCPU, 
                         PPERF_COUNTER  pPRIV, 
                         PPERF_COUNTER  pProcID, 
                         double         fTime, 
                         LPTSTR         str) 
{ 
DWORD           *pdwProcID; 
LARGE_INTEGER   *liCPU; 
LARGE_INTEGER   *liPRIV; 
double          fCPU = 0; 
double          fPRIV = 0; 
INT             PcntPRIV = 0; 
INT             PcntUSER = 0; 
TIME_FIELD      TimeFld; 
TCHAR           szTemp[100]; 
 
 
    if (pCPU) 
        { 
        liCPU = (LARGE_INTEGER *) CounterData (pInst, pCPU); 
        fCPU  = Li2Double (*liCPU); 
        } 
 
    if (pPRIV) 
        { 
        liPRIV = (LARGE_INTEGER *) CounterData (pInst, pPRIV); 
        fPRIV  = Li2Double (*liPRIV); 
        } 
 
    if (fCPU > 0) 
        { 
        PcntPRIV = (INT)(fPRIV / fCPU * 100 + 0.5); 
        PcntUSER = 100 - PcntPRIV; 
        } 
 
 
 
    if (pProcID) 
        { 
        pdwProcID = (DWORD *) CounterData (pInst, pProcID); 
        wsprintf (szTemp, TEXT("%ls (%#x)"), InstanceName(pInst), *pdwProcID); 
        } 
    else 
        wsprintf (szTemp, TEXT("%ls"), InstanceName(pInst)); 
 
 
 
    FormatTimeFields (fCPU/1.0e7, &TimeFld); 
 
    wsprintf (str, 
              TEXT("%s\t%3ld:%02ld:%02ld.%03ld\t%3ld%%\t%3ld%%"), 
              szTemp, 
              TimeFld.Hours, 
              TimeFld.Mins, 
              TimeFld.Secs, 
              TimeFld.mSecs, 
              PcntPRIV, 
              PcntUSER); 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshProcessList 
// 
//  Find all process and update the process list. 
// 
void RefreshProcessList (HWND           hProcessList, 
                         PPERF_OBJECT   pObject) 
{ 
PPERF_INSTANCE  pInstance; 
TCHAR           szListText[256]; 
INT             ListIndex; 
 
PPERF_COUNTER   pCounterCPU; 
PPERF_COUNTER   pCounterPRIV; 
PPERF_COUNTER   pCounterProcID; 
double          fObjectFreq; 
double          fObjectTime; 
double          fTime; 
 
INT             InstanceIndex = 0; 
INT             err; 
 
 
    if (pObject) 
        { 
        if ((pCounterCPU    = FindCounter (pObject, PX_PROCESS_CPU))  && 
            (pCounterPRIV   = FindCounter (pObject, PX_PROCESS_PRIV)) && 
            (pCounterProcID = FindCounter (pObject, PX_PROCESS_ID))) 
            { 
 
            fObjectFreq = Li2Double (pObject->PerfFreq); 
            fObjectTime = Li2Double (pObject->PerfTime); 
            fTime = fObjectTime / fObjectFreq; 
 
            pInstance = FirstInstance (pObject); 
 
            while (pInstance && InstanceIndex < pObject->NumInstances) 
                { 
                SetProcessListText (pInstance, 
                                    pCounterCPU, 
                                    pCounterPRIV, 
                                    pCounterProcID, 
                                    fTime, 
                                    szListText); 
 
                ListIndex = SendMessage (hProcessList, LB_ADDSTRING, 0, (DWORD)szListText); 
                err = SendMessage (hProcessList, LB_SETITEMDATA, ListIndex, InstanceIndex); 
 
                pInstance = NextInstance (pInstance); 
                InstanceIndex++; 
                } 
            } 
        } 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshProcessData 
// 
//  Find data for a given process and update. 
// 
void RefreshProcessData    (HWND            hWnd, 
                            PPERF_OBJECT    pObject, 
                            DWORD           ProcessIndex) 
{ 
PPERF_INSTANCE  pInstance; 
 
 
    if (pInstance = FindInstanceN (pObject, ProcessIndex)) 
{ 
        PutCounterDWKB (hWnd, PVIEW_WS, pInstance, pObject, PX_PROCESS_WORKING_SET); 
 
 
        SetDlgItemText (hWnd, PVIEW_TOTALPRIVATE_COMMIT, NODATA); 
 
        // set priority 
        // 
        CheckRadioButton (hWnd, 
                          PVIEW_PRIORITY_HIGH, 
                          PVIEW_PRIORITY_IDL, 
                          ProcessPriority (pObject, pInstance)); 
        } 
} 
 
 
 
 
//********************************************************************* 
// 
//      SetThreadListText 
// 
//  Format the thread list text. 
// 
void SetThreadListText (PPERF_INSTANCE  pInst, 
                        PPERF_COUNTER   pCPU, 
                        PPERF_COUNTER   pPRIV, 
                        double          fTime, 
                        LPTSTR          str) 
{ 
LARGE_INTEGER   *liCPU; 
LARGE_INTEGER   *liPRIV; 
double          fCPU = 0; 
double          fPRIV = 0; 
INT             PcntPRIV = 0; 
INT             PcntUSER = 0; 
TIME_FIELD      TimeFld; 
TCHAR           szTemp[100]; 
 
 
    if (pCPU) 
        { 
        liCPU = (LARGE_INTEGER *) CounterData (pInst, pCPU); 
        fCPU  = Li2Double (*liCPU); 
        } 
 
    if (pPRIV) 
        { 
        liPRIV = (LARGE_INTEGER *) CounterData (pInst, pPRIV); 
        fPRIV  = Li2Double (*liPRIV); 
        } 
 
    if (fCPU > 0) 
        { 
        PcntPRIV = (INT)(fPRIV / fCPU * 100 + 0.5); 
        PcntUSER = 100 - PcntPRIV; 
        } 
 
 
 
    if (pInst->UniqueID != PERF_NO_UNIQUE_ID) 
        wsprintf (szTemp, TEXT("%ls (%#x)"), InstanceName(pInst), pInst->UniqueID); 
    else 
        wsprintf (szTemp, TEXT("%ls"), InstanceName(pInst)); 
 
 
 
 
    FormatTimeFields (fCPU/1.0e7, &TimeFld); 
 
    wsprintf (str, 
              TEXT("%s\t%3ld:%02ld:%02ld.%03ld\t%3ld%%\t%3ld %%"), 
              szTemp, 
              TimeFld.Hours, 
              TimeFld.Mins, 
              TimeFld.Secs, 
              TimeFld.mSecs, 
              PcntPRIV, 
              PcntUSER); 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshThreadList 
// 
//  Find all threads for a given process and update the thread list. 
// 
void RefreshThreadList (HWND            hThreadList, 
                        PPERF_OBJECT    pObject, 
                        DWORD           ParentIndex) 
{ 
PPERF_INSTANCE  pInstance; 
TCHAR           szListText[256]; 
INT             ListIndex; 
 
PPERF_COUNTER   pCounterCPU; 
PPERF_COUNTER   pCounterPRIV; 
double          fObjectFreq; 
double          fObjectTime; 
double          fTime; 
 
INT             InstanceIndex = 0; 
INT             err; 
 
 
    if (pObject) 
        { 
        if ((pCounterCPU  = FindCounter (pObject, PX_THREAD_CPU)) && 
            (pCounterPRIV = FindCounter (pObject, PX_THREAD_PRIV))) 
            { 
 
            fObjectFreq = Li2Double (pObject->PerfFreq); 
            fObjectTime = Li2Double (pObject->PerfTime); 
            fTime = fObjectTime / fObjectFreq; 
 
 
            pInstance = FirstInstance (pObject); 
 
            while (pInstance && InstanceIndex < pObject->NumInstances) 
                { 
                if (ParentIndex == pInstance->ParentObjectInstance) 
                    { 
                    SetThreadListText (pInstance, 
                                       pCounterCPU, 
                                       pCounterPRIV, 
                                       fTime, 
                                       szListText); 
 
                    ListIndex = SendMessage (hThreadList, 
                                             LB_INSERTSTRING, 
                                             (WPARAM)-1, 
                                             (DWORD)szListText); 
                    err = SendMessage (hThreadList, LB_SETITEMDATA, ListIndex, InstanceIndex); 
                    } 
 
                pInstance = NextInstance (pInstance); 
                InstanceIndex++; 
                } 
            } 
        } 
 
} 
 
 
 
 
//********************************************************************* 
// 
//      RefreshThreadData 
// 
//  Find data for a given thread and update. 
// 
void RefreshThreadData (HWND              hWnd, 
                        PPERF_OBJECT      pThreadObj, 
                        DWORD             ThreadIndex, 
                        PPERF_OBJECT      pProcessObj, 
                        PPERF_INSTANCE    pProcessInst) 
{ 
PPERF_INSTANCE  pInstance; 
PPERF_COUNTER   pCounter; 
DWORD           *pdwData; 
DWORD           *pdwProcPrio; 
BOOL            bPrioCounter = TRUE; 
 
 
 
    if (pInstance = FindInstanceN (pThreadObj, ThreadIndex)) 
        { 
        SetDlgItemText (hWnd, PVIEW_THREAD_PC, NODATA); 
 
        PutCounterHEX (hWnd, PVIEW_THREAD_START,    pInstance, pThreadObj, PX_THREAD_START); 
        PutCounterDW  (hWnd, PVIEW_THREAD_SWITCHES, pInstance, pThreadObj, PX_THREAD_SWITCHES); 
        PutCounterDW  (hWnd, PVIEW_THREAD_DYNAMIC,  pInstance, pThreadObj, PX_THREAD_PRIO); 
        } 
 
 
 
 
    if (pInstance) 
        { 
        // get thread base priority 
        // 
 
        if (pCounter = FindCounter (pThreadObj, PX_THREAD_BASE_PRIO)) 
            pdwData = CounterData (pInstance, pCounter); 
        else 
            bPrioCounter = FALSE; 
 
 
        // get process priority 
        // 
 
        if (pCounter = FindCounter (pProcessObj, PX_PROCESS_PRIO)) 
            pdwProcPrio = CounterData (pProcessInst, pCounter); 
        else 
            bPrioCounter = FALSE; 
        } 
    else 
        bPrioCounter = FALSE; 
 
 
 
 
 
    // set thread base priority 
    // 
 
    if (!bPrioCounter) 
        CheckRadioButton (hWnd, 
                          PVIEW_THREAD_HIGHEST, 
                          PVIEW_THREAD_LOWEST, 
                          PVIEW_THREAD_NORMAL); 
    else 
        { 
        switch (*pdwData - *pdwProcPrio) 
            { 
            case 2: 
                CheckRadioButton (hWnd, 
                                  PVIEW_THREAD_HIGHEST, 
                                  PVIEW_THREAD_LOWEST, 
                                  PVIEW_THREAD_HIGHEST); 
                break; 
 
            case 1: 
                CheckRadioButton (hWnd, 
                                  PVIEW_THREAD_HIGHEST, 
                                  PVIEW_THREAD_LOWEST, 
                                  PVIEW_THREAD_ABOVE); 
                break; 
 
            case -1: 
                CheckRadioButton (hWnd, 
                                  PVIEW_THREAD_HIGHEST, 
                                  PVIEW_THREAD_LOWEST, 
                                  PVIEW_THREAD_BELOW); 
                break; 
 
            case -2: 
                CheckRadioButton (hWnd, 
                                  PVIEW_THREAD_HIGHEST, 
                                  PVIEW_THREAD_LOWEST, 
                                  PVIEW_THREAD_LOWEST); 
                break; 
 
            case 0: 
            default: 
                CheckRadioButton (hWnd, 
                                  PVIEW_THREAD_HIGHEST, 
                                  PVIEW_THREAD_LOWEST, 
                                  PVIEW_THREAD_NORMAL); 
                break; 
            } 
        } 
}