2008-09-28 21:27:06 +04:00
|
|
|
/* GKrellM
|
2009-12-27 14:48:30 +03:00
|
|
|
| Copyright (C) 1999-2009 Bill Wilson
|
2008-12-28 17:51:59 +03:00
|
|
|
| 2002 Bill Nalen
|
2009-12-27 14:48:30 +03:00
|
|
|
| 2007-2009 Stefan Gehn
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
2008-12-28 17:51:59 +03:00
|
|
|
| Authors: Bill Wilson billw@gkrellm.net
|
|
|
|
| Bill Nalen bill@nalens.com
|
|
|
|
| Stefan Gehn stefan@gkrellm.srcbox.net
|
2008-02-01 21:36:15 +03:00
|
|
|
| Latest versions might be found at: http://gkrellm.net
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| GKrellM is free software: you can redistribute it and/or modify it
|
|
|
|
| under the terms of the GNU General Public License as published by
|
|
|
|
| the Free Software Foundation, either version 3 of the License, or
|
|
|
|
| (at your option) any later version.
|
|
|
|
|
|
|
|
|
| GKrellM is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
| or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
|
|
| License for more details.
|
|
|
|
|
|
|
|
|
| You should have received a copy of the GNU General Public License
|
|
|
|
| along with this program. If not, see http://www.gnu.org/licenses/
|
2008-10-04 12:55:47 +04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
| Additional permission under GNU GPL version 3 section 7
|
|
|
|
|
|
|
|
|
| If you modify this program, or any covered work, by linking or
|
|
|
|
| combining it with the OpenSSL project's OpenSSL library (or a
|
|
|
|
| modified version of that library), containing parts covered by
|
|
|
|
| the terms of the OpenSSL or SSLeay licenses, you are granted
|
|
|
|
| additional permission to convey the resulting work.
|
|
|
|
| Corresponding Source for a non-source form of such a combination
|
|
|
|
| shall include the source code for the parts of OpenSSL used as well
|
|
|
|
| as that of the covered work.
|
2008-02-01 21:36:15 +03:00
|
|
|
*/
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
#include "../inet.h" // For struct ActiveTCP
|
|
|
|
#if defined(GKRELLM_SERVER)
|
2008-02-01 21:36:15 +03:00
|
|
|
#include "../../server/win32-plugin.h"
|
2008-09-28 21:27:06 +04:00
|
|
|
#else
|
|
|
|
#include "../win32-plugin.h"
|
2008-02-01 21:36:15 +03:00
|
|
|
#endif
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
#include <largeint.h> // For disk space calculation
|
|
|
|
#include <winioctl.h> // For cdrom eject
|
|
|
|
#include <iphlpapi.h> // For tcp connection stats
|
|
|
|
// Following two are for cpu, proc, disk and network stats
|
|
|
|
// which are queried via "performance data counters"
|
2008-02-01 21:36:15 +03:00
|
|
|
#include <pdh.h>
|
2008-02-01 22:11:29 +03:00
|
|
|
#include <pdhmsg.h>
|
2008-09-28 21:27:06 +04:00
|
|
|
// Following two are used to determine number of logged in users and
|
|
|
|
// pagefile usage via NT-APIs
|
2008-02-01 21:36:15 +03:00
|
|
|
#include <ntdef.h>
|
2008-09-28 21:27:06 +04:00
|
|
|
#include <ntsecapi.h>
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2009-12-30 17:56:17 +03:00
|
|
|
#if _WIN32_WINNT >= 0x501 // Windows XP or newer
|
|
|
|
#include <wtsapi32.h>
|
|
|
|
#endif // _WIN32_WINNT >= 0x501
|
|
|
|
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-02-01 21:36:15 +03:00
|
|
|
// Needed to determine pagefile usage
|
2008-09-28 21:27:06 +04:00
|
|
|
//
|
|
|
|
// These definitions were taken from MinGW include/ddk/ntapi.h because you
|
|
|
|
// cannot mix ddk includes with normal windows includes although you can call
|
|
|
|
// these functions without being a driver.
|
2008-02-01 21:36:15 +03:00
|
|
|
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
|
|
|
|
#define SystemPagefileInformation 18
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
NTSTATUS NTAPI ZwQuerySystemInformation(
|
2008-02-01 21:36:15 +03:00
|
|
|
/*IN*/ UINT SystemInformationClass,
|
2008-09-30 20:48:09 +04:00
|
|
|
/*IN OUT*/ VOID *SystemInformation,
|
2008-02-01 21:36:15 +03:00
|
|
|
/*IN*/ ULONG SystemInformationLength,
|
2008-09-30 20:48:09 +04:00
|
|
|
/*OUT*/ ULONG *ReturnLength /*OPTIONAL*/);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
typedef struct _SYSTEM_PAGEFILE_INFORMATION
|
|
|
|
{
|
2008-02-01 21:36:15 +03:00
|
|
|
ULONG NextEntryOffset;
|
|
|
|
ULONG CurrentSize;
|
|
|
|
ULONG TotalUsed;
|
|
|
|
ULONG PeakUsed;
|
|
|
|
UNICODE_STRING FileName;
|
2008-09-30 20:48:09 +04:00
|
|
|
}
|
|
|
|
SYSTEM_PAGEFILE_INFORMATION;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Structs and typedefs used to determine the number of logged in users.
|
|
|
|
// These should be in ntsecapi.h but are missing in MinGW currently.
|
|
|
|
// Docs: http://msdn.microsoft.com/en-us/library/aa378290(VS.85).aspx
|
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
typedef struct _SECURITY_LOGON_SESSION_DATA
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
ULONG Size;
|
|
|
|
LUID LogonId;
|
|
|
|
LSA_UNICODE_STRING UserName;
|
|
|
|
LSA_UNICODE_STRING LogonDomain;
|
|
|
|
LSA_UNICODE_STRING AuthenticationPackage;
|
|
|
|
ULONG LogonType;
|
|
|
|
ULONG Session;
|
|
|
|
PSID Sid;
|
|
|
|
LARGE_INTEGER LogonTime;
|
|
|
|
LSA_UNICODE_STRING LogonServer;
|
|
|
|
LSA_UNICODE_STRING DnsDomainName;
|
|
|
|
LSA_UNICODE_STRING Upn;
|
2008-09-30 20:48:09 +04:00
|
|
|
}
|
|
|
|
SECURITY_LOGON_SESSION_DATA;
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
// Definitions for function pointers (functions resolved manually at runtime)
|
|
|
|
typedef NTSTATUS (NTAPI *pfLsaEnumerateLogonSessions)(
|
2008-09-30 20:48:09 +04:00
|
|
|
ULONG *LogonSessionCount, LUID **LogonSessionList);
|
2008-09-28 21:27:06 +04:00
|
|
|
typedef NTSTATUS (NTAPI *pfLsaGetLogonSessionData)(
|
2008-09-30 20:48:09 +04:00
|
|
|
LUID *LogonId, SECURITY_LOGON_SESSION_DATA **ppLogonSessionData);
|
|
|
|
typedef NTSTATUS (NTAPI *pfLsaFreeReturnBuffer)(VOID *Buffer);
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// Max len of device names returned by clean_dev_name().
|
|
|
|
// Value taken from net.c load_net_config() and disk.c load_disk_config().
|
2008-05-25 15:59:22 +04:00
|
|
|
#define MAX_DEV_NAME 31
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
#define ARR_SZ(x) (sizeof(x) / sizeof(x[0]))
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static PDH_HQUERY pdhQueryHandle = NULL;
|
|
|
|
|
|
|
|
static const wchar_t* PDHDLL = L"PDH.DLL";
|
|
|
|
static const wchar_t* NTDLL = L"NTDLL.DLL";
|
2009-12-26 18:11:13 +03:00
|
|
|
static const wchar_t* WTSAPI32 = L"WTSAPI32.DLL";
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-09-28 21:27:06 +04:00
|
|
|
// Own cleanup functions, called in gkrellm_sys_main_cleanup() to cleanup
|
|
|
|
// resources allocated by gkrellm_sys_*_init()
|
|
|
|
|
|
|
|
static void gkrellm_sys_cpu_cleanup(void);
|
|
|
|
static void gkrellm_sys_disk_cleanup(void);
|
|
|
|
static void gkrellm_sys_mem_cleanup(void);
|
|
|
|
static void gkrellm_sys_net_cleanup(void);
|
|
|
|
static void gkrellm_sys_proc_cleanup(void);
|
|
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
//! print a warning and (if possible) decode a windows error number
|
|
|
|
static void
|
|
|
|
win32_warning(const wchar_t *dll_name, DWORD status, const gchar *format, ...)
|
2008-05-25 15:59:22 +04:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
va_list varargs;
|
|
|
|
wchar_t *status_msg = NULL;
|
|
|
|
gchar *formatted_msg = NULL;
|
|
|
|
HMODULE dll_handle = NULL;
|
|
|
|
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER
|
|
|
|
| FORMAT_MESSAGE_FROM_SYSTEM
|
|
|
|
| FORMAT_MESSAGE_IGNORE_INSERTS;
|
|
|
|
|
|
|
|
va_start(varargs, format);
|
|
|
|
// Format passed message string
|
|
|
|
formatted_msg = g_strdup_vprintf(format, varargs);
|
|
|
|
va_end(varargs);
|
|
|
|
|
|
|
|
// Load library for message strings if one was passed
|
|
|
|
if (dll_name != NULL)
|
|
|
|
{
|
|
|
|
dll_handle = LoadLibraryW(dll_name);
|
|
|
|
if (dll_handle != NULL)
|
|
|
|
flags |= FORMAT_MESSAGE_FROM_HMODULE;
|
|
|
|
}
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
// NOTE: yes, this call takes a wchar_t **, it's a known flaw in the
|
|
|
|
// WIN32 API, you can ignore any compiler warning about arg 5
|
2008-09-28 21:27:06 +04:00
|
|
|
if (FormatMessageW(
|
|
|
|
flags // dwFlags
|
|
|
|
, dll_handle // lpSource
|
|
|
|
, status // dwMessageId
|
|
|
|
, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) // dwLanguageId
|
|
|
|
, (LPWSTR)&status_msg // lpBuffer
|
|
|
|
, 0 // nSize
|
|
|
|
, NULL // varargs
|
|
|
|
) > 0)
|
|
|
|
{
|
|
|
|
g_log(NULL, G_LOG_LEVEL_WARNING, "%s; Error 0x%lX: %ls",
|
|
|
|
formatted_msg, status, status_msg);
|
|
|
|
LocalFree(status_msg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_log(NULL, G_LOG_LEVEL_WARNING, "%s; Error 0x%lX\n",
|
|
|
|
formatted_msg, status);
|
|
|
|
}
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
g_free(formatted_msg);
|
|
|
|
if (dll_handle != NULL)
|
|
|
|
FreeLibrary(dll_handle);
|
|
|
|
}
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
// Simple wrapper around PdhAddCounter with error/debug handling
|
|
|
|
static gboolean
|
|
|
|
add_counter(const wchar_t *counter_path, PDH_HCOUNTER *counter_handle)
|
2008-02-09 01:33:37 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
PDH_STATUS st;
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pdhQueryHandle == NULL || !counter_path || !counter_handle)
|
|
|
|
return FALSE;
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
st = PdhAddCounterW(pdhQueryHandle, counter_path, 0, counter_handle);
|
|
|
|
if (st != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
win32_warning(PDHDLL, st, "Failed adding pdh-counter for path '%ls'",
|
|
|
|
counter_path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Added pdh-counter for path '%ls'\n",
|
|
|
|
counter_path);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static gboolean
|
|
|
|
get_formatted_counter_value(
|
|
|
|
PDH_HCOUNTER counter_handle, const gchar *counter_name,
|
|
|
|
DWORD format, PDH_FMT_COUNTERVALUE *val)
|
|
|
|
{
|
|
|
|
PDH_STATUS st;
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
st = PdhGetFormattedCounterValue(counter_handle, format, NULL, val);
|
|
|
|
if ((st != ERROR_SUCCESS) || (val->CStatus != PDH_CSTATUS_VALID_DATA))
|
|
|
|
{
|
|
|
|
win32_warning(PDHDLL, st,
|
|
|
|
"Getting pdh-counter (%s) failed; CStatus %lX",
|
|
|
|
counter_name, val->CStatus);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Simple wrapper around PdhLookupPerfNameByIndex with error handling
|
|
|
|
static gboolean
|
|
|
|
lookup_perfname(DWORD index, wchar_t *perfname, DWORD perfname_max_len)
|
2008-02-09 01:33:37 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
PDH_STATUS st;
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-10-03 20:27:46 +04:00
|
|
|
if (!perfname || perfname_max_len == 0)
|
|
|
|
return FALSE;
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
st = PdhLookupPerfNameByIndexW(NULL, index, perfname, &perfname_max_len);
|
|
|
|
if (st != ERROR_SUCCESS)
|
|
|
|
{
|
2008-10-03 20:27:46 +04:00
|
|
|
win32_warning(PDHDLL, st, "Could not lookup perfname for index %lu",
|
2008-09-28 21:27:06 +04:00
|
|
|
index);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-10-03 20:27:46 +04:00
|
|
|
if (perfname[0] == 0)
|
|
|
|
{
|
|
|
|
g_warning("Got empty perfname for index %lu, performance counters " \
|
|
|
|
"appear to be broken on this system!\n", index);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Looked up perfname '%ls' for index %lu\n",
|
2008-09-28 21:27:06 +04:00
|
|
|
perfname, index);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef void (*add_counter_cb) (wchar_t *name, PDH_HCOUNTER *c1, PDH_HCOUNTER *c2);
|
|
|
|
|
|
|
|
static void
|
|
|
|
add_counter_list(guint object_index,
|
|
|
|
guint counter_index1, guint counter_index2,
|
|
|
|
add_counter_cb cb)
|
|
|
|
{
|
|
|
|
PDH_STATUS st;
|
2008-09-30 20:48:09 +04:00
|
|
|
wchar_t obj_name[PDH_MAX_COUNTER_NAME];
|
|
|
|
wchar_t c1_name[PDH_MAX_COUNTER_NAME];
|
|
|
|
wchar_t c2_name[PDH_MAX_COUNTER_NAME];
|
2008-09-28 21:27:06 +04:00
|
|
|
wchar_t * obj_list = NULL;
|
|
|
|
DWORD obj_list_size = 0;
|
|
|
|
wchar_t * inst_list = NULL;
|
|
|
|
DWORD inst_list_size = 0;
|
2008-09-30 20:48:09 +04:00
|
|
|
wchar_t counter_path[PDH_MAX_COUNTER_PATH];
|
2008-09-28 21:27:06 +04:00
|
|
|
wchar_t * inst = NULL;
|
|
|
|
PDH_HCOUNTER c1;
|
|
|
|
PDH_HCOUNTER c2;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "add_counter_list()\n");
|
|
|
|
if (pdhQueryHandle == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Get translated name for object_index
|
2008-09-30 20:48:09 +04:00
|
|
|
if (!lookup_perfname(object_index, obj_name, PDH_MAX_COUNTER_NAME))
|
2008-09-28 21:27:06 +04:00
|
|
|
return;
|
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
if (!lookup_perfname(counter_index1, c1_name, PDH_MAX_COUNTER_NAME))
|
2008-09-28 21:27:06 +04:00
|
|
|
return;
|
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
if (!lookup_perfname(counter_index2, c2_name, PDH_MAX_COUNTER_NAME))
|
2008-09-28 21:27:06 +04:00
|
|
|
return;
|
|
|
|
|
|
|
|
// Get number of counters/instances that can be queried
|
|
|
|
st = PdhEnumObjectItemsW(NULL, NULL, obj_name,
|
|
|
|
NULL, &obj_list_size,
|
|
|
|
NULL, &inst_list_size,
|
|
|
|
PERF_DETAIL_WIZARD, 0);
|
|
|
|
|
|
|
|
if ((st != PDH_MORE_DATA) && (st != ERROR_SUCCESS))
|
|
|
|
{
|
|
|
|
// Either no data at all or other error
|
|
|
|
win32_warning(PDHDLL, st,
|
|
|
|
"Failed to get pdh-counter count for object '%ls'", obj_name);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do nothing if there's no counters
|
|
|
|
if (inst_list_size == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Allocate buffers to hold object and instance names
|
2008-09-30 20:48:09 +04:00
|
|
|
obj_list = (wchar_t *)g_malloc(sizeof(wchar_t) * obj_list_size);
|
|
|
|
inst_list = (wchar_t *)g_malloc(sizeof(wchar_t) * inst_list_size);
|
2008-09-28 21:27:06 +04:00
|
|
|
|
2008-10-03 20:27:46 +04:00
|
|
|
//gkrellm_debug(DEBUG_SYSDEP, "Max instance list size: %lu\n", inst_list_size);
|
2008-09-28 21:27:06 +04:00
|
|
|
// Get actual information about counters
|
|
|
|
st = PdhEnumObjectItemsW(NULL, NULL, obj_name,
|
|
|
|
obj_list, &obj_list_size,
|
|
|
|
inst_list, &inst_list_size,
|
|
|
|
PERF_DETAIL_WIZARD, 0);
|
|
|
|
if (st != ERROR_SUCCESS)
|
|
|
|
{
|
|
|
|
// Either no data at all or other error
|
|
|
|
win32_warning(PDHDLL, st,
|
|
|
|
"Failed to enumerate pdh-counters for object '%ls'", obj_name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-10-03 20:27:46 +04:00
|
|
|
/*gkrellm_debug(DEBUG_SYSDEP, "Returned instance list size: %lu\n",
|
|
|
|
inst_list_size);*/
|
2008-09-28 21:27:06 +04:00
|
|
|
for (inst = inst_list; *inst != 0; inst += wcslen(inst) + 1)
|
|
|
|
{
|
2008-10-03 20:27:46 +04:00
|
|
|
//gkrellm_debug(DEBUG_SYSDEP, "counter instance '%ls'\n", inst);
|
2008-09-30 20:48:09 +04:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Ignore total counter, gkrellm provides that functionality
|
|
|
|
if (wcsnicmp(L"_Total", inst, 6) == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// "\Disks(DiskOne)\ReadBytes"
|
2008-09-30 20:48:09 +04:00
|
|
|
_snwprintf(counter_path, ARR_SZ(counter_path), L"\\%ls(%ls)\\%ls",
|
2008-09-28 21:27:06 +04:00
|
|
|
obj_name, inst, c1_name);
|
2008-09-30 00:57:01 +04:00
|
|
|
if (!add_counter(counter_path, &c1))
|
|
|
|
continue;
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
// "\Disks(DiskOne)\WriteBytes"
|
2008-09-30 20:48:09 +04:00
|
|
|
_snwprintf(counter_path, ARR_SZ(counter_path), L"\\%ls(%ls)\\%ls",
|
2008-09-28 21:27:06 +04:00
|
|
|
obj_name, inst, c2_name);
|
2008-09-30 00:57:01 +04:00
|
|
|
if (!add_counter(counter_path, &c2))
|
|
|
|
continue;
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
if (c1 && c2)
|
|
|
|
cb(inst, &c1, &c2);
|
|
|
|
}
|
|
|
|
}
|
2008-09-30 20:48:09 +04:00
|
|
|
g_free((gpointer)obj_list);
|
|
|
|
g_free((gpointer)inst_list);
|
2008-09-28 21:27:06 +04:00
|
|
|
}
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
static
|
2008-09-28 21:27:06 +04:00
|
|
|
gchar *clean_dev_name(const wchar_t *name)
|
2008-05-25 15:59:22 +04:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
gchar *clean_name;
|
|
|
|
gchar *p;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
clean_name = g_utf16_to_utf8(name, -1, NULL, NULL, NULL);
|
|
|
|
//FIXME: handle clean_name being NULL
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
p = clean_name;
|
|
|
|
while (*p)
|
|
|
|
{
|
|
|
|
p = g_utf8_next_char(p);
|
|
|
|
if (*p == ' ' || *p == '\t')
|
|
|
|
*p = '_';
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// limit length of device name, gkrellm can't handle longer names :(
|
|
|
|
if (strlen(clean_name) > MAX_DEV_NAME)
|
|
|
|
clean_name[MAX_DEV_NAME] = '\0';
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
return clean_name;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
// ----------------------------------------------------------------------------
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
void gkrellm_sys_main_init(void)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
PDH_STATUS st;
|
2008-02-01 22:11:29 +03:00
|
|
|
WSADATA wsdata;
|
|
|
|
int err;
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Starting Winsock\n");
|
2008-02-01 22:11:29 +03:00
|
|
|
err = WSAStartup(MAKEWORD(1,1), &wsdata);
|
|
|
|
if (err != 0)
|
2008-09-28 21:27:06 +04:00
|
|
|
g_warning("Starting Winsock failed with error code %d\n", err);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Opening PDH query\n");
|
|
|
|
st = PdhOpenQueryW(NULL, 0, &pdhQueryHandle);
|
|
|
|
if ((st != ERROR_SUCCESS) || (pdhQueryHandle == NULL))
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
win32_warning(PDHDLL, st, "Opening PDH query failed");
|
2008-02-01 22:11:29 +03:00
|
|
|
pdhQueryHandle = 0;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-02-01 22:11:29 +03:00
|
|
|
// we don't have local mail on Windows (yet?)
|
|
|
|
gkrellm_mail_local_unsupported();
|
|
|
|
|
|
|
|
// initialize call back structure for plugins
|
|
|
|
win32_init_callbacks();
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
|
|
|
void gkrellm_sys_main_cleanup(void)
|
2008-09-28 21:27:06 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
PDH_STATUS st;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Waiting for mail checking thread to end.\n");
|
|
|
|
i = 0;
|
|
|
|
while (gkrellm_mail_get_active_thread() != NULL && (i++ < 120))
|
|
|
|
{
|
|
|
|
// wait here till it finishes
|
|
|
|
// in case we are trying to get mail info
|
|
|
|
g_usleep(G_USEC_PER_SEC); // 1 second wait
|
|
|
|
}
|
|
|
|
|
|
|
|
// Close PDH query-handle
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Closing PDH query\n");
|
|
|
|
st = PdhCloseQuery(pdhQueryHandle);
|
|
|
|
if (st != ERROR_SUCCESS)
|
|
|
|
win32_warning(PDHDLL, st, "Closing PDH query handle failed");
|
|
|
|
pdhQueryHandle = NULL;
|
|
|
|
|
|
|
|
gkrellm_sys_cpu_cleanup();
|
|
|
|
gkrellm_sys_disk_cleanup();
|
|
|
|
gkrellm_sys_net_cleanup();
|
|
|
|
gkrellm_sys_proc_cleanup();
|
|
|
|
gkrellm_sys_mem_cleanup();
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Closing Winsock\n");
|
|
|
|
i = WSACleanup();
|
|
|
|
if (i != 0)
|
|
|
|
g_warning("Stopping Winsock failed, error %d\n", i);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
// only need to collect pdhQueryHandle data once for all those monitors that use it
|
2008-09-28 21:27:06 +04:00
|
|
|
static
|
|
|
|
void win32_read_proc_stat(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
static gint s_data_read_tick = -1;
|
|
|
|
PDH_STATUS st;
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pdhQueryHandle == NULL)
|
2008-05-25 15:59:22 +04:00
|
|
|
return;
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (s_data_read_tick == gkrellm_get_timer_ticks()) // One read per tick
|
2008-02-01 21:36:15 +03:00
|
|
|
return;
|
2008-09-28 21:27:06 +04:00
|
|
|
s_data_read_tick = gkrellm_get_timer_ticks();
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Collecting PDH query data\n");
|
|
|
|
st = PdhCollectQueryData(pdhQueryHandle);
|
|
|
|
if (st != ERROR_SUCCESS)
|
|
|
|
win32_warning(PDHDLL, st, "Failed to collect PDH query data");
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* Sensor interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
#define MBM_INTERFACE 1 /* MotherBoardMonitor 5 */
|
|
|
|
#define SF_INTERFACE 2 /* SpeedFan */
|
|
|
|
#define CT_INTERFACE 3 /* CoreTemp */
|
|
|
|
|
|
|
|
static
|
|
|
|
HANDLE gkrellm_sys_sensors_open_shm_helper(const wchar_t *shm_name,
|
|
|
|
const gchar *app_name)
|
|
|
|
{
|
|
|
|
HANDLE hData = NULL;
|
|
|
|
gboolean ret;
|
|
|
|
GError *err = NULL;
|
|
|
|
|
|
|
|
// Try to open shm-file and return if successful
|
|
|
|
hData = OpenFileMappingW(FILE_MAP_READ, FALSE, shm_name);
|
|
|
|
if (hData != 0)
|
|
|
|
return hData;
|
|
|
|
|
|
|
|
// shm-file could not be opened, try to start sensor-app
|
|
|
|
ret = g_spawn_command_line_async(app_name, &err);
|
|
|
|
if (!ret && err)
|
|
|
|
{
|
|
|
|
g_warning("Could not start sensor-app %s: %s\n",
|
|
|
|
app_name, err->message);
|
|
|
|
g_error_free(err);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP,
|
|
|
|
"Started sensor-app %s, waiting for it to initialize\n",
|
|
|
|
app_name);
|
|
|
|
// 5 second wait to allow sensor-app init
|
|
|
|
g_usleep(5 * G_USEC_PER_SEC);
|
|
|
|
// Retry open of shm-file
|
|
|
|
hData = OpenFileMappingW(FILE_MAP_READ, FALSE, shm_name);
|
|
|
|
}
|
|
|
|
return hData;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
2008-09-28 21:27:06 +04:00
|
|
|
// Interface to work with shared memory for MBM5
|
|
|
|
//
|
|
|
|
// Copyright 2001 A@majland.org
|
|
|
|
// Alteration for use in Visual C by Chris Zahrt techn0@iastate.edu
|
2008-02-01 21:36:15 +03:00
|
|
|
//
|
|
|
|
// Version : 0.1
|
|
|
|
// Date : 02-27-2002
|
|
|
|
// MBM : version 5.1
|
|
|
|
//
|
2008-09-28 21:27:06 +04:00
|
|
|
// Author : - Anders@Majland.org (author of original c code)
|
|
|
|
// http://www.majland.org/sw/mbmcaf
|
|
|
|
// - Chris Zahrt techn0@iastate.edu (visual c alterations)
|
|
|
|
// http://techn0.dhs.org/programming/vcmbmsm.html
|
2008-02-01 21:36:15 +03:00
|
|
|
//
|
|
|
|
// Licence : Cardware. (Send me a note/email if you find it usefull.)
|
|
|
|
// Basically you may use it as you see fit as long as the origin
|
|
|
|
// of the code remains clear
|
|
|
|
//
|
|
|
|
// History :
|
|
|
|
// 0.1 02-27-2002 conversion of 0.3 borland to this version
|
2008-09-28 21:27:06 +04:00
|
|
|
//
|
2008-02-01 21:36:15 +03:00
|
|
|
// Update for MBM 5.1.9 by Bill Nalen bill@nalens.com
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
#define BusType char
|
2008-02-01 21:36:15 +03:00
|
|
|
#define SMBType char
|
|
|
|
#define SensorType char
|
2008-09-28 21:27:06 +04:00
|
|
|
#define stUnknown (char)(0)
|
|
|
|
#define stTemperature (char)(1)
|
|
|
|
#define stVoltage (char)(2)
|
|
|
|
#define stFan (char)(3)
|
|
|
|
//#define stMhz (char)(4)
|
|
|
|
//#define stPercentage (char)(5)
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
typedef struct _MBMSharedIndex
|
|
|
|
{
|
|
|
|
SensorType iType; // type of sensor
|
|
|
|
int Count; // number of sensor for that type
|
|
|
|
}
|
|
|
|
MBMSharedIndex;
|
|
|
|
|
|
|
|
typedef struct _MBMSharedSensor
|
|
|
|
{
|
|
|
|
SensorType ssType; // type of sensor
|
|
|
|
unsigned char ssName[12]; // name of sensor
|
|
|
|
char sspadding1[3]; // padding of 3 byte
|
|
|
|
double ssCurrent; // current value
|
|
|
|
double ssLow; // lowest readout
|
|
|
|
double ssHigh; // highest readout
|
|
|
|
long ssCount; // total number of readout
|
|
|
|
char sspadding2[4]; // padding of 4 byte
|
|
|
|
long double ssTotal; // total amout of all readouts
|
|
|
|
char sspadding3[6]; // padding of 6 byte
|
|
|
|
double ssAlarm1; // temp & fan: high alarm; voltage: % off;
|
|
|
|
double ssAlarm2; // temp: low alarm
|
|
|
|
}
|
|
|
|
MBMSharedSensor;
|
|
|
|
|
|
|
|
typedef struct _MBMSharedInfo
|
|
|
|
{
|
|
|
|
short siSMB_Base; // SMBus base address
|
|
|
|
BusType siSMB_Type; // SMBus/Isa bus used to access chip
|
|
|
|
SMBType siSMB_Code; // SMBus sub type, Intel, AMD or ALi
|
|
|
|
char siSMB_Addr; // Address of sensor chip on SMBus
|
|
|
|
unsigned char siSMB_Name[41]; // Nice name for SMBus
|
|
|
|
short siISA_Base; // ISA base address of sensor chip on ISA
|
|
|
|
int siChipType; // Chip nr, connects with Chipinfo.ini
|
|
|
|
char siVoltageSubType; // Subvoltage option selected
|
|
|
|
}
|
|
|
|
MBMSharedInfo;
|
|
|
|
|
|
|
|
typedef struct _MBMSharedData
|
|
|
|
{
|
|
|
|
double sdVersion; // version number (example: 51090)
|
|
|
|
MBMSharedIndex sdIndex[10]; // Sensor index
|
|
|
|
MBMSharedSensor sdSensor[100]; // sensor info
|
|
|
|
MBMSharedInfo sdInfo; // misc. info
|
|
|
|
unsigned char sdStart[41]; // start time
|
|
|
|
unsigned char sdCurrent[41]; // current time
|
|
|
|
unsigned char sdPath[256]; // MBM path
|
|
|
|
}
|
|
|
|
MBMSharedData;
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
static const wchar_t* MBM_SHM_NAME = L"$M$B$M$5$S$D$";
|
|
|
|
static const gchar* MBM_EXE_NAME = "MBM5.exe";
|
|
|
|
|
|
|
|
static SensorType gkrellm_sensor_type_to_mbm(gint type)
|
|
|
|
{
|
|
|
|
if (type == SENSOR_TEMPERATURE)
|
|
|
|
return stTemperature;
|
|
|
|
if (type == SENSOR_VOLTAGE)
|
|
|
|
return stVoltage;
|
|
|
|
if (type == SENSOR_FAN)
|
|
|
|
return stFan;
|
|
|
|
return stUnknown;
|
|
|
|
}
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static gboolean
|
|
|
|
gkrellm_sys_sensors_mbm_get_value(gint sensor_id, gint sensor_type, gfloat *value)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
HANDLE hData;
|
|
|
|
MBMSharedData *pData;
|
|
|
|
MBMSharedSensor *pSensor;
|
|
|
|
gboolean ret = FALSE;
|
|
|
|
SensorType st = gkrellm_sensor_type_to_mbm(sensor_type);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (st == stUnknown || sensor_id < 0 || sensor_id > 99)
|
|
|
|
return FALSE; // id out of range
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
hData = OpenFileMappingW(FILE_MAP_READ, FALSE, MBM_SHM_NAME);
|
|
|
|
if (hData == 0)
|
|
|
|
return FALSE;
|
|
|
|
pData = (MBMSharedData *)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if (pData != NULL)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Fetching sensor value %d from MBM\n", sensor_id);
|
|
|
|
pSensor = &(pData->sdSensor[sensor_id]);
|
|
|
|
if (pSensor->ssType == st)
|
|
|
|
{
|
|
|
|
*value = pSensor->ssCurrent;
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
UnmapViewOfFile(pData);
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
CloseHandle(hData);
|
|
|
|
return ret;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static gboolean
|
|
|
|
gkrellm_sys_sensors_mbm_init(void)
|
|
|
|
{
|
|
|
|
HANDLE hData;
|
|
|
|
MBMSharedData *pData;
|
|
|
|
MBMSharedSensor *pSensor;
|
|
|
|
gboolean ret = FALSE;
|
|
|
|
gint i, sensorCount, tempCount, voltCount, fanCount;
|
|
|
|
gchar *id_name;
|
|
|
|
|
|
|
|
hData = gkrellm_sys_sensors_open_shm_helper(MBM_SHM_NAME, MBM_EXE_NAME);
|
|
|
|
if (hData == 0)
|
|
|
|
return FALSE;
|
2008-12-28 18:59:37 +03:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Mapping MBM SHM file\n");
|
2008-09-28 21:27:06 +04:00
|
|
|
pData = (MBMSharedData *)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if (pData != NULL)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
ret = TRUE; // MBM available, return TRUE
|
|
|
|
|
|
|
|
sensorCount = 0;
|
|
|
|
for (i = 0; i < 9; i++)
|
|
|
|
sensorCount += pData->sdIndex[i].Count;
|
|
|
|
|
|
|
|
tempCount = 0;
|
|
|
|
voltCount = 0;
|
|
|
|
fanCount = 0;
|
|
|
|
for (i = 0; i < sensorCount; i++)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
pSensor = &(pData->sdSensor[i]);
|
|
|
|
switch (pSensor->ssType)
|
|
|
|
{
|
|
|
|
case stTemperature:
|
|
|
|
id_name = g_strdup_printf("mbm-temp-%d", tempCount);
|
|
|
|
|
|
|
|
gkrellm_sensors_add_sensor(SENSOR_TEMPERATURE, /*sensor_path*/NULL,
|
|
|
|
/*id_name*/id_name, /*id*/i, /*iodev*/0,
|
|
|
|
/*inter*/MBM_INTERFACE, /*factor*/1, /*offset*/0,
|
2009-12-30 17:56:17 +03:00
|
|
|
/*vref*/NULL, /*default_label*/(gchar *)pSensor->ssName);
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
g_free(id_name);
|
|
|
|
++tempCount;
|
|
|
|
break;
|
|
|
|
case stVoltage:
|
|
|
|
id_name = g_strdup_printf("mbm-volt-%d", voltCount);
|
|
|
|
|
|
|
|
gkrellm_sensors_add_sensor(SENSOR_VOLTAGE, /*sensor_path*/NULL,
|
|
|
|
/*id_name*/id_name, /*id*/i, /*iodev*/0,
|
|
|
|
/*inter*/MBM_INTERFACE, /*factor*/1, /*offset*/0,
|
2009-12-30 17:56:17 +03:00
|
|
|
/*vref*/NULL, /*default_label*/(gchar *)pSensor->ssName);
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
g_free(id_name);
|
|
|
|
++voltCount;
|
|
|
|
break;
|
|
|
|
case stFan:
|
|
|
|
id_name = g_strdup_printf("mbm-fan-%d", fanCount);
|
|
|
|
|
|
|
|
gkrellm_sensors_add_sensor(SENSOR_FAN, /*sensor_path*/NULL,
|
|
|
|
/*id_name*/id_name, /*id*/i, /*iodev*/0,
|
|
|
|
/*inter*/MBM_INTERFACE, /*factor*/1, /*offset*/0,
|
2009-12-30 17:56:17 +03:00
|
|
|
/*vref*/NULL, /*default_label*/(gchar *)pSensor->ssName);
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
g_free(id_name);
|
|
|
|
fanCount++;
|
|
|
|
break;
|
|
|
|
} /* switch() */
|
|
|
|
} /* for() */
|
|
|
|
|
|
|
|
UnmapViewOfFile(pData);
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
CloseHandle(hData);
|
|
|
|
return ret;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
|
|
|
/* ======================================================================== */
|
|
|
|
// SpeedFan
|
|
|
|
|
|
|
|
// Strucure of the shared block
|
|
|
|
#pragma pack(push, 1)
|
2008-09-30 20:48:09 +04:00
|
|
|
typedef struct _SFSharedMemory
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
|
|
|
unsigned short int version;
|
|
|
|
unsigned short int flags;
|
|
|
|
signed int MemSize;
|
|
|
|
HANDLE handle;
|
|
|
|
unsigned short int NumTemps;
|
|
|
|
unsigned short int NumFans;
|
|
|
|
unsigned short int NumVolts;
|
|
|
|
signed int temps[32];
|
|
|
|
signed int fans[32];
|
|
|
|
signed int volts[32];
|
|
|
|
} SFSharedMemory;
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static const wchar_t* SPEEDFAN_SHM_NAME = L"SFSharedMemory_ALM";
|
|
|
|
static const gchar* SPEEDFAN_EXE_NAME = "speedfan.exe";
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static gboolean
|
|
|
|
gkrellm_sys_sensors_sf_get_value(gint sensor_id, gint sensor_type, gfloat *value)
|
|
|
|
{
|
|
|
|
HANDLE hData;
|
|
|
|
SFSharedMemory *pData;
|
|
|
|
gboolean ret = FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (sensor_id < 0 || sensor_id > 31)
|
|
|
|
return FALSE; // id out of range
|
|
|
|
|
|
|
|
hData = OpenFileMappingW(FILE_MAP_READ, FALSE, SPEEDFAN_SHM_NAME);
|
|
|
|
if (hData == 0)
|
2008-02-01 22:11:29 +03:00
|
|
|
return FALSE;
|
2008-09-28 21:27:06 +04:00
|
|
|
pData = (SFSharedMemory *)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if (pData != NULL)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Fetching sensor value %d from SpeedFan\n", sensor_id);
|
|
|
|
switch(sensor_type)
|
|
|
|
{
|
|
|
|
case SENSOR_TEMPERATURE:
|
|
|
|
if (sensor_id < pData->NumTemps)
|
|
|
|
{
|
|
|
|
*value = pData->temps[sensor_id] / 100.0;
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SENSOR_VOLTAGE:
|
|
|
|
if (sensor_id < pData->NumVolts)
|
|
|
|
{
|
|
|
|
*value = pData->volts[sensor_id] / 100.0;
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SENSOR_FAN:
|
|
|
|
if (sensor_id < pData->NumFans)
|
|
|
|
{
|
|
|
|
*value = pData->fans[sensor_id];
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
UnmapViewOfFile(pData);
|
|
|
|
}
|
|
|
|
CloseHandle(hData);
|
|
|
|
return ret;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static gboolean
|
|
|
|
gkrellm_sys_sensors_sf_init(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
HANDLE hData;
|
|
|
|
SFSharedMemory *pData;
|
|
|
|
gboolean ret = FALSE;
|
|
|
|
gint i;
|
|
|
|
gchar *id_name;
|
|
|
|
gchar *default_label;
|
|
|
|
|
|
|
|
hData = gkrellm_sys_sensors_open_shm_helper(SPEEDFAN_SHM_NAME, SPEEDFAN_EXE_NAME);
|
|
|
|
if (hData == 0)
|
2008-02-01 22:11:29 +03:00
|
|
|
return FALSE;
|
2008-12-28 18:59:37 +03:00
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Mapping SpeedFan SHM file\n");
|
2008-09-28 21:27:06 +04:00
|
|
|
pData = (SFSharedMemory *)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if (pData != NULL)
|
|
|
|
{
|
|
|
|
ret = TRUE; // Mark SpeedFan as available
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-12-28 18:59:37 +03:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Enumerating %hu temps, %hu voltages and %hu fans\n",
|
|
|
|
pData->NumTemps, pData->NumVolts, pData->NumFans);
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
for (i = 0; i < pData->NumTemps; i++)
|
|
|
|
{
|
|
|
|
id_name = g_strdup_printf("speedfan-temp-%d", i);
|
|
|
|
default_label = g_strdup_printf("Temp %d", i+1);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_sensors_add_sensor(SENSOR_TEMPERATURE, /*sensor_path*/NULL,
|
|
|
|
/*id_name*/id_name, /*id*/i, /*iodev*/0,
|
|
|
|
/*inter*/SF_INTERFACE, /*factor*/1, /*offset*/0,
|
|
|
|
/*vref*/NULL, /*default_label*/default_label);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
g_free(id_name);
|
|
|
|
g_free(default_label);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
for (i = 0; i < pData->NumVolts; i++)
|
|
|
|
{
|
|
|
|
id_name = g_strdup_printf("speedfan-volt-%d", i);
|
|
|
|
default_label = g_strdup_printf("Voltage %d", i+1);
|
|
|
|
|
|
|
|
gkrellm_sensors_add_sensor(SENSOR_VOLTAGE, /*sensor_path*/NULL,
|
|
|
|
/*id_name*/id_name, /*id*/i, /*iodev*/0,
|
|
|
|
/*inter*/SF_INTERFACE, /*factor*/1, /*offset*/0,
|
|
|
|
/*vref*/NULL, /*default_label*/default_label);
|
|
|
|
|
|
|
|
g_free(id_name);
|
|
|
|
g_free(default_label);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < pData->NumFans; i++)
|
|
|
|
{
|
|
|
|
id_name = g_strdup_printf("speedfan-fan-%d", i);
|
|
|
|
default_label = g_strdup_printf("Fan %d", i+1);
|
|
|
|
|
|
|
|
gkrellm_sensors_add_sensor(SENSOR_FAN, /*sensor_path*/NULL,
|
|
|
|
/*id_name*/id_name, /*id*/i, /*iodev*/0,
|
|
|
|
/*inter*/SF_INTERFACE, /*factor*/1, /*offset*/0,
|
|
|
|
/*vref*/NULL, /*default_label*/default_label);
|
|
|
|
|
|
|
|
g_free(id_name);
|
|
|
|
g_free(default_label);
|
|
|
|
}
|
|
|
|
|
|
|
|
UnmapViewOfFile(pData);
|
|
|
|
}
|
|
|
|
CloseHandle(hData);
|
|
|
|
return ret;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
/* ======================================================================== */
|
2008-09-28 21:27:06 +04:00
|
|
|
// CoreTemp
|
|
|
|
|
|
|
|
/**
|
|
|
|
* ucFahrenheit and ucDeltaToTjMax represent boolean values. 0 = false, 1 = true.
|
|
|
|
* If ucFahrenheit is set, the temperature is reported in Fahrenheit.
|
|
|
|
* If ucDeltaToTjMax is set, the temperature reported respresents the distance
|
|
|
|
* from TjMax.
|
|
|
|
*
|
|
|
|
* Information and struct taken from
|
|
|
|
* http://www.alcpu.com/CoreTemp/developers.html
|
|
|
|
**/
|
2008-09-30 20:48:09 +04:00
|
|
|
typedef struct _CORE_TEMP_SHARED_DATA
|
2008-09-28 21:27:06 +04:00
|
|
|
{
|
|
|
|
unsigned int uiLoad[256];
|
|
|
|
unsigned int uiTjMax[128];
|
|
|
|
unsigned int uiCoreCnt;
|
|
|
|
unsigned int uiCPUCnt;
|
|
|
|
float fTemp[256];
|
|
|
|
float fVID;
|
|
|
|
float fCPUSpeed;
|
|
|
|
float fFSBSpeed;
|
|
|
|
float fMultipier;
|
|
|
|
char sCPUName[100];
|
|
|
|
unsigned char ucFahrenheit;
|
|
|
|
unsigned char ucDeltaToTjMax;
|
|
|
|
} CORE_TEMP_SHARED_DATA;
|
|
|
|
|
|
|
|
static const wchar_t* CORE_TEMP_SHM_NAME = L"CoreTempMappingObject";
|
|
|
|
static const gchar* CORE_TEMP_EXE_NAME = "CoreTemp.exe";
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gkrellm_sys_sensors_ct_get_temp(guint core_index, guint cpu_index, gfloat *temp)
|
|
|
|
{
|
|
|
|
HANDLE hData;
|
|
|
|
CORE_TEMP_SHARED_DATA *pData;
|
|
|
|
gboolean ret = FALSE;
|
|
|
|
guint temp_index;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (core_index < 0 || core_index > 255 || cpu_index < 0 || cpu_index > 127)
|
|
|
|
return FALSE; // core or cpu index out of range
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
hData = OpenFileMappingW(FILE_MAP_READ, FALSE, CORE_TEMP_SHM_NAME);
|
|
|
|
if (hData == 0)
|
2008-02-01 22:11:29 +03:00
|
|
|
return FALSE;
|
2008-09-28 21:27:06 +04:00
|
|
|
pData = (CORE_TEMP_SHARED_DATA *)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if (pData != NULL)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP,
|
|
|
|
"Fetching temp for core %d, cpu %d from CoreTemp\n", core_index,
|
|
|
|
cpu_index);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// 'core index' + ( 'cpu index' * 'number of cores per cpu' )
|
|
|
|
temp_index = core_index + (cpu_index * pData->uiCoreCnt);
|
|
|
|
|
|
|
|
// make absolute value from delta
|
|
|
|
if (pData->ucDeltaToTjMax == '\1')
|
|
|
|
*temp = pData->uiTjMax[cpu_index] - pData->fTemp[temp_index];
|
|
|
|
else
|
|
|
|
*temp = pData->fTemp[temp_index];
|
|
|
|
|
|
|
|
// Convert Fahrenheit to Celsius
|
|
|
|
if (pData->ucFahrenheit == '\1')
|
|
|
|
*temp = (*temp - 32) * 5 / 9;
|
|
|
|
|
|
|
|
UnmapViewOfFile(pData);
|
|
|
|
}
|
|
|
|
CloseHandle(hData);
|
|
|
|
return ret;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static gboolean
|
|
|
|
gkrellm_sys_sensors_ct_init(void)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
HANDLE hData;
|
|
|
|
CORE_TEMP_SHARED_DATA *pData;
|
|
|
|
gboolean ret = FALSE;
|
|
|
|
guint uiCpu;
|
|
|
|
guint uiCore;
|
|
|
|
gchar *id_name;
|
|
|
|
gchar *default_label;
|
|
|
|
|
|
|
|
hData = gkrellm_sys_sensors_open_shm_helper(CORE_TEMP_SHM_NAME, CORE_TEMP_EXE_NAME);
|
|
|
|
if (hData == 0)
|
2008-02-01 22:11:29 +03:00
|
|
|
return FALSE;
|
2008-12-28 18:59:37 +03:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Mapping CoreTemp SHM file\n");
|
2008-09-28 21:27:06 +04:00
|
|
|
pData = (CORE_TEMP_SHARED_DATA *)MapViewOfFile(hData, FILE_MAP_READ, 0, 0, 0);
|
|
|
|
if (pData != NULL)
|
|
|
|
{
|
|
|
|
ret = TRUE; // Mark CoreTemp as available
|
|
|
|
|
|
|
|
for (uiCpu = 0; uiCpu < pData->uiCPUCnt; uiCpu++)
|
|
|
|
{
|
|
|
|
for (uiCore = 0; uiCore < pData->uiCoreCnt; uiCore++)
|
|
|
|
{
|
|
|
|
id_name = g_strdup_printf("coretemp-cpu%u-core%u", uiCpu, uiCore);
|
|
|
|
if (pData->uiCPUCnt == 1)
|
|
|
|
default_label = g_strdup_printf("CPU Core %u", uiCore+1);
|
|
|
|
else
|
|
|
|
default_label = g_strdup_printf("CPU %u, Core %u", uiCpu+1, uiCore+1);
|
|
|
|
|
|
|
|
gkrellm_sensors_add_sensor(SENSOR_TEMPERATURE, /*sensor_path*/NULL,
|
|
|
|
/*id_name*/id_name, /*id*/uiCore, /*iodev*/uiCpu,
|
|
|
|
/*inter*/CT_INTERFACE, /*factor*/1, /*offset*/0,
|
|
|
|
/*vref*/NULL, /*default_label*/default_label);
|
|
|
|
|
|
|
|
g_free(id_name);
|
|
|
|
g_free(default_label);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
UnmapViewOfFile(pData);
|
|
|
|
}
|
|
|
|
CloseHandle(hData);
|
|
|
|
return ret;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
/* ======================================================================== */
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_sensors_get_voltage(gchar *device_name, gint id,
|
|
|
|
gint iodev, gint inter, gfloat *volt)
|
|
|
|
{
|
|
|
|
if (inter == MBM_INTERFACE)
|
|
|
|
return gkrellm_sys_sensors_mbm_get_value(id, SENSOR_VOLTAGE, volt);
|
|
|
|
if (inter == SF_INTERFACE)
|
|
|
|
return gkrellm_sys_sensors_sf_get_value(id, SENSOR_VOLTAGE, volt);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_sensors_get_fan(gchar *device_name, gint id,
|
|
|
|
gint iodev, gint inter, gfloat *fan)
|
|
|
|
{
|
|
|
|
if (inter == MBM_INTERFACE)
|
|
|
|
return gkrellm_sys_sensors_mbm_get_value(id, SENSOR_FAN, fan);
|
|
|
|
if (inter == SF_INTERFACE)
|
|
|
|
return gkrellm_sys_sensors_sf_get_value(id, SENSOR_FAN, fan);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_sensors_get_temperature(gchar *device_name, gint id,
|
|
|
|
gint iodev, gint inter, gfloat *temp)
|
|
|
|
{
|
|
|
|
if (inter == MBM_INTERFACE)
|
|
|
|
return gkrellm_sys_sensors_mbm_get_value(id, SENSOR_TEMPERATURE, temp);
|
|
|
|
if (inter == SF_INTERFACE)
|
|
|
|
return gkrellm_sys_sensors_sf_get_value(id, SENSOR_TEMPERATURE, temp);
|
|
|
|
if (inter == CT_INTERFACE)
|
|
|
|
return gkrellm_sys_sensors_ct_get_temp((guint)id, (guint)iodev, temp);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_sensors_init(void)
|
|
|
|
{
|
|
|
|
gboolean init_ok = FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT sensors\n");
|
|
|
|
init_ok |= gkrellm_sys_sensors_sf_init();
|
|
|
|
init_ok |= gkrellm_sys_sensors_ct_init();
|
|
|
|
init_ok |= gkrellm_sys_sensors_mbm_init();
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-12-28 18:59:37 +03:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT sensors finished, result is %d\n", init_ok);
|
2008-09-28 21:27:06 +04:00
|
|
|
// returns true if at least one sensors interface has been found
|
|
|
|
return init_ok;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* CPU monitor interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
typedef struct _GK_CPU
|
|
|
|
{
|
|
|
|
PDH_HCOUNTER total_pdh_counter;
|
|
|
|
PDH_HCOUNTER sys_pdh_counter;
|
|
|
|
gulong user;
|
|
|
|
gulong sys;
|
|
|
|
gulong idle;
|
|
|
|
} GK_CPU;
|
|
|
|
|
|
|
|
static GPtrArray *s_cpu_ptr_array = NULL;
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
void
|
|
|
|
gkrellm_sys_cpu_read_data(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
PDH_FMT_COUNTERVALUE tot;
|
|
|
|
PDH_FMT_COUNTERVALUE sys;
|
2008-05-25 15:59:22 +04:00
|
|
|
gint i;
|
|
|
|
GK_CPU *cpu;
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pdhQueryHandle == NULL)
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
2008-05-25 15:59:22 +04:00
|
|
|
win32_read_proc_stat(); // eventually fetch new pdh data
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Reading cpu data for %d CPUs\n",
|
|
|
|
s_cpu_ptr_array->len);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
for (i = 0; i < s_cpu_ptr_array->len; i++)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
cpu = (GK_CPU *)g_ptr_array_index(s_cpu_ptr_array, i);
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (!get_formatted_counter_value(cpu->total_pdh_counter, "cpu total time", PDH_FMT_LONG, &tot))
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (!get_formatted_counter_value(cpu->sys_pdh_counter, "cpu system time", PDH_FMT_LONG, &sys))
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// user time = (total time - system time)
|
|
|
|
cpu->user += (tot.longValue - sys.longValue);
|
|
|
|
cpu->sys += sys.longValue;
|
|
|
|
// idle time = 100% - total time - system time
|
|
|
|
cpu->idle += (100 - tot.longValue - sys.longValue);
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
gkrellm_cpu_assign_data(i, cpu->user, 0 /*nice*/, cpu->sys, cpu->idle);
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static void
|
|
|
|
gkrellm_sys_cpu_add_cb(wchar_t *name, PDH_HCOUNTER *total, PDH_HCOUNTER *sys)
|
|
|
|
{
|
|
|
|
GK_CPU *cpu;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Adding CPU '%ls'\n", name);
|
|
|
|
|
|
|
|
cpu = g_new0(GK_CPU, 1);
|
|
|
|
cpu->total_pdh_counter = *total;
|
|
|
|
cpu->sys_pdh_counter = *sys;
|
|
|
|
g_ptr_array_add(s_cpu_ptr_array, cpu);
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
gkrellm_sys_cpu_init(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT CPU Monitoring\n");
|
|
|
|
|
|
|
|
s_cpu_ptr_array = g_ptr_array_new();
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-02-09 01:33:37 +03:00
|
|
|
gkrellm_cpu_nice_time_unsupported();
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
add_counter_list(
|
|
|
|
238 // object_index
|
|
|
|
, 6 // counter_index1, cpu time
|
|
|
|
, 144 // counter_index2, system time
|
|
|
|
, gkrellm_sys_cpu_add_cb);
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Found %i CPUs for monitoring.\n",
|
|
|
|
s_cpu_ptr_array->len);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
gkrellm_cpu_set_number_of_cpus(s_cpu_ptr_array->len);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
return (s_cpu_ptr_array->len == 0 ? FALSE : TRUE);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static void
|
|
|
|
gkrellm_sys_cpu_cleanup(void)
|
|
|
|
{
|
|
|
|
guint i;
|
|
|
|
if (!s_cpu_ptr_array)
|
|
|
|
return;
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Freeing counters for %u cpu(s)\n",
|
|
|
|
s_cpu_ptr_array->len);
|
|
|
|
for (i = 0; i < s_cpu_ptr_array->len; i++)
|
|
|
|
g_free(g_ptr_array_index(s_cpu_ptr_array, i));
|
|
|
|
g_ptr_array_free(s_cpu_ptr_array, TRUE);
|
|
|
|
s_cpu_ptr_array = NULL;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* Net monitor interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
typedef struct _GK_NET
|
2008-09-28 21:27:06 +04:00
|
|
|
{
|
|
|
|
PDH_HCOUNTER recv_pdh_counter;
|
|
|
|
PDH_HCOUNTER send_pdh_counter;
|
|
|
|
gchar *name;
|
|
|
|
gulong recv;
|
|
|
|
gulong send;
|
|
|
|
}
|
|
|
|
GK_NET;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static GPtrArray *s_net_ptr_array = NULL;
|
|
|
|
|
|
|
|
static GK_NET *
|
|
|
|
gk_net_new()
|
|
|
|
{
|
|
|
|
return g_new0(GK_NET, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gk_net_free(GK_NET *net)
|
|
|
|
{
|
|
|
|
g_free(net->name);
|
|
|
|
g_free(net);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
gkrellm_sys_net_read_data(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-02-01 22:11:29 +03:00
|
|
|
gint i;
|
2008-05-25 15:59:22 +04:00
|
|
|
GK_NET *net;
|
|
|
|
PDH_FMT_COUNTERVALUE recvVal;
|
|
|
|
PDH_FMT_COUNTERVALUE sendVal;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pdhQueryHandle == NULL)
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
|
|
|
win32_read_proc_stat();
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Reading net data for %d network devices\n",
|
|
|
|
s_net_ptr_array->len);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
for (i = 0; i < s_net_ptr_array->len; i++)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
net = (GK_NET *)g_ptr_array_index(s_net_ptr_array, i);
|
2008-05-25 15:59:22 +04:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (!get_formatted_counter_value(net->recv_pdh_counter, "net recv", PDH_FMT_LONG, &recvVal))
|
|
|
|
continue;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (!get_formatted_counter_value(net->send_pdh_counter, "net send", PDH_FMT_LONG, &sendVal))
|
|
|
|
continue;
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
net->recv += recvVal.longValue / _GK.update_HZ;
|
|
|
|
net->send += sendVal.longValue / _GK.update_HZ;
|
2008-09-28 21:27:06 +04:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
gkrellm_net_assign_data(net->name, net->recv, net->send);
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
void
|
|
|
|
gkrellm_sys_net_check_routes(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
//TODO: Implement if possible, detects enable/disable of network-interfaces
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_net_isdn_online(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
return FALSE; //TODO: Implement if possible
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static void
|
|
|
|
gkrellm_sys_net_add_cb(wchar_t *name, PDH_HCOUNTER *recv, PDH_HCOUNTER *send)
|
2008-05-25 15:59:22 +04:00
|
|
|
{
|
|
|
|
GK_NET *net;
|
2008-09-30 00:57:01 +04:00
|
|
|
guint i;
|
|
|
|
gchar unique = '0';
|
|
|
|
GK_NET *other_net;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
net = gk_net_new();
|
|
|
|
net->name = clean_dev_name(name);
|
2008-09-30 00:57:01 +04:00
|
|
|
for (i = 0; i < s_net_ptr_array->len; i++)
|
|
|
|
{
|
|
|
|
other_net = (GK_NET *)(g_ptr_array_index(s_net_ptr_array, i));
|
|
|
|
while (strncmp(net->name, other_net->name, MAX_DEV_NAME) == 0)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP,
|
|
|
|
"net names '%s' and '%s' conflict, renaming new one\n",
|
|
|
|
net->name, other_net->name);
|
|
|
|
net->name[strlen(net->name) - 1] = unique++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
net->recv_pdh_counter = *recv;
|
|
|
|
net->send_pdh_counter = *send;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Adding network interface %s\n", net->name);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// TODO: determine network type
|
|
|
|
gkrellm_net_add_timer_type_ppp(net->name);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
g_ptr_array_add(s_net_ptr_array, net);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_net_init(void)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT network monitoring\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
s_net_ptr_array = g_ptr_array_new();
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
add_counter_list(
|
|
|
|
510 // object_index
|
|
|
|
, 264 // counter_index1
|
2008-10-28 14:05:52 +03:00
|
|
|
, 506 // counter_index2
|
2008-09-28 21:27:06 +04:00
|
|
|
, gkrellm_sys_net_add_cb);
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Found %i network adapters for monitoring.\n",
|
|
|
|
s_net_ptr_array->len);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
return (s_net_ptr_array->len == 0 ? FALSE : TRUE);
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static void
|
|
|
|
gkrellm_sys_net_cleanup(void)
|
|
|
|
{
|
|
|
|
guint i;
|
|
|
|
if (!s_net_ptr_array)
|
|
|
|
return;
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Freeing counters for %u network adapter(s)\n",
|
|
|
|
s_net_ptr_array->len);
|
|
|
|
for (i = 0; i < s_net_ptr_array->len; i++)
|
2008-09-30 00:57:01 +04:00
|
|
|
gk_net_free((GK_NET *)g_ptr_array_index(s_net_ptr_array, i));
|
2008-09-28 21:27:06 +04:00
|
|
|
g_ptr_array_free(s_net_ptr_array, TRUE);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* Disk monitor interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
typedef struct _GK_DISK
|
|
|
|
{
|
|
|
|
PDH_HCOUNTER read_pdh_counter;
|
|
|
|
PDH_HCOUNTER write_pdh_counter;
|
|
|
|
gchar *name;
|
|
|
|
gulong read;
|
|
|
|
gulong write;
|
|
|
|
} GK_DISK;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static GPtrArray *s_disk_ptr_array = NULL;
|
|
|
|
|
|
|
|
static GK_DISK *
|
|
|
|
gk_disk_new()
|
|
|
|
{
|
|
|
|
return g_new0(GK_DISK, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gk_disk_free(GK_DISK *disk)
|
|
|
|
{
|
|
|
|
g_free(disk->name);
|
|
|
|
g_free(disk);
|
|
|
|
}
|
|
|
|
|
|
|
|
gchar *gkrellm_sys_disk_name_from_device(gint device_number, gint unit_number,
|
2008-02-01 21:36:15 +03:00
|
|
|
gint *order)
|
|
|
|
{
|
2008-05-25 15:59:22 +04:00
|
|
|
static gchar name[37];
|
|
|
|
GK_DISK *disk;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
disk = g_ptr_array_index(s_disk_ptr_array, device_number);
|
|
|
|
snprintf(name, sizeof(name), "Disk%s", disk->name);
|
2008-02-01 21:36:15 +03:00
|
|
|
*order = device_number;
|
2008-09-28 21:27:06 +04:00
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
gint gkrellm_sys_disk_order_from_name(gchar *name)
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
return 0; // Disk by name not implemented in Windows
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void gkrellm_sys_disk_read_data(void)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-05-25 15:59:22 +04:00
|
|
|
guint i;
|
|
|
|
GK_DISK *disk;
|
|
|
|
PDH_FMT_COUNTERVALUE readVal;
|
|
|
|
PDH_FMT_COUNTERVALUE writeVal;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pdhQueryHandle == NULL)
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
|
|
|
win32_read_proc_stat();
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Reading disk data\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
for (i = 0; i < s_disk_ptr_array->len; i++)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-05-25 15:59:22 +04:00
|
|
|
disk = g_ptr_array_index(s_disk_ptr_array, i);
|
2008-09-28 21:27:06 +04:00
|
|
|
|
|
|
|
if (!get_formatted_counter_value(disk->read_pdh_counter, "disk read", PDH_FMT_DOUBLE, &readVal))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!get_formatted_counter_value(disk->write_pdh_counter, "disk write", PDH_FMT_DOUBLE, &writeVal))
|
|
|
|
continue;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
disk->read += readVal.doubleValue / _GK.update_HZ;
|
|
|
|
disk->write += writeVal.doubleValue / _GK.update_HZ;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
gkrellm_disk_assign_data_by_device(i, 0, disk->read, disk->write, FALSE);
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static
|
|
|
|
void gkrellm_sys_disk_add_cb(wchar_t *name, PDH_HCOUNTER *read, PDH_HCOUNTER *write)
|
|
|
|
{
|
2008-05-25 15:59:22 +04:00
|
|
|
GK_DISK *disk;
|
2008-09-30 00:57:01 +04:00
|
|
|
GK_DISK *other_disk;
|
|
|
|
guint i;
|
|
|
|
gchar unique = '0';
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
disk = gk_disk_new();
|
|
|
|
disk->name = clean_dev_name(name);
|
2008-09-30 00:57:01 +04:00
|
|
|
for (i = 0; i < s_disk_ptr_array->len; i++)
|
|
|
|
{
|
|
|
|
other_disk = (GK_DISK *)(g_ptr_array_index(s_disk_ptr_array, i));
|
|
|
|
while (strncmp(disk->name, other_disk->name, MAX_DEV_NAME) == 0)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP,
|
|
|
|
"disk names '%s' and '%s' conflict, renaming new one\n",
|
|
|
|
disk->name, other_disk->name);
|
|
|
|
disk->name[strlen(disk->name) - 1] = unique++;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
disk->read_pdh_counter = *read;
|
|
|
|
disk->write_pdh_counter = *write;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Adding disk %s\n", disk->name);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
g_ptr_array_add(s_disk_ptr_array, disk);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_disk_init(void)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT disk monitoring\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
s_disk_ptr_array = g_ptr_array_new();
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
add_counter_list(
|
|
|
|
234 // object_index
|
|
|
|
, 220 // counter_index1
|
|
|
|
, 222 // counter_index2
|
|
|
|
, gkrellm_sys_disk_add_cb);
|
2008-02-09 01:33:37 +03:00
|
|
|
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Found %i disk(s) for monitoring.\n",
|
|
|
|
s_disk_ptr_array->len);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-05-25 15:59:22 +04:00
|
|
|
return (s_disk_ptr_array->len == 0 ? FALSE : TRUE);
|
2008-02-09 01:33:37 +03:00
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static void
|
|
|
|
gkrellm_sys_disk_cleanup(void)
|
|
|
|
{
|
|
|
|
guint i;
|
|
|
|
if (!s_disk_ptr_array)
|
|
|
|
return;
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Freeing counters for %u disk(s)\n",
|
|
|
|
s_disk_ptr_array->len);
|
|
|
|
for (i = 0; i < s_disk_ptr_array->len; i++)
|
|
|
|
gk_disk_free(g_ptr_array_index(s_disk_ptr_array, i));
|
|
|
|
g_ptr_array_free(s_disk_ptr_array, TRUE);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* Proc monitor interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Counters for proc monitor interface
|
|
|
|
static PDH_HCOUNTER processCounter = NULL;
|
|
|
|
static PDH_HCOUNTER waitQueueCounter = NULL;
|
|
|
|
// Library handle for secur32.dll, lib is loaded at runtime
|
|
|
|
static HANDLE hSecur32 = NULL;
|
|
|
|
// Function pointers to various functions from secur32.dll
|
|
|
|
static pfLsaEnumerateLogonSessions pfLELS = NULL;
|
|
|
|
static pfLsaFreeReturnBuffer pfLFRB = NULL;
|
|
|
|
static pfLsaGetLogonSessionData pfLGLSD = NULL;
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
// We need to subtract 1 on Win2k, the "idle process" seems to be counted
|
|
|
|
// as waiting on win2k (not on winxp though)
|
|
|
|
// TODO: check on vista, win2k3, win2k8 etc.
|
|
|
|
static long proc_load_correction_val = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
|
|
|
gkrellm_sys_proc_read_data(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
static gulong last_num_processes = 0;
|
|
|
|
static gfloat fload = 0;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-02-01 22:11:29 +03:00
|
|
|
PDH_FMT_COUNTERVALUE value;
|
2008-09-28 21:27:06 +04:00
|
|
|
LONG num_processes;
|
|
|
|
LONG num_forks = 0;
|
|
|
|
LONG num_waiting;
|
2008-02-01 22:11:29 +03:00
|
|
|
gfloat a;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pdhQueryHandle == NULL)
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
|
|
|
win32_read_proc_stat();
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Reading proc data\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (!get_formatted_counter_value(processCounter, "process count",
|
|
|
|
PDH_FMT_LONG, &value))
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
2008-09-28 21:27:06 +04:00
|
|
|
num_processes = value.longValue;
|
|
|
|
if ((last_num_processes) > 0 && (last_num_processes < num_processes))
|
|
|
|
num_forks = num_processes - last_num_processes;
|
|
|
|
last_num_processes = num_processes;
|
|
|
|
|
|
|
|
if (!get_formatted_counter_value(waitQueueCounter, "wait queue size",
|
|
|
|
PDH_FMT_LONG, &value))
|
|
|
|
return;
|
|
|
|
#if 0
|
|
|
|
num_waiting = (value.longValue + proc_load_correction_val);
|
|
|
|
#else
|
|
|
|
num_waiting = value.longValue;
|
|
|
|
#endif
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
//fload - is the system load average, an exponential moving average over a
|
|
|
|
//period of a minute of n_running. It measures how heavily a system is
|
|
|
|
//loaded with processes or threads competing for cpu time slices.
|
|
|
|
//
|
|
|
|
//All the unix OSs have a system call for getting the load average. But if
|
|
|
|
//you don't and can get a n_running number, you can calculate fload. An
|
|
|
|
//exponential moving average (ema) is done like:
|
|
|
|
//
|
|
|
|
// a = 2 / (period + 1)
|
|
|
|
// ema = ema + a * (new_value - ema)
|
|
|
|
//
|
|
|
|
// See also
|
|
|
|
// http://en.wikipedia.org/wiki/Load_(computing)
|
|
|
|
a = 2.0 / ((_GK.update_HZ * 60.) + 1.);
|
|
|
|
fload += a * (num_waiting - fload);
|
|
|
|
if (fload < 0)
|
|
|
|
fload = 0;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "num_forks %ld; num_waiting %ld; a %f; fload %f\n",
|
|
|
|
num_forks, num_waiting, a, fload);
|
|
|
|
|
|
|
|
gkrellm_proc_assign_data(num_processes, 0 /*n_running*/,
|
|
|
|
num_forks /*n_forks*/, fload);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2009-12-26 18:11:13 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
void
|
|
|
|
gkrellm_sys_proc_read_users(void)
|
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
// Number of interactive users
|
|
|
|
gint n_users = 0;
|
2009-12-26 18:11:13 +03:00
|
|
|
|
|
|
|
#if _WIN32_WINNT >= 0x501 // Windows XP or newer
|
|
|
|
BOOL ret;
|
2009-12-30 17:56:17 +03:00
|
|
|
WTS_SESSION_INFOW *pSessionList = NULL;
|
2009-12-26 18:11:13 +03:00
|
|
|
DWORD sessionListCount = 0;
|
2009-12-30 17:56:17 +03:00
|
|
|
WTS_SESSION_INFOW *pSession = NULL;
|
2009-12-26 18:11:13 +03:00
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Enumerating terminal sessions...\n");
|
|
|
|
// Returns list of terminal sessions in pSessionInfo[]
|
|
|
|
ret = WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionList,
|
|
|
|
&sessionListCount);
|
|
|
|
if (!ret)
|
|
|
|
{
|
|
|
|
win32_warning(WTSAPI32,
|
|
|
|
GetLastError(),
|
|
|
|
"Enumerating terminal sessions failed");
|
|
|
|
}
|
|
|
|
else if (pSessionList != NULL)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Found %d terminal sessions\n", sessionListCount);
|
|
|
|
for (i = 0; i < sessionListCount; i++)
|
|
|
|
{
|
|
|
|
pSession = &pSessionList[i];
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Session %d (%ls) has state %d\n",
|
|
|
|
pSession->SessionId, pSession->pWinStationName, pSession->State);
|
|
|
|
if (pSession->State == WTSActive)
|
|
|
|
n_users++;
|
|
|
|
}
|
|
|
|
WTSFreeMemory(pSessionList);
|
|
|
|
}
|
|
|
|
#else // TODO: Remove this code-branch if nobody wants win2k-support anymore
|
2008-09-28 21:27:06 +04:00
|
|
|
// Return value for Lsa functions
|
|
|
|
NTSTATUS ntstatus;
|
|
|
|
// Arguments for LsaEnumerateLogonSessions()
|
|
|
|
ULONG numSessions = 0;
|
|
|
|
PLUID pSessions = NULL;
|
|
|
|
// Argument for LsaGetLogonSessionData()
|
2008-09-30 20:48:09 +04:00
|
|
|
SECURITY_LOGON_SESSION_DATA *pSessionData;
|
2008-09-28 21:27:06 +04:00
|
|
|
wchar_t acc_name[256];
|
|
|
|
wchar_t acc_dom[256];
|
|
|
|
DWORD dwSize;
|
|
|
|
SID_NAME_USE sid_type;
|
|
|
|
|
|
|
|
/* Silently fail if secur32.dll is missing functions that we use */
|
|
|
|
if ((pfLELS == NULL) || (pfLFRB == NULL) || (pfLGLSD == NULL))
|
|
|
|
return;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Getting number of logged in users\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
ntstatus = pfLELS(&numSessions, &pSessions);
|
|
|
|
if (NT_SUCCESS(ntstatus))
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Found %lu user-sessions\n", numSessions);
|
|
|
|
for (i = 0; i < (int)numSessions; i++)
|
|
|
|
{
|
|
|
|
//gkrellm_debug(DEBUG_SYSDEP, "Fetching session-data for session %d\n", i);
|
|
|
|
pSessionData = NULL;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
ntstatus = pfLGLSD(&pSessions[i], &pSessionData);
|
|
|
|
if (NT_SUCCESS(ntstatus) && (pSessionData != NULL))
|
|
|
|
{
|
|
|
|
if ((SECURITY_LOGON_TYPE)pSessionData->LogonType == Interactive
|
|
|
|
&& (pSessionData->UserName.Buffer != NULL))
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Interactive User %d; '%ls'\n",
|
|
|
|
i, pSessionData->UserName.Buffer);
|
|
|
|
|
|
|
|
dwSize = 256;
|
|
|
|
if (LookupAccountSidW(NULL, pSessionData->Sid,
|
|
|
|
acc_name, &dwSize,
|
|
|
|
acc_dom, &dwSize,
|
|
|
|
&sid_type))
|
|
|
|
{
|
|
|
|
if (sid_type == 1)
|
|
|
|
{
|
|
|
|
n_users++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP,
|
|
|
|
"SID type %d is not a normal account\n",
|
|
|
|
(int)sid_type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win32_warning(NTDLL,
|
|
|
|
GetLastError(),
|
|
|
|
"Looking up user account id failed");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win32_warning(NTDLL, ntstatus,
|
|
|
|
"Could not get session-data for session %d", i);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Free session-data provided by OS, even if function returned
|
|
|
|
// an error before
|
|
|
|
pfLFRB(pSessionData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win32_warning(NTDLL, ntstatus, "Could not enumerate user-sessions\n");
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Free LUID list provided by OS, even if function returned an error before
|
|
|
|
pfLFRB(pSessions);
|
2009-12-26 18:11:13 +03:00
|
|
|
#endif
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_proc_assign_users(n_users);
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_proc_init(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-30 20:48:09 +04:00
|
|
|
wchar_t system_name[PDH_MAX_COUNTER_NAME];
|
|
|
|
wchar_t counter_name[PDH_MAX_COUNTER_NAME];
|
2008-09-28 21:27:06 +04:00
|
|
|
wchar_t counter_path[128+128+3];
|
|
|
|
#if 0
|
|
|
|
OSVERSIONINFOEXW vi;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT process monitoring\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pdhQueryHandle == NULL)
|
|
|
|
return FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Fetch prefix for both counter paths ("System" index is 2)
|
2008-09-30 20:48:09 +04:00
|
|
|
if (!lookup_perfname(2, system_name, ARR_SZ(system_name)))
|
2008-09-28 21:27:06 +04:00
|
|
|
return FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Add counter for number of processes (index is 248)
|
|
|
|
if (!lookup_perfname(248, counter_name, 128))
|
|
|
|
return FALSE;
|
2008-09-30 20:48:09 +04:00
|
|
|
_snwprintf(counter_path, ARR_SZ(counter_path), L"\\%ls\\%ls",
|
2008-09-28 21:27:06 +04:00
|
|
|
system_name, counter_name);
|
|
|
|
if (!add_counter(counter_path, &processCounter))
|
|
|
|
return FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// --- Add counter for waiting queue size (index is 44)
|
|
|
|
if (!lookup_perfname(44, counter_name, 128))
|
|
|
|
return FALSE;
|
2008-09-30 20:48:09 +04:00
|
|
|
_snwprintf(counter_path, ARR_SZ(counter_path), L"\\%ls\\%ls",
|
2008-09-28 21:27:06 +04:00
|
|
|
system_name, counter_name);
|
|
|
|
if (!add_counter(counter_path, &waitQueueCounter))
|
|
|
|
return FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Dynamically load secur32.dll and lookup functions.
|
|
|
|
// Needed to determine number of logged in users
|
|
|
|
hSecur32 = LoadLibraryW(L"secur32.dll");
|
|
|
|
if (hSecur32 != NULL)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Loaded secur32.dll\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
pfLELS = (pfLsaEnumerateLogonSessions)GetProcAddress(hSecur32,
|
|
|
|
"LsaEnumerateLogonSessions");
|
|
|
|
if (pfLELS == NULL)
|
|
|
|
{
|
|
|
|
g_warning("Could not get address for " \
|
|
|
|
"LsaEnumerateLogonSessions() in secur32.dll\n");
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
pfLFRB = (pfLsaFreeReturnBuffer)GetProcAddress(hSecur32,
|
|
|
|
"LsaFreeReturnBuffer");
|
|
|
|
if (pfLFRB == NULL)
|
|
|
|
{
|
|
|
|
g_warning("Could not get address for " \
|
|
|
|
"LsaFreeReturnBuffer() in secur32.dll\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
pfLGLSD = (pfLsaGetLogonSessionData)GetProcAddress(hSecur32,
|
|
|
|
"LsaGetLogonSessionData");
|
|
|
|
if (pfLGLSD == NULL)
|
|
|
|
{
|
|
|
|
g_warning("Could not get address for " \
|
|
|
|
"LsaGetLogonSessionData() in secur32.dll\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win32_warning(NULL, GetLastError(),
|
|
|
|
"Could not load secur32.dll, number of logged in " \
|
|
|
|
"users will not be detected\n");
|
|
|
|
}
|
2008-02-01 22:11:29 +03:00
|
|
|
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Determine OS for proper load-average computation
|
|
|
|
// (wait-queue value on win2k is off by one)
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
memset(&vi, 0, sizeof(OSVERSIONINFOEXW));
|
|
|
|
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
|
|
|
|
if (GetVersionExW((OSVERSIONINFOW *)(&vi)))
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "major %ld; minor %ld\n",
|
|
|
|
vi.dwMajorVersion, vi.dwMinorVersion);
|
|
|
|
if ((vi.dwMajorVersion == 5) && (vi.dwMinorVersion == 0))
|
|
|
|
proc_load_correction_val = -1;
|
|
|
|
}
|
|
|
|
#endif
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static void
|
|
|
|
gkrellm_sys_proc_cleanup(void)
|
|
|
|
{
|
|
|
|
// Unload secur32.dll and invalidate function pointers
|
|
|
|
pfLELS = NULL;
|
|
|
|
pfLFRB = NULL;
|
|
|
|
pfLGLSD = NULL;
|
|
|
|
if (hSecur32 != NULL)
|
|
|
|
FreeLibrary(hSecur32);
|
|
|
|
hSecur32 = NULL;
|
|
|
|
}
|
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* Memory/Swap monitor interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
typedef struct _PERFORMANCE_INFORMATION {
|
|
|
|
DWORD cb;
|
|
|
|
SIZE_T CommitTotal;
|
|
|
|
SIZE_T CommitLimit;
|
|
|
|
SIZE_T CommitPeak;
|
|
|
|
SIZE_T PhysicalTotal;
|
|
|
|
SIZE_T PhysicalAvailable;
|
|
|
|
SIZE_T SystemCache;
|
|
|
|
SIZE_T KernelTotal;
|
|
|
|
SIZE_T KernelPaged;
|
|
|
|
SIZE_T KernelNonpaged;
|
|
|
|
SIZE_T PageSize;
|
|
|
|
DWORD HandleCount;
|
|
|
|
DWORD ProcessCount;
|
|
|
|
DWORD ThreadCount;
|
2008-09-28 21:27:06 +04:00
|
|
|
} PERFORMANCE_INFORMATION;
|
|
|
|
|
|
|
|
typedef BOOL (WINAPI *pfGetPerformanceInfo)(PERFORMANCE_INFORMATION *, DWORD);
|
|
|
|
|
|
|
|
static HINSTANCE psapi_instance = NULL;
|
|
|
|
static pfGetPerformanceInfo pGPI = NULL;
|
|
|
|
static DWORD page_size = 1;
|
|
|
|
|
|
|
|
void
|
|
|
|
gkrellm_sys_mem_read_data(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Checking memory utilization\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
guint64 total = 0;
|
|
|
|
guint64 used = 0;
|
|
|
|
guint64 avail = 0;
|
|
|
|
guint64 cache = 0;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pGPI)
|
|
|
|
{
|
|
|
|
PERFORMANCE_INFORMATION pi;
|
|
|
|
|
|
|
|
// See http://msdn.microsoft.com/en-us/library/ms684824(VS.85).aspx
|
|
|
|
// for the confusing description of PERFORMANCE_INFORMATION
|
|
|
|
//
|
|
|
|
// total = PhysicalTotal
|
|
|
|
// used = PhysicalTotal - PhysicalAvailable
|
|
|
|
// NOTE: (avail value is not exactly correct but we can't know better)
|
|
|
|
// avail = PhysicalAvailable - SystemCache
|
|
|
|
// cache = SystemCache
|
|
|
|
|
|
|
|
if (pGPI(&pi, sizeof(PERFORMANCE_INFORMATION)))
|
|
|
|
{
|
|
|
|
total = pi.PhysicalTotal * pi.PageSize;
|
|
|
|
used = (pi.PhysicalTotal - pi.PhysicalAvailable) * pi.PageSize;
|
|
|
|
avail = (pi.PhysicalAvailable - pi.SystemCache) * pi.PageSize;
|
|
|
|
cache = pi.SystemCache * pi.PageSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MEMORYSTATUSEX ms;
|
|
|
|
ms.dwLength = sizeof(ms);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (GlobalMemoryStatusEx(&ms))
|
|
|
|
{
|
|
|
|
total = ms.ullTotalPhys;
|
|
|
|
used = ms.ullTotalPhys - ms.ullAvailPhys;
|
|
|
|
avail = ms.ullAvailPhys;
|
|
|
|
}
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_mem_assign_data(total, used, avail, 0, 0, cache);
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
void
|
|
|
|
gkrellm_sys_swap_read_data(void)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
guint64 swapTotal = 0;
|
|
|
|
guint64 swapUsed = 0;
|
2008-02-01 21:36:15 +03:00
|
|
|
NTSTATUS ntstatus;
|
|
|
|
ULONG szBuf = 3*sizeof(SYSTEM_PAGEFILE_INFORMATION);
|
2008-09-30 20:48:09 +04:00
|
|
|
SYSTEM_PAGEFILE_INFORMATION *pInfo;
|
2008-09-28 21:27:06 +04:00
|
|
|
LPVOID pBuf = NULL;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Checking swap utilization\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
// it is difficult to determine beforehand which size of the
|
|
|
|
// buffer will be enough to retrieve all information, so we
|
|
|
|
// start with a minimal buffer and increase its size until we get
|
|
|
|
// the information successfully
|
|
|
|
do
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
pBuf = g_malloc(szBuf);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
ntstatus = ZwQuerySystemInformation(SystemPagefileInformation, pBuf,
|
|
|
|
szBuf, NULL);
|
2008-02-01 21:36:15 +03:00
|
|
|
if (ntstatus == STATUS_INFO_LENGTH_MISMATCH)
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
// Buffer was too small, double its size and try again
|
|
|
|
g_free(pBuf);
|
2008-02-01 21:36:15 +03:00
|
|
|
szBuf *= 2;
|
|
|
|
}
|
|
|
|
else if (!NT_SUCCESS(ntstatus))
|
2008-09-28 21:27:06 +04:00
|
|
|
{
|
|
|
|
win32_warning(NTDLL, ntstatus, "Could not determine swap usage");
|
|
|
|
g_free(pBuf);
|
|
|
|
// Some other error occured, give up
|
|
|
|
return;
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
while (ntstatus == STATUS_INFO_LENGTH_MISMATCH);
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pBuf != NULL)
|
|
|
|
{
|
|
|
|
// iterate over information for all pagefiles
|
2008-09-30 20:48:09 +04:00
|
|
|
pInfo = (SYSTEM_PAGEFILE_INFORMATION *)pBuf;
|
2008-09-28 21:27:06 +04:00
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
swapTotal += pInfo->CurrentSize * page_size;
|
|
|
|
swapUsed += pInfo->TotalUsed * page_size;
|
|
|
|
if (pInfo->NextEntryOffset == 0)
|
|
|
|
break; // end of list
|
|
|
|
// get pointer to next struct
|
2008-09-30 20:48:09 +04:00
|
|
|
pInfo = (SYSTEM_PAGEFILE_INFORMATION *)((BYTE *)pInfo +
|
2008-09-28 21:27:06 +04:00
|
|
|
pInfo->NextEntryOffset);
|
|
|
|
}
|
|
|
|
g_free(pBuf);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// TODO: calculate swapin/swapout values
|
|
|
|
gkrellm_swap_assign_data(swapTotal, swapUsed, 0, 0);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean
|
|
|
|
gkrellm_sys_mem_init(void)
|
|
|
|
{
|
|
|
|
SYSTEM_INFO si;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT memory monitoring\n");
|
|
|
|
|
|
|
|
GetSystemInfo(&si);
|
|
|
|
page_size = si.dwPageSize;
|
|
|
|
|
|
|
|
psapi_instance = LoadLibraryW(L"PSAPI.DLL");
|
|
|
|
if (psapi_instance)
|
|
|
|
{
|
|
|
|
pGPI = GetProcAddress(psapi_instance, "GetPerformanceInfo");
|
|
|
|
if (pGPI == NULL)
|
|
|
|
{
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "No GetPerformanceInfo() in " \
|
|
|
|
"PSAPI.DLL, cache-memory will stay at 0!\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win32_warning(NULL, GetLastError(), "Could not load PSAPI.DLL");
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
return TRUE;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static void
|
|
|
|
gkrellm_sys_mem_cleanup(void)
|
|
|
|
{
|
|
|
|
pGPI = NULL;
|
|
|
|
if (psapi_instance)
|
|
|
|
FreeLibrary(psapi_instance);
|
|
|
|
psapi_instance = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* Battery monitor interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
|
|
|
void gkrellm_sys_battery_read_data(void)
|
|
|
|
{
|
2008-02-01 22:11:29 +03:00
|
|
|
gboolean available, on_line, charging;
|
|
|
|
gint percent, time_left;
|
|
|
|
SYSTEM_POWER_STATUS power;
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Checking battery state\n");
|
|
|
|
|
2008-02-01 22:11:29 +03:00
|
|
|
GetSystemPowerStatus(&power);
|
2008-09-28 21:27:06 +04:00
|
|
|
if ( (power.BatteryFlag & BATTERY_FLAG_NO_BATTERY) == BATTERY_FLAG_NO_BATTERY
|
|
|
|
|| (power.BatteryFlag & BATTERY_FLAG_UNKNOWN) == BATTERY_FLAG_UNKNOWN
|
2008-02-01 22:11:29 +03:00
|
|
|
)
|
|
|
|
{
|
2008-02-01 21:36:15 +03:00
|
|
|
available = FALSE;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
else
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-02-01 21:36:15 +03:00
|
|
|
available = TRUE;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
on_line = ((power.ACLineStatus & AC_LINE_ONLINE) == AC_LINE_ONLINE) ? TRUE : FALSE;
|
|
|
|
charging = ((power.BatteryFlag & BATTERY_FLAG_CHARGING) == BATTERY_FLAG_CHARGING) ? TRUE : FALSE;
|
2008-02-01 22:11:29 +03:00
|
|
|
time_left = power.BatteryLifeTime;
|
2008-09-28 21:27:06 +04:00
|
|
|
percent = power.BatteryLifePercent;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_battery_assign_data(0, available, on_line, charging, percent,
|
|
|
|
time_left);
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
|
2008-02-01 22:11:29 +03:00
|
|
|
gboolean gkrellm_sys_battery_init()
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT battery monitoring\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
return TRUE;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
/* ===================================================================== */
|
2008-02-01 21:36:15 +03:00
|
|
|
/* FS monitor interfaces */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
|
|
|
gboolean gkrellm_sys_fs_fstab_modified(void)
|
2008-02-09 01:33:37 +03:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static
|
2008-02-01 21:36:15 +03:00
|
|
|
void eject_win32_cdrom(gchar *device)
|
2008-02-09 01:33:37 +03:00
|
|
|
{
|
|
|
|
HANDLE hFile;
|
|
|
|
BOOL err;
|
2008-09-28 21:27:06 +04:00
|
|
|
char device_path[MAX_PATH];
|
2008-02-09 01:33:37 +03:00
|
|
|
DWORD numBytes;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (!device || *device == '\0')
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// FIXME: This assumes device names like "D:"
|
|
|
|
snprintf(device_path, MAX_PATH, "\\\\.\\%c:", device[0]);
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
hFile = CreateFileA(device_path, GENERIC_READ,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
|
2008-02-01 21:36:15 +03:00
|
|
|
if (hFile != 0 && hFile != INVALID_HANDLE_VALUE)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
|
|
|
// this should be safe for non-removable drives
|
2008-02-01 21:36:15 +03:00
|
|
|
err = DeviceIoControl(hFile, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0,
|
2008-02-09 01:33:37 +03:00
|
|
|
&numBytes, NULL);
|
2008-02-01 21:36:15 +03:00
|
|
|
if (!err)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-02-01 21:36:15 +03:00
|
|
|
err = DeviceIoControl(hFile, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0,
|
2008-02-01 22:11:29 +03:00
|
|
|
NULL, 0, &numBytes, NULL);
|
|
|
|
}
|
|
|
|
CloseHandle(hFile);
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gboolean gkrellm_sys_fs_init(void)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT filesystem monitoring\n");
|
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
gkrellm_fs_mounting_unsupported();
|
|
|
|
gkrellm_fs_setup_eject(NULL, NULL, eject_win32_cdrom, NULL);
|
2008-02-01 22:11:29 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
void gkrellm_sys_fs_get_fsusage(gpointer fs, gchar *dir)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
|
|
|
BOOL err = 0;
|
2008-09-28 21:27:06 +04:00
|
|
|
ULARGE_INTEGER availToCaller;
|
|
|
|
ULARGE_INTEGER totalBytes;
|
|
|
|
ULARGE_INTEGER freeBytes;
|
|
|
|
gunichar2 *w_dir = NULL;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (!dir || *dir == '\0')
|
2008-02-01 22:11:29 +03:00
|
|
|
return;
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Checking fs usage for %s\n", dir);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
w_dir = g_utf8_to_utf16(dir, -1, NULL, NULL, NULL);
|
|
|
|
if (!w_dir)
|
|
|
|
return;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
err = GetDiskFreeSpaceExW(w_dir, &availToCaller, &totalBytes, &freeBytes);
|
2008-02-01 22:11:29 +03:00
|
|
|
if (err != 0)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-02-01 22:11:29 +03:00
|
|
|
// fs, blocks, avail, free, size
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_fs_assign_fsusage_data(fs
|
|
|
|
, EnlargedUnsignedDivide(totalBytes, 1024, 0) /* total */
|
|
|
|
, EnlargedUnsignedDivide(availToCaller, 1024, 0) /* free to caller */
|
|
|
|
, EnlargedUnsignedDivide(freeBytes, 1024, 0) /* free */
|
|
|
|
, 1024 /* block size */
|
|
|
|
);
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
|
|
|
else
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
/* This may happen on cd/dvd drives, ignore error silently */
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
g_free(w_dir);
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
|
|
|
void gkrellm_sys_fs_get_mounts_list(void)
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
wchar_t drive_list[4*26];
|
|
|
|
wchar_t *drive;
|
|
|
|
gchar *drive_utf8;
|
2008-02-09 01:33:37 +03:00
|
|
|
DWORD ret;
|
2008-09-28 21:27:06 +04:00
|
|
|
DWORD sz;
|
|
|
|
UINT drive_type;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Getting list of mounted drives\n");
|
|
|
|
|
|
|
|
drive_list[0] = '\0';
|
2008-09-30 20:48:09 +04:00
|
|
|
sz = ARR_SZ(drive_list) - sizeof(drive_list[0]);
|
2008-09-28 21:27:06 +04:00
|
|
|
ret = GetLogicalDriveStringsW(sz, drive_list);
|
|
|
|
if (ret == 0 || ret > sz)
|
|
|
|
{
|
|
|
|
win32_warning(NULL, GetLastError(), "Failed enumerating mounted drives");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (drive = drive_list; (*drive) != '\0'; drive += wcslen(drive) + 1)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
drive_type = GetDriveTypeW(drive);
|
|
|
|
|
|
|
|
if ( (drive_type == DRIVE_REMOVABLE)
|
|
|
|
&& (!wcsncmp(drive, L"A:\\", 3) || !wcsncmp(drive, L"B:\\", 3)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Found mounted drive '%ls' of type %u\n",
|
|
|
|
drive, drive_type);
|
|
|
|
drive_utf8 = g_utf16_to_utf8(drive, -1, NULL, NULL, NULL);
|
|
|
|
gkrellm_fs_add_to_mounts_list(drive_utf8, drive_utf8,
|
|
|
|
(drive_type == DRIVE_REMOTE ? "smbfs" : ""));
|
|
|
|
g_free(drive_utf8);
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-02-01 22:11:29 +03:00
|
|
|
void gkrellm_sys_fs_get_fstab_list(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
wchar_t drive_list[4*26];
|
|
|
|
wchar_t *drive;
|
|
|
|
gchar *drive_utf8;
|
2008-02-09 01:33:37 +03:00
|
|
|
DWORD ret;
|
2008-09-28 21:27:06 +04:00
|
|
|
DWORD sz;
|
|
|
|
UINT drive_type;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Getting list of drives in fstab\n");
|
|
|
|
|
|
|
|
drive_list[0] = '\0';
|
2008-09-30 20:48:09 +04:00
|
|
|
sz = ARR_SZ(drive_list) - sizeof(drive_list[0]);
|
2008-09-28 21:27:06 +04:00
|
|
|
ret = GetLogicalDriveStringsW(sz, drive_list);
|
|
|
|
if (ret == 0 || ret > sz)
|
|
|
|
{
|
|
|
|
win32_warning(NULL, GetLastError(), "Failed enumerating fstab drives");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (drive = drive_list; (*drive) != '\0'; drive += wcslen(drive) + 1)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
drive_type = GetDriveTypeW(drive);
|
|
|
|
|
|
|
|
if ( (drive_type == DRIVE_REMOVABLE)
|
|
|
|
&& (!wcsncmp(drive, L"A:\\", 3) || !wcsncmp(drive, L"B:\\", 3)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Found fstab drive '%ls' of type %u\n",
|
|
|
|
drive, drive_type);
|
|
|
|
|
|
|
|
drive_utf8 = g_utf16_to_utf8(drive, -1, NULL, NULL, NULL);
|
|
|
|
gkrellm_fs_add_to_fstab_list(drive_utf8, drive_utf8,
|
|
|
|
(drive_type == DRIVE_REMOTE ? "smbfs" : ""), "");
|
|
|
|
g_free(drive_utf8);
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
/* ===================================================================== */
|
|
|
|
/* INET monitor interfaces */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
|
|
|
gboolean gkrellm_sys_inet_init(void)
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT inet port monitoring\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
void gkrellm_sys_inet_read_tcp_data(void)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
// TODO: Make use of GetTcp6Table() by loading it at runtime
|
|
|
|
// (only available on vista and newer)
|
2008-02-01 22:11:29 +03:00
|
|
|
PMIB_TCPTABLE pTcpTable = NULL;
|
|
|
|
DWORD dwTableSize = 0;
|
2008-09-28 21:27:06 +04:00
|
|
|
DWORD dwStatus;
|
|
|
|
MIB_TCPROW *tcprow;
|
|
|
|
ActiveTCP tcp;
|
|
|
|
DWORD i;
|
|
|
|
|
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Fetching list of TCP connections\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
// Make an initial call to GetTcpTable to
|
|
|
|
// get the necessary size into the dwSize variable
|
2008-09-28 21:27:06 +04:00
|
|
|
dwStatus = GetTcpTable(NULL, &dwTableSize, FALSE);
|
|
|
|
|
|
|
|
if ((dwStatus == ERROR_INSUFFICIENT_BUFFER) && (dwTableSize > 0))
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
pTcpTable = (MIB_TCPTABLE *)g_malloc(dwTableSize);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
// Make a second call to GetTcpTable to get
|
|
|
|
// the actual data we require
|
2008-09-28 21:27:06 +04:00
|
|
|
dwStatus = GetTcpTable(pTcpTable, &dwTableSize, FALSE);
|
|
|
|
|
|
|
|
if (dwStatus == NO_ERROR)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-02-01 22:11:29 +03:00
|
|
|
for (i = 0; i < pTcpTable->dwNumEntries; i++)
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
tcprow = &pTcpTable->table[i];
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Skip connections that are not fully established
|
|
|
|
if (tcprow->dwState != MIB_TCP_STATE_ESTAB)
|
2008-02-01 22:11:29 +03:00
|
|
|
continue;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
tcp.family = AF_INET;
|
2008-09-28 21:27:06 +04:00
|
|
|
tcp.local_port = htons(tcprow->dwLocalPort);
|
|
|
|
tcp.remote_addr.s_addr = tcprow->dwRemoteAddr;
|
|
|
|
#if defined(INET6)
|
|
|
|
tcp.in6_addr = 0;
|
|
|
|
#endif
|
|
|
|
tcp.remote_port = htons(tcprow->dwRemotePort);
|
|
|
|
tcp.is_udp = FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-02-01 22:11:29 +03:00
|
|
|
gkrellm_inet_log_tcp_port_data(&tcp);
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
win32_warning(NULL, dwStatus,
|
|
|
|
"Could not fetch list of TCP connections");
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free(pTcpTable);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
win32_warning(NULL, dwStatus,
|
|
|
|
"Could not fetch list of TCP connections");
|
2008-02-01 21:36:15 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* Uptime monitor interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
static PDH_HCOUNTER uptimeCounter = NULL;
|
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
time_t gkrellm_sys_uptime_read_uptime(void)
|
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
PDH_FMT_COUNTERVALUE val;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pdhQueryHandle == NULL)
|
|
|
|
return (time_t)0;
|
2008-02-01 22:11:29 +03:00
|
|
|
win32_read_proc_stat();
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Reading system uptime\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (!get_formatted_counter_value(uptimeCounter, "uptime", PDH_FMT_LONG, &val))
|
|
|
|
return (time_t)0;
|
|
|
|
return (time_t)val.longValue;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-02-01 22:11:29 +03:00
|
|
|
gboolean gkrellm_sys_uptime_init(void)
|
2008-02-01 21:36:15 +03:00
|
|
|
{
|
2008-09-30 20:48:09 +04:00
|
|
|
wchar_t system_name[PDH_MAX_COUNTER_NAME];
|
|
|
|
wchar_t uptime_name[PDH_MAX_COUNTER_NAME];
|
|
|
|
wchar_t counter_path[PDH_MAX_COUNTER_PATH];
|
2008-02-01 22:11:29 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "INIT uptime monitoring\n");
|
|
|
|
|
|
|
|
if (pdhQueryHandle == NULL)
|
2008-02-01 22:11:29 +03:00
|
|
|
return FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Fetch prefix for counter ("System" index is 2)
|
2008-09-30 20:48:09 +04:00
|
|
|
if (!lookup_perfname(2, system_name, ARR_SZ(system_name)))
|
2008-09-28 21:27:06 +04:00
|
|
|
return FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Fetch name for uptime ("Uptime" index is 674)
|
2008-09-30 20:48:09 +04:00
|
|
|
if (!lookup_perfname(674, uptime_name, ARR_SZ(uptime_name)))
|
2008-09-28 21:27:06 +04:00
|
|
|
return FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-30 20:48:09 +04:00
|
|
|
_snwprintf(counter_path, ARR_SZ(counter_path), L"\\%ls\\%ls",
|
2008-09-28 21:27:06 +04:00
|
|
|
system_name, uptime_name);
|
|
|
|
|
|
|
|
if (!add_counter(counter_path, &uptimeCounter))
|
|
|
|
return FALSE;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
return TRUE;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
|
|
|
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
/* ===================================================================== */
|
|
|
|
/* System name interface */
|
|
|
|
/* ===================================================================== */
|
|
|
|
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
typedef void (WINAPI *PGetNativeSystemInfo)(SYSTEM_INFO *);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gchar *gkrellm_sys_get_system_name(void)
|
|
|
|
{
|
|
|
|
static gboolean have_sys_name;
|
|
|
|
static gchar sysname[32];
|
|
|
|
OSVERSIONINFOEXW vi;
|
|
|
|
SYSTEM_INFO si;
|
|
|
|
PGetNativeSystemInfo pGNSI;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (have_sys_name)
|
|
|
|
return sysname;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
gkrellm_debug(DEBUG_SYSDEP, "Retrieving system name\n");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Default value for sysname
|
|
|
|
g_strlcpy(sysname, "Unknown", sizeof(sysname));
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Query version info
|
|
|
|
memset(&vi, 0, sizeof(OSVERSIONINFOEXW));
|
|
|
|
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
|
|
|
|
if (!GetVersionExW((OSVERSIONINFOW *)(&vi)))
|
|
|
|
return sysname;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// We actually only support decoding NT-based version info
|
|
|
|
if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
|
|
|
return sysname;
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
// Try to call native version first, as this allows detecting
|
|
|
|
// 64bit hosts from within a 32bit process.
|
|
|
|
pGNSI = (PGetNativeSystemInfo)GetProcAddress(
|
|
|
|
GetModuleHandleW(L"kernel32.dll"), "GetNativeSystemInfo");
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (pGNSI != NULL)
|
|
|
|
pGNSI(&si);
|
|
|
|
else
|
|
|
|
GetSystemInfo(&si);
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (vi.dwMajorVersion == 6 && vi.dwMinorVersion == 0)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
// Windows 6.0 aka Vista or Server 2008
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (vi.wProductType == VER_NT_WORKSTATION)
|
|
|
|
g_strlcpy(sysname, "Windows Vista", sizeof(sysname));
|
2008-02-01 21:36:15 +03:00
|
|
|
else
|
2008-09-28 21:27:06 +04:00
|
|
|
g_strlcpy(sysname, "Windows Server 2008", sizeof(sysname));
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
else if (vi.dwMajorVersion == 5)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
// Windows 5.x aka 2000, XP, Server 2003
|
2008-02-09 01:33:37 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
if (vi.dwMinorVersion == 0)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
if (vi.wProductType == VER_NT_WORKSTATION)
|
|
|
|
g_strlcpy(sysname, "Windows 2000 Professional", sizeof(sysname));
|
|
|
|
else
|
|
|
|
g_strlcpy(sysname, "Windows 2000 Server", sizeof(sysname));
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
else if (vi.dwMinorVersion == 1)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
if (vi.wSuiteMask & VER_SUITE_PERSONAL)
|
|
|
|
g_strlcpy(sysname, "Windows XP Home Edition", sizeof(sysname));
|
|
|
|
else
|
|
|
|
g_strlcpy(sysname, "Windows XP Professional", sizeof(sysname));
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-09-28 21:27:06 +04:00
|
|
|
else if (vi.dwMinorVersion == 2)
|
2008-02-01 22:11:29 +03:00
|
|
|
{
|
2008-09-28 21:27:06 +04:00
|
|
|
if (GetSystemMetrics(SM_SERVERR2))
|
|
|
|
g_strlcpy(sysname, "Windows Server 2003 R2", sizeof(sysname));
|
|
|
|
else if (vi.wSuiteMask == VER_SUITE_STORAGE_SERVER)
|
|
|
|
g_strlcpy(sysname, "Windows Storage Server 2003", sizeof(sysname));
|
|
|
|
else if ( vi.wProductType == VER_NT_WORKSTATION
|
|
|
|
&& si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
|
|
|
|
g_strlcpy(sysname, "Windows XP Professional x64", sizeof(sysname));
|
|
|
|
else
|
|
|
|
g_strlcpy(sysname, "Windows Server 2003", sizeof(sysname));
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
return sysname;
|
2008-02-01 22:11:29 +03:00
|
|
|
}
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
|
2008-09-28 21:27:06 +04:00
|
|
|
/* ===================================================================== */
|
|
|
|
/* Misc functions */
|
|
|
|
/* ===================================================================== */
|
2008-02-01 21:36:15 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Copyright (c) 1983, 1990, 1993
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
|
|
|
* This product includes software developed by the University of
|
|
|
|
* California, Berkeley and its contributors.
|
|
|
|
* 4. Neither the name of the University nor the names of its contributors
|
|
|
|
* may be used to endorse or promote products derived from this software
|
|
|
|
* without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies, and that
|
|
|
|
* the name of Digital Equipment Corporation not be used in advertising or
|
|
|
|
* publicity pertaining to distribution of the document or software without
|
|
|
|
* specific, written prior permission.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
|
|
|
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
|
|
|
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|
|
|
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|
|
|
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
|
|
* SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Portions Copyright (c) 1996-1999 by Internet Software Consortium.
|
|
|
|
*
|
|
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
|
|
* copyright notice and this permission notice appear in all copies.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
|
|
|
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
|
|
|
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|
|
|
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|
|
|
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|
|
|
* SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* BeOS doesn't yet have it's own inet_aton and Bind won't be ported
|
|
|
|
* until R5, so this is from a Bind 8 distribution. It's currently untested.
|
|
|
|
*/
|
|
|
|
|
|
|
|
int inet_aton(const char *cp, struct in_addr *addr) {
|
|
|
|
u_long val;
|
|
|
|
int base, n;
|
|
|
|
char c;
|
|
|
|
short parts[4];
|
|
|
|
short *pp = parts;
|
|
|
|
int digit;
|
|
|
|
|
|
|
|
c = *cp;
|
|
|
|
for (;;) {
|
|
|
|
/*
|
|
|
|
* Collect number up to ``.''.
|
|
|
|
* Values are specified as for C:
|
|
|
|
* 0x=hex, 0=octal, isdigit=decimal.
|
|
|
|
*/
|
|
|
|
if (!isdigit(c))
|
|
|
|
return (0);
|
|
|
|
val = 0; base = 10; digit = 0;
|
|
|
|
if (c == '0') {
|
|
|
|
c = *++cp;
|
|
|
|
if (c == 'x' || c == 'X')
|
|
|
|
base = 16, c = *++cp;
|
|
|
|
else {
|
|
|
|
base = 8;
|
|
|
|
digit = 1 ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (;;) {
|
|
|
|
if (isascii(c) && isdigit(c)) {
|
|
|
|
if (base == 8 && (c == '8' || c == '9'))
|
|
|
|
return (0);
|
|
|
|
val = (val * base) + (c - '0');
|
|
|
|
c = *++cp;
|
|
|
|
digit = 1;
|
|
|
|
} else if (base == 16 && isascii(c) && isxdigit(c)) {
|
|
|
|
val = (val << 4) |
|
|
|
|
(c + 10 - (islower(c) ? 'a' : 'A'));
|
|
|
|
c = *++cp;
|
|
|
|
digit = 1;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (c == '.') {
|
|
|
|
/*
|
|
|
|
* Internet format:
|
|
|
|
* a.b.c.d
|
|
|
|
* a.b.c (with c treated as 16 bits)
|
|
|
|
* a.b (with b treated as 24 bits)
|
|
|
|
*/
|
|
|
|
if (pp >= parts + 3 || val > 0xff)
|
|
|
|
return (0);
|
|
|
|
*pp++ = val;
|
|
|
|
c = *++cp;
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Check for trailing characters.
|
|
|
|
*/
|
|
|
|
if (c != '\0' && (!isascii(c) || !isspace(c)))
|
|
|
|
return (0);
|
|
|
|
/*
|
|
|
|
* Did we get a valid digit?
|
|
|
|
*/
|
|
|
|
if (!digit)
|
|
|
|
return (0);
|
|
|
|
/*
|
|
|
|
* Concoct the address according to
|
|
|
|
* the number of parts specified.
|
|
|
|
*/
|
|
|
|
n = pp - parts + 1;
|
|
|
|
switch (n) {
|
|
|
|
case 1: /* a -- 32 bits */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2: /* a.b -- 8.24 bits */
|
|
|
|
if (val > 0xffffff)
|
|
|
|
return (0);
|
|
|
|
val |= parts[0] << 24;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3: /* a.b.c -- 8.8.16 bits */
|
|
|
|
if (val > 0xffff)
|
|
|
|
return (0);
|
|
|
|
val |= (parts[0] << 24) | (parts[1] << 16);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
|
|
|
if (val > 0xff)
|
|
|
|
return (0);
|
|
|
|
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (addr != NULL)
|
|
|
|
addr->s_addr = htonl(val);
|
|
|
|
return (1);
|
|
|
|
}
|