Link to home
Start Free TrialLog in
Avatar of deck16
deck16

asked on

Harddrive Usage?

Is it possible to get a usage statistic for the harddrive? I'm looking for somthing similar to the CPU usage statistic that can be found in the registry. This wouldn't have to be a perfect statistic, but just an approximate indicator of how hard the harddrive is working. For example 0% when it's idle. And 100% when it's spinning at it's full speed and conducting intensive access. If that's not possible, is there a way to just detect if harddrive activity is occuring at a certain point in time?
Avatar of jonnin
jonnin

winnt and family have this in the performance monitor, it will graph it for you and give numbers, but its not something you can read in a program, just for humans to read and see what the holdup is...
Avatar of deck16

ASKER

umm, if the performance monitor can get the stats i should be able to do the same thing in my program.
Avatar of deck16

ASKER

does anybody have any ideas?
if you can't find a windows way, you can go low level. Trap the interrupt(s?) that writes to the hd and do something (take stats) when it trips.  The hd write is probably a bios interrupt, not sure, haven't looked at this since 386's were common...

windows may have a way you can use or it can cheat (the os knows when it is writing, even if it does not have a method to look at this that can be used)


probably u can do it thru StartTrace() function. fill out the EVENT_TRACE_PROPERTIES structure and enable the EVENT_TRACE_FLAG_DISK_IO flag.

see article "Starting an Event Tracing Session" on MSDN.

this may help u
good luck
ASKER CERTIFIED SOLUTION
Avatar of jdrescher
jdrescher

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
> performance monitor, it will graph it for you and give numbers, but
its not something you can read in a program, just for humans to read and see what the holdup is

You can read the performance monitor data in a C++ program. Here is code to read the CPU Usage:

// CpuUsage.h: interface for the CCpuUsage class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_)
#define AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000




#define MAX_RAW_VALUES          20

const char szCounterName[] = "\\Processor(_Total)\\% Processor Time";

typedef struct _tag_PDHCounterStruct {
    HCOUNTER hCounter;      // Handle to the counter - given to use by PDH Library
    int nNextIndex;         // element to get the next raw value
    int nOldestIndex;       // element containing the oldes raw value
    int nRawCount;          // number of elements containing raw values
    PDH_RAW_COUNTER a_RawValue[MAX_RAW_VALUES]; // Ring buffer to contain raw values
} PDHCOUNTERSTRUCT, *PPDHCOUNTERSTRUCT;


class CCpuUsage  
{
public:
     CCpuUsage();
     virtual ~CCpuUsage();
     BOOL     Init();
     int GetUsage();

protected:

     PPDHCOUNTERSTRUCT               m_pCounterStruct;
     HQUERY                              m_hQuery;


};

#endif // !defined(AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_)


// CpuUsage.cpp: implementation of the CCpuUsage class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CpuUsage.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCpuUsage::CCpuUsage()
{
     m_hQuery = NULL;
     m_pCounterStruct = NULL;

}

CCpuUsage::~CCpuUsage()
{

     PdhCloseQuery(m_hQuery);
     delete m_pCounterStruct;
}


BOOL CCpuUsage::Init()
{
     if (ERROR_SUCCESS != PdhOpenQuery(NULL, 1, &m_hQuery))
          return FALSE;

    m_pCounterStruct = (PPDHCOUNTERSTRUCT) new PDHCOUNTERSTRUCT;

     PDH_STATUS pdh_status = PdhAddCounter(m_hQuery, szCounterName, (DWORD) m_pCounterStruct, &(m_pCounterStruct->hCounter));
    if (ERROR_SUCCESS != pdh_status)
     {
          return FALSE;
     }



     return TRUE;
}


int CCpuUsage::GetUsage()
{
    PDH_FMT_COUNTERVALUE pdhFormattedValue;

     PdhCollectQueryData(m_hQuery);

    if (ERROR_SUCCESS != PdhGetFormattedCounterValue(
                                    m_pCounterStruct->hCounter,
                                    PDH_FMT_LONG,
                                    NULL,
                                    &pdhFormattedValue ))


     {
          return 0;
     }

     return pdhFormattedValue.longValue;
}

remember to include pdh.h and link with pdh.lib.

To update this for harddrives change szCounterName[] = "\\PhysicalDisk(_Total)\\% Disk Time";


The _Total means all harddrives so if you want individual drives you must use their drive # ( can be found in disk administrator).

John

P.S. This code only works in NT 4.0, Win2k or XP. Because Win9X uses different perfomance monitor than nt4.0 +.

There is a wrapper class for Win9X that will allow you to read its performance counters at the following link:
http://www.naughter.com/dyndata.html

and
Avatar of deck16

ASKER

oh dear, i seem to have forgotten about this question. thanks for the info. For 50 extra points could you tell me the string to use for szCounterName for all the different monitors (CPU, HDD, MEM, etc.)
>could you tell me the string to use for szCounterName for all the different monitors (CPU, HDD, MEM, etc.)

There are too many to list.
CPU
\\Processor(_Total)\\% Processor Time

HDD
\\PhysicalDisk(_Total)\\% Disk Time

MEM
Depends on what you want.

To get the counters for different objects run perfmon from the run command of the start menu and click add.

The format for the string is \\<object name>(<instance>)\\<counter> so in the cpu example:

object = Processor
instance = _Total
counter = % Processor Time