summaryrefslogtreecommitdiff
path: root/agent/mibgroup/host/data_access/swrun_cygwin.c
diff options
context:
space:
mode:
Diffstat (limited to 'agent/mibgroup/host/data_access/swrun_cygwin.c')
-rw-r--r--agent/mibgroup/host/data_access/swrun_cygwin.c279
1 files changed, 279 insertions, 0 deletions
diff --git a/agent/mibgroup/host/data_access/swrun_cygwin.c b/agent/mibgroup/host/data_access/swrun_cygwin.c
new file mode 100644
index 0000000..ca5194d
--- /dev/null
+++ b/agent/mibgroup/host/data_access/swrun_cygwin.c
@@ -0,0 +1,279 @@
+/*
+ * swrun_cygwin.c:
+ * hrSWRunTable data access:
+ * Cygwin interface
+ */
+#include <net-snmp/net-snmp-config.h>
+
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <windows.h>
+#include <sys/cygwin.h>
+#include <tlhelp32.h>
+#include <psapi.h>
+
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include <net-snmp/library/container.h>
+#include <net-snmp/library/snmp_debug.h>
+#include <net-snmp/data_access/swrun.h>
+#include <net-snmp/data_access/swrun.h>
+
+/*
+ * a lot of this is "stolen" from cygwin ps.cc
+ */
+
+typedef BOOL(WINAPI * ENUMPROCESSMODULES) (HANDLE hProcess,
+ HMODULE * lphModule,
+ DWORD cb,
+ LPDWORD lpcbNeeded);
+
+typedef DWORD(WINAPI * GETMODULEFILENAME) (HANDLE hProcess,
+ HMODULE hModule,
+ LPTSTR lpstrFIleName,
+ DWORD nSize);
+
+typedef DWORD(WINAPI * GETPROCESSMEMORYINFO) (HANDLE hProcess,
+ PPROCESS_MEMORY_COUNTERS
+ pmc, DWORD nSize);
+
+typedef HANDLE(WINAPI * CREATESNAPSHOT) (DWORD dwFlags,
+ DWORD th32ProcessID);
+
+typedef BOOL(WINAPI * PROCESSWALK) (HANDLE hSnapshot,
+ LPPROCESSENTRY32 lppe);
+
+ENUMPROCESSMODULES myEnumProcessModules;
+GETMODULEFILENAME myGetModuleFileNameEx;
+CREATESNAPSHOT myCreateToolhelp32Snapshot;
+PROCESSWALK myProcess32First;
+PROCESSWALK myProcess32Next;
+GETPROCESSMEMORYINFO myGetProcessMemoryInfo = NULL;
+cygwin_getinfo_types query = CW_GETPINFO;
+
+static BOOL WINAPI
+dummyprocessmodules(HANDLE hProcess,
+ HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded)
+{
+ lphModule[0] = (HMODULE) * lpcbNeeded;
+ *lpcbNeeded = 1;
+ return 1;
+}
+
+static DWORD WINAPI
+GetModuleFileNameEx95(HANDLE hProcess,
+ HMODULE hModule, LPTSTR lpstrFileName, DWORD n)
+{
+ HANDLE h;
+ DWORD pid = (DWORD) hModule;
+ PROCESSENTRY32 proc;
+
+ h = myCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
+ if (!h)
+ return 0;
+ proc.dwSize = sizeof(proc);
+ if (myProcess32First(h, &proc))
+ do
+ if (proc.th32ProcessID == pid) {
+ CloseHandle(h);
+ strcpy(lpstrFileName, proc.szExeFile);
+ return 1;
+ }
+ while (myProcess32Next(h, &proc));
+ CloseHandle(h);
+ return 0;
+}
+
+#define FACTOR (0x19db1ded53ea710LL)
+#define NSPERSEC 10000000LL
+#define NSPERMSEC 10000LL
+
+static time_t __stdcall
+to_time_t(PFILETIME ptr)
+{
+ long rem;
+ long long x =
+ ((long long) ptr->dwHighDateTime << 32) +
+ ((unsigned) ptr->dwLowDateTime);
+ x -= FACTOR;
+ rem = x % NSPERSEC;
+ rem += NSPERSEC / 2;
+ x /= NSPERSEC;
+ x += rem / NSPERSEC;
+ return x;
+}
+
+static long
+to_msec(PFILETIME ptr)
+{
+ long long x =
+ ((long long) ptr->dwHighDateTime << 32) +
+ (unsigned) ptr->dwLowDateTime;
+ x /= NSPERMSEC;
+ return x;
+}
+
+OSVERSIONINFO ver;
+HMODULE h;
+
+/* ---------------------------------------------------------------------
+ */
+void
+netsnmp_arch_swrun_init(void)
+{
+ memset(&ver, 0, sizeof ver);
+ ver.dwOSVersionInfoSize = sizeof ver;
+ GetVersionEx(&ver);
+
+ if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
+ h = LoadLibrary("psapi.dll");
+ if (h) {
+ myEnumProcessModules = (ENUMPROCESSMODULES)
+ GetProcAddress(h, "EnumProcessModules");
+ myGetModuleFileNameEx = (GETMODULEFILENAME)
+ GetProcAddress(h, "GetModuleFileNameExA");
+ myGetProcessMemoryInfo = (GETPROCESSMEMORYINFO)
+ GetProcAddress(h, "GetProcessMemoryInfo");
+ if (myEnumProcessModules && myGetModuleFileNameEx)
+ query = CW_GETPINFO_FULL;
+ else
+ snmp_log(LOG_ERR, "hr_swrun failed NT init\n");
+ } else
+ snmp_log(LOG_ERR, "hr_swrun failed to load psapi.dll\n");
+ } else {
+ h = GetModuleHandle("KERNEL32.DLL");
+ myCreateToolhelp32Snapshot = (CREATESNAPSHOT)
+ GetProcAddress(h, "CreateToolhelp32Snapshot");
+ myProcess32First = (PROCESSWALK) GetProcAddress(h, "Process32First");
+ myProcess32Next = (PROCESSWALK) GetProcAddress(h, "Process32Next");
+ myEnumProcessModules = dummyprocessmodules;
+ myGetModuleFileNameEx = GetModuleFileNameEx95;
+ if (myCreateToolhelp32Snapshot && myProcess32First
+ && myProcess32Next)
+#if 0
+ /*
+ * This doesn't work after all on Win98 SE
+ */
+ query = CW_GETPINFO_FULL;
+#else
+ query = CW_GETPINFO;
+#endif
+ else
+ snmp_log(LOG_ERR, "hr_swrun failed non-NT init\n");
+ }
+ return;
+}
+
+/* ---------------------------------------------------------------------
+ */
+int
+netsnmp_arch_swrun_container_load( netsnmp_container *container, u_int flags)
+{
+ struct external_pinfo *curproc;
+ pid_t curpid = 0;
+ DWORD n;
+ HANDLE h;
+ FILETIME ct, et, kt, ut;
+ PROCESS_MEMORY_COUNTERS pmc;
+ char *cp1, *cp2;
+ netsnmp_swrun_entry *entry;
+
+ cygwin_internal(CW_LOCK_PINFO, 1000);
+ while (curproc = (struct external_pinfo *)
+ cygwin_internal(query, curpid | CW_NEXTPID)) {
+
+ curpid = curproc->pid;
+ if (( PID_EXITED & curproc.process_state ) ||
+ ( ~0xffff & curproc.exitcode ))
+ continue;
+ entry = netsnmp_swrun_entry_create(curpid);
+ if (NULL == entry)
+ continue; /* error already logged by function */
+ rc = CONTAINER_INSERT(container, entry);
+
+
+ n = lowproc.dwProcessId & 0xffff;
+ h = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, n);
+
+ if (curproc.ppid) {
+ entry->hrSWRunPath_len = snprintf(entry->hrSWRunPath,
+ sizeof(entry->hrSWRunPath)-1, "%s",
+ cygwin_conv_to_posix_path(curproc.progname));
+ } else if (query == CW_GETPINFO_FULL) {
+
+ if (h) {
+ HMODULE hm[1000];
+ if (!myEnumProcessModules(h, hm, sizeof hm, &n))
+ n = 0;
+ if (n && myGetModuleFileNameEx(h, hm[0], string,
+ sizeof string)) {
+ entry->hrSWRunPath_len = snprintf(entry->hrSWRunPath,
+ sizeof(entry->hrSWRunPath)-1,
+ "%s", string );
+ }
+ }
+ }
+ /*
+ * Set hrSWRunName to be the last component of hrSWRunPath,
+ * but without any file extension
+ */
+ if ( entry->hrSWRunPath_len ) {
+ cp1 = strrchr( entry->hrSWRunPath, '.' );
+ if ( cp1 )
+ *cp1 = '\0'; /* Mask the file extension */
+
+ cp2 = strrchr( entry->hrSWRunPath, '/' );
+ if (cp2)
+ cp2++; /* Find the final component ... */
+ else
+ cp2 = entry->hrSWRunPath; /* ... if any */
+ entry->hrSWRunName_len = snprintf(entry->hrSWRunName,
+ sizeof(entry->hrSWRunName)-1, "%s", cp2);
+
+ if ( cp1 )
+ *cp1 = '.'; /* Restore the file extension */
+ }
+
+ /*
+ * XXX - No information regarding process arguments
+ * XXX - No information regarding system processes vs applications
+ */
+
+ if (PID_STOPPED & curproc.process_state ) {
+ entry->hrSWRunStatus = HRSWRUNSTATUS_NOTRUNNABLE;
+ }
+ /* else if (PID_ZOMBIE & curproc.process_state ) */
+ else if ( ~0xffff & curproc.exitcode )
+ {
+ entry->hrSWRunStatus = HRSWRUNSTATUS_INVALID;
+ } else {
+ /* entry->hrSWRunStatus = HRSWRUNSTATUS_RUNNABLE; ?? */
+ entry->hrSWRunStatus = HRSWRUNSTATUS_RUNNING;
+ }
+
+ if (h) {
+ if (GetProcessTimes(h, &ct, &et, &kt, &ut))
+ entry->hrSWRunPerfCPU = (to_msec(&kt) + to_msec(&ut)) / 10;
+ if (myGetProcessMemoryInfo
+ && myGetProcessMemoryInfo(h, &pmc, sizeof pmc))
+ entry->hrSWRunPerfMem = pmc.WorkingSetSize / 1024;
+
+ CloseHandle(h);
+ }
+ }
+ cygwin_internal(CW_UNLOCK_PINFO);
+
+ DEBUGMSGTL(("swrun:load:arch"," loaded %d entries\n",
+ CONTAINER_SIZE(container)));
+
+ return 0;
+}