コード例 #1
0
ファイル: perfctr_collect.cpp プロジェクト: ChineseDr/mongo
Status PerfCounterCollector::collectCounters(const std::vector<CounterInfo>& counters,
                                             BSONObjBuilder* builder) {
    for (const auto& counterInfo : counters) {

        DWORD dwType = 0;
        PDH_RAW_COUNTER rawCounter = {0};

        PDH_STATUS status = PdhGetRawCounterValue(counterInfo.handle, &dwType, &rawCounter);
        if (status != ERROR_SUCCESS) {
            return {ErrorCodes::WindowsPdhError,
                    formatFunctionCallError("PdhGetRawCounterValue", status)};
        }

        if (counterInfo.hasSecondValue) {
            // Delta, Rate, and Elapsed Time counters require the second value in the raw counter
            // information
            builder->append(counterInfo.firstName, rawCounter.FirstValue);
            builder->append(counterInfo.secondName, rawCounter.SecondValue);
        } else {
            builder->append(counterInfo.firstName, rawCounter.FirstValue);
        }
    }

    return Status::OK();
}
コード例 #2
0
__int64 PerfCounter::GetRawValue(int id)
{
	if(id == 0)
		return 0;

	PDH_RAW_COUNTER value;
	PdhGetRawCounterValue(m_counters[id - 1], NULL, &value);
	return value.FirstValue;
}
コード例 #3
0
PerfCounter::PerfCounter()
{
	PdhOpenQuery(NULL, NULL, &m_query);

	HMODULE hProcess = GetModuleHandle(NULL);
	wchar_t fileNameBuf[MAX_PATH];
	GetModuleFileName((HMODULE) hProcess, fileNameBuf, MAX_PATH);
	wchar_t baseNameBuf[MAX_PATH];
	_wsplitpath_s(fileNameBuf, NULL, 0, NULL, 0, baseNameBuf, MAX_PATH, NULL, 0);
	m_processName = baseNameBuf;
	DWORD processId = GetProcessId(GetCurrentProcess());

	//we need to figure out the correct instance name
	//start by asking for all the counters which match the process name
	std::wstring wildcard = (boost::wformat(L"\\Process(%1%*)\\ID Process") % m_processName).str();
	wchar_t paths[1024];
	DWORD size = 1024;
	PdhExpandWildCardPath(NULL, wildcard.c_str(), paths, &size, 0);

	//create each ProcessID counter, check its value to see if it's the one we want
	size_t len = wcslen(paths);
	wchar_t* pathPtr = paths;
	bool found = false;
	while(len != 0)
	{
		PDH_HCOUNTER counter;
		PdhAddCounter(m_query, pathPtr, NULL, &counter);
		PdhCollectQueryData(m_query);
		PDH_RAW_COUNTER counterValue;
		PdhGetRawCounterValue(counter, 0, &counterValue);
		PdhRemoveCounter(counter);

		if(counterValue.FirstValue == processId)
		{
			found = true;
			break;
		}

		pathPtr += len + 1;
		len = wcslen(pathPtr);
	}

	if(found)
	{
		//we've got our desired instance name, which is ProcessName#N
		const wchar_t* instStart = wcschr(wildcard.c_str(), L'(') + 1;
		const wchar_t* instEnd = wcschr(wildcard.c_str(), L')') - 1;
		m_instName = std::wstring(instStart, instEnd - instStart);
	}
	else
	{
		//oh well, just roll with what we've got
		m_instName = m_processName;
	}
}
コード例 #4
0
ファイル: mssql_pdh.cpp プロジェクト: GerryStydy/hq
JNIEXPORT jdouble JNICALL Java_org_hyperic_hq_plugin_mssql_PDH_pdhGetRawCounterValue(JNIEnv *env, jclass, jlong counter) {
    HCOUNTER  h_counter = (HCOUNTER)counter;
    PDH_RAW_COUNTER raw_value;
	DWORD type;

	PDH_STATUS status = PdhGetRawCounterValue(h_counter, &type, &raw_value);

    if (status != ERROR_SUCCESS) {
        plugin_throw_exception(env, get_error_message(status));
        return 0;
    }

	return (jdouble)raw_value.FirstValue;
}
コード例 #5
0
ファイル: pdh.c プロジェクト: 40a/sigar
JNIEXPORT jdouble SIGAR_JNI(win32_Pdh_pdhGetValue)
(JNIEnv *env, jclass cur, jlong query, jlong counter, jboolean fmt)
{
    HCOUNTER              h_counter      = (HCOUNTER)counter;
    HQUERY                h_query        = (HQUERY)query;
    PDH_STATUS            status;
    PDH_RAW_COUNTER raw_value;
    PDH_FMT_COUNTERVALUE fmt_value;
    DWORD type;

    status = PdhCollectQueryData(h_query);
   
    if (status != ERROR_SUCCESS) {
        win32_throw_exception(env, get_error_message(status));
        return 0;
    }

    if (fmt) {
        /* may require 2 counters, see msdn docs */
        int i=0;
        for (i=0; i<2; i++) {
            status = PdhGetFormattedCounterValue(h_counter,
                                                 PDH_FMT_DOUBLE,
                                                 (LPDWORD)NULL,
                                                 &fmt_value);
            if (status == ERROR_SUCCESS) {
                break;
            }

            PdhCollectQueryData(h_query);
        }
    }
    else {
        status = PdhGetRawCounterValue(h_counter, &type, &raw_value);
    }

    if (status != ERROR_SUCCESS) {
        win32_throw_exception(env, get_error_message(status));
        return 0;
    }

    if (fmt) {
        return fmt_value.doubleValue;
    }
    else {
        return (jdouble)raw_value.FirstValue;
    }
}
コード例 #6
0
ファイル: perfmon.c プロジェクト: jbfavre/debian-zabbix
PDH_STATUS	zbx_PdhGetRawCounterValue(const char *function, const char *counterpath, PDH_HCOUNTER handle, PPDH_RAW_COUNTER value)
{
    PDH_STATUS	pdh_status;

    if (ERROR_SUCCESS != (pdh_status = PdhGetRawCounterValue(handle, NULL, value)) ||
            (PDH_CSTATUS_VALID_DATA != value->CStatus && PDH_CSTATUS_NEW_DATA != value->CStatus))
    {
        if (ERROR_SUCCESS == pdh_status)
            pdh_status = value->CStatus;

        zabbix_log(LOG_LEVEL_DEBUG, "%s(): cannot get counter value '%s': %s",
                   function, counterpath, strerror_from_module(pdh_status, L"PDH.DLL"));
    }

    return pdh_status;
}
コード例 #7
0
ファイル: readWindowsCounters.c プロジェクト: bradomyn/sFlow
uint64_t readSingleCounter(char* path)
{
    PDH_HQUERY Query = NULL;
    PDH_HCOUNTER Counter;
	DWORD dwType;
	PDH_RAW_COUNTER Value;
	LONGLONG ret = 0;

    if(PdhOpenQuery(NULL, 0, &Query) == ERROR_SUCCESS) {
		if(PdhAddCounter(Query, path, 0, &Counter) == ERROR_SUCCESS &&
		   PdhCollectQueryData(Query) == ERROR_SUCCESS &&
		   PdhGetRawCounterValue(Counter, &dwType, &Value) == ERROR_SUCCESS) {
			ret = Value.FirstValue;
		}
        if (Query) PdhCloseQuery(Query);
    }
	return (uint64_t)ret;
}
コード例 #8
0
ファイル: perfctr_collect.cpp プロジェクト: acmorrow/mongo
Status PerfCounterCollector::collectCounters(const std::vector<CounterInfo>& counters,
                                             BSONObjBuilder* builder) {
    for (const auto& counterInfo : counters) {

        DWORD dwType = 0;

        // Elapsed Time is an unusual counter in that being able to control the sample period for
        // the counter is uninteresting even though it is computed from two values. Just return the
        // computed value instead.
        if (counterInfo.type == PERF_ELAPSED_TIME) {
            PDH_FMT_COUNTERVALUE counterValue = {0};
            PDH_STATUS status = PdhGetFormattedCounterValue(
                counterInfo.handle, PDH_FMT_DOUBLE, &dwType, &counterValue);
            if (status != ERROR_SUCCESS) {
                return {ErrorCodes::WindowsPdhError,
                        formatFunctionCallError("PdhGetFormattedCounterValue", status)};
            }

            builder->append(counterInfo.firstName, counterValue.doubleValue);

        } else {

            PDH_RAW_COUNTER rawCounter = {0};
            PDH_STATUS status = PdhGetRawCounterValue(counterInfo.handle, &dwType, &rawCounter);
            if (status != ERROR_SUCCESS) {
                return {ErrorCodes::WindowsPdhError,
                        formatFunctionCallError("PdhGetRawCounterValue", status)};
            }

            if (counterInfo.hasSecondValue) {
                // Precise counters require the second value in the raw counter information
                builder->append(counterInfo.firstName, rawCounter.FirstValue);
                builder->append(counterInfo.secondName, rawCounter.SecondValue);
            } else {
                builder->append(counterInfo.firstName, rawCounter.FirstValue);
            }
        }
    }

    return Status::OK();
}
コード例 #9
0
ファイル: perfmon.cpp プロジェクト: SnipeDragon/gamecq
// Function name	: CPerfMon::UpdateRawValue
// Description	    : Update the raw values for the counter in pCounter
// Return type		: BOOL ; false fail ; true success
// Argument         : PPDHCOUNTERSTRUCT pCounter
//
// R E V I S I O N S:
// DATE       PROGRAMMER      CHANGES
//
BOOL CPerfMon::UpdateRawValue(PPDHCOUNTERSTRUCT pCounter)
{
    PPDH_RAW_COUNTER ppdhRawCounter;

    // Assign the next value into the array
    ppdhRawCounter = &(pCounter->a_RawValue[pCounter->nNextIndex]);

	if (PdhGetRawCounterValue(pCounter->hCounter, NULL, ppdhRawCounter) != ERROR_SUCCESS)
		return false;
	
    // update raw counter - up to MAX_RAW_VALUES
    pCounter->nRawCount = min(pCounter->nRawCount + 1, MAX_RAW_VALUES);

    // Update next index - rolls back to zero upon reaching MAX_RAW_VALUES
    pCounter->nNextIndex = (pCounter->nNextIndex + 1) % MAX_RAW_VALUES;

    // The Oldest index remains zero until the array is filled.
    // It will now be the same as the 'next' index since it was previously assigned.
    if (pCounter->nRawCount >= MAX_RAW_VALUES)
        pCounter->nOldestIndex = pCounter->nNextIndex;

	return true;
}
コード例 #10
0
ファイル: fetch.c プロジェクト: Aconex/pcp
/*
 * Instantiate a value for a single metric-instance pair
 */
