// SysInfo.h: interface for the CSysInfo class.
//
//////////////////////////////////////////////////////////////////////
#pragma once

//#define SYSINFO_USE_MIB //We don't need MIB data
#ifdef SYSINFO_USE_MIB
#include <iphlpapi.h>
#include "mibaccess.h"

typedef DWORD (WINAPI *pGetAdaptersInfo)(PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen);
typedef DWORD (WINAPI *pGetIfEntry)(PMIB_IFROW pIfRow);
#endif

/*
typedef struct _MEMORYSTATUSEX {
	DWORD dwLength; 
	DWORD dwMemoryLoad; 
	DWORDLONG ullTotalPhys; 
	DWORDLONG ullAvailPhys; 
	DWORDLONG ullTotalPageFile; 
	DWORDLONG ullAvailPageFile; 
	DWORDLONG ullTotalVirtual; 
	DWORDLONG ullAvailVirtual; 
	DWORDLONG ullAvailExtendedVirtual;
} MEMORYSTATUSEX, *LPMEMORYSTATUSEX;
*/

typedef BOOL (WINAPI *pGlobalMemoryStatusEx)(LPMEMORYSTATUSEX lpBuffer);

// The set of operational states of the network interface.
typedef struct _PROCESS_MEMORY_COUNTERS {
	DWORD cb;
	DWORD PageFaultCount;
	SIZE_T PeakWorkingSetSize;
	SIZE_T WorkingSetSize;
	SIZE_T QuotaPeakPagedPoolUsage;
	SIZE_T QuotaPagedPoolUsage;
	SIZE_T QuotaPeakNonPagedPoolUsage;
	SIZE_T QuotaNonPagedPoolUsage;
	SIZE_T PagefileUsage;
	SIZE_T PeakPagefileUsage;
} PROCESS_MEMORY_COUNTERS;

typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS;
typedef	BOOL (WINAPI *pGetProcessMemoryInfo)(HANDLE, PPROCESS_MEMORY_COUNTERS, DWORD);

class CSysInfo  
{
public:
	time_t GetUpTime();
	time_t m_StartupTime;

	LPCTSTR GetWorkingDir() const	{return (LPCTSTR)m_sWorkingDir;};
	LPCTSTR GetLoginUserName() const{return (LPCTSTR)m_sUserName;};
	BOOL GetSystemFileInfo(LPCTSTR lpszFileName, DWORD *v_major, DWORD *v_minor, DWORD *v_build, DWORD *v_something, DWORD *size);
	BOOL GetFileInfo(LPCTSTR lpszFileName, DWORD *v_major, DWORD *v_minor, DWORD *v_build, DWORD *v_something, DWORD *size);
	BOOL IsWindowsNT() const {return m_bWindowsNT;};
	BOOL IsUserAdmin() const {return m_bUserAdmin;};

#ifdef SYSINFO_USE_MIB
	DWORD m_dwMIBIPArray[MAX_IPADDRESSES];
	DWORD GetMIBAdapterMaskDword(int i);
	DWORD GetMIBAdapterIPDword(int i);
	int GetMIBAdapterType(int i);
	DWORD GetMIBAdapterOperStatus(int i);
	DWORD GetMIBAdapterSpeed(int i);
	int GetMIBNumAdapters() { return m_nMIBAdapters; }
	void GetMIBAdapterMaskStr(int i, LPTSTR lpMaskStr);
	void GetMIBAdapterIPStr(int i, LPTSTR lpIPStr);
	LPCSTR GetMIBAdapterDescr(int i);
	void DetectAdaptersMIB();
	void SetShowLoopback(BOOL bStatus) { m_bMIBShowLoopback=bStatus; };
	BOOL IsShowLoopback() { return m_bMIBShowLoopback; };
	DWORD GetMIBIP(int index);
	int GetMIBAddresses() { return m_nMIBAddresses; };
	int MIBRefreshAddresses();

	BOOL IsIphlpapiCompat() { return m_bIphlpapiCompat; };
	BOOL GetAPIAdapterSpeedStatus(int i, DWORD *pdwSpeed, DWORD *pdwStatus);
	DWORD GetAPIAdapterIndex(int i);
	LPCSTR GetAPIAdapterMaskStr(int i,int indexIP);
	LPCSTR GetAPIAdapterIPStr(int i, int indexIP);
	int GetAPINumAddresses(int i);
	LPCSTR GetAPIAdapterName(int i);
	LPCSTR GetAPIAdapterDescr(int i);
	int GetAPINumAdapters() const	{return m_nNumAdaptersIphlpapi;};

	DWORD GetADOSomething() const	{return m_dwADOSomething;};
	DWORD GetADOBuild() const		{return m_dwADOBuild;};
	DWORD GetADOMinor() const		{return m_dwADOMinor;};
	DWORD GetADOMajor() const		{return m_dwADOMajor;};
#endif

	LPCTSTR GetCPUNameString() const	{return (LPCTSTR)m_sCPUNameString;};
	LPCTSTR GetCPUVendorIdentifier() const {return (LPCTSTR)m_sCPUVendorIdentifier;};
	LPCTSTR GetCPUIdentifier() const	{return (LPCTSTR)m_sCPUIdentifier;};
	DWORD GetCPUSpeed() const		{return m_dwCPUSpeed;};
	DWORD GetNumProcessors() const	{return m_dwNumProcessors;};

#ifdef SYSINFO_USE_MIB
	DWORD GetIESomething() const	{return m_dwIESomething;};
	DWORD GetIEBuild() const		{return m_dwIEBuild;};
	DWORD GetIEMinor() const		{return m_dwIEMinor;};
	DWORD GetIEMajor() const		{return m_dwIEMajor;};
#endif

	DWORD GetProcessMemoryUsage();
	DWORD GetMemoryLoad() const		{return m_dwMemoryLoad;};
	DWORD64 GetAvailVirtual() const {return m_dwAvailVirtual;};
	DWORD64 GetTotalVirtual() const {return m_dwTotalVirtual;};
	DWORD64 GetAvailPageFile() const{return m_dwAvailPageFile;};
	DWORD64 GetTotalPageFile() const{return m_dwTotalPageFile;};
	DWORD64 GetAvailPhys() const	{return m_dwAvailPhys;};
	DWORD64 GetTotalPhys() const	{return m_dwTotalPhys;};

	DWORD GetWinMajor()	const		{return m_dwWinMajor;};
	DWORD GetWinMinor() const		{return m_dwWinMinor;};
	DWORD GetBuildNumber() const	{return m_dwBuildNumber;};
	DWORD GetServicePack() const	{return m_dwServicePack;};
	LPCTSTR GetOSType() const		{return (LPCTSTR)m_sOSType;};

	void Init();
	CSysInfo();
	virtual ~CSysInfo();

protected:
	// Misc variables
	CString m_sWorkingDir;
	CString m_sUserName;
	BOOL m_bUserAdmin;

#ifdef SYSINFO_USE_MIB
	// NIC list with MIB
	BOOL m_bMIBAllocated;
	tSTRUCTNICINFO *m_pMIBAdapters;
	int m_nMIBAdapters;
	int m_nMIBAddresses;
	DWORD m_dwMIBIPArray_tmp[MAX_IPADDRESSES];
	BOOL  m_bMIBShowLoopback;
	MibII	m_mib;
	BOOL	m_bMibDll;

	// NIC list with Iphlpapi
	BOOL m_bIphlpapiCompat;
	int m_nNumAdaptersIphlpapi;
	pGetIfEntry m_GetIfEntry;
	pGetAdaptersInfo m_GetAdaptersInfo;
	BOOL m_bIphlpapiAllocated;
	BOOL m_bIphlpapiObtained;
	BOOL	m_bIphlpapiDll;
	HMODULE	m_hmIphlpapiDll;
	PIP_ADAPTER_INFO m_pai;
#endif

	// Windows version and CPU type
	CString m_sCPUNameString;
	CString m_sCPUIdentifier;
	CString m_sCPUVendorIdentifier;
	CString	m_sOSType;
	BOOL  m_bWindowsNT;
	DWORD m_dwCPUSpeed;
	DWORD m_dwNumProcessors;
	DWORD m_dwServicePack;
	DWORD m_dwBuildNumber;
	DWORD m_dwWinMinor;
	DWORD m_dwWinMajor;

	// Memory counters
	BOOL m_bPsapiUsed;
	BOOL	m_bPsapiDll;
	HMODULE m_hmPsapiDll;
	PROCESS_MEMORY_COUNTERS m_ProcMemCounters;
	pGetProcessMemoryInfo m_GetProcessMemoryInfo;
	pGlobalMemoryStatusEx m_pGlobalMemoryStatusEx;
	DWORD m_dwMemoryLoad;
	DWORD64 m_dwAvailVirtual;
	DWORD64 m_dwTotalVirtual;
	DWORD64 m_dwAvailPageFile;
	DWORD64 m_dwTotalPageFile;
	DWORD64 m_dwAvailPhys;
	DWORD64 m_dwTotalPhys;

#ifdef SYSINFO_USE_MIB
	// IE version
	DWORD m_dwIESomething;
	DWORD m_dwIEBuild;
	DWORD m_dwIEMinor;
	DWORD m_dwIEMajor;

	// ADO version
	DWORD m_dwADOSomething;
	DWORD m_dwADOBuild;
	DWORD m_dwADOMinor;
	DWORD m_dwADOMajor;
#endif

	void DetectWorkingDir();
	void DetectLoginUserName();
	void DetectUserAdmin();
#ifdef SYSINFO_USE_MIB
	void DetectAdaptersIphlpapi();
	void DetectADOVersion();
#endif
	void DetectCPUType();
#ifdef SYSINFO_USE_MIB
	void DetectIEVersion();
#endif
	void DetectMemory();
	void DetectNumProcessors();
	void DetectOSType();
};