refactor interaction with windows dlls

This commit is contained in:
Doug MacEachern 2005-12-20 23:09:34 +00:00
parent c2b8921196
commit 0d2a149924
3 changed files with 495 additions and 341 deletions

View File

@ -1192,27 +1192,8 @@ JNIEXPORT void SIGAR_JNI(SigarLog_setLevel)
* in the future would better to integrate win32bindings w/ sigar. * in the future would better to integrate win32bindings w/ sigar.
*/ */
#ifdef WIN32 #ifdef WIN32
typedef struct _SERVICE_STATUS_PROCESS { #define sigar_QueryServiceStatusEx \
DWORD dwServiceType; sigar->advapi.query_service_status.func
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
DWORD dwProcessId;
DWORD dwServiceFlags;
} SERVICE_STATUS_PROCESS;
typedef enum {
SC_STATUS_PROCESS_INFO = 0
} SC_STATUS_TYPE;
typedef BOOL (CALLBACK *QueryServiceStatusExFunc)(SC_HANDLE,
SC_STATUS_TYPE,
LPBYTE,
DWORD,
LPDWORD);
#endif #endif
JNIEXPORT jlong SIGAR_JNI(Sigar_getServicePid) JNIEXPORT jlong SIGAR_JNI(Sigar_getServicePid)
@ -1226,8 +1207,9 @@ JNIEXPORT jlong SIGAR_JNI(Sigar_getServicePid)
SC_HANDLE mgr; SC_HANDLE mgr;
dSIGAR(0); dSIGAR(0);
if (!sigar->adv_handle) { if (!sigar_QueryServiceStatusEx) {
sigar_throw_notimpl(env, "advapi32.dll not available"); sigar_throw_notimpl(env,
"QueryServiceStatusEx not available");
return 0; return 0;
} }
@ -1242,17 +1224,11 @@ JNIEXPORT jlong SIGAR_JNI(Sigar_getServicePid)
if (svc) { if (svc) {
SERVICE_STATUS_PROCESS status; SERVICE_STATUS_PROCESS status;
DWORD bytes; DWORD bytes;
QueryServiceStatusExFunc status_query =
(QueryServiceStatusExFunc)
GetProcAddress(sigar->adv_handle,
"QueryServiceStatusEx");
if (!status_query) { if (sigar_QueryServiceStatusEx(svc,
err = SIGAR_ENOTIMPL; SC_STATUS_PROCESS_INFO,
} (LPBYTE)&status,
else if (status_query(svc, sizeof(status), &bytes))
SC_STATUS_PROCESS_INFO,
(LPBYTE)&status, sizeof(status), &bytes))
{ {
pid = status.dwProcessId; pid = status.dwProcessId;
} }

View File

@ -97,6 +97,23 @@ typedef struct _IP_ADAPTER_INFO {
/* end iptypes.h */ /* end iptypes.h */
/* service manager stuff not in vs6.0 */
typedef struct _SERVICE_STATUS_PROCESS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
DWORD dwProcessId;
DWORD dwServiceFlags;
} SERVICE_STATUS_PROCESS;
typedef enum {
SC_STATUS_PROCESS_INFO = 0
} SC_STATUS_TYPE;
/* from wtsapi32.h not in vs6.0 */ /* from wtsapi32.h not in vs6.0 */
typedef enum { typedef enum {
WTSInitialProgram, WTSInitialProgram,
@ -205,54 +222,6 @@ typedef struct {
/* end undocumented structures */ /* end undocumented structures */
typedef BOOL (CALLBACK *LPCONVERTSTRINGSID)(LPCSTR, PSID *);
typedef DWORD (CALLBACK *LPGETIPFORWARDTABLE)(PMIB_IPFORWARDTABLE, PULONG, BOOL);
typedef DWORD (CALLBACK *LPGETIFTABLE)(PMIB_IFTABLE, PULONG, BOOL);
typedef DWORD (CALLBACK *LPGETIFENTRY)(PMIB_IFROW);
typedef DWORD (CALLBACK *LPGETTCPTABLE)(PMIB_TCPTABLE, PDWORD, BOOL);
typedef DWORD (CALLBACK *LPGETUDPTABLE)(PMIB_UDPTABLE, PDWORD, BOOL);
typedef DWORD (CALLBACK *LPGETTCPEXTABLE)(PMIB_TCPEXTABLE *, BOOL, HANDLE,
DWORD, DWORD);
typedef DWORD (CALLBACK *LPGETUDPEXTABLE)(PMIB_UDPEXTABLE *, BOOL, HANDLE,
DWORD, DWORD);
typedef DWORD (CALLBACK *LPNETPARAMS)(PFIXED_INFO, PULONG);
typedef DWORD (CALLBACK *LPADAPTERSINFO)(PIP_ADAPTER_INFO, PULONG);
typedef DWORD (CALLBACK *LPSYSINFO)(DWORD, PVOID, ULONG, PULONG);
typedef BOOL (CALLBACK *LPENUMMODULES)(HANDLE, HMODULE*,
DWORD, LPDWORD);
typedef DWORD (CALLBACK *LPGETMODULENAME)(HANDLE, HMODULE,
LPTSTR, DWORD);
typedef BOOLEAN (CALLBACK *LPSTATIONQUERYINFO)(HANDLE,
ULONG,
WINSTATION_INFO_CLASS,
PVOID, ULONG, PULONG);
typedef BOOL (CALLBACK *LPWTSENUMERATESESSIONS)(HANDLE,
DWORD,
DWORD,
PWTS_SESSION_INFO *,
DWORD *);
typedef void (CALLBACK *LPWTSFREEMEMORY)(PVOID);
typedef BOOL (CALLBACK *LPWTSQUERYSESSION)(HANDLE,
DWORD,
WTS_INFO_CLASS,
LPSTR *, DWORD *);
/* no longer in the standard header files */ /* no longer in the standard header files */
typedef struct { typedef struct {
LARGE_INTEGER IdleTime; LARGE_INTEGER IdleTime;
@ -279,6 +248,174 @@ typedef struct {
sigar_uint64_t page_faults; sigar_uint64_t page_faults;
} sigar_win32_pinfo_t; } sigar_win32_pinfo_t;
typedef struct {
const char *name;
HINSTANCE handle;
} sigar_dll_handle_t;
typedef struct {
const char *name;
FARPROC func;
} sigar_dll_func_t;
typedef struct {
const char *name;
HINSTANCE handle;
sigar_dll_func_t funcs[12];
} sigar_dll_module_t;
/* wtsapi.dll */
typedef BOOL (CALLBACK *wtsapi_enum_sessions)(HANDLE,
DWORD,
DWORD,
PWTS_SESSION_INFO *,
DWORD *);
typedef void (CALLBACK *wtsapi_free_mem)(PVOID);
typedef BOOL (CALLBACK *wtsapi_query_session)(HANDLE,
DWORD,
WTS_INFO_CLASS,
LPSTR *, DWORD *);
/* iphlpapi.dll */
typedef DWORD (CALLBACK *iphlpapi_get_ipforward_table)(PMIB_IPFORWARDTABLE,
PULONG,
BOOL);
typedef DWORD (CALLBACK *iphlpapi_get_if_table)(PMIB_IFTABLE,
PULONG,
BOOL);
typedef DWORD (CALLBACK *iphlpapi_get_if_entry)(PMIB_IFROW);
typedef DWORD (CALLBACK *iphlpapi_get_tcp_table)(PMIB_TCPTABLE,
PDWORD,
BOOL);
typedef DWORD (CALLBACK *iphlpapi_get_udp_table)(PMIB_UDPTABLE,
PDWORD,
BOOL);
typedef DWORD (CALLBACK *iphlpapi_get_tcpx_table)(PMIB_TCPEXTABLE *,
BOOL,
HANDLE,
DWORD,
DWORD);
typedef DWORD (CALLBACK *iphlpapi_get_udpx_table)(PMIB_UDPEXTABLE *,
BOOL,
HANDLE,
DWORD,
DWORD);
typedef DWORD (CALLBACK *iphlpapi_get_net_params)(PFIXED_INFO,
PULONG);
typedef DWORD (CALLBACK *iphlpapi_get_adapters_info)(PIP_ADAPTER_INFO,
PULONG);
/* advapi32.dll */
typedef BOOL (CALLBACK *advapi_convert_string_sid)(LPCSTR,
PSID *);
typedef BOOL (CALLBACK *advapi_query_service_status)(SC_HANDLE,
SC_STATUS_TYPE,
LPBYTE,
DWORD,
LPDWORD);
/* ntdll.dll */
typedef DWORD (CALLBACK *ntdll_query_sys_info)(DWORD,
PVOID,
ULONG,
PULONG);
/* psapi.dll */
typedef BOOL (CALLBACK *psapi_enum_modules)(HANDLE,
HMODULE *,
DWORD,
LPDWORD);
typedef DWORD (CALLBACK *psapi_get_module_name)(HANDLE,
HMODULE,
LPTSTR,
DWORD);
/* winsta.dll */
typedef BOOLEAN (CALLBACK *winsta_query_info)(HANDLE,
ULONG,
WINSTATION_INFO_CLASS,
PVOID,
ULONG,
PULONG);
#define SIGAR_DLLFUNC(api, name) \
struct { \
const char *name; \
##api##_##name func; \
} ##name
typedef struct {
sigar_dll_handle_t handle;
SIGAR_DLLFUNC(wtsapi, enum_sessions);
SIGAR_DLLFUNC(wtsapi, free_mem);
SIGAR_DLLFUNC(wtsapi, query_session);
sigar_dll_func_t end;
} sigar_wtsapi_t;
typedef struct {
sigar_dll_handle_t handle;
SIGAR_DLLFUNC(iphlpapi, get_ipforward_table);
SIGAR_DLLFUNC(iphlpapi, get_if_table);
SIGAR_DLLFUNC(iphlpapi, get_if_entry);
SIGAR_DLLFUNC(iphlpapi, get_tcp_table);
SIGAR_DLLFUNC(iphlpapi, get_udp_table);
SIGAR_DLLFUNC(iphlpapi, get_tcpx_table);
SIGAR_DLLFUNC(iphlpapi, get_udpx_table);
SIGAR_DLLFUNC(iphlpapi, get_net_params);
SIGAR_DLLFUNC(iphlpapi, get_adapters_info);
sigar_dll_func_t end;
} sigar_iphlpapi_t;
typedef struct {
sigar_dll_handle_t handle;
SIGAR_DLLFUNC(advapi, convert_string_sid);
SIGAR_DLLFUNC(advapi, query_service_status);
sigar_dll_func_t end;
} sigar_advapi_t;
typedef struct {
sigar_dll_handle_t handle;
SIGAR_DLLFUNC(ntdll, query_sys_info);
sigar_dll_func_t end;
} sigar_ntdll_t;
typedef struct {
sigar_dll_handle_t handle;
SIGAR_DLLFUNC(psapi, enum_modules);
SIGAR_DLLFUNC(psapi, get_module_name);
sigar_dll_func_t end;
} sigar_psapi_t;
typedef struct {
sigar_dll_handle_t handle;
SIGAR_DLLFUNC(winsta, query_info);
sigar_dll_func_t end;
} sigar_winsta_t;
struct sigar_t { struct sigar_t {
SIGAR_T_BASE; SIGAR_T_BASE;
char *machine; char *machine;
@ -287,30 +424,13 @@ struct sigar_t {
HKEY handle; HKEY handle;
char *perfbuf; char *perfbuf;
DWORD perfbuf_size; DWORD perfbuf_size;
HINSTANCE adv_handle; sigar_wtsapi_t wtsapi;
HINSTANCE ip_handle; sigar_iphlpapi_t iphlpapi;
HINSTANCE nt_handle; sigar_advapi_t advapi;
HINSTANCE ps_handle; sigar_ntdll_t ntdll;
HINSTANCE wts_handle; sigar_psapi_t psapi;
HINSTANCE sta_handle; sigar_winsta_t winsta;
LPCONVERTSTRINGSID convert_string_sid;
LPGETIFTABLE get_if_table;
LPGETIFENTRY get_if_entry;
LPGETIPFORWARDTABLE get_ipforward_table;
LPGETTCPTABLE get_tcp_table;
LPGETTCPEXTABLE get_tcpx_table;
LPGETUDPTABLE get_udp_table;
LPGETUDPEXTABLE get_udpx_table;
LPNETPARAMS get_net_params;
LPADAPTERSINFO get_adapters_info;
LPSYSINFO get_ntsys_info;
LPENUMMODULES enum_modules;
LPGETMODULENAME get_module_name;
sigar_win32_pinfo_t pinfo; sigar_win32_pinfo_t pinfo;
LPSTATIONQUERYINFO query_station;
LPWTSENUMERATESESSIONS wts_enum_sessions;
LPWTSFREEMEMORY wts_free;
LPWTSQUERYSESSION wts_query_session;
WORD ws_version; WORD ws_version;
int ws_error; int ws_error;
LPBYTE peb; //scratch pad for getting peb info LPBYTE peb; //scratch pad for getting peb info

View File

@ -94,27 +94,6 @@ typedef enum {
#define PERF_VAL_CPU(ix) \ #define PERF_VAL_CPU(ix) \
NS100_2SEC(PERF_VAL(ix)) NS100_2SEC(PERF_VAL(ix))
static FARPROC sigar_GetProcAddress(sigar_t *sigar,
HMODULE hModule, LPCSTR lpProcName)
{
FARPROC ptr;
if (!hModule) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"GetProcAddress(%s): No module handle",
lpProcName);
return NULL;
}
if (!(ptr = GetProcAddress(hModule, lpProcName))) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"GetProcAddress(%s): %s",
lpProcName, sigar_strerror(sigar, GetLastError()));
}
return ptr;
}
static PERF_OBJECT_TYPE *get_perf_object(sigar_t *sigar, char *counter_key, static PERF_OBJECT_TYPE *get_perf_object(sigar_t *sigar, char *counter_key,
DWORD *err) DWORD *err)
{ {
@ -192,11 +171,145 @@ SIGAR_DECLARE(sigar_t *) sigar_new(void)
return sigar; return sigar;
} }
static sigar_wtsapi_t sigar_wtsapi = {
"wtsapi32.dll",
NULL,
{ "WTSEnumerateSessionsA", NULL },
{ "WTSFreeMemory", NULL },
{ "WTSQuerySessionInformationA", NULL },
{ NULL, NULL }
};
static sigar_iphlpapi_t sigar_iphlpapi = {
"iphlpapi.dll",
NULL,
{ "GetIpForwardTable", NULL },
{ "GetIfTable", NULL },
{ "GetIfEntry", NULL },
{ "GetTcpTable", NULL },
{ "GetUdpTable", NULL },
{ "AllocateAndGetTcpExTableFromStack", NULL },
{ "AllocateAndGetUdpExTableFromStack", NULL },
{ "GetNetworkParams", NULL },
{ "GetAdaptersInfo", NULL },
{ NULL, NULL }
};
static sigar_advapi_t sigar_advapi = {
"advapi32.dll",
NULL,
{ "ConvertStringSidToSidA", NULL },
{ "QueryServiceStatusEx", NULL },
{ NULL, NULL }
};
static sigar_ntdll_t sigar_ntdll = {
"ntdll.dll",
NULL,
{ "NtQuerySystemInformation", NULL },
{ NULL, NULL }
};
static sigar_psapi_t sigar_psapi = {
"psapi.dll",
NULL,
{ "EnumProcessModules", NULL },
{ "GetModuleFileNameExA", NULL },
{ NULL, NULL }
};
static sigar_psapi_t sigar_winsta = {
"winsta.dll",
NULL,
{ "WinStationQueryInformationW", NULL },
{ NULL, NULL }
};
#define DLLMOD_COPY(name) \
memcpy(&(*sigar)->##name, &sigar_##name, sizeof(sigar_##name))
#define DLLMOD_INIT(name, all) \
sigar_dllmod_init(sigar, (sigar_dll_module_t *)&(sigar->##name), all)
#define DLLMOD_FREE(name) \
sigar_dllmod_free((sigar_dll_module_t *)&(sigar->##name))
static void sigar_dllmod_free(sigar_dll_module_t *module)
{
if (module->handle) {
FreeLibrary(module->handle);
module->handle = NULL;
}
}
static int sigar_dllmod_init(sigar_t *sigar,
sigar_dll_module_t *module,
int all)
{
sigar_dll_func_t *funcs = &module->funcs[0];
int is_debug = SIGAR_LOG_IS_DEBUG(sigar);
int rc, success;
if (module->handle == INVALID_HANDLE_VALUE) {
return ENOENT; /* XXX better rc */
}
if (module->handle) {
return SIGAR_OK;
}
module->handle = LoadLibrary(module->name);
if (!(success = (module->handle ? TRUE : FALSE))) {
rc = GetLastError();
/* dont try again */
module->handle = INVALID_HANDLE_VALUE;
}
if (is_debug) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"LoadLibrary(%s): %s",
module->name,
success ?
"OK" :
sigar_strerror(sigar, rc));
}
if (!success) {
return rc;
}
while (funcs->name) {
funcs->func = GetProcAddress(module->handle, funcs->name);
if (!(success = (funcs->func ? TRUE : FALSE))) {
rc = GetLastError();
}
if (is_debug) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
"GetProcAddress(%s:%s): %s",
module->name, funcs->name,
success ?
"OK" :
sigar_strerror(sigar, rc));
}
if (all && !success) {
return rc;
}
funcs++;
}
return SIGAR_OK;
}
int sigar_os_open(sigar_t **sigar) int sigar_os_open(sigar_t **sigar)
{ {
LONG result; LONG result;
HINSTANCE h; HINSTANCE h;
OSVERSIONINFO version; OSVERSIONINFO version;
int i;
*sigar = malloc(sizeof(**sigar)); *sigar = malloc(sizeof(**sigar));
(*sigar)->machine = ""; /* local machine */ (*sigar)->machine = ""; /* local machine */
@ -231,88 +344,18 @@ int sigar_os_open(sigar_t **sigar)
get_sysinfo(*sigar); get_sysinfo(*sigar);
if ((h = LoadLibrary("iphlpapi.dll"))) { DLLMOD_COPY(wtsapi);
(*sigar)->get_if_entry = DLLMOD_COPY(iphlpapi);
(LPGETIFENTRY)GetProcAddress(h, "GetIfEntry"); DLLMOD_COPY(advapi);
(*sigar)->get_if_table = DLLMOD_COPY(ntdll);
(LPGETIFTABLE)GetProcAddress(h, "GetIfTable"); DLLMOD_COPY(psapi);
(*sigar)->get_ipforward_table = DLLMOD_COPY(winsta);
(LPGETIPFORWARDTABLE)GetProcAddress(h, "GetIpForwardTable");
(*sigar)->get_tcp_table =
(LPGETTCPTABLE)GetProcAddress(h, "GetTcpTable");
(*sigar)->get_tcpx_table =
(LPGETTCPEXTABLE)GetProcAddress(h,
"AllocateAndGet"
"TcpExTableFromStack");
(*sigar)->get_udp_table =
(LPGETUDPTABLE)GetProcAddress(h, "GetUdpTable");
(*sigar)->get_udpx_table =
(LPGETUDPEXTABLE)GetProcAddress(h,
"AllocateAndGet"
"UdpExTableFromStack");
(*sigar)->get_net_params =
(LPNETPARAMS)GetProcAddress(h, "GetNetworkParams");
(*sigar)->get_adapters_info =
(LPADAPTERSINFO)GetProcAddress(h, "GetAdaptersInfo");
(*sigar)->ip_handle = h;
}
else {
(*sigar)->get_if_entry = NULL;
(*sigar)->get_if_table = NULL;
(*sigar)->get_ipforward_table = NULL;
(*sigar)->ip_handle = NULL;
}
if ((h = LoadLibrary("advapi32.dll"))) { (*sigar)->log_level = -1; /* else below segfaults */
(*sigar)->convert_string_sid = /* XXX init early for use by javasigar.c */
(LPCONVERTSTRINGSID)GetProcAddress(h, sigar_dllmod_init(*sigar,
"ConvertStringSidToSidA"); (sigar_dll_module_t *)&(*sigar)->advapi,
(*sigar)->adv_handle = h; FALSE);
}
else {
(*sigar)->adv_handle = NULL;
(*sigar)->convert_string_sid = NULL;
}
if ((h = LoadLibrary("Ntdll.dll"))) {
(*sigar)->get_ntsys_info =
(LPSYSINFO)GetProcAddress(h, "NtQuerySystemInformation");
(*sigar)->nt_handle = h;
}
else {
(*sigar)->get_ntsys_info = NULL;
(*sigar)->nt_handle = NULL;
}
if ((h = LoadLibrary("psapi.dll"))) {
(*sigar)->enum_modules =
(LPENUMMODULES)GetProcAddress(h, "EnumProcessModules");
(*sigar)->get_module_name =
(LPGETMODULENAME)GetProcAddress(h, "GetModuleFileNameExA");
(*sigar)->ps_handle = h;
}
else {
(*sigar)->ps_handle = NULL;
}
(*sigar)->wts_enum_sessions = NULL;
(*sigar)->wts_free = NULL;
(*sigar)->wts_query_session = NULL;
(*sigar)->query_station = NULL;
if ((h = LoadLibrary("wtsapi32.dll"))) {
(*sigar)->wts_handle = h;
}
else {
(*sigar)->wts_handle = NULL;
}
if ((h = LoadLibrary("winsta.dll"))) {
(*sigar)->sta_handle = h;
}
else {
(*sigar)->sta_handle = NULL;
}
(*sigar)->pinfo.pid = -1; (*sigar)->pinfo.pid = -1;
(*sigar)->ws_version = 0; (*sigar)->ws_version = 0;
@ -326,36 +369,19 @@ int sigar_os_close(sigar_t *sigar)
{ {
int retval; int retval;
DLLMOD_FREE(wtsapi);
DLLMOD_FREE(iphlpapi);
DLLMOD_FREE(advapi);
DLLMOD_FREE(ntdll);
DLLMOD_FREE(psapi);
DLLMOD_FREE(winsta);
if (sigar->perfbuf) { if (sigar->perfbuf) {
free(sigar->perfbuf); free(sigar->perfbuf);
} }
retval = RegCloseKey(sigar->handle); retval = RegCloseKey(sigar->handle);
if (sigar->adv_handle) {
FreeLibrary(sigar->adv_handle);
}
if (sigar->ip_handle) {
FreeLibrary(sigar->ip_handle);
}
if (sigar->nt_handle) {
FreeLibrary(sigar->nt_handle);
}
if (sigar->ps_handle) {
FreeLibrary(sigar->ps_handle);
}
if (sigar->wts_handle) {
FreeLibrary(sigar->wts_handle);
}
if (sigar->sta_handle) {
FreeLibrary(sigar->sta_handle);
}
if (sigar->ws_version != 0) { if (sigar->ws_version != 0) {
WSACleanup(); WSACleanup();
} }
@ -450,6 +476,9 @@ static PERF_INSTANCE_DEFINITION *get_cpu_instance(sigar_t *sigar,
return PdhFirstInstance(object); return PdhFirstInstance(object);
} }
#define sigar_NtQuerySystemInformation \
sigar->ntdll.query_sys_info.func
static int get_idle_cpu(sigar_t *sigar, sigar_cpu_t *cpu, static int get_idle_cpu(sigar_t *sigar, sigar_cpu_t *cpu,
DWORD idx, DWORD idx,
PERF_COUNTER_BLOCK *counter_block, PERF_COUNTER_BLOCK *counter_block,
@ -463,13 +492,14 @@ static int get_idle_cpu(sigar_t *sigar, sigar_cpu_t *cpu,
else { else {
/* windows NT and 2000 do not have an Idle counter */ /* windows NT and 2000 do not have an Idle counter */
sigar_cpu_count(sigar); sigar_cpu_count(sigar);
if (sigar->get_ntsys_info) { DLLMOD_INIT(ntdll, FALSE);
if (sigar_NtQuerySystemInformation) {
DWORD retval, num; DWORD retval, num;
/* XXX unhardcode 16 */ /* XXX unhardcode 16 */
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[16]; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[16];
/* into the lungs of hell */ /* into the lungs of hell */
sigar->get_ntsys_info(SystemProcessorPerformanceInformation, sigar_NtQuerySystemInformation(SystemProcessorPerformanceInformation,
&info, sizeof(info), &retval); &info, sizeof(info), &retval);
if (!retval) { if (!retval) {
return GetLastError(); return GetLastError();
@ -539,8 +569,8 @@ static int sigar_cpu_ntsys_get(sigar_t *sigar, sigar_cpu_t *cpu)
/* XXX unhardcode 16 */ /* XXX unhardcode 16 */
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[16]; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[16];
/* into the lungs of hell */ /* into the lungs of hell */
sigar->get_ntsys_info(SystemProcessorPerformanceInformation, sigar_NtQuerySystemInformation(SystemProcessorPerformanceInformation,
&info, sizeof(info), &retval); &info, sizeof(info), &retval);
if (!retval) { if (!retval) {
return GetLastError(); return GetLastError();
@ -561,7 +591,8 @@ static int sigar_cpu_ntsys_get(sigar_t *sigar, sigar_cpu_t *cpu)
SIGAR_DECLARE(int) sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu) SIGAR_DECLARE(int) sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
{ {
if (sigar->get_ntsys_info) { DLLMOD_INIT(ntdll, FALSE);
if (sigar_NtQuerySystemInformation) {
return sigar_cpu_ntsys_get(sigar, cpu); return sigar_cpu_ntsys_get(sigar, cpu);
} }
else { else {
@ -642,7 +673,7 @@ static int sigar_cpu_list_ntsys_get(sigar_t *sigar,
/* XXX unhardcode 16 */ /* XXX unhardcode 16 */
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[16]; SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION info[16];
/* into the lungs of hell */ /* into the lungs of hell */
sigar->get_ntsys_info(SystemProcessorPerformanceInformation, sigar_NtQuerySystemInformation(SystemProcessorPerformanceInformation,
&info, sizeof(info), &retval); &info, sizeof(info), &retval);
if (!retval) { if (!retval) {
@ -694,7 +725,8 @@ static int sigar_cpu_list_ntsys_get(sigar_t *sigar,
SIGAR_DECLARE(int) sigar_cpu_list_get(sigar_t *sigar, SIGAR_DECLARE(int) sigar_cpu_list_get(sigar_t *sigar,
sigar_cpu_list_t *cpulist) sigar_cpu_list_t *cpulist)
{ {
if (sigar->get_ntsys_info) { DLLMOD_INIT(ntdll, FALSE);
if (sigar_NtQuerySystemInformation) {
return sigar_cpu_list_ntsys_get(sigar, cpulist); return sigar_cpu_list_ntsys_get(sigar, cpulist);
} }
else { else {
@ -1344,6 +1376,12 @@ SIGAR_DECLARE(int) sigar_proc_exe_get(sigar_t *sigar, sigar_pid_t pid,
return status; return status;
} }
#define sigar_EnumProcessModules \
sigar->psapi.enum_modules.func
#define sigar_GetModuleFileNameEx \
sigar->psapi.get_module_name.func
SIGAR_DECLARE(int) sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid, SIGAR_DECLARE(int) sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid,
sigar_proc_modules_t *procmods) sigar_proc_modules_t *procmods)
{ {
@ -1352,7 +1390,7 @@ SIGAR_DECLARE(int) sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid,
DWORD size = 0; DWORD size = 0;
unsigned int i; unsigned int i;
if (!sigar->ps_handle) { if (DLLMOD_INIT(psapi, TRUE) != SIGAR_OK) {
return SIGAR_ENOTIMPL; return SIGAR_ENOTIMPL;
} }
@ -1360,7 +1398,7 @@ SIGAR_DECLARE(int) sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid,
return GetLastError(); return GetLastError();
} }
if (!sigar->enum_modules(proc, modules, sizeof(modules), &size)) { if (!sigar_EnumProcessModules(proc, modules, sizeof(modules), &size)) {
CloseHandle(proc); CloseHandle(proc);
return GetLastError(); return GetLastError();
} }
@ -1369,7 +1407,9 @@ SIGAR_DECLARE(int) sigar_proc_modules_get(sigar_t *sigar, sigar_pid_t pid,
int status; int status;
char name[MAX_PATH]; char name[MAX_PATH];
if (!sigar->get_module_name(proc, modules[i], name, sizeof(name))) { if (!sigar_GetModuleFileNameEx(proc, modules[i],
name, sizeof(name)))
{
continue; continue;
} }
@ -1679,6 +1719,12 @@ SIGAR_DECLARE(int) sigar_cpu_info_list_get(sigar_t *sigar,
return SIGAR_OK; return SIGAR_OK;
} }
#define sigar_GetNetworkParams \
sigar->iphlpapi.get_net_params.func
#define sigar_GetAdaptersInfo \
sigar->iphlpapi.get_adapters_info.func
SIGAR_DECLARE(int) sigar_net_info_get(sigar_t *sigar, SIGAR_DECLARE(int) sigar_net_info_get(sigar_t *sigar,
sigar_net_info_t *netinfo) sigar_net_info_t *netinfo)
{ {
@ -1686,20 +1732,22 @@ SIGAR_DECLARE(int) sigar_net_info_get(sigar_t *sigar,
ULONG len = 0; ULONG len = 0;
IP_ADDR_STRING *ip; IP_ADDR_STRING *ip;
DWORD rc; DWORD rc;
DLLMOD_INIT(iphlpapi, FALSE);
if (!sigar->get_net_params) { if (!sigar_GetNetworkParams) {
return SIGAR_ENOTIMPL; return SIGAR_ENOTIMPL;
} }
SIGAR_ZERO(netinfo); SIGAR_ZERO(netinfo);
rc = sigar->get_net_params(NULL, &len); rc = sigar_GetNetworkParams(NULL, &len);
if (rc != ERROR_BUFFER_OVERFLOW) { if (rc != ERROR_BUFFER_OVERFLOW) {
return rc; return rc;
} }
info = malloc(len); info = malloc(len);
rc = sigar->get_net_params(info, &len); rc = sigar_GetNetworkParams(info, &len);
if (rc != NO_ERROR) { if (rc != NO_ERROR) {
free(info); free(info);
return rc; return rc;
@ -1717,17 +1765,17 @@ SIGAR_DECLARE(int) sigar_net_info_get(sigar_t *sigar,
free(info); free(info);
if (sigar->get_adapters_info) { if (sigar_GetAdaptersInfo) {
PIP_ADAPTER_INFO buffer, info; PIP_ADAPTER_INFO buffer, info;
len = 0; len = 0;
rc = sigar->get_adapters_info(NULL, &len); rc = sigar_GetAdaptersInfo(NULL, &len);
if (rc != ERROR_BUFFER_OVERFLOW) { if (rc != ERROR_BUFFER_OVERFLOW) {
return rc; return rc;
} }
buffer = malloc(len); buffer = malloc(len);
rc = sigar->get_adapters_info(buffer, &len); rc = sigar_GetAdaptersInfo(buffer, &len);
if (rc != NO_ERROR) { if (rc != NO_ERROR) {
free(buffer); free(buffer);
return rc; return rc;
@ -1756,28 +1804,30 @@ SIGAR_DECLARE(int) sigar_net_info_get(sigar_t *sigar,
return SIGAR_OK; return SIGAR_OK;
} }
#define sigar_GetIpForwardTable \
sigar->iphlpapi.get_ipforward_table.func
SIGAR_DECLARE(int) sigar_net_route_list_get(sigar_t *sigar, SIGAR_DECLARE(int) sigar_net_route_list_get(sigar_t *sigar,
sigar_net_route_list_t *routelist) sigar_net_route_list_t *routelist)
{ {
char *buffer = NULL; PMIB_IPFORWARDTABLE buffer = NULL;
ULONG bufsize = 0; ULONG bufsize = 0;
DWORD rc, i; DWORD rc, i;
MIB_IPFORWARDTABLE *ipt; MIB_IPFORWARDTABLE *ipt;
sigar_net_route_t *route; sigar_net_route_t *route;
if (!sigar->get_ipforward_table) { DLLMOD_INIT(iphlpapi, FALSE);
if (!sigar_GetIpForwardTable) {
return SIGAR_ENOTIMPL; return SIGAR_ENOTIMPL;
} }
rc = (*(sigar->get_ipforward_table))((PMIB_IPFORWARDTABLE)buffer, rc = sigar_GetIpForwardTable(buffer, &bufsize, FALSE);
&bufsize, FALSE);
if (rc != ERROR_INSUFFICIENT_BUFFER) { if (rc != ERROR_INSUFFICIENT_BUFFER) {
return GetLastError(); return GetLastError();
} }
buffer = malloc(bufsize); buffer = malloc(bufsize);
rc = (*(sigar->get_ipforward_table))((PMIB_IPFORWARDTABLE)buffer, rc = sigar_GetIpForwardTable(buffer, &bufsize, FALSE);
&bufsize, FALSE);
if (rc != NO_ERROR) { if (rc != NO_ERROR) {
free(buffer); free(buffer);
return GetLastError(); return GetLastError();
@ -1786,7 +1836,7 @@ SIGAR_DECLARE(int) sigar_net_route_list_get(sigar_t *sigar,
sigar_net_route_list_create(routelist); sigar_net_route_list_create(routelist);
routelist->size = routelist->number = 0; routelist->size = routelist->number = 0;
ipt = (MIB_IPFORWARDTABLE *)buffer; ipt = buffer;
for (i=0; i<ipt->dwNumEntries; i++) { for (i=0; i<ipt->dwNumEntries; i++) {
MIB_IPFORWARDROW *ipr = ipt->table + i; MIB_IPFORWARDROW *ipr = ipt->table + i;
@ -1814,17 +1864,22 @@ SIGAR_DECLARE(int) sigar_net_route_list_get(sigar_t *sigar,
return SIGAR_OK; return SIGAR_OK;
} }
#define sigar_GetIfTable \
sigar->iphlpapi.get_if_table.func
static int sigar_get_if_table(sigar_t *sigar) static int sigar_get_if_table(sigar_t *sigar)
{ {
ULONG size = sigar->ifconf_len; ULONG size = sigar->ifconf_len;
DWORD rc; DWORD rc;
if (!sigar->get_if_table) { DLLMOD_INIT(iphlpapi, FALSE);
if (!sigar_GetIfTable) {
return SIGAR_ENOTIMPL; return SIGAR_ENOTIMPL;
} }
rc = sigar->get_if_table((PMIB_IFTABLE)sigar->ifconf_buf, rc = sigar_GetIfTable((PMIB_IFTABLE)sigar->ifconf_buf,
&size, FALSE); &size, FALSE);
if (rc == ERROR_INSUFFICIENT_BUFFER) { if (rc == ERROR_INSUFFICIENT_BUFFER) {
sigar_log_printf(sigar, SIGAR_LOG_DEBUG, sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
@ -1834,8 +1889,8 @@ static int sigar_get_if_table(sigar_t *sigar)
sigar->ifconf_buf = realloc(sigar->ifconf_buf, sigar->ifconf_buf = realloc(sigar->ifconf_buf,
sigar->ifconf_len); sigar->ifconf_len);
rc = sigar->get_if_table((PMIB_IFTABLE)sigar->ifconf_buf, rc = sigar_GetIfTable((PMIB_IFTABLE)sigar->ifconf_buf,
&size, FALSE); &size, FALSE);
} }
if (rc != NO_ERROR) { if (rc != NO_ERROR) {
@ -1917,21 +1972,29 @@ sigar_net_interface_stat_get(sigar_t *sigar, const char *name,
#define IS_TCP_CLIENT(state, flags) \ #define IS_TCP_CLIENT(state, flags) \
((flags & SIGAR_NETCONN_CLIENT) && (state != MIB_TCP_STATE_LISTEN)) ((flags & SIGAR_NETCONN_CLIENT) && (state != MIB_TCP_STATE_LISTEN))
#define sigar_GetTcpTable \
sigar->iphlpapi.get_tcp_table.func
static int net_conn_get_tcp(sigar_t *sigar, static int net_conn_get_tcp(sigar_t *sigar,
sigar_net_connection_list_t *connlist, sigar_net_connection_list_t *connlist,
int flags) int flags)
{ {
int status; int status;
DWORD rc, size, i; DWORD rc, size=0, i;
PMIB_TCPTABLE tcp; PMIB_TCPTABLE tcp;
size = 0; DLLMOD_INIT(iphlpapi, FALSE);
rc = sigar->get_tcp_table(NULL, &size, FALSE);
if (!sigar_GetTcpTable) {
return SIGAR_ENOTIMPL;
}
rc = sigar_GetTcpTable(NULL, &size, FALSE);
if (rc != ERROR_INSUFFICIENT_BUFFER) { if (rc != ERROR_INSUFFICIENT_BUFFER) {
return GetLastError(); return GetLastError();
} }
tcp = malloc(size); tcp = malloc(size);
rc = sigar->get_tcp_table(tcp, &size, FALSE); rc = sigar_GetTcpTable(tcp, &size, FALSE);
if (rc) { if (rc) {
free(tcp); free(tcp);
return GetLastError(); return GetLastError();
@ -2015,21 +2078,29 @@ static int net_conn_get_tcp(sigar_t *sigar,
#define IS_UDP_CLIENT(state, flags) \ #define IS_UDP_CLIENT(state, flags) \
((flags & SIGAR_NETCONN_CLIENT) && conn.remote_port) ((flags & SIGAR_NETCONN_CLIENT) && conn.remote_port)
#define sigar_GetUdpTable \
sigar->iphlpapi.get_udp_table.func
static int net_conn_get_udp(sigar_t *sigar, static int net_conn_get_udp(sigar_t *sigar,
sigar_net_connection_list_t *connlist, sigar_net_connection_list_t *connlist,
int flags) int flags)
{ {
int status; int status;
DWORD rc, size, i; DWORD rc, size=0, i;
PMIB_UDPTABLE udp; PMIB_UDPTABLE udp;
size = 0; DLLMOD_INIT(iphlpapi, FALSE);
rc = sigar->get_udp_table(NULL, &size, FALSE);
if (!sigar_GetTcpTable) {
return SIGAR_ENOTIMPL;
}
rc = sigar_GetUdpTable(NULL, &size, FALSE);
if (rc != ERROR_INSUFFICIENT_BUFFER) { if (rc != ERROR_INSUFFICIENT_BUFFER) {
return GetLastError(); return GetLastError();
} }
udp = malloc(size); udp = malloc(size);
rc = sigar->get_udp_table(udp, &size, FALSE); rc = sigar_GetUdpTable(udp, &size, FALSE);
if (rc) { if (rc) {
free(udp); free(udp);
return GetLastError(); return GetLastError();
@ -2093,6 +2164,12 @@ sigar_net_connection_list_get(sigar_t *sigar,
return SIGAR_OK; return SIGAR_OK;
} }
#define sigar_GetTcpExTable \
sigar->iphlpapi.get_tcpx_table.func
#define sigar_GetUdpExTable \
sigar->iphlpapi.get_udpx_table.func
SIGAR_DECLARE(int) sigar_proc_port_get(sigar_t *sigar, SIGAR_DECLARE(int) sigar_proc_port_get(sigar_t *sigar,
int protocol, int protocol,
unsigned long port, unsigned long port,
@ -2100,15 +2177,17 @@ SIGAR_DECLARE(int) sigar_proc_port_get(sigar_t *sigar,
{ {
DWORD rc, i; DWORD rc, i;
DLLMOD_INIT(iphlpapi, FALSE);
if (protocol == SIGAR_NETCONN_TCP) { if (protocol == SIGAR_NETCONN_TCP) {
PMIB_TCPEXTABLE tcp; PMIB_TCPEXTABLE tcp;
if (!sigar->get_tcpx_table) { if (!sigar_GetTcpExTable) {
return SIGAR_ENOTIMPL; return SIGAR_ENOTIMPL;
} }
rc = sigar->get_tcpx_table(&tcp, FALSE, GetProcessHeap(), rc = sigar_GetTcpExTable(&tcp, FALSE, GetProcessHeap(),
2, 2); 2, 2);
if (rc) { if (rc) {
return GetLastError(); return GetLastError();
@ -2131,12 +2210,12 @@ SIGAR_DECLARE(int) sigar_proc_port_get(sigar_t *sigar,
else if (protocol == SIGAR_NETCONN_UDP) { else if (protocol == SIGAR_NETCONN_UDP) {
PMIB_UDPEXTABLE udp; PMIB_UDPEXTABLE udp;
if (!sigar->get_udpx_table) { if (!sigar_GetUdpExTable) {
return SIGAR_ENOTIMPL; return SIGAR_ENOTIMPL;
} }
rc = sigar->get_udpx_table(&udp, FALSE, GetProcessHeap(), rc = sigar_GetUdpExTable(&udp, FALSE, GetProcessHeap(),
2, 2); 2, 2);
if (rc) { if (rc) {
return GetLastError(); return GetLastError();
@ -2269,13 +2348,16 @@ static int get_logon_info(HKEY users,
return SIGAR_OK; return SIGAR_OK;
} }
#define sigar_ConvertStringSidToSid \
sigar->advapi.convert_string_sid.func
static int sigar_who_registry(sigar_t *sigar, static int sigar_who_registry(sigar_t *sigar,
sigar_who_list_t *wholist) sigar_who_list_t *wholist)
{ {
HKEY users; HKEY users;
DWORD index=0, status; DWORD index=0, status;
if (!sigar->convert_string_sid) { if (!sigar_ConvertStringSidToSid) {
return ENOENT; return ENOENT;
} }
@ -2307,7 +2389,7 @@ static int sigar_who_registry(sigar_t *sigar,
continue; continue;
} }
if (!sigar->convert_string_sid(subkey, &sid)) { if (!sigar_ConvertStringSidToSid(subkey, &sid)) {
continue; continue;
} }
@ -2337,57 +2419,33 @@ static int sigar_who_registry(sigar_t *sigar,
return SIGAR_OK; return SIGAR_OK;
} }
#define sigar_WTSEnumerateSessions \
sigar->wtsapi.enum_sessions.func
#define sigar_WTSFreeMemory \
sigar->wtsapi.free_mem.func
#define sigar_WTSQuerySessionInformation \
sigar->wtsapi.query_session.func
#define sigar_WinStationQueryInformation \
sigar->winsta.query_info.func
static int sigar_who_wts(sigar_t *sigar, static int sigar_who_wts(sigar_t *sigar,
sigar_who_list_t *wholist) sigar_who_list_t *wholist)
{ {
DWORD count=0, i; DWORD count=0, i;
WTS_SESSION_INFO *sessions = NULL; WTS_SESSION_INFO *sessions = NULL;
if (!sigar->wts_enum_sessions && sigar->wts_handle) { if (DLLMOD_INIT(wtsapi, TRUE) != SIGAR_OK) {
FARPROC ptr;
if ((ptr = sigar_GetProcAddress(sigar,
sigar->wts_handle,
"WTSEnumerateSessionsA")))
{
sigar->wts_enum_sessions = (LPWTSENUMERATESESSIONS)ptr;
}
if ((ptr = sigar_GetProcAddress(sigar,
sigar->wts_handle,
"WTSFreeMemory")))
{
sigar->wts_free = (LPWTSFREEMEMORY)ptr;
}
if ((ptr = sigar_GetProcAddress(sigar,
sigar->wts_handle,
"WTSQuerySessionInformationA")))
{
sigar->wts_query_session = (LPWTSQUERYSESSION)ptr;
}
if ((ptr = sigar_GetProcAddress(sigar,
sigar->sta_handle,
"WinStationQueryInformationW")))
{
sigar->query_station = (LPSTATIONQUERYINFO)ptr;
}
sigar_log(sigar, SIGAR_LOG_DEBUG,
"Done looking up Terminal Services api functions");
}
if (!(sigar->wts_enum_sessions &&
sigar->wts_free &&
sigar->wts_query_session))
{
sigar_log(sigar, SIGAR_LOG_DEBUG, sigar_log(sigar, SIGAR_LOG_DEBUG,
"Terminal Services api functions not available"); "Terminal Services api functions not available");
return ENOENT; return ENOENT;
} }
if (!sigar->wts_enum_sessions(0, 0, 1, &sessions, &count)) { DLLMOD_INIT(winsta, FALSE);
if (!sigar_WTSEnumerateSessions(0, 0, 1, &sessions, &count)) {
return GetLastError(); return GetLastError();
} }
@ -2404,16 +2462,16 @@ static int sigar_who_wts(sigar_t *sigar,
buffer = NULL; buffer = NULL;
bytes = 0; bytes = 0;
if (sigar->wts_query_session(0, if (sigar_WTSQuerySessionInformation(0,
sessionId, sessionId,
WTSClientProtocolType, WTSClientProtocolType,
&buffer, &buffer,
&bytes)) &bytes))
{ {
int isConsole = int isConsole =
(*buffer == WTS_PROTOCOL_TYPE_CONSOLE); (*buffer == WTS_PROTOCOL_TYPE_CONSOLE);
sigar->wts_free(buffer); sigar_WTSFreeMemory(buffer);
if (isConsole) { if (isConsole) {
continue; continue;
@ -2427,11 +2485,11 @@ static int sigar_who_wts(sigar_t *sigar,
buffer = NULL; buffer = NULL;
bytes = 0; bytes = 0;
if (sigar->wts_query_session(0, if (sigar_WTSQuerySessionInformation(0,
sessionId, sessionId,
WTSClientAddress, WTSClientAddress,
&buffer, &buffer,
&bytes)) &bytes))
{ {
PWTS_CLIENT_ADDRESS client = PWTS_CLIENT_ADDRESS client =
(PWTS_CLIENT_ADDRESS)buffer; (PWTS_CLIENT_ADDRESS)buffer;
@ -2442,7 +2500,7 @@ static int sigar_who_wts(sigar_t *sigar,
client->Address[4], client->Address[4],
client->Address[5]); client->Address[5]);
sigar->wts_free(buffer); sigar_WTSFreeMemory(buffer);
} }
else { else {
SIGAR_SSTRCPY(who->host, "unknown"); SIGAR_SSTRCPY(who->host, "unknown");
@ -2450,14 +2508,14 @@ static int sigar_who_wts(sigar_t *sigar,
buffer = NULL; buffer = NULL;
bytes = 0; bytes = 0;
if (sigar->wts_query_session(0, if (sigar_WTSQuerySessionInformation(0,
sessionId, sessionId,
WTSUserName, WTSUserName,
&buffer, &buffer,
&bytes)) &bytes))
{ {
SIGAR_SSTRCPY(who->user, buffer); SIGAR_SSTRCPY(who->user, buffer);
sigar->wts_free(buffer); sigar_WTSFreeMemory(buffer);
} }
else { else {
SIGAR_SSTRCPY(who->user, "unknown"); SIGAR_SSTRCPY(who->user, "unknown");
@ -2465,13 +2523,13 @@ static int sigar_who_wts(sigar_t *sigar,
buffer = NULL; buffer = NULL;
bytes = 0; bytes = 0;
if (sigar->query_station && if (sigar_WinStationQueryInformation &&
sigar->query_station(0, sigar_WinStationQueryInformation(0,
sessionId, sessionId,
WinStationInformation, WinStationInformation,
&station_info, &station_info,
sizeof(station_info), sizeof(station_info),
&bytes)) &bytes))
{ {
who->time = who->time =
FileTimeToTime(&station_info.ConnectTime) / 1000000; FileTimeToTime(&station_info.ConnectTime) / 1000000;
@ -2481,7 +2539,7 @@ static int sigar_who_wts(sigar_t *sigar,
} }
} }
sigar->wts_free(sessions); sigar_WTSFreeMemory(sessions);
return SIGAR_OK; return SIGAR_OK;
} }