Click here to Skip to main content
15,894,343 members
Articles / Programming Languages / C#

SYSInfo: System info desktop tool

Rate me:
Please Sign up or sign in to vote.
4.92/5 (142 votes)
10 Aug 2015GPL319 min read 298K   17.2K   348  
Displays system information like free disk space and free memory on the desktop.
//============================================================================
// SYSInfo 1.0
// Copyright � 2010 Stephan Berger
// 
//This file is part of SYSInfo.
//
//SYSInfo 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.
//
//SYSInfo 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 SYSInfo.  If not, see <http://www.gnu.org/licenses/>.
//
//============================================================================
/// <summary>
/// This code was taken from http://www.codeproject.com/KB/IP/iphlpapi2.aspx
/// created by Warlib (http://www.codeproject.com/script/Membership/View.aspx?mid=856529)
/// </summary>

using System;
using System.Net;
using System.Collections;
using System.Runtime.InteropServices;
using System.Text;

namespace IpHlpApidotnet
{
	#region UDP

    [StructLayout(LayoutKind.Sequential)]
    public struct MIB_UDPROW_OWNER_PID
    {
        public IPEndPoint Local;
        public int dwOwningPid;
        public string ProcessName;
    }

    public struct MIB_UDPROW_OWNER_MODULE
    {
        public IPEndPoint Local;
        public uint dwOwningPid;
        public long liCreateTimestamp; //LARGE_INTEGER
        /*union {
            struct {
                DWORD   SpecificPortBind : 1;
            };
            DWORD       dwFlags;
        };*/
        public ulong[] OwningModuleInfo; //size TCPIP_OWNING_MODULE_SIZE
    }

    public struct MIB_UDPTABLE_OWNER_PID
    {
        public int dwNumEntries;
        public MIB_UDPROW_OWNER_PID[] table;
    }

    public struct _MIB_UDPTABLE_OWNER_MODULE
    {
        public uint dwNumEntries;
        public MIB_UDPROW_OWNER_MODULE[] table;
    }

    public enum UDP_TABLE_CLASS
    {
        UDP_TABLE_BASIC, //A MIB_UDPTABLE table that contains all UDP endpoints on the machine is returned to the caller.
        UDP_TABLE_OWNER_PID, //A MIB_UDPTABLE_OWNER_PID or MIB_UDP6TABLE_OWNER_PID that contains all UDP endpoints on the machine is returned to the caller.
        UDP_TABLE_OWNER_MODULE //A MIB_UDPTABLE_OWNER_MODULE or MIB_UDP6TABLE_OWNER_MODULE that contains all UDP endpoints on the machine is returned to the caller.
    }

	public struct MIB_UDPSTATS
	{
		public int dwInDatagrams ;
		public int dwNoPorts ;
		public int dwInErrors ;
		public int dwOutDatagrams ;
		public int dwNumAddrs;
	}

	public struct MIB_UDPTABLE 
	{
		public int dwNumEntries;  
		public MIB_UDPROW[] table;
	}

	public struct MIB_UDPROW 
	{
		public IPEndPoint Local;
	}

	public struct MIB_EXUDPTABLE
	{
		public int dwNumEntries;  
		public MIB_EXUDPROW[] table;

	}

	public struct MIB_EXUDPROW
	{
		public IPEndPoint Local;  
		public int dwProcessId;
		public string ProcessName;
	}

	#endregion

	#region TCP
    [StructLayout(LayoutKind.Sequential)]
    public struct MIB_TCPTABLE_OWNER_MODULE
    {
        public uint dwNumEntries;
        public MIB_TCPROW_OWNER_MODULE[] table;
    }

    public struct MIB_TCPROW_OWNER_MODULE
    {
        public const int TCPIP_OWNING_MODULE_SIZE = 16;
        public uint dwState;
        public IPEndPoint Local; //LocalAddress
        public IPEndPoint Remote; //RemoteAddress
        public uint dwOwningPid;
        public uint liCreateTimestamp; //LARGE_INTEGER
        public ulong[] OwningModuleInfo; //Look how to define array size in structure ULONGLONG   = new ulong[TCPIP_OWNING_MODULE_SIZE]     
    }

    public struct MIB_TCPTABLE_OWNER_PID
    {
        public int dwNumEntries;
        public MIB_TCPROW_OWNER_PID[] table;
    }

    public struct MIB_TCPROW_OWNER_PID
    {
        public int dwState;
        public IPEndPoint Local; //LocalAddress
        public IPEndPoint Remote; //RemoteAddress
        public int dwOwningPid;
        public string State;
        public string ProcessName;
    }

    public enum TCP_TABLE_CLASS
    {
        TCP_TABLE_BASIC_LISTENER,
        TCP_TABLE_BASIC_CONNECTIONS,
        TCP_TABLE_BASIC_ALL,
        TCP_TABLE_OWNER_PID_LISTENER,
        TCP_TABLE_OWNER_PID_CONNECTIONS,
        TCP_TABLE_OWNER_PID_ALL,
        TCP_TABLE_OWNER_MODULE_LISTENER,
        TCP_TABLE_OWNER_MODULE_CONNECTIONS,
        TCP_TABLE_OWNER_MODULE_ALL,
    }

