locked
PDH counter issue on Vista and later RRS feed

  • Question

  • Hi all,

    Really hoping for some help here - maybe there's an obvious reason for this behaviour, but it's escaping me at the moment. Maybe I'm missing something in the docs?

    I have some fairly old C++ code that is intended to keep an eye on the disk queue PDH counter. It still works fine on older Windows operating systems, e.g. XP, Server 2003. However, on Vista, Windows 7 etc, the counter seems to be set up fine, but always returns an error when I try to retrieve the value (I get a PDH_NO_DATA error, which is completely unhelpful).

     PDH_STATUS status;
     wchar_t  diskQueueCounterPath[] = L"\\\\.\\PhysicalDisk(_Total)\\Current Disk Queue Length";
    
     // Create a PDH query
     status = PdhOpenQuery( NULL, 0, &m_perfQuery );
     if(status != ERROR_SUCCESS ){
      Log(llWarning, L"Failed to open PDH query during disk queue retrieval");
      m_perfQuery = NULL;
      //return failure;
     }
     else
     {
      Log(llMessage, L"Opened PDH query during disk queue retrieval");
      // Associate the disk queue counter with the query
      status = PdhAddCounter( m_perfQuery, diskQueueCounterPath, 0, &m_DiskQueueCounter );
      if( status != ERROR_SUCCESS ){
       Log(llWarning, (CPString)L"Failed to associate PDH counter during disk queue retrieval. Error: " + (uint32)status);
       m_DiskQueueCounter = NULL;
      } else {
       Log(llMessage, (CPString)L"Associate PDH counter during disk queue retrieval. Error: " + (uint32)status);
      }
     }
    
     // Test the counter
    //#ifdef _Debug_
     if(m_perfQuery == NULL || m_DiskQueueCounter == NULL)
     {
      return failure;
     }
    
     // Get the actual data
     PDH_FMT_COUNTERVALUE vDiskQueueValue;
    
     status = PdhCollectQueryData( m_perfQuery );
     if (status == ERROR_SUCCESS){
      DWORD err = GetLastError();
      CPString sErr;
      sErr.SetHex(status);
      Log(llMessage, (CPString)L"OK - Collected query data during disk queue retrieval, status was " + (int32)status + L", err was " + err + L" (" + sErr + L")");
     } else {
      DWORD err = GetLastError();
      CPString sErr;
      sErr.SetHex(status);
      Log(llWarning, (CPString)L"Failed to collect query data during disk queue retrieval, status was " + (int32)status + L", err was " + err + L" (" + sErr + L")");
     }
    
     // Get the formatted counter value
     status = PdhGetFormattedCounterValue( m_DiskQueueCounter, PDH_FMT_LARGE , NULL, &vDiskQueueValue );
     if( status != ERROR_SUCCESS ){
      DWORD err = GetLastError();
      Log(llWarning, (CPString)L"Failed to format counter data during disk queue retrieval, err was " + err);
      SetUsage(0);
     } else {
      Log(llMessage, (CPString)L"OK - formatted counter data during disk queue retrieval");
     }
    



    On Vista (x86), this produces the following output, even when run as Administrator:

    [Message] Opened PDH query during disk queue retrieval
    [Message] Associate PDH counter during disk queue retrieval. Error: 0
    [Warning] Failed to collect query data during disk queue retrieval, status was -2147481643, err was 2147485648 (800007D5)
    [Warning] Failed to format counter data during disk queue retrieval, err was 183

    However, on Server 2003, it produces:

    [Message] Opened PDH query during disk queue retrieval
    [Message] Associate PDH counter during disk queue retrieval. Error: 0
    [Message] OK - Collected query data during disk queue retrieval, status was 0, err was 997 (00000000)
    [Message] OK - formatted counter data during disk queue retrieval

    PDH error 800007D5 is PDH_NO_DATA, which tells me pretty much nothing. Windows 7 (also x86) does the same thing. However, the counter does seem to work fine:

    C:\Users\mikevbokhoven>typeperf "\PhysicalDisk(_Total)\Current Disk Queue Length"

    "(PDH-CSV 4.0)","\\X86-WIN7PRO\PhysicalDisk(_Total)\Current Disk Queue Length"
    "07/04/2011 19:06:57.223","0.000000"
    "07/04/2011 19:06:58.227","0.000000"
    "07/04/2011 19:06:59.230","0.000000"
    ...
    "07/04/2011 19:07:30.353","0.000000"
    "07/04/2011 19:07:31.360","0.000000"
    "07/04/2011 19:07:32.409","1.000000"
    "07/04/2011 19:07:33.449","3.000000"
    "07/04/2011 19:07:34.463","0.000000"
    "07/04/2011 19:07:35.491","0.000000"


    Can anyone shed any light on this behaviour? Any help much appreciated.
    Tuesday, July 5, 2011 4:40 AM