--- projects/libstatgrab/src/libstatgrab/os_info.c 2004/11/07 12:31:33 1.22 +++ projects/libstatgrab/src/libstatgrab/os_info.c 2005/09/24 13:29:22 1.23 @@ -18,14 +18,16 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA * - * $Id: os_info.c,v 1.22 2004/11/07 12:31:33 ats Exp $ + * $Id: os_info.c,v 1.23 2005/09/24 13:29:22 tdb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#ifndef WIN32 #include +#endif #include "statgrab.h" #include #ifdef SOLARIS @@ -51,13 +53,120 @@ #include #include #endif +#ifdef WIN32 +#include +#include "win32.h" +#define WINDOWS2000 "Windows 2000" +#define WINDOWSXP "Windows XP" +#define WINDOWS2003 "Windows Server 2003" +#define BUFSIZE 12 +static int runonce = 0; +#endif #include "tools.h" -sg_host_info *sg_get_host_info(){ +#ifdef WIN32 +static int home_or_pro(const OSVERSIONINFOEX osinfo, char **name) +{ + int r; + if (osinfo.wSuiteMask & VER_SUITE_PERSONAL) { + r = sg_concat_string(name, " Home Edition"); + } else { + r = sg_concat_string(name, " Professional"); + } + return r; +} + +static char *get_os_name(const OSVERSIONINFOEX osinfo) +{ + char *name; + char tmp[10]; + int r = 0; + + /* we only compile on 2k or newer, which is version 5 + * Covers 2000, XP and 2003 */ + if (osinfo.dwMajorVersion != 5) { + return "Unknown"; + } + switch(osinfo.dwMinorVersion) { + case 0: /* Windows 2000 */ + name = strdup(WINDOWS2000); + if(name == NULL) { + goto out; + } + if (osinfo.wProductType == VER_NT_WORKSTATION) { + r = home_or_pro(osinfo, &name); + } else if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) { + r = sg_concat_string(&name, " Datacenter Server"); + } else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) { + r = sg_concat_string(&name, " Advanced Server"); + } else { + r = sg_concat_string(&name, " Server"); + } + break; + case 1: /* Windows XP */ + name = strdup(WINDOWSXP); + if(name == NULL) { + goto out; + } + r = home_or_pro(osinfo, &name); + break; + case 2: /* Windows 2003 */ + name = strdup(WINDOWS2003); + if(name == NULL) { + goto out; + } + if (osinfo.wSuiteMask & VER_SUITE_DATACENTER) { + r = sg_concat_string(&name, " Datacenter Edition"); + } else if (osinfo.wSuiteMask & VER_SUITE_ENTERPRISE) { + r = sg_concat_string(&name, " Enterprise Edition"); + } else if (osinfo.wSuiteMask & VER_SUITE_BLADE) { + r = sg_concat_string(&name, " Web Edition"); + } else { + r = sg_concat_string(&name, " Standard Edition"); + } + break; + default: + name = strdup("Windows 2000 based"); + break; + } + if(r != 0) { + free (name); + return NULL; + } + /* Add on service pack version */ + if (osinfo.wServicePackMajor != 0) { + if(osinfo.wServicePackMinor == 0) { + if(snprintf(tmp, sizeof(tmp), " SP%d", osinfo.wServicePackMajor) != -1) { + r = sg_concat_string(&name, tmp); + } + } else { + if(snprintf(tmp, sizeof(tmp), " SP%d.%d", osinfo.wServicePackMajor, + osinfo.wServicePackMinor) != -1) { + r = sg_concat_string(&name, tmp); + } + } + if(r) { + free(name); + return NULL; + } + } + return name; + +out: + /* strdup failed */ + sg_set_error_with_errno(SG_ERROR_MALLOC, NULL); + return NULL; +} +#endif + +sg_host_info *sg_get_host_info() +{ static sg_host_info general_stat; +#ifndef WIN32 static struct utsname os; +#endif #ifdef HPUX struct pst_static *pstat_static; @@ -79,18 +188,122 @@ sg_host_info *sg_get_host_info(){ time_t curtime; size_t size; #endif +#ifdef WIN32 + unsigned long nameln; + char *name; + long long result; + OSVERSIONINFOEX osinfo; + SYSTEM_INFO sysinfo; + char *tmp_name; + char tmp[10]; +#endif +#ifndef WIN32 /* Trust windows to be different */ if((uname(&os)) < 0){ sg_set_error_with_errno(SG_ERROR_UNAME, NULL); return NULL; } - + general_stat.os_name = os.sysname; general_stat.os_release = os.release; general_stat.os_version = os.version; general_stat.platform = os.machine; general_stat.hostname = os.nodename; +#else /* WIN32 */ + if (!runonce) { + /* these settings are static after boot, so why get them + * constantly? */ + /* get system name */ + nameln = MAX_COMPUTERNAME_LENGTH + 1; + name = sg_malloc(nameln); + if(name == NULL) { + return NULL; + } + if(GetComputerName(name, &nameln) == 0) { + free(name); + sg_set_error(SG_ERROR_HOST, "GetComputerName"); + return NULL; + } + if(sg_update_string(&general_stat.hostname, name)) { + free(name); + return NULL; + } + free(name); + + /* get OS name, version and build */ + ZeroMemory(&osinfo, sizeof(OSVERSIONINFOEX)); + osinfo.dwOSVersionInfoSize = sizeof(osinfo); + if(!GetVersionEx(&osinfo)) { + sg_set_error(SG_ERROR_HOST, "GetVersionEx"); + return NULL; + } + + /* Release - single number */ + if(snprintf(tmp, sizeof(tmp), "%ld", osinfo.dwBuildNumber) == -1) { + free(tmp); + return NULL; + } + if(sg_update_string(&general_stat.os_release, tmp)) { + free(tmp); + return NULL; + } + + /* Version */ + /* usually a single digit . single digit, eg 5.0 */ + if(snprintf(tmp, sizeof(tmp), "%ld.%ld", osinfo.dwMajorVersion, + osinfo.dwMinorVersion) == -1) { + free(tmp); + return NULL; + } + if(sg_update_string(&general_stat.os_version, tmp)) { + free(tmp); + return NULL; + } + + /* OS name */ + tmp_name = get_os_name(osinfo); + if(tmp_name == NULL) { + return NULL; + } + if(sg_update_string(&general_stat.os_name, tmp_name)) { + free(tmp_name); + return NULL; + } + free(tmp_name); + runonce = 1; + + /* Platform */ + GetSystemInfo(&sysinfo); + switch(sysinfo.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_INTEL: + if(sg_update_string(&general_stat.platform, + "Intel")) { + return NULL; + } + break; + case PROCESSOR_ARCHITECTURE_IA64: + if(sg_update_string(&general_stat.platform, + "IA64")) { + return NULL; + } + break; + case PROCESSOR_ARCHITECTURE_AMD64: + if(sg_update_string(&general_stat.platform, + "AMD64")) { + return NULL; + } + break; + default: + if(sg_update_string(&general_stat.platform, + "Unknown")){ + return NULL; + } + break; + } + } +#endif /* WIN32 */ + /* get uptime */ #ifdef HPUX pstat_static = sg_get_pstat_static(); @@ -150,6 +363,13 @@ sg_host_info *sg_get_host_info(){ } time(&curtime); general_stat.uptime=curtime-boottime.tv_sec; +#endif +#ifdef WIN32 + if(read_counter_large(SG_WIN32_UPTIME, &result)) { + sg_set_error(SG_ERROR_PDHREAD, PDH_UPTIME); + return NULL; + } + general_stat.uptime = (time_t) result; #endif return &general_stat;