	public struct MIB_TCPSTATS
	{
		public int dwRtoAlgorithm ;
		public int dwRtoMin ;
		public int dwRtoMax ;
		public int dwMaxConn ;
		public int dwActiveOpens ;
		public int dwPassiveOpens ;
		public int dwAttemptFails ;
		public int dwEstabResets ;
		public int dwCurrEstab ;
		public int dwInSegs ;
		public int dwOutSegs ;
		public int dwRetransSegs ;
		public int dwInErrs ;
		public int dwOutRsts ;
		public int dwNumConns ;
	}

	public struct MIB_TCPTABLE 
	{
		public int dwNumEntries;  
		public MIB_TCPROW[] table;
	}

	public struct MIB_TCPROW 
	{
        //public string StrgState; 
        //public int iState;
        //public IPEndPoint Local;  
        //public IPEndPoint Remote;
        public int dwState;
        public int dwLocalAddr;
        public int dwLocalPort;
        public int dwRemoteAddr;
        public int dwRemotePort;
    }

	public struct MIB_EXTCPTABLE
	{
		public int dwNumEntries;  
		public MIB_EXTCPROW[] table;

	}

	public struct MIB_EXTCPROW
	{
		public string StrgState;
		public int iState;
		public IPEndPoint Local;  
		public IPEndPoint Remote;
		public int dwProcessId;
		public string ProcessName;
	}
	#endregion

	
	public class IPHlpAPI32Wrapper
	{
		public const byte NO_ERROR  = 0;
		public const int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
		public const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
		public const int FORMAT_MESSAGE_FROM_SYSTEM  = 0x00001000;
		public int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | 
			FORMAT_MESSAGE_FROM_SYSTEM | 
			FORMAT_MESSAGE_IGNORE_INSERTS;

		[DllImport("iphlpapi.dll",SetLastError=true)]
		public extern static int GetUdpStatistics (ref MIB_UDPSTATS pStats );

		[DllImport("iphlpapi.dll",SetLastError=true)]
		public static extern int GetUdpTable(byte[] UcpTable, out int pdwSize, bool bOrder);

		[DllImport("iphlpapi.dll",SetLastError=true)]
		public extern static int GetTcpStatistics (ref MIB_TCPSTATS pStats );

		[DllImport("iphlpapi.dll",SetLastError=true)]
		public static extern int GetTcpTable(byte[] pTcpTable, out int pdwSize, bool bOrder);

		[DllImport("iphlpapi.dll",SetLastError=true)]
        private static extern int GetTcpTable(IntPtr pTcpTable, ref int pdwSize, bool bOrder); 

		[ DllImport( "kernel32" ,SetLastError=true)]
		private static extern int FormatMessage( int flags, IntPtr source, int messageId,
			int languageId, StringBuilder buffer, int size, IntPtr arguments ); 

		[DllImport("iphlpapi.dll", SetLastError=true)]
        public static extern int GetExtendedTcpTable(byte[] pTcpTable, out int dwOutBufLen, bool sort, 
            int ipVersion, TCP_TABLE_CLASS tblClass, int reserved);

		[DllImport("iphlpapi.dll", SetLastError=true)]
        public static extern int GetExtendedUdpTable(byte[] pUdpTable, out int dwOutBufLen, bool sort, 
            int ipVersion, UDP_TABLE_CLASS tblClass, int reserved);

        //API to change status of connection  
        [DllImport("iphlpapi.dll", SetLastError=true)]
        //private static extern int SetTcpEntry(MIB_TCPROW tcprow);  
        private static extern int SetTcpEntry(IntPtr pTcprow); 


        public static string GetAPIErrorMessageDescription(int ApiErrNumber ) 
		{
			System.Text.StringBuilder sError = new System.Text.StringBuilder(512); 
			int lErrorMessageLength; 
			lErrorMessageLength = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,(IntPtr)0, ApiErrNumber, 0, sError, sError.Capacity, (IntPtr)0) ;
			
			if(lErrorMessageLength > 0)
			{ 
				string strgError = sError.ToString();
				strgError=strgError.Substring(0,strgError.Length-2);
				return strgError+" ("+ApiErrNumber.ToString()+")";
			}
			return "none";
		}

        
        ///<Summary>
        ///close an TCP-connection
        ///Code found @ http://stackoverflow.com/questions/1672062/how-to-close-a-tcp-connection-by-port
        /// </summary>  

