Solved

Harddrive Usage?

Posted on 2002-04-27
9
445 Views
Last Modified: 2007-11-27
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?
0
Comment
Question by:deck16
  • 3
  • 3
  • 2
  • +1
9 Comments
 
LVL 2

Expert Comment

by:jonnin
Comment Utility
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...
0
 

Author Comment

by:deck16
Comment Utility
umm, if the performance monitor can get the stats i should be able to do the same thing in my program.
0
 

Author Comment

by:deck16
Comment Utility
does anybody have any ideas?
0
 
LVL 2

Expert Comment

by:jonnin
Comment Utility
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)

0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Expert Comment

by:1cand01t
Comment Utility

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
0
 
LVL 1

Accepted Solution

by:
jdrescher earned 100 total points
Comment Utility
> 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
0
 
LVL 1

Expert Comment

by:jdrescher
Comment Utility
> 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
0
 

Author Comment

by:deck16
Comment Utility
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.)
0
 
LVL 1

Expert Comment

by:jdrescher
Comment Utility
>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

0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now