int
windows_collect_metric(pdh_metric_t *mp, LPSTR pat, pdh_value_t *vp)
{
    PDH_STATUS  	pdhsts;
    PDH_HQUERY		queryhdl = NULL;
    PDH_HCOUNTER	counthdl = NULL;
    int			sts = -1;

    if (mp->flags & M_NOVALUES)
	return sts;

    pdhsts = PdhOpenQueryA(NULL, 0, &queryhdl);
    if (pdhsts != ERROR_SUCCESS) {
	__pmNotifyErr(LOG_ERR, "windows_open: PdhOpenQueryA failed: %s\n",
			pdherrstr(pdhsts));
	return sts;
    }

    pdhsts = PdhAddCounterA(queryhdl, pat, vp->inst, &counthdl);
    if (pdhsts != ERROR_SUCCESS) {
	__pmNotifyErr(LOG_ERR, "windows_open: Warning: PdhAddCounterA "
				"@ pmid=%s pat=\"%s\": %s\n",
			    pmIDStr(mp->desc.pmid), pat, pdherrstr(pdhsts));
	PdhCloseQuery(queryhdl);
	return sts;
    }

    pdhsts = PdhCollectQueryData(queryhdl);
    if (pdhsts != ERROR_SUCCESS) {
	if ((vp->flags & V_ERROR_SEEN) == 0) {
	    __pmNotifyErr(LOG_ERR, "pdh_fetch: Error: PdhCollectQueryData "
				   "failed for metric %s pat %s: %s\n",
			pmIDStr(mp->desc.pmid), pat, pdherrstr(pdhsts));
	    vp->flags |= V_ERROR_SEEN;
	}
    } else if ((mp->ctype == PERF_ELAPSED_TIME) ||
		mp->ctype == PERF_LARGE_RAW_FRACTION) {
	PDH_FMT_COUNTERVALUE fmt;
	DWORD type;

	if (mp->ctype == PERF_ELAPSED_TIME)
	    type = PDH_FMT_LARGE;
	else	/* PERF_LARGE_RAW_FRACTION */
	    type = PDH_FMT_DOUBLE;

	pdhsts = PdhGetFormattedCounterValue(counthdl, type, NULL, &fmt);
	if (pdhsts != ERROR_SUCCESS) {
	    __pmNotifyErr(LOG_ERR, "Error: PdhGetFormattedCounterValue "
			"failed for metric %s inst %d: %s\n",
			pmIDStr(mp->desc.pmid), vp->inst, pdherrstr(pdhsts));
	    vp->flags = V_NONE;	/* no values for you! */
	} else if (mp->ctype == PERF_ELAPSED_TIME) {
	    vp->atom.ull = fmt.largeValue;
	    sts = 0;
	} else {	/* PERF_LARGE_RAW_FRACTION */
	    vp->atom.d = fmt.doubleValue;
	    sts = 0;
	}
    } else {
	PDH_RAW_COUNTER	raw;

	pdhsts = PdhGetRawCounterValue(counthdl, NULL, &raw);
	if (pdhsts != ERROR_SUCCESS) {
	    __pmNotifyErr(LOG_ERR, "pdh_fetch: Error: PdhGetRawCounterValue "
				"failed for metric %s inst %d: %s\n",
			pmIDStr(mp->desc.pmid), vp->inst, pdherrstr(pdhsts));
	    vp->flags = V_NONE;	/* no values for you! */
	} else {
	    switch (mp->ctype) {
		case PERF_COUNTER_COUNTER:
		case PERF_COUNTER_RAWCOUNT:
		    /* these counters are only 32-bit */
		    vp->atom.ul = (__uint32_t)raw.FirstValue;
		    break;

		case PERF_100NSEC_TIMER:
		case PERF_PRECISION_100NS_TIMER:
		    /* convert 100nsec units to usec */
		    vp->atom.ull = raw.FirstValue / 10;
		    break;

		case PERF_RAW_FRACTION:
		    /* v1 / v2 as percentage */
		    vp->atom.f = (float)raw.FirstValue / raw.SecondValue;
		    break;

		case PERF_COUNTER_BULK_COUNT:
		case PERF_COUNTER_LARGE_RAWCOUNT:
		default:
		    vp->atom.ull = raw.FirstValue;
	    }
	    sts = 0;
	}
    }
    PdhRemoveCounter(counthdl);
    PdhCloseQuery(queryhdl);
    return sts;
}
コード例 #11
0
ファイル: CPUInfo.cpp プロジェクト: Karlson2k/xbmc
bool CCPUInfo::readProcStat(unsigned long long& user, unsigned long long& nice,
    unsigned long long& system, unsigned long long& idle, unsigned long long& io)
{

#ifdef TARGET_WINDOWS
  FILETIME idleTime;
  FILETIME kernelTime;
  FILETIME userTime;
  if (GetSystemTimes(&idleTime, &kernelTime, &userTime) == 0)
    return false;

  idle = (uint64_t(idleTime.dwHighDateTime) << 32) + uint64_t(idleTime.dwLowDateTime);
  // returned "kernelTime" includes "idleTime"
  system = (uint64_t(kernelTime.dwHighDateTime) << 32) + uint64_t(kernelTime.dwLowDateTime) - idle;
  user = (uint64_t(userTime.dwHighDateTime) << 32) + uint64_t(userTime.dwLowDateTime);
  nice = 0;
  io = 0;

  if (m_cpuFreqCounter && PdhCollectQueryData(m_cpuQueryLoad) == ERROR_SUCCESS)
  {
    for (std::map<int, CoreInfo>::iterator it = m_cores.begin(); it != m_cores.end(); ++it)
    {
      CoreInfo& curCore = it->second; // simplify usage
      PDH_RAW_COUNTER cnt;
      DWORD cntType;
      if (curCore.m_coreCounter && PdhGetRawCounterValue(curCore.m_coreCounter, &cntType, &cnt) == ERROR_SUCCESS &&
          (cnt.CStatus == PDH_CSTATUS_VALID_DATA || cnt.CStatus == PDH_CSTATUS_NEW_DATA))
      {
        const LONGLONG coreTotal = cnt.SecondValue,
                       coreIdle  = cnt.FirstValue;
        const LONGLONG deltaTotal = coreTotal - curCore.m_total,
                       deltaIdle  = coreIdle - curCore.m_idle;
        const double load = (double(deltaTotal - deltaIdle) * 100.0) / double(deltaTotal);
        
        // win32 has some problems with calculation of load if load close to zero
        curCore.m_fPct = (load < 0) ? 0 : load;
        if (load >= 0 || deltaTotal > 5 * 10 * 1000 * 1000) // do not update (smooth) values for 5 seconds on negative loads
        {
          curCore.m_total = coreTotal;
          curCore.m_idle = coreIdle;
        }
      }
      else
        curCore.m_fPct = double(m_lastUsedPercentage); // use CPU average as fallback
    }
  }
  else
    for (std::map<int, CoreInfo>::iterator it = m_cores.begin(); it != m_cores.end(); ++it)
      it->second.m_fPct = double(m_lastUsedPercentage); // use CPU average as fallback
#elif defined(TARGET_FREEBSD)
  long *cptimes;
  size_t len;
  int i;

  len = sizeof(long) * 32 * CPUSTATES;
  if (sysctlbyname("kern.cp_times", NULL, &len, NULL, 0) != 0)
    return false;
  cptimes = (long*)malloc(len);
  if (cptimes == NULL)
    return false;
  if (sysctlbyname("kern.cp_times", cptimes, &len, NULL, 0) != 0)
  {
    free(cptimes);
    return false;
  }
  user = 0;
  nice = 0;
  system = 0;
  idle = 0;
  io = 0;
  for (i = 0; i < m_cpuCount; i++)
  {
    long coreUser, coreNice, coreSystem, coreIdle, coreIO;
    double total;

    coreUser   = cptimes[i * CPUSTATES + CP_USER];
    coreNice   = cptimes[i * CPUSTATES + CP_NICE];
    coreSystem = cptimes[i * CPUSTATES + CP_SYS];
    coreIO     = cptimes[i * CPUSTATES + CP_INTR];
    coreIdle   = cptimes[i * CPUSTATES + CP_IDLE];

    std::map<int, CoreInfo>::iterator iter = m_cores.find(i);
    if (iter != m_cores.end())
    {
      coreUser -= iter->second.m_user;
      coreNice -= iter->second.m_nice;
      coreSystem -= iter->second.m_system;
      coreIdle -= iter->second.m_idle;
      coreIO -= iter->second.m_io;

      total = (double)(coreUser + coreNice + coreSystem + coreIdle + coreIO);
      if(total != 0.0f)
        iter->second.m_fPct = ((double)(coreUser + coreNice + coreSystem) * 100.0) / total;

      iter->second.m_user += coreUser;
      iter->second.m_nice += coreNice;
      iter->second.m_system += coreSystem;
      iter->second.m_idle += coreIdle;
      iter->second.m_io += coreIO;

      user   += coreUser;
      nice   += coreNice;
      system += coreSystem;
      idle   += coreIdle;
      io     += coreIO;
    }
  }
  free(cptimes);
#else
  if (m_fProcStat == NULL)
    return false;

#ifdef TARGET_ANDROID
  // Just another (vanilla) NDK quirk:
  // rewind + fflush do not actually flush the buffers,
  // the same initial content is returned rather than re-read
  fclose(m_fProcStat);
  m_fProcStat = fopen("/proc/stat", "r");
#else
  rewind(m_fProcStat);
  fflush(m_fProcStat);
#endif

  char buf[256];
  if (!fgets(buf, sizeof(buf), m_fProcStat))
    return false;

  int num = sscanf(buf, "cpu %llu %llu %llu %llu %llu %*s\n", &user, &nice, &system, &idle, &io);
  if (num < 5)
    io = 0;

  while (fgets(buf, sizeof(buf), m_fProcStat) && num >= 4)
  {
    unsigned long long coreUser, coreNice, coreSystem, coreIdle, coreIO;
    int nCpu=0;
    num = sscanf(buf, "cpu%d %llu %llu %llu %llu %llu %*s\n", &nCpu, &coreUser, &coreNice, &coreSystem, &coreIdle, &coreIO);
    if (num < 6)
      coreIO = 0;

    std::map<int, CoreInfo>::iterator iter = m_cores.find(nCpu);
    if (num > 4 && iter != m_cores.end())
    {
      coreUser -= iter->second.m_user;
      coreNice -= iter->second.m_nice;
      coreSystem -= iter->second.m_system;
      coreIdle -= iter->second.m_idle;
      coreIO -= iter->second.m_io;

      double total = (double)(coreUser + coreNice + coreSystem + coreIdle + coreIO);
      if(total == 0.0f)
        iter->second.m_fPct = 0.0f;
      else
        iter->second.m_fPct = ((double)(coreUser + coreNice + coreSystem) * 100.0) / total;

      iter->second.m_user += coreUser;
      iter->second.m_nice += coreNice;
      iter->second.m_system += coreSystem;
      iter->second.m_idle += coreIdle;
      iter->second.m_io += coreIO;
    }
  }
#endif

  return true;
}
コード例 #12
0
ファイル: CPUInfo.cpp プロジェクト: Karlson2k/xbmc
float CCPUInfo::getCPUFrequency()
{
  // Get CPU frequency, scaled to MHz.
#if defined(TARGET_DARWIN)
  long long hz = 0;
  size_t len = sizeof(hz);
  if (sysctlbyname("hw.cpufrequency", &hz, &len, NULL, 0) == -1)
    return 0.f;
  return hz / 1000000.0;
#elif defined TARGET_WINDOWS
  if (m_cpuFreqCounter && PdhCollectQueryData(m_cpuQueryFreq) == ERROR_SUCCESS)
  {
    PDH_RAW_COUNTER cnt;
    DWORD cntType;
    if (PdhGetRawCounterValue(m_cpuFreqCounter, &cntType, &cnt) == ERROR_SUCCESS &&
        (cnt.CStatus == PDH_CSTATUS_VALID_DATA || cnt.CStatus == PDH_CSTATUS_NEW_DATA))
    {
      return float(cnt.FirstValue);
    }
  }
  
  if (!m_cores.empty())
    return float(m_cores.begin()->second.m_fSpeed);
  else
    return 0.f;
#elif defined(TARGET_FREEBSD)
  int hz = 0;
  size_t len = sizeof(hz);
  if (sysctlbyname("dev.cpu.0.freq", &hz, &len, NULL, 0) != 0)
    hz = 0;
  return (float)hz;
#else
  int value = 0;
  if (m_fCPUFreq && !m_cpuInfoForFreq)
  {
    rewind(m_fCPUFreq);
    fflush(m_fCPUFreq);
    fscanf(m_fCPUFreq, "%d", &value);
    value /= 1000.0;
  }
  if (m_fCPUFreq && m_cpuInfoForFreq)
  {
    rewind(m_fCPUFreq);
    fflush(m_fCPUFreq);
    float mhz, avg=0.0;
    int n, cpus=0;
    while(EOF!=(n=fscanf(m_fCPUFreq," MHz : %f ", &mhz)))
    {
      if (n>0) {
        cpus++;
        avg += mhz;
      }
      fscanf(m_fCPUFreq,"%*s");
    }

    if (cpus > 0)
      value = avg/cpus;
  }
  return value;
#endif
}
コード例 #13
0
ファイル: pdhmon.c プロジェクト: Shmuma/z
int	PERF_MONITOR(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
{
	HQUERY		query;
	HCOUNTER	counter;
	PDH_STATUS	status;

	PDH_RAW_COUNTER		rawData, rawData2;
	PDH_FMT_COUNTERVALUE	counterValue;

	char	counter_name[MAX_STRING_LEN];

	int	ret = SYSINFO_RET_FAIL;

	if(num_param(param) > 1)
	{
		return SYSINFO_RET_FAIL;
	}

	if(get_param(param, 1, counter_name, sizeof(counter_name)) != 0)
	{
		counter_name[0] = '\0';
	}
	if(counter_name[0] == '\0')
	{
		return SYSINFO_RET_FAIL;
	}

	if (ERROR_SUCCESS == PdhOpenQuery(NULL,0,&query))
	{
		if (ERROR_SUCCESS == (status = PdhAddCounter(query,counter_name,0,&counter)))
		{
			if (ERROR_SUCCESS == (status = PdhCollectQueryData(query)))
			{
				if(ERROR_SUCCESS == (status = PdhGetRawCounterValue(counter, NULL, &rawData)) &&
					(rawData.CStatus == PDH_CSTATUS_VALID_DATA || rawData.CStatus == PDH_CSTATUS_NEW_DATA))
				{
					if( PDH_CSTATUS_INVALID_DATA == (status = PdhCalculateCounterFromRawValue(
						counter, 
						PDH_FMT_DOUBLE, 
						&rawData, 
						NULL, 
						&counterValue
						)) )
					{
						zbx_sleep(1);
						PdhCollectQueryData(query);
						PdhGetRawCounterValue(counter, NULL, &rawData2);
						status = PdhCalculateCounterFromRawValue(
							counter, 
							PDH_FMT_DOUBLE, 
							&rawData2, 
							&rawData, 
							&counterValue);

					}

					if(ERROR_SUCCESS == status)
					{
						SET_DBL_RESULT(result, counterValue.doubleValue);
						ret = SYSINFO_RET_OK;
					}
					else
					{
						zabbix_log(LOG_LEVEL_DEBUG, "Can't format counter value [%s] [%s]", counter_name, strerror_from_module(status,"PDH.DLL"));
					}
				}
				else
				{
					if(ERROR_SUCCESS == status) status = rawData.CStatus;

					zabbix_log(LOG_LEVEL_DEBUG, "Can't get counter value [%s] [%s]", counter_name, strerror_from_module(status,"PDH.DLL"));
				}
			}
			else
			{
				zabbix_log(LOG_LEVEL_DEBUG, "Can't collect data [%s] [%s]", counter_name, strerror_from_module(status,"PDH.DLL"));
			}
			PdhRemoveCounter(&counter);
		}
		else
		{
			zabbix_log(LOG_LEVEL_DEBUG, "Can't add counter [%s] [%s]", counter_name, strerror_from_module(status,"PDH.DLL"));
		}


		PdhCloseQuery(query);
	}

	return ret;
}