        /// <summary>  
        /// Close all connection to the remote IP  
        /// </summary>  
        /// <param name="IP">IP remote PC</param>  
        public static void CloseRemoteIP(string IP)
        {
            MIB_TCPROW[] rows = getTcpTable();
            for (int i = 0; i < rows.Length; i++)
            {
                if (rows[i].dwRemoteAddr == IPStringToInt(IP))
                {
                    rows[i].dwState = 12;
                    IntPtr ptr = GetPtrToNewObject(rows[i]);
                    int ret = SetTcpEntry(ptr);
                }
            }
        }
        /// <summary>  
        /// Close all connections at current local IP  
        /// </summary>  
        /// <param name="IP"></param>  
        public static void CloseLocalIP(string IP)
        {
            MIB_TCPROW[] rows = getTcpTable();
            for (int i = 0; i < rows.Length; i++)
            {
                if (rows[i].dwLocalAddr == IPStringToInt(IP))
                {
                    rows[i].dwState = 12;
                    IntPtr ptr = GetPtrToNewObject(rows[i]);
                    int ret = SetTcpEntry(ptr);
                }
            }
        }
        /// <summary>  
        /// Closes all connections to the local port  
        /// </summary>  
        /// <param name="port"></param>  
        public static void CloseLocalPort(int port, string IP)
        {
            MIB_TCPROW[] rows = getTcpTable();
            for (int i = 0; i < rows.Length; i++)
            {
                if (port == ntohs(rows[i].dwLocalPort) && rows[i].dwLocalAddr == IPStringToInt(IP))
                {
                    rows[i].dwState = 12;
                    IntPtr ptr = GetPtrToNewObject(rows[i]);
                    int ret = SetTcpEntry(ptr);
                }
            }
        } 

        //Convert 16-bit value from network to host byte order  
        [DllImport("wsock32.dll")]
        private static extern int ntohs(int netshort);

        //Convert 16-bit value back again  
        [DllImport("wsock32.dll")]
        private static extern int htons(int netshort); 

        /// <summary>  
        /// Closes all connections to the remote port  
        /// </summary>  
        /// <param name="port"></param>  
        public static void CloseRemotePort(int port, string IP)
        {
            MIB_TCPROW[] rows = getTcpTable();
            for (int i = 0; i < rows.Length; i++)
            {
                if (port == ntohs(rows[i].dwRemotePort) && rows[i].dwRemoteAddr == IPStringToInt(IP))
                {
                    rows[i].dwState = 12;
                    IntPtr ptr = GetPtrToNewObject(rows[i]);
                    int ret = SetTcpEntry(ptr);
                }
            }
        } 

        //The function that fills the MIB_TCPROW array with connectioninfos  
        private static MIB_TCPROW[] getTcpTable()
        {
            IntPtr buffer = IntPtr.Zero; bool allocated = false;
            try
            {
                int iBytes = 0;
                GetTcpTable(IntPtr.Zero, ref iBytes, false); //Getting size of return data  
                buffer = Marshal.AllocCoTaskMem(iBytes); //allocating the datasize  

                allocated = true;

                GetTcpTable(buffer, ref iBytes, false); //Run it again to fill the memory with the data  

                int structCount = Marshal.ReadInt32(buffer); // Get the number of structures  

                IntPtr buffSubPointer = buffer; //Making a pointer that will point into the buffer  
                buffSubPointer = (IntPtr)((int)buffer + 4); //Move to the first data (ignoring dwNumEntries from the original MIB_TCPTABLE struct)  

                MIB_TCPROW[] tcpRows = new MIB_TCPROW[structCount]; //Declaring the array  

                //Get the struct size  
                MIB_TCPROW tmp = new MIB_TCPROW();
                int sizeOfTCPROW = Marshal.SizeOf(tmp);

                //Fill the array 1 by 1  
                for (int i = 0; i < structCount; i++)
                {
                    tcpRows[i] = (MIB_TCPROW)Marshal.PtrToStructure(buffSubPointer, typeof(MIB_TCPROW)); //copy struct data  
                    buffSubPointer = (IntPtr)((int)buffSubPointer + sizeOfTCPROW); //move to next structdata  
                }

                return tcpRows;

            }
            catch (Exception ex)
            {
                throw new Exception("getTcpTable failed! [" + ex.GetType().ToString() + "," + ex.Message + "]");
            }
            finally
            {
                if (allocated) Marshal.FreeCoTaskMem(buffer); //Free the allocated memory  
            }

        }
        static IntPtr GetPtrToNewObject(object obj)
        {
            IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(obj));
            Marshal.StructureToPtr(obj, ptr, false);
            return ptr;
        }
        //Convert an IP string to the INT value  
        private static int IPStringToInt(string IP)
        {
            if (IP.IndexOf(".") < 0) throw new Exception("Invalid IP address");
            string[] addr = IP.Split('.');
            if (addr.Length != 4) throw new Exception("Invalid IP address");
            byte[] bytes = new byte[] { byte.Parse(addr[0]), byte.Parse(addr[1]), byte.Parse(addr[2]), byte.Parse(addr[3]) };
            return BitConverter.ToInt32(bytes, 0);
        }
        //Convert an IP integer to IP string  
        private static string IPIntToString(int IP)
        {
            byte[] addr = System.BitConverter.GetBytes(IP);
            return addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3];
        }

	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer Engineering office for automation Dr. Lupp
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions