/* * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of SIGAR. * * SIGAR is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License as * published by the Free Software Foundation. This program 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ #ifndef SIGAR_OS_H #define SIGAR_OS_H #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include #include #include #include #include #include #include "sigar_util.h" #define INT64_C(val) val##i64 /* see apr/include/arch/win32/atime.h */ #define EPOCH_DELTA INT64_C(11644473600000000) #define SIGAR_CMDLINE_MAX 4096 static __inline sigar_uint64_t FileTimeToTime(FILETIME *ft) { sigar_uint64_t time; time = ft->dwHighDateTime; time = time << 32; time |= ft->dwLowDateTime; time /= 10; time -= EPOCH_DELTA; return time; } /* XXX: support CP_UTF8 ? */ #define SIGAR_A2W(lpa, lpw, bytes) \ (lpw[0] = 0, MultiByteToWideChar(CP_ACP, 0, \ lpa, -1, lpw, (bytes/sizeof(WCHAR)))) #define SIGAR_W2A(lpw, lpa, chars) \ (lpa[0] = '\0', WideCharToMultiByte(CP_ACP, 0, \ lpw, -1, (LPSTR)lpa, chars, \ NULL, NULL)) /* from iptypes.h not in vs6.0 */ #define MAX_ADAPTER_DESCRIPTION_LENGTH 128 #define MAX_ADAPTER_NAME_LENGTH 256 #define MAX_ADAPTER_ADDRESS_LENGTH 8 #define MAX_HOSTNAME_LEN 128 #define MAX_DOMAIN_NAME_LEN 128 #define MAX_SCOPE_ID_LEN 256 typedef struct { char String[4 * 4]; } IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING; typedef struct _IP_ADDR_STRING { struct _IP_ADDR_STRING* Next; IP_ADDRESS_STRING IpAddress; IP_MASK_STRING IpMask; DWORD Context; } IP_ADDR_STRING, *PIP_ADDR_STRING; typedef struct { char HostName[MAX_HOSTNAME_LEN + 4]; char DomainName[MAX_DOMAIN_NAME_LEN + 4]; PIP_ADDR_STRING CurrentDnsServer; IP_ADDR_STRING DnsServerList; UINT NodeType; char ScopeId[MAX_SCOPE_ID_LEN + 4]; UINT EnableRouting; UINT EnableProxy; UINT EnableDns; } FIXED_INFO, *PFIXED_INFO; typedef struct _IP_ADAPTER_INFO { struct _IP_ADAPTER_INFO* Next; DWORD ComboIndex; char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]; char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]; UINT AddressLength; BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]; DWORD Index; UINT Type; UINT DhcpEnabled; PIP_ADDR_STRING CurrentIpAddress; IP_ADDR_STRING IpAddressList; IP_ADDR_STRING GatewayList; IP_ADDR_STRING DhcpServer; BOOL HaveWins; IP_ADDR_STRING PrimaryWinsServer; IP_ADDR_STRING SecondaryWinsServer; time_t LeaseObtained; time_t LeaseExpires; } IP_ADAPTER_INFO, *PIP_ADAPTER_INFO; /* end iptypes.h */ /* from wtsapi32.h not in vs6.0 */ typedef enum { WTSInitialProgram, WTSApplicationName, WTSWorkingDirectory, WTSOEMId, WTSSessionId, WTSUserName, WTSWinStationName, WTSDomainName, WTSConnectState, WTSClientBuildNumber, WTSClientName, WTSClientDirectory, WTSClientProductId, WTSClientHardwareId, WTSClientAddress, WTSClientDisplay, WTSClientProtocolType, } WTS_INFO_CLASS; typedef enum _WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit } WTS_CONNECTSTATE_CLASS; #define WTS_PROTOCOL_TYPE_CONSOLE 0 #define WTS_PROTOCOL_TYPE_ICA 1 #define WTS_PROTOCOL_TYPE_RDP 2 typedef struct _WTS_SESSION_INFO { DWORD SessionId; LPTSTR pWinStationName; DWORD State; } WTS_SESSION_INFO, *PWTS_SESSION_INFO; typedef struct _WTS_PROCESS_INFO { DWORD SessionId; DWORD ProcessId; LPSTR pProcessName; PSID pUserSid; } WTS_PROCESS_INFO, *PWTS_PROCESS_INFO; typedef struct _WTS_CLIENT_ADDRESS { DWORD AddressFamily; BYTE Address[20]; } WTS_CLIENT_ADDRESS, *PWTS_CLIENT_ADDRESS; /* the WINSTATION_INFO stuff here is undocumented * got the howto from google groups: * http://redirx.com/?31gy */ typedef enum _WINSTATION_INFO_CLASS { WinStationInformation = 8 } WINSTATION_INFO_CLASS; typedef struct _WINSTATION_INFO { BYTE Reserved1[72]; ULONG SessionId; BYTE Reserved2[4]; FILETIME ConnectTime; FILETIME DisconnectTime; FILETIME LastInputTime; FILETIME LoginTime; BYTE Reserved3[1096]; FILETIME CurrentTime; } WINSTATION_INFO, *PWINSTATION_INFO; /* end wtsapi32.h */ #if _MSC_VER <= 1200 /* from winbase.h not in vs6.0 */ typedef struct { DWORD dwLength; DWORD dwMemoryLoad; DWORDLONG ullTotalPhys; DWORDLONG ullAvailPhys; DWORDLONG ullTotalPageFile; DWORDLONG ullAvailPageFile; DWORDLONG ullTotalVirtual; DWORDLONG ullAvailVirtual; DWORDLONG ullAvailExtendedVirtual; } MEMORYSTATUSEX; /* 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; #endif /* _MSC_VER */ #include /* undocumented structures */ typedef struct { DWORD dwState; DWORD dwLocalAddr; DWORD dwLocalPort; DWORD dwRemoteAddr; DWORD dwRemotePort; DWORD dwProcessId; } MIB_TCPEXROW, *PMIB_TCPEXROW; typedef struct { DWORD dwNumEntries; MIB_TCPEXROW table[ANY_SIZE]; } MIB_TCPEXTABLE, *PMIB_TCPEXTABLE; typedef struct { DWORD dwLocalAddr; DWORD dwLocalPort; DWORD dwProcessId; } MIB_UDPEXROW, *PMIB_UDPEXROW; typedef struct { DWORD dwNumEntries; MIB_UDPEXROW table[ANY_SIZE]; } MIB_UDPEXTABLE, *PMIB_UDPEXTABLE; /* end undocumented structures */ /* no longer in the standard header files */ typedef struct { LARGE_INTEGER IdleTime; LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER Reserved1[2]; ULONG Reserved2; } SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; #define SystemProcessorPerformanceInformation 8 typedef struct { sigar_pid_t pid; int ppid; int priority; time_t mtime; sigar_uint64_t size; sigar_uint64_t resident; char name[SIGAR_PROC_NAME_LEN]; char state; sigar_uint64_t handles; sigar_uint64_t threads; sigar_uint64_t page_faults; } 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); typedef BOOL (CALLBACK *psapi_enum_processes)(DWORD *, DWORD, DWORD *); /* winsta.dll */ typedef BOOLEAN (CALLBACK *winsta_query_info)(HANDLE, ULONG, WINSTATION_INFO_CLASS, PVOID, ULONG, PULONG); /* kernel32.dll */ typedef BOOL (CALLBACK *kernel_memory_status)(MEMORYSTATUSEX *); #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, enum_processes); 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; typedef struct { sigar_dll_handle_t handle; SIGAR_DLLFUNC(kernel, memory_status); sigar_dll_func_t end; } sigar_kernel_t; struct sigar_t { SIGAR_T_BASE; char *machine; int using_wide; long pagesize; HKEY handle; char *perfbuf; DWORD perfbuf_size; sigar_wtsapi_t wtsapi; sigar_iphlpapi_t iphlpapi; sigar_advapi_t advapi; sigar_ntdll_t ntdll; sigar_psapi_t psapi; sigar_winsta_t winsta; sigar_kernel_t kernel; sigar_win32_pinfo_t pinfo; sigar_cache_t *netif_adapters; sigar_cache_t *netif_mib_rows; WORD ws_version; int ws_error; LPBYTE peb; //scratch pad for getting peb info int ht_enabled; int lcpu; //number of logical cpus int winnt; }; int sigar_wsa_init(sigar_t *sigar); int sigar_proc_exe_peb_get(sigar_t *sigar, HANDLE proc, sigar_proc_exe_t *procexe); int sigar_proc_args_peb_get(sigar_t *sigar, HANDLE proc, sigar_proc_args_t *procargs); int sigar_parse_proc_args(sigar_t *sigar, WCHAR *buf, sigar_proc_args_t *procargs); unsigned int sigar_cpu_count(sigar_t *sigar); int sigar_cpu_info_get(sigar_t *sigar, sigar_cpu_info_t *info); #define SIGAR_NO_SUCH_PROCESS (SIGAR_OS_START_ERROR+1) #endif /* SIGAR_OS_H */