Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/zbxsysinfo/win32/system.c')
-rw-r--r--src/libs/zbxsysinfo/win32/system.c188
1 files changed, 163 insertions, 25 deletions
diff --git a/src/libs/zbxsysinfo/win32/system.c b/src/libs/zbxsysinfo/win32/system.c
index dbac07c9990..3a9a6ac038e 100644
--- a/src/libs/zbxsysinfo/win32/system.c
+++ b/src/libs/zbxsysinfo/win32/system.c
@@ -22,7 +22,7 @@
#include "perfmon.h"
#pragma comment(lib, "user32.lib")
-static void get_50_version(char **os, size_t *os_alloc, size_t *os_offset, OSVERSIONINFOEX *vi)
+static void get_50_version(char **os, size_t *os_alloc, size_t *os_offset, const OSVERSIONINFOEX *vi)
{
zbx_strcpy_alloc(os, os_alloc, os_offset, " Microsoft Windows 2000");
@@ -40,7 +40,7 @@ static void get_50_version(char **os, size_t *os_alloc, size_t *os_offset, OSVER
}
-static void get_51_version(char **os, size_t *os_alloc, size_t *os_offset, OSVERSIONINFOEX *vi)
+static void get_51_version(char **os, size_t *os_alloc, size_t *os_offset, const OSVERSIONINFOEX *vi)
{
zbx_strcpy_alloc(os, os_alloc, os_offset, " Microsoft Windows XP");
@@ -56,7 +56,8 @@ static void get_51_version(char **os, size_t *os_alloc, size_t *os_offset, OSVER
zbx_strcpy_alloc(os, os_alloc, os_offset, " Professional");
}
-static void get_52_version(char **os, size_t *os_alloc, size_t *os_offset, OSVERSIONINFOEX *vi, SYSTEM_INFO *si)
+static void get_52_version(char **os, size_t *os_alloc, size_t *os_offset, const OSVERSIONINFOEX *vi,
+ const SYSTEM_INFO *si)
{
zbx_strcpy_alloc(os, os_alloc, os_offset, " Microsoft Windows");
@@ -84,7 +85,8 @@ static void get_52_version(char **os, size_t *os_alloc, size_t *os_offset, OSVER
}
}
-static void get_6x_version(char **os, size_t *os_alloc, size_t *os_offset, OSVERSIONINFOEX *vi, SYSTEM_INFO *si)
+static void get_6x_version(char **os, size_t *os_alloc, size_t *os_offset, const OSVERSIONINFOEX *vi,
+ const SYSTEM_INFO *si)
{
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
@@ -106,6 +108,9 @@ static void get_6x_version(char **os, size_t *os_alloc, size_t *os_offset, OSVER
case 2:
zbx_strcpy_alloc(os, os_alloc, os_offset, " 8");
break;
+ case 3:
+ zbx_strcpy_alloc(os, os_alloc, os_offset, " 8.1");
+ break;
}
}
else
@@ -121,6 +126,9 @@ static void get_6x_version(char **os, size_t *os_alloc, size_t *os_offset, OSVER
case 2:
zbx_strcpy_alloc(os, os_alloc, os_offset, " Server 2012");
break;
+ case 3:
+ zbx_strcpy_alloc(os, os_alloc, os_offset, " Server 2012 R2");
+ break;
}
}
@@ -186,7 +194,7 @@ static void get_6x_version(char **os, size_t *os_alloc, size_t *os_offset, OSVER
}
}
-static void get_cpu_type(char **os, size_t *os_alloc, size_t *os_offset, SYSTEM_INFO *si)
+static void get_cpu_type(char **os, size_t *os_alloc, size_t *os_offset, const SYSTEM_INFO *si)
{
switch (si->wProcessorArchitecture)
{
@@ -202,17 +210,146 @@ static void get_cpu_type(char **os, size_t *os_alloc, size_t *os_offset, SYSTEM_
}
}
+/******************************************************************************
+ * *
+ * Function: read_registry_value *
+ * *
+ * Purpose: read value from Windows registry *
+ * *
+ ******************************************************************************/
+static wchar_t *read_registry_value(HKEY hKey, LPCTSTR name)
+{
+ DWORD szData;
+ wchar_t *value = NULL;
+
+ if (ERROR_SUCCESS == RegQueryValueEx(hKey, name, NULL, NULL, NULL, &szData))
+ {
+ value = zbx_malloc(NULL, szData);
+ if (ERROR_SUCCESS != RegQueryValueEx(hKey, name, NULL, NULL, (LPBYTE)value, &szData))
+ zbx_free(value);
+ }
+
+ return value;
+}
+
+/******************************************************************************
+ * *
+ * Function: zbx_win_getversion *
+ * *
+ * Purpose: get Windows version information *
+ * *
+ ******************************************************************************/
+const OSVERSIONINFOEX *zbx_win_getversion()
+{
+# define ZBX_REGKEY_VERSION "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion"
+# define ZBX_REGVALUE_CURRENTVERSION "CurrentVersion"
+# define ZBX_REGVALUE_CURRENTBUILDNUMBER "CurrentBuildNumber"
+# define ZBX_REGVALUE_CSDVERSION "CSDVersion"
+
+# define ZBX_REGKEY_PRODUCT "System\\CurrentControlSet\\Control\\ProductOptions"
+# define ZBX_REGVALUE_PRODUCTTYPE "ProductType"
+
+ static OSVERSIONINFOEX vi = {sizeof(OSVERSIONINFOEX)};
+
+ OSVERSIONINFOEX *pvi = NULL;
+ HKEY h_key_registry = NULL;
+ wchar_t *key_value = NULL, *ptr;
+
+ if (0 != vi.dwMajorVersion)
+ return &vi;
+
+ if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(ZBX_REGKEY_VERSION), 0, KEY_READ, &h_key_registry))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "failed to open registry key '%s'", ZBX_REGKEY_VERSION);
+ goto out;
+ }
+
+ if (NULL == (key_value = read_registry_value(h_key_registry, TEXT(ZBX_REGVALUE_CURRENTVERSION))))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "failed to read registry value '%s'", ZBX_REGVALUE_CURRENTVERSION);
+ goto out;
+ }
+
+ if (NULL != (ptr = wcschr(key_value, TEXT('.'))))
+ {
+ *ptr++ = L'\0';
+ vi.dwMinorVersion = _wtoi(ptr);
+ }
+
+ vi.dwMajorVersion = _wtoi(key_value);
+
+ zbx_free(key_value);
+
+ if (6 > vi.dwMajorVersion || 2 > vi.dwMinorVersion)
+ {
+ GetVersionEx((OSVERSIONINFO *)&vi);
+ }
+ else
+ {
+ if (NULL != (key_value = read_registry_value(h_key_registry, TEXT(ZBX_REGVALUE_CSDVERSION))))
+ {
+ wcscpy_s(vi.szCSDVersion, sizeof(vi.szCSDVersion) / sizeof(*vi.szCSDVersion), key_value);
+
+ zbx_free(key_value);
+ }
+
+ if (NULL == (key_value = read_registry_value(h_key_registry, TEXT(ZBX_REGVALUE_CURRENTBUILDNUMBER))))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "failed to read registry value '%s'",
+ ZBX_REGVALUE_CURRENTBUILDNUMBER);
+ goto out;
+ }
+
+ vi.dwBuildNumber = _wtoi(key_value);
+ zbx_free(key_value);
+
+ RegCloseKey(h_key_registry);
+ h_key_registry = NULL;
+
+ if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT(ZBX_REGKEY_PRODUCT), 0, KEY_READ,
+ &h_key_registry))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "failed to open registry key '%s'", ZBX_REGKEY_PRODUCT);
+ goto out;
+ }
+
+ if (NULL == (key_value = read_registry_value(h_key_registry, TEXT(ZBX_REGVALUE_PRODUCTTYPE))))
+ {
+ zabbix_log(LOG_LEVEL_DEBUG, "failed to read registry value '%s'", ZBX_REGVALUE_PRODUCTTYPE);
+ goto out;
+ }
+
+ if (0 == wcscmp(key_value, L"WinNT"))
+ vi.wProductType = 1;
+ else if (0 == wcscmp(key_value, L"LenmanNT"))
+ vi.wProductType = 2;
+ else if (0 == wcscmp(key_value, L"ServerNT"))
+ vi.wProductType = 3;
+
+ zbx_free(key_value);
+
+ vi.dwPlatformId = VER_PLATFORM_WIN32_NT;
+ }
+
+ pvi = &vi;
+out:
+ if (NULL != h_key_registry)
+ RegCloseKey(h_key_registry);
+
+ return pvi;
+}
+
int SYSTEM_UNAME(AGENT_REQUEST *request, AGENT_RESULT *result)
{
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
- DWORD dwSize = 256;
- TCHAR computer_name[256];
- SYSTEM_INFO si;
- OSVERSIONINFOEX vi;
- char *os = NULL, *utf8;
- size_t os_alloc = 256, os_offset = 0;
- PGNSI pGNSI;
+ DWORD dwSize = 256;
+ wchar_t computer_name[256];
+ SYSTEM_INFO si;
+ const OSVERSIONINFOEX *vi;
+ char *os = NULL, *utf8;
+ size_t os_alloc = 256, os_offset = 0;
+ PGNSI pGNSI;
/* Buffer size is chosen large enough to contain any DNS name, not just MAX_COMPUTERNAME_LENGTH + 1 */
/* characters. MAX_COMPUTERNAME_LENGTH is usually less than 32, but it varies among systems, so we */
@@ -221,11 +358,12 @@ int SYSTEM_UNAME(AGENT_REQUEST *request, AGENT_RESULT *result)
*computer_name = '\0';
memset(&si, 0, sizeof(si));
- memset(&vi, 0, sizeof(vi));
- vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
- if (TRUE != GetVersionEx((OSVERSIONINFO *)&vi))
+ if (NULL == (vi = zbx_win_getversion()))
+ {
+ SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system information."));
return SYSINFO_RET_FAIL;
+ }
if (NULL != (pGNSI = (PGNSI)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo")))
pGNSI(&si);
@@ -244,35 +382,35 @@ int SYSTEM_UNAME(AGENT_REQUEST *request, AGENT_RESULT *result)
}
zbx_snprintf_alloc(&os, &os_alloc, &os_offset, " %d.%d.%d",
- vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber);
+ vi->dwMajorVersion, vi->dwMinorVersion, vi->dwBuildNumber);
- if (VER_PLATFORM_WIN32_NT == vi.dwPlatformId)
+ if (VER_PLATFORM_WIN32_NT == vi->dwPlatformId)
{
- switch (vi.dwMajorVersion)
+ switch (vi->dwMajorVersion)
{
case 5:
- switch (vi.dwMinorVersion)
+ switch (vi->dwMinorVersion)
{
case 0:
- get_50_version(&os, &os_alloc, &os_offset, &vi);
+ get_50_version(&os, &os_alloc, &os_offset, vi);
break;
case 1:
- get_51_version(&os, &os_alloc, &os_offset, &vi);
+ get_51_version(&os, &os_alloc, &os_offset, vi);
break;
case 2:
- get_52_version(&os, &os_alloc, &os_offset, &vi, &si);
+ get_52_version(&os, &os_alloc, &os_offset, vi, &si);
break;
}
break;
case 6:
- get_6x_version(&os, &os_alloc, &os_offset, &vi, &si);
+ get_6x_version(&os, &os_alloc, &os_offset, vi, &si);
break;
}
}
- if ('\0' != *vi.szCSDVersion)
+ if ('\0' != *vi->szCSDVersion)
{
- utf8 = zbx_unicode_to_utf8(vi.szCSDVersion);
+ utf8 = zbx_unicode_to_utf8(vi->szCSDVersion);
zbx_snprintf_alloc(&os, &os_alloc, &os_offset, " %s", utf8);
zbx_free(utf8);
}