Module: check_mk
Branch: master
Commit: b18cfc52de1473b2054d6e0decb486443235fa25
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=b18cfc52de1473…
Author: Sebastian Herbord <sh(a)mathias-kettner.de>
Date: Wed Feb 3 15:36:34 2016 +0100
#3066 FIX windows agent: 32-bit performance counters were not returned correctly
---
.werks/3066 | 9 +++++++++
ChangeLog | 1 +
agents/windows/PerfCounter.cc | 42 ++++++++++++++++++++++++-----------------
3 files changed, 35 insertions(+), 17 deletions(-)
diff --git a/.werks/3066 b/.werks/3066
new file mode 100644
index 0000000..6552d0f
--- /dev/null
+++ b/.werks/3066
@@ -0,0 +1,9 @@
+Title: windows agent: 32-bit performance counters were not returned correctly
+Level: 1
+Component: checks
+Compatible: compat
+Version: 1.2.7i4
+Date: 1454510131
+Class: fix
+
+
diff --git a/ChangeLog b/ChangeLog
index 8b675b3..3f6e4fe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -244,6 +244,7 @@
* 3065 FIX: mem.win: renamed "Pagefile" to "Commit Charge" to
clarify what the number actually expresses...
* 3043 FIX: agent_emcvnx: Fixed error handling in case of missing naviseccli command
* 3045 FIX: veeam_backup_status: Fixed wrong date format reported by agent...
+ * 3066 FIX: windows agent: 32-bit performance counters were not returned correctly
Multisite:
* 2684 Added icons for downloading agent data / walks of hosts...
diff --git a/agents/windows/PerfCounter.cc b/agents/windows/PerfCounter.cc
index 5826aa2..ddd3620 100644
--- a/agents/windows/PerfCounter.cc
+++ b/agents/windows/PerfCounter.cc
@@ -111,25 +111,33 @@ std::string PerfCounter::typeName() const {
ULONGLONG PerfCounter::extractValue(PERF_COUNTER_BLOCK *block) const {
unsigned offset = _counter->CounterOffset;
- int size = _counter->CounterSize;
BYTE *pData = ((BYTE *)block) + offset;
- if (_counter->CounterType & PERF_SIZE_DWORD) {
- return static_cast<ULONGLONG>(*(DWORD *)block);
- } else if (_counter->CounterType & PERF_SIZE_LARGE) {
- return *(UNALIGNED ULONGLONG *)pData;
- }
- // handle other data generically. This is wrong in some situation.
- // Once upon a time in future we might implement a conversion as
- // described in
- //
http://msdn.microsoft.com/en-us/library/aa373178%28v=vs.85%29.aspx
- else if (size == 4) {
- return static_cast<ULONGLONG>(*(DWORD *)pData);
- } else if (size == 8) {
- DWORD *data_at = (DWORD *)pData;
- return (DWORDLONG)*data_at + ((DWORDLONG) * (data_at + 1) << 32);
- } else {
- return 0ULL;
+ static const DWORD PERF_SIZE_MASK = 0x00000300;
+
+ switch (_counter->CounterType & PERF_SIZE_MASK) {
+ case PERF_SIZE_DWORD:
+ return static_cast<ULONGLONG>(*(DWORD *)block);
+ case PERF_SIZE_LARGE:
+ return *(UNALIGNED ULONGLONG *)pData;
+ case PERF_SIZE_ZERO:
+ return 0ULL;
+ default: { // PERF_SIZE_VARIABLE_LEN
+ // handle other data generically. This is wrong in some situation.
+ // Once upon a time in future we might implement a conversion as
+ // described in
+ //
http://msdn.microsoft.com/en-us/library/aa373178%28v=vs.85%29.aspx
+ int size = _counter->CounterSize;
+ if (size == 4) {
+ return static_cast<ULONGLONG>(*(DWORD *)pData);
+ } else if (size == 8) {
+ DWORD *data_at = (DWORD *)pData;
+ return (DWORDLONG)*data_at +
+ ((DWORDLONG) * (data_at + 1) << 32);
+ } else {
+ return 0ULL;
+ }
+ } break;
}
}