Projekt Monitorowanie aktywności serwera NAS (Qlogger)

Poniżej zamieszczam trochę kodu z niedoszłego, nowego programu kompatybilnego z QTS 3 i 4 pisanego w C#.

Helper do autoryzacji (na bazie JavaScriptu z procesu logowania do panelu zarządzania QNAP)
C#:
public class Helpers
{

    static public UInt32 SecureRandom()
    {
        RNGCryptoServiceProvider secureRandom = new RNGCryptoServiceProvider();
        byte[] randBytes = new byte[4];
        secureRandom.GetNonZeroBytes(randBytes);
        return (BitConverter.ToUInt32(randBytes, 0));
    }

    static string ezEncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    static public string ezEncode(string str)
    {
        string rOut = "";

        int len = str.Length;
        int i = 0;

        int c1, c2, c3;

        while (i < len)
        {
            c1 = str[i++] & 0xff;
            if (i == len)
            {
                rOut += ezEncodeChars[c1 >> 2];
                rOut += ezEncodeChars[(c1 & 0x3) << 4];
                rOut += "==";
                break;
            }
            c2 = str[i++];
            if (i == len)
            {
                rOut += ezEncodeChars[c1 >> 2];
                rOut += ezEncodeChars[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
                rOut += ezEncodeChars[(c2 & 0xF) << 2];
                rOut += "=";
                break;
            }
            c3 = str[i++];
            rOut += ezEncodeChars[c1 >> 2];
            rOut += ezEncodeChars[((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4)];
            rOut += ezEncodeChars[((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6)];
            rOut += ezEncodeChars[(c3 & 0x3F)];
        }
        return rOut;
    }

}

Autoryzacja klienta i pobranie session ID:
C#:
/// <summary>
/// This method authorize client and gets sid
/// </summary>
/// <param name="hostName">Destination IP/Hostname address</param>
/// <param name="Port">Destination Port</param>
/// <param name="authName">User credentials ID</param>
/// <param name="authPass">User password</param>
/// <param name="getFile">Remote file</param>
/// <param name="prxServer">Specify proxy server or set null or empty value</param>
/// <param name="prxPort">Specify proxy server port or set 0</param>
/// <param name="webAuth">In case of secure request this would be true</param>
/// <param name="SSL">In case of SSL connection request this would be true</param>
/// <returns>Server response</returns>
private string AuthClient(string countNumber, string hostName, int Port, string authName, string authPass, string getFile,
    string prxServer, int prxPrt, bool webAuth, bool SSL)
{
    // --- POST DATA
    string postData = "count=" + countNumber + "&user=" + authName + "&pwd=" + authPass + "&admin=1";

    // build URI
    string protocol = "http";
    if (SSL) protocol += "s";
    string sUri = protocol + "://" + hostName + ":" + Port + "/" + getFile;

    var hpp = new HttpRequestResponse(postData, sUri);

    if (webAuth) //do not use it, because stored password is encoded!
    {
        hpp.HTTP_USER_NAME = global.var_Username;
        hpp.HTTP_USER_PASSWORD = global.var_encodedPassword;
    }
    if (prxServer == null) hpp.PROXY_SERVER = "";
    else hpp.PROXY_SERVER = prxServer;

    return hpp.SendRequest();
}
 
Pobranie konkretnego węzła z XML'a
C#:
private bool GetNode(string inXML, string path, string node, out string value)
{
    value = null;

    XmlDocument xml = new XmlDocument();
    xml.LoadXml(inXML);

    XmlNodeList xnList = xml.SelectNodes(path);
    foreach (XmlNode xn in xnList)
    {
        if (xn[node] != null) value = xn[node].InnerText;
        else value = null;
    }

    if (!String.IsNullOrEmpty(value))
        return true;
    else
        return false;
}

Pobranie ciągu danych z XML'a:
C#:
private string GetResponse(string countNumber, string authSid, string hostName, int Port, string getFile, string Params,
    string prxServer, int prxPrt, bool webAuth, bool SSL)
{
    // --- POST DATA
    string postData = "count=" + countNumber + "&sid=" + authSid + "&" + Params;

    // build URI
    string protocol = "http";
    if (SSL) protocol += "s";
    string sUri = protocol + "://" + hostName + ":" + Port + "/" + getFile;

    var hpp = new HttpRequestResponse(postData, sUri);

    if (webAuth) //do not use it, because stored password is encoded!
    {
        hpp.HTTP_USER_NAME = global.var_Username;
        hpp.HTTP_USER_PASSWORD = global.var_encodedPassword;
    }
    if (prxServer == null) hpp.PROXY_SERVER = "";
    else hpp.PROXY_SERVER = prxServer;

    return hpp.SendRequest();
}

Główna funkcja pobierająca dane dla programu:
C#:
private bool RetreiveData(string hostName, int Port, string authName, string authPass, string getFile,
    string prxServer, int prxPrt, bool webAuth, bool SSL, string datatype, ref Int64 highNo)
{
    bool value = true;
    string _tmp_response;

    if (String.IsNullOrEmpty(sessionID) || sessionID == "") // || authLost
    {
        rndCount = Helpers.SecureRandom().ToString();
        _tmp_response = AuthClient(rndCount, hostName, Port, authName, authPass, getFile
            + "/authLogin.cgi", prxServer, prxPrt, webAuth, SSL);
        value = GetNode(_tmp_response, "/QDocRoot", "authSid", out sessionID);
    }

    if (value && (!String.IsNullOrEmpty(sessionID) || sessionID != ""))
    {
        string logCount; Int64 ilogCount;

        _tmp_response = GetResponse(rndCount, sessionID, hostName, Port, getFile
            + "/sys/sysRequest.cgi", "subfunc=sys_logs&" + datatype + "log=1&getcount=1&filter=0",
            prxServer, prxPrt, webAuth, SSL);
        if (GetNode(_tmp_response, "/QDocRoot/logroot", "count", out logCount)
            && Int64.TryParse(logCount, out ilogCount) && ilogCount > 0)
        {
            string XEntryID; Int64 elementHi;
            _tmp_response = GetResponse(rndCount, sessionID, hostName, Port, getFile
                + "/sys/sysRequest.cgi", "subfunc=sys_logs&" + datatype + "log=1&getdata=1&filter=0&lower=0&upper="
                + "1" + "&sort=13", prxServer, prxPrt, webAuth, SSL);
            if (GetNode(_tmp_response, "/QDocRoot/logroot/data/" + datatype, "id", out XEntryID)
                && Int64.TryParse(XEntryID, out elementHi) && (elementHi > highNo))
            {
                Int64 Upper = elementHi - highNo;
                if (Upper > 0)
                {
                    _tmp_response = GetResponse(rndCount, sessionID, hostName, Port, getFile
                        + "/sys/sysRequest.cgi", "subfunc=sys_logs&" + datatype + "log=1&getdata=1&filter=0&lower=0&upper="
                        + Upper.ToString() + "&sort=13",
                        prxServer, prxPrt, webAuth, SSL);
                 
                    if (datatype == "event")
                        LoadXMLtoListView(folvEvents, _tmp_response, datatype, ref highNo);
                    else if (datatype == "conn")
                        LoadXMLtoListView(folvConnections, _tmp_response, datatype, ref highNo);

                }
            }
            else
                value = false;
        }
        else
            value = false;

        _tmp_response = string.Empty;
        logCount = string.Empty;
    }
    return value;
}
 
Wątek:
C#:
private void WorkThread(object credentials)
{
    if (credentials is Credentials)
    {
        Credentials cr = (Credentials)credentials;

        bool workStatus = true;

        if (!connEstablished)
        {
            this.helperThread = new Thread(new ParameterizedThreadStart(this.changeTab));
            helperThread.Start(0);
            while (helperThread.IsAlive) ;
            Thread.Sleep(300);
        }
        if (workStatus) RetreiveData(cr.hostName, cr.Port, cr.authName, cr.authPass,
            cr.getFile, cr.prxServer, cr.prxPort, cr.webAuth, cr.SSL, "event", ref this.logEvents_HiID);

        if (!connEstablished)
        {
            this.helperThread = new Thread(new ParameterizedThreadStart(this.changeTab));
            helperThread.Start(1);
            while (helperThread.IsAlive) ;
            Thread.Sleep(300);
        }
        if (workStatus) RetreiveData(cr.hostName, cr.Port, cr.authName, cr.authPass,
            cr.getFile, cr.prxServer, cr.prxPort, cr.webAuth, cr.SSL, "conn", ref this.logConn_HiID);

        if ((!workStatus && connEstablished) || workStatus)
        {
            connEstablished = true; // mark first connection
            if (!closingQlogr)
            {
                Thread.Sleep(Convert.ToInt16(global.Interval * 1000));

                this.workThread = new Thread(new ParameterizedThreadStart(WorkThread));
                workThread.Start(credentials);
            }
        }
        else
        {
            connEstablished = false;
            ResetState();
            MessageBox.Show("Please check destination host, credentials settings and your network connection.");
        }
    }
}

Utworzenie połączenia i uruchomienie wątku pobierającego dane:
C#:
private void Connect()
{
    ResetState();

    Credentials credentials = new Credentials();
    credentials.authName =  Uri.EscapeUriString(global.var_Username);
    credentials.authPass = Uri.EscapeUriString(global.var_encodedPassword);
    credentials.hostName = global.var_Hostname;
    credentials.Port = Convert.ToInt16(global.var_Port);
    credentials.getFile = "cgi-bin";
    credentials.prxServer = null;
    credentials.prxPort = 0;
    credentials.webAuth = false;
    credentials.SSL = global.var_SSL;

    this.startThread = new Thread(new ParameterizedThreadStart(this.WorkThread));
    startThread.Start(credentials);

    credentials = null;
}
 
Klasa zmiennych globalnych:
C#:
using System;
using System.Collections.Generic;
using System.Text;

namespace qLogr
{
    public static class global //A public static class to store global variables
    {
        public static string var_Username;
        //public static string var_encodedUsername;

        //public static string var_Password;
        public static string var_encodedPassword;

        public static string var_Hostname;
        public static decimal var_Port;

        public static bool var_SSL = false;

        public static bool var_notifyEvents_Warning = false;
        public static bool var_notifyEvents_Error = false;
        public static bool var_notifyConnections_Warning = false;
        public static bool var_notifyConnections_Error = false;
        public static bool var_notifyHDD_all = false;

        public static bool var_startMinimized = false;
        public static bool var_startWithWindows = false;
        public static bool var_connectOnStart = false;

        public static bool var_removeDuplicates = false;

        public static decimal Interval = 5;

        public static byte var_speakerWarning = 0;
        public static byte var_speakerError = 0;
        public static byte var_speakerHDD = 0;
    }
}
 
Ostatnio edytowane:
Klasy danych:
C#:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;

namespace qLogr
{
    public class Credentials
    {
        public string hostName;
        public int Port;
        public string authName;
        public string authPass;
        public string getFile;
        public string prxServer;
        public int prxPort;
        public Boolean webAuth;
        public Boolean SSL;

        public Credentials() { }
        public Credentials(string hostName, int Port, string authName, string authPass, string getFile,
        string prxServer, int prxPort, Boolean webAuth, Boolean SSL)
        {
            this.hostName = hostName;
            this.Port = Port;
            this.authName = authName;
            this.authName = authPass;
            this.getFile = getFile;
            this.prxServer = prxServer;
            this.prxPort = prxPort;
            this.webAuth = webAuth;
            this.SSL = SSL;
        }
    }

    public class QEvent
    {
        public string Icon;
        public Int64 ID;
        public string Level;
        public string LoDate;
        public string LoTime;
        public string HiDate;
        public string HiTime;
        public int CompareDateFlag;
        public string TotalRangeTime;
        public Int16 Occurs;
        public string User;
        public string Host;
        public string IPaddr;
        public string Description;
        public string XMLDetails;
        public string Details;

        public QEvent() { }
        public QEvent(string Icon, Int64 ID, string Level,
            string LoDate, string LoTime, string HiDate, string HiTime, int CompareDateFlag, string TotalRangeTime,
            Int16 Occurs, string User, string Host, string IPaddr, string Description,
            string XMLDetails, string Details)
        {
            this.Icon = Icon;
            this.ID = ID;
            this.Level = Level;
            this.LoDate = LoDate;
            this.LoTime = LoTime;
            this.HiDate = HiDate;
            this.CompareDateFlag = CompareDateFlag;
            this.TotalRangeTime = TotalRangeTime;
            this.Occurs = Occurs;
            this.User = User;
            this.Host = Host;
            this.IPaddr = IPaddr;
            this.Description = Description;
            this.XMLDetails = XMLDetails;
            this.Details = Details;
        }
    }

    public class QConnection
    {
        public Int64 ID;
        public string Level;
        public string LogTime;
        public string LoDate;
        public string LoTime;
        public string HiDate;
        public string HiTime;
        public int CompareDateFlag;
        public string TotalRangeTime;
        public Int16 Occurs;
        public string User;
        public string MachineID;
        public string IPaddr;
        public string Protocol;
        public string Action;
        public string Object;

        public QConnection() { }
        public QConnection(Int64 ID, string Level, string LogTime,
            string LoDate, string LoTime, string HiDate, string HiTime, int CompareDateFlag, string TotalRangeTime,
            Int16 Occurs, string User, string MachineID, string IPaddr, string Protocol,
            string Action, string Object)
        {
            this.ID = ID;
            this.Level = Level;
            this.LogTime = LogTime;
            this.LoDate = LoDate;
            this.LoTime = LoTime;
            this.HiDate = HiDate;
            this.CompareDateFlag = CompareDateFlag;
            this.TotalRangeTime = TotalRangeTime;
            this.Occurs = Occurs;
            this.User = User;
            this.MachineID = MachineID;
            this.IPaddr = IPaddr;
            this.Protocol = Protocol;
            this.Action = Action;
            this.Object = Object;
        }
    }
}
 
Wczytanie XML'a do widoku ListView:
C#:
private void LoadXMLtoListView(ObjectListView lv, string inXML, string datatype, ref Int64 highNo)
{
    // DataType:
    // 0 --> Events
    // 1 --> Connections
    // 2 --> Volume list
    // 3 --> HDD Parameters
    // 4 --> HDD Smart
    if (string.IsNullOrEmpty(inXML) == false)
    {
        XmlDocument xml = new XmlDocument();
        xml.LoadXml(inXML);

        XmlNodeList authPassed = xml.SelectNodes("/QDocRoot/authPassed");
        if (authPassed != null && !string.IsNullOrEmpty(authPassed[0].InnerText)
            && authPassed[0].InnerText == "1")
        {
            XmlNodeList lstRootItems = xml.SelectNodes("/QDocRoot/logroot/count");
            int elementsNo;
            if(lstRootItems[0] != null && Int32.TryParse(lstRootItems[0].InnerText, out elementsNo))
            if (elementsNo > 0)
            {
                XmlNodeList lstItems = xml.SelectNodes("/QDocRoot/logroot/data");
                if (lstItems != null && lstItems.Count > 0)
                {
                    // --- EVENTS data
                    //
                    if (datatype == "event")
                    {
                        List<QEvent> qEvents = new List<QEvent>();

                        Int64 _tmp_new_logEvents_high = highNo;

                        XmlNode nItem = lstItems[0];
                        foreach (XmlNode nChild in nItem.ChildNodes)
                        {
                            QEvent itemObject = new QEvent { };

                            if (nChild.Name == "event")
                            {
                                itemObject.XMLDetails = nChild.InnerXml;
                                itemObject.Details = "Details";
                                itemObject.CompareDateFlag = 0;
                                itemObject.Occurs = 1;
                                foreach (XmlNode nData in nChild.ChildNodes)
                                {
                                    if (nData.Name == "id")
                                    {
                                        string _tmp_value = nData.InnerText;
                                        if (Int64.TryParse(_tmp_value, out itemObject.ID))
                                        {
                                            if (itemObject.ID > _tmp_new_logEvents_high)
                                                _tmp_new_logEvents_high = itemObject.ID;
                                        }
                                        else
                                            itemObject.ID = 0;
                                    }
                                    else if (nData.Name == "type")
                                    {
                                        Int16 _tmp_value = -1;
                                        if (Int16.TryParse(nData.InnerText, out _tmp_value))
                                        {
                                            itemObject.Icon = _tmp_value.ToString();
                                            switch (_tmp_value)
                                            {
                                                case 0:
                                                    itemObject.Level = "Information";
                                                    itemObject.Icon = "Info";
                                                    break;
                                                case 1:
                                                    itemObject.Level = "Warning";
                                                    itemObject.Icon = "Warning";
                                                    break;
                                                case 2:
                                                    itemObject.Level = "Error";
                                                    itemObject.Icon = "Error";
                                                    break;
                                                default:
                                                    itemObject.Level = "Unknown";
                                                    itemObject.Icon = "Default";
                                                    break;
                                            }
                                        }
                                        else
                                        {
                                            itemObject.Level = "Unknown";
                                            itemObject.Icon = "Default";
                                        }
                                    }
                                    else if (nData.Name == "date")
                                    {
                                        itemObject.LoDate = nData.InnerText;
                                        itemObject.HiDate = nData.InnerText;
                                    }
                                    else if (nData.Name == "time")
                                    {
                                        itemObject.LoTime = nData.InnerText;
                                        itemObject.HiTime = nData.InnerText;
                                    }
                                    else if (nData.Name == "user") itemObject.User = nData.InnerText;
                                    else if (nData.Name == "ip") itemObject.IPaddr = nData.InnerText;
                                    else if (nData.Name == "comp") itemObject.Host = nData.InnerText;
                                    else if (nData.Name == "desc") itemObject.Description = nData.InnerText;

                                }
                            }


                            if (itemObject.ID > highNo)
                            {
                                //* --- REMOVE DUPLICATES ---
                                if (global.var_removeDuplicates && qEvents.Count > 1 && ((
                                    qEvents[qEvents.Count - 1].User == itemObject.User &&
                                    qEvents[qEvents.Count - 1].IPaddr == itemObject.IPaddr &&
                                    qEvents[qEvents.Count - 1].Description == itemObject.Description
                                    ) || (
                                    qEvents[qEvents.Count - 1].User == itemObject.User &&
                                    qEvents[qEvents.Count - 1].Host == itemObject.Host &&
                                    qEvents[qEvents.Count - 1].Description == itemObject.Description)))
                                {
                                    DateTimeRoutines.ParsedDateTime loPDT;
                                    DateTimeRoutines.ParsedDateTime hiPDT;
                                    DateTimeRoutines.ParsedDateTime thisItemPDT;

                                    if (DateTimeRoutines.TryParseDateTime(string.Format("{0} {1}",
                                        qEvents[qEvents.Count - 1].HiDate, qEvents[qEvents.Count - 1].HiTime),
                                        DateTimeRoutines.DateTimeFormat.UK_DATE, out hiPDT)

                                        && hiPDT.IsDateFound && hiPDT.IsTimeFound &&

                                        DateTimeRoutines.TryParseDateTime(string.Format("{0} {1}",
                                        qEvents[qEvents.Count - 1].LoDate, qEvents[qEvents.Count - 1].LoTime),
                                        DateTimeRoutines.DateTimeFormat.UK_DATE, out loPDT)

                                        && loPDT.IsDateFound && loPDT.IsTimeFound &&

                                        DateTimeRoutines.TryParseDateTime(string.Format("{0} {1}",
                                        itemObject.LoDate, itemObject.LoTime),
                                        DateTimeRoutines.DateTimeFormat.UK_DATE, out thisItemPDT)

                                        && thisItemPDT.IsDateFound && thisItemPDT.IsTimeFound)
                                    {
                                        int loCompareFlag = DateTime.Compare(thisItemPDT.DateTime, loPDT.DateTime);
                                        int hiCompareFlag = DateTime.Compare(thisItemPDT.DateTime, hiPDT.DateTime);
                                        // (date1 > date2) result > 0
                                        // (date1 = date2) result = 0
                                        // (date1 < date2) result < 0
                                        if (loCompareFlag < 0)
                                        {
                                            qEvents[qEvents.Count - 1].LoDate = itemObject.HiDate;
                                            qEvents[qEvents.Count - 1].LoTime = itemObject.HiTime;
                                            qEvents[qEvents.Count - 1].CompareDateFlag = loCompareFlag;
                                        }
                                        if (hiCompareFlag > 0)
                                        {
                                            qEvents[qEvents.Count - 1].HiDate = itemObject.HiDate;
                                            qEvents[qEvents.Count - 1].HiTime = itemObject.HiTime;
                                            qEvents[qEvents.Count - 1].CompareDateFlag = hiCompareFlag;
                                        }
                                        TimeSpan rangeTime = loPDT.DateTime.Subtract(thisItemPDT.DateTime);
                                        qEvents[qEvents.Count - 1].TotalRangeTime = rangeTime.Seconds.ToString();
                                    }

                                    qEvents[qEvents.Count - 1].Occurs++;

                                }
                                // --- END OF REMOVE DUPLICATES
                                // */
                                else
                                    qEvents.Add(itemObject);

                                //clear item
                                itemObject = null;
                            }
                        }

                        if (_tmp_new_logEvents_high > highNo)
                        {
                            highNo = _tmp_new_logEvents_high;
                            if (qEvents.Count > 0)
                            {
                                virtual_qEvents.InsertRange(0, qEvents);
                                UpdateEventsListView(virtual_qEvents);
                            }
                        }
                        qEvents.Clear();
                    }

                    // --- CONNECTIONS data
                    //
                    if (datatype == "conn")
                    {
                        List<QConnection> qConnections = new List<QConnection>();

                        Int64 _tmp_new_logConnections_high = highNo;

                        XmlNode nItem = lstItems[0];
                        foreach (XmlNode nChild in nItem.ChildNodes)
                        {
                            QConnection itemObject = new QConnection { };

                            if (nChild.Name == "conn")
                            {
                                itemObject.CompareDateFlag = 0;
                                itemObject.Occurs = 1;
                                foreach (XmlNode nData in nChild.ChildNodes)
                                {
                                    if (nData.Name == "id")
                                    {
                                        string _tmp_value = nData.InnerText;
                                        if (Int64.TryParse(_tmp_value, out itemObject.ID))
                                        {
                                            if (itemObject.ID > _tmp_new_logConnections_high)
                                                _tmp_new_logConnections_high = itemObject.ID;
                                        }
                                        else
                                            itemObject.ID = 0;
                                    }
                                    else if (nData.Name == "type")
                                    {
                                        Int16 _tmp_value = -1;
                                        if (Int16.TryParse(nData.InnerText, out _tmp_value))
                                        {
                                            itemObject.Icon = _tmp_value.ToString();
                                            switch (_tmp_value)
                                            {
                                                case 0:
                                                    itemObject.Level = "Information";
                                                    itemObject.Icon = "Info";
                                                    break;
                                                case 1:
                                                    itemObject.Level = "Warning";
                                                    itemObject.Icon = "Warning";
                                                    break;
                                                case 2:
                                                    itemObject.Level = "Error";
                                                    itemObject.Icon = "Error";
                                                    break;
                                                default:
                                                    itemObject.Level = "Unknown";
                                                    itemObject.Icon = "Default";
                                                    break;
                                            }
                                        }
                                        else
                                        {
                                            itemObject.Level = "Unknown";
                                            itemObject.Icon = "Default";
                                        }
                                        itemObject.LogID = itemObject.ID + ": " + itemObject.Level;
                                    }
                                    else if (nData.Name == "date")
                                    {
                                        itemObject.LoDate = nData.InnerText;
                                        itemObject.HiDate = nData.InnerText;
                                    }
                                    else if (nData.Name == "time")
                                    {
                                        itemObject.LoTime = nData.InnerText;
                                        itemObject.HiTime = nData.InnerText;
                                    }
                                    else if (nData.Name == "user") itemObject.User = nData.InnerText;
                                    else if (nData.Name == "ip") itemObject.IPaddr = nData.InnerText;
                                    else if (nData.Name == "comp") itemObject.MachineID = nData.InnerText;
                                    else if (nData.Name == "serv")
                                    {
                                        Int16 _tmp_value = 0;
                                        if (Int16.TryParse(nData.InnerText, out _tmp_value))
                                        {
                                            switch (_tmp_value)
                                            {
                                                case 1:
                                                    itemObject.Protocol = "Samba";
                                                    break;
                                                case 2:
                                                    itemObject.Protocol = "FTP";
                                                    break;
                                                case 3:
                                                    itemObject.Protocol = "HTTP";
                                                    break;
                                                case 4:
                                                    itemObject.Protocol = "NFS";
                                                    break;
                                                case 5:
                                                    itemObject.Protocol = "AFP";
                                                    break;
                                                case 6:
                                                    itemObject.Protocol = "TELNET";
                                                    break;
                                                case 7:
                                                    itemObject.Protocol = "SSH";
                                                    break;
                                                case 8:
                                                    itemObject.Protocol = "iSCSI";
                                                    break;
                                                case 9:
                                                    itemObject.Protocol = "RADIUS";
                                                    break;
                                                case 10:
                                                    itemObject.Protocol = "VPN";
                                                    break;
                                                default:
                                                    itemObject.Protocol = "Unknown";
                                                    break;
                                            }
                                        }
                                        else
                                        {
                                            itemObject.Protocol = "Unknown";
                                        }
                                    }
                                    else if (nData.Name == "action")
                                    {
                                        Int16 _tmp_value = 0;
                                        if (Int16.TryParse(nData.InnerText, out _tmp_value))
                                        {
                                            switch (_tmp_value)
                                            {
                                                case 1:
                                                    itemObject.Action = "Delete";
                                                    break;
                                                case 2:
                                                    itemObject.Action = "Read";
                                                    break;
                                                case 3:
                                                    itemObject.Action = "Write";
                                                    break;
                                                case 4:
                                                    itemObject.Action = "Open";
                                                    break;
                                                case 5:
                                                    itemObject.Action = "MakeDir";
                                                    break;
                                                case 6:
                                                    itemObject.Action = "Mounted"; //?!?!
                                                    break;
                                                case 7:
                                                    itemObject.Action = "Mount Fail";
                                                    break;
                                                case 8:
                                                    itemObject.Action = "Rename";
                                                    break;
                                                case 9:
                                                    itemObject.Action = "Login Fail";
                                                    break;
                                                case 10:
                                                    itemObject.Action = "Logged in";
                                                    break;
                                                case 11:
                                                    itemObject.Action = "Logout";
                                                    break;
                                                case 12:
                                                    itemObject.Action = "Unmount";
                                                    break;
                                                case 13:
                                                    itemObject.Action = "Copy";
                                                    break;
                                                case 14:
                                                    itemObject.Action = "Move";
                                                    break;
                                                case 15:
                                                    itemObject.Action = "Add";
                                                    break;
                                                case 16:
                                                    itemObject.Action = "Auth Fail";
                                                    break;
                                                case 17:
                                                    itemObject.Action = "Authorized";
                                                    break;
                                                default:
                                                    itemObject.Action = "Unknown";
                                                    break;
                                            }
                                        }
                                        else
                                        {
                                            itemObject.Action = "Unknown";
                                        }
                                    }
                                    else if (nData.Name == "res") itemObject.Object = nData.InnerText;

                                }
                                itemObject.LogTime = itemObject.HiDate + " " + itemObject.HiTime;
                                if (itemObject.MachineID == itemObject.IPaddr) itemObject.MachineID = "---";
                            }

                            if (itemObject.ID > highNo)
                            {
                                //* --- REMOVE DUPLICATES ---
                                if (global.var_removeDuplicates && qConnections.Count > 1 && ((
                                    qConnections[qConnections.Count - 1].Icon == itemObject.Icon &&
                                    qConnections[qConnections.Count - 1].User == itemObject.User &&
                                    qConnections[qConnections.Count - 1].IPaddr == itemObject.IPaddr &&
                                    qConnections[qConnections.Count - 1].Action == itemObject.Action &&
                                    qConnections[qConnections.Count - 1].Object == itemObject.Object &&
                                    qConnections[qConnections.Count - 1].Protocol == itemObject.Protocol
                                    ) || (
                                    qConnections[qConnections.Count - 1].Icon == itemObject.Icon &&
                                    qConnections[qConnections.Count - 1].User == itemObject.User &&
                                    qConnections[qConnections.Count - 1].MachineID == itemObject.MachineID &&
                                    qConnections[qConnections.Count - 1].Action == itemObject.Action &&
                                    qConnections[qConnections.Count - 1].Object == itemObject.Object &&
                                    qConnections[qConnections.Count - 1].Protocol == itemObject.Protocol)))
                                {
                                    DateTimeRoutines.ParsedDateTime loPDT;
                                    DateTimeRoutines.ParsedDateTime hiPDT;
                                    DateTimeRoutines.ParsedDateTime thisItemPDT;

                                    if (DateTimeRoutines.TryParseDateTime(string.Format("{0} {1}",
                                        qConnections[qConnections.Count - 1].HiDate, qConnections[qConnections.Count - 1].HiTime),
                                        DateTimeRoutines.DateTimeFormat.UK_DATE, out hiPDT)

                                        && hiPDT.IsDateFound && hiPDT.IsTimeFound &&

                                        DateTimeRoutines.TryParseDateTime(string.Format("{0} {1}",
                                        qConnections[qConnections.Count - 1].LoDate, qConnections[qConnections.Count - 1].LoTime),
                                        DateTimeRoutines.DateTimeFormat.UK_DATE, out loPDT)

                                        && loPDT.IsDateFound && loPDT.IsTimeFound &&

                                        DateTimeRoutines.TryParseDateTime(string.Format("{0} {1}",
                                        itemObject.LoDate, itemObject.LoTime),
                                        DateTimeRoutines.DateTimeFormat.UK_DATE, out thisItemPDT)

                                        && thisItemPDT.IsDateFound && thisItemPDT.IsTimeFound)
                                    {
                                        int loCompareFlag = DateTime.Compare(thisItemPDT.DateTime, loPDT.DateTime);
                                        int hiCompareFlag = DateTime.Compare(thisItemPDT.DateTime, hiPDT.DateTime);
                                        // (date1 > date2) result > 0
                                        // (date1 = date2) result = 0
                                        // (date1 < date2) result < 0
                                        if (loCompareFlag < 0)
                                        {
                                            qConnections[qConnections.Count - 1].LoDate = itemObject.HiDate;
                                            qConnections[qConnections.Count - 1].LoTime = itemObject.HiTime;
                                            qConnections[qConnections.Count - 1].CompareDateFlag = loCompareFlag;
                                        }
                                        if (hiCompareFlag > 0)
                                        {
                                            qConnections[qConnections.Count - 1].HiDate = itemObject.HiDate;
                                            qConnections[qConnections.Count - 1].HiTime = itemObject.HiTime;
                                            qConnections[qConnections.Count - 1].CompareDateFlag = hiCompareFlag;
                                        }
                                        TimeSpan rangeTime = loPDT.DateTime.Subtract(thisItemPDT.DateTime);
                                        qConnections[qConnections.Count - 1].TotalRangeTime = rangeTime.Seconds.ToString();
                                    }

                                    qConnections[qConnections.Count - 1].Occurs++;

                                    if (qConnections[qConnections.Count - 1].Occurs != 0)
                                    {
                                        qConnections[qConnections.Count - 1].LogID = qConnections[qConnections.Count - 1].ID
                                            + ": " + qConnections[qConnections.Count - 1].Level
                                            + " [x" + qConnections[qConnections.Count - 1].Occurs + "]";

                                        // set date
                                        if (qConnections[qConnections.Count - 1].CompareDateFlag != 0 &&
                                            qConnections[qConnections.Count - 1].Occurs != 1)
                                        {
                                            if (qConnections[qConnections.Count - 1].LoDate == qConnections[qConnections.Count - 1].HiDate)
                                                qConnections[qConnections.Count - 1].LogTime =
                                                    string.Format("{0} {1} <-- x {2}",
                                                    qConnections[qConnections.Count - 1].HiDate, qConnections[qConnections.Count - 1].HiTime,
                                                    qConnections[qConnections.Count - 1].LoTime);
                                            else
                                                qConnections[qConnections.Count - 1].LogTime =
                                                    string.Format("{0} {1} <-- {2} {3}",
                                                    qConnections[qConnections.Count - 1].HiDate, qConnections[qConnections.Count - 1].HiTime,
                                                    qConnections[qConnections.Count - 1].LoDate, qConnections[qConnections.Count - 1].LoTime);
                                        }
                                    }

                                }
                                // --- END OF REMOVE DUPLICATES
                                // */
                                else
                                    qConnections.Add(itemObject);

                                itemObject = null;
                            }
                        }

                        if (_tmp_new_logConnections_high > highNo)
                        {
                            highNo = _tmp_new_logConnections_high;
                            if (qConnections.Count > 0)
                            {
                                virtual_qConnections.InsertRange(0, qConnections);
                                UpdateConnectionsListView(virtual_qConnections);
                            }
                        }
                        qConnections.Clear();
                    }
                }
            }
        }

    }
}
 
Klasa QNAP.Web.Base
C#:
using System;
using System.Collections.Specialized;
using System.Net;
using System.Net.Cache;
using System.Text;
using System.IO;

namespace QNAP.Web.Base
{
    /// <summary>
    ///This base class provides implementation of request
    ///and response methods during Http Calls.
    /// </summary>
    public class HttpBaseClass
    {
        private string UserName;
        private string UserPwd;
        private string ProxyServer;
        private int ProxyPort;
        private string Request;

        public HttpBaseClass(string HttpUserName, string HttpUserPwd, string HttpProxyServer, int HttpProxyPort, string HttpRequest)
        {
            UserName = HttpUserName;
            UserPwd = HttpUserPwd;
            ProxyServer = HttpProxyServer;
            ProxyPort = HttpProxyPort;
            Request = HttpRequest;
        }

        /// <summary>
        /// This method creates secure/non secure web
        /// request based on the parameters passed.
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="collHeader">This parameter of type
        ///    NameValueCollection may contain any extra header
        ///    elements to be included in this request      </param>
        /// <param name="RequestMethod">Value can POST OR GET</param>
        /// <param name="NwCred">In case of secure request this would be true</param>
        /// <returns></returns>
        public virtual HttpWebRequest CreateWebRequest(string uri, NameValueCollection collHeader, string RequestMethod, bool NwCred)
        {
            if ((RequestMethod.ToUpper() != "GET") && (RequestMethod.ToUpper() != "POST"))
                throw new ArgumentException(RequestMethod + " is not a valid method. Use GET or POST.", "method");

            // not sure - begin
            System.Net.ServicePointManager.Expect100Continue = false;

            //allows all SSL certificates
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

            HttpRequestCachePolicy cache = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
            HttpWebRequest.DefaultCachePolicy = cache;
            // not sure - ends

            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);

            webrequest.CachePolicy = cache;

            webrequest.KeepAlive = false;
            webrequest.Accept = "*/*";
            webrequest.Method = RequestMethod;
            webrequest.UserAgent = "Qlogr/1.0+(compatible;+MSIE+5.01;+Windows+NT+5.0";

            int iCount = collHeader.Count;
            string key;
            string keyvalue;

            for (int i = 0; i < iCount; i++)
            {
                key = collHeader.Keys[i];
                keyvalue = collHeader[i];
                webrequest.Headers.Add(key, keyvalue);
            }

            //webrequest.ContentType = "text/html";
            webrequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";

            if (ProxyServer.Length > 0)
            {
                webrequest.Proxy = new
                 WebProxy(ProxyServer, ProxyPort);
            }
            webrequest.AllowAutoRedirect = false;

            if (NwCred)
            {
                CredentialCache wrCache = new CredentialCache();
                wrCache.Add(new Uri(uri), "Basic", new NetworkCredential(UserName, UserPwd));
                webrequest.Credentials = wrCache;
            }
            else
            {
                webrequest.Credentials = CredentialCache.DefaultCredentials;
                webrequest.UseDefaultCredentials = true;
            }

            //Remove collection elements
            collHeader.Clear();

            return webrequest;
        } //End of secure CreateWebRequest

        /// <summary>
        /// This method retreives redirected URL from
        /// response header and also passes back
        /// any cookie (if there is any)
        /// </summary>
        /// <param name="webresponse"></param>
        /// <param name="Cookie"></param>
        /// <returns></returns>
        public virtual string GetRedirectURL(HttpWebResponse webresponse, ref string Cookie)
        {
            string uri = "";

            WebHeaderCollection headers = webresponse.Headers;

            if ((webresponse.StatusCode == HttpStatusCode.Found) ||
              (webresponse.StatusCode == HttpStatusCode.Redirect) ||
              (webresponse.StatusCode == HttpStatusCode.Moved) ||
              (webresponse.StatusCode == HttpStatusCode.MovedPermanently))
            {
                // Get redirected uri
                uri = headers["Location"];
                uri = uri.Trim();
            }

            //Check for any cookies
            if (headers["Set-Cookie"] != null)
            {
                Cookie = headers["Set-Cookie"];
            }
            //                string StartURI = "http:/";
            //                if (uri.Length > 0 && uri.StartsWith(StartURI)==false)
            //                {
            //                      uri = StartURI + uri;
            //                }
            return uri;
        } //End of GetRedirectURL method

        public virtual string GetFinalResponse(string ReUri, string Cookie, string RequestMethod, bool NwCred)
        {
            NameValueCollection collHeader = new NameValueCollection();

            if (Cookie.Length > 0)
            {
                collHeader.Add("Cookie", Cookie);
            }

            // not sure - begin
            System.Net.ServicePointManager.Expect100Continue = false;

            //allows all SSL certificates
            ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

            HttpRequestCachePolicy cache = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
            HttpWebRequest.DefaultCachePolicy = cache;
            // not sure - ends

            HttpWebRequest webrequest = CreateWebRequest(ReUri, collHeader, RequestMethod, NwCred);

            webrequest.CachePolicy = cache;

            BuildReqStream(ref webrequest);

            HttpWebResponse webresponse;

            webresponse = (HttpWebResponse)webrequest.GetResponse();

            //Encoding enc = System.Text.Encoding.GetEncoding(1252);
            Encoding enc = System.Text.Encoding.GetEncoding("utf-8");
            StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream(), enc);

            string Response = loResponseStream.ReadToEnd();

            loResponseStream.Close();
            webresponse.Close();

            return Response;
        }

        private void BuildReqStream(ref HttpWebRequest webrequest)
        //This method build the request stream for WebRequest
        {
            byte[] bytes = Encoding.ASCII.GetBytes(Request);
            webrequest.ContentLength = bytes.Length;

            Stream oStreamOut = webrequest.GetRequestStream();
            oStreamOut.Write(bytes, 0, bytes.Length);
            oStreamOut.Close();
        }
    }
} //End of HttpBaseClass class

//End of Base Class
 
Klasa QNAP.Web.Service
C#:
using System;
using System.Collections.Specialized;
using System.Net;
using System.Text;
using System.IO;
using QNAP.Web.Base;

namespace QNAP.Web.Service
{
    public class HttpRequestResponse
    {
        private string URI;
        private string Request;
        private string UserName;
        private string UserPwd;
        private string ProxyServer;
        private int ProxyPort;
        private string RequestMethod = "GET";
        //private string RequestMethod = "POST";

        public HttpRequestResponse(string pRequest, string pURI) //Constructor
        {
            Request = pRequest;
            URI = pURI;
        }

        public string HTTP_USER_NAME
        {
            get
            {
                return UserName;
            }
            set
            {
                UserName = value;
            }
        }

        public string HTTP_USER_PASSWORD
        {
            get
            {
                return UserPwd;
            }
            set
            {
                UserPwd = value;
            }
        }

        public string PROXY_SERVER
        {
            get
            {
                return ProxyServer;
            }
            set
            {
                ProxyServer = value;
            }
        }

        public int PROXY_PORT
        {
            get
            {
                return ProxyPort;
            }
            set
            {
                ProxyPort = value;
            }
        }

        public string SendRequest()
        /* This public interface receives the request and send the response of type string. // */
        {
            string FinalResponse = "";
            string Cookie = "";
         
            bool NwCred = false;
            if ((UserName != null) && (UserPwd != null)) NwCred = true;

            NameValueCollection collHeader = new NameValueCollection();

            HttpWebResponse webresponse;

            HttpBaseClass BaseHttp = new HttpBaseClass(UserName, UserPwd, ProxyServer, ProxyPort, Request);
            try
            {
                HttpWebRequest webrequest = BaseHttp.CreateWebRequest(URI, collHeader, RequestMethod, NwCred);
                webresponse = (HttpWebResponse)webrequest.GetResponse();

                //Check if there is any redirected URI.
                string ReUri = BaseHttp.GetRedirectURL(webresponse, ref Cookie);

                webresponse.Close();
                ReUri = ReUri.Trim();
                if (ReUri.Length == 0) //No redirection URI
                {
                    ReUri = URI;
                }
                RequestMethod = "POST";
                FinalResponse = BaseHttp.GetFinalResponse(ReUri, Cookie, RequestMethod, NwCred);

            } //End of Try Block

#if !DEBUG
            catch (WebException e)
            {
                throw CatchHttpExceptions(FinalResponse = e.Message);
            }
            catch (System.Exception e)
            {
                throw new Exception(FinalResponse = e.Message);
            }
#endif

            finally
            {
                BaseHttp = null;
            }
            return FinalResponse;
        } //End of SendRequestTo method

        private WebException CatchHttpExceptions(string ErrMsg)
        {
            ErrMsg = "Error During Web Interface. Error is: " + ErrMsg;
            return new WebException(ErrMsg);
        }
    } //End of RequestResponse Class
}
 
Helper dla ustawienia aplikacji w autouruchomieniu Windows'a:
C#:
public class Helpers
{
    private const string RUN_LOCATION = @"Software\Microsoft\Windows\CurrentVersion\Run";

    /// <summary>  
    /// Sets the autostart value for the assembly.  
    /// </summary>  
    /// <param name="keyName">Registry Key Name</param>  
    /// <param name="assemblyLocation">Assembly location (e.g. Assembly.GetExecutingAssembly().Location)</param>  
    public static void SetAutoStart(string keyName, string assemblyLocation)
    {
        RegistryKey key = Registry.CurrentUser.CreateSubKey(RUN_LOCATION);
        key.SetValue(keyName, assemblyLocation);
    }

    /// <summary>  
    /// Returns whether auto start is enabled.  
    /// </summary>  
    /// <param name="keyName">Registry Key Name</param>  
    /// <param name="assemblyLocation">Assembly location (e.g. Assembly.GetExecutingAssembly().Location)</param>
    public static bool IsAutoStartEnabled(string keyName, string assemblyLocation)
    {
        RegistryKey key = Registry.CurrentUser.OpenSubKey(RUN_LOCATION);
        if (key == null) return false;
        string value = (string)key.GetValue(keyName);
        if (value == null) return false;
        return (value == assemblyLocation);
    }

    /// <summary>  
    /// Unsets the autostart value for the assembly.  
    /// </summary>  
    /// <param name="keyName">Registry Key Name</param>  
    public static void UnSetAutoStart(string keyName)
    {
        RegistryKey key = Registry.CurrentUser.CreateSubKey(RUN_LOCATION);
        key.DeleteValue(keyName);
    }
}
 
Helper włączający podwójne buforowanie formy (rozwiązuje problem migotania w przypadlku aktualizacji dużej ilości elementów podczas widoku ListView itp.)
C#:
public class Helpers
{
    public static void SetDoubleBuffered(System.Windows.Forms.Control c)
    {
        //Taxes: Remote Desktop Connection and painting
        //http://blogs.msdn.com/oldnewthing/archive/2006/01/03/508694.aspx
        if (System.Windows.Forms.SystemInformation.TerminalServerSession)
            return;

        System.Reflection.PropertyInfo aProp =
              typeof(System.Windows.Forms.Control).GetProperty(
                    "DoubleBuffered",
                    System.Reflection.BindingFlags.NonPublic |
                    System.Reflection.BindingFlags.Instance);

        aProp.SetValue(c, true, null);
    }

}
 
Formatowanie komórek ListView (np. przypisanie ikony ostrzeżenia, błędu lub informacji dla elementu)
C#:
private void folvEvents_FormatCell(object sender, FormatCellEventArgs e)
{
    QEvent qEvent = (QEvent)e.Model;

    if (qEvent.Level == "Warning") e.SubItem.BackColor = Settings.Default.listviewWarningBackgroundColor;
    else if (qEvent.Level == "Error") e.SubItem.BackColor = Settings.Default.listviewErrorBackgroundColor;

    if (e.ColumnIndex == 0)
    {
        //QEvent qEvent = (QEvent)e.Model;
        itemDecorationReport decoration = new itemDecorationReport();
        decoration.ImageList = this.imageList32;
        decoration.Icon = qEvent.Icon ?? "Unknown";
        decoration.ID = qEvent.ID;
        decoration.Level = qEvent.Level ?? "Unknown";
        decoration.CompareDateFlag = qEvent.CompareDateFlag;
        decoration.TotalRangeTime = qEvent.TotalRangeTime;
        decoration.Occurs = qEvent.Occurs;
        e.SubItem.Decoration = decoration;
    }
    else if (e.ColumnIndex == 1)
    {
        itemDecorationTime decoration = new itemDecorationTime();
        decoration.LoDate = qEvent.LoDate ?? "Unknown date";
        decoration.LoTime = qEvent.LoTime ?? "Unknown time";
        decoration.HiDate = qEvent.HiDate ?? "Unknown date";
        decoration.HiTime = qEvent.HiTime ?? "Unknown time";
        decoration.CompareDateFlag = qEvent.CompareDateFlag;
        decoration.Occurs = qEvent.Occurs;
        e.SubItem.Decoration = decoration;
    }
    else if (e.ColumnIndex == 2)
    {
        itemDecorationIdentity decoration = new itemDecorationIdentity();
        decoration.User = qEvent.User ?? "Unknown user";
        decoration.Host = qEvent.Host ?? "Unknown";
        decoration.IPaddr = qEvent.IPaddr ?? "Unknown";
        e.SubItem.Decoration = decoration;
    }
    else if (e.ColumnIndex == 3)
    {
        itemDecorationDescription decoration = new itemDecorationDescription();
        decoration.Description = qEvent.Description ?? "Unknown user";
        e.SubItem.Decoration = decoration;
    }
}
 
Klasa przetwarzania daty i czasu.
DateTimeRoutines | Free software downloads at SourceForge.net
C# Date Time Parser - CodeProject
C#:
//********************************************************************************************
//Author: Sergey Stoyan, CliverSoft.com
//        http://cliversoft.com
//        stoyan@cliversoft.com
//        sergey.stoyan@gmail.com
//        27 February 2007
//********************************************************************************************

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Collections;
using System.Web;

namespace DataTimeRoutines
{
    /// <summary>
    /// Miscellaneous and parsing methods for DateTime
    /// </summary>
    public static class DateTimeRoutines
    {
        #region miscellaneous methods

        /// <summary>
        /// Amount of seconds elapsed between 1970-01-01 00:00:00 and the date-time.
        /// </summary>
        /// <param name="date_time">date-time</param>
        /// <returns>seconds</returns>
        public static uint GetSecondsSinceUnixEpoch(DateTime date_time)
        {
            TimeSpan t = date_time - new DateTime(1970, 1, 1);
            int ss = (int)t.TotalSeconds;
            if (ss < 0)
                return 0;
            return (uint)ss;
        }

        #endregion

        #region parsing definitions

        /// <summary>
        /// Defines a substring where date-time was found and result of conversion
        /// </summary>
        public class ParsedDateTime
        {
            /// <summary>
            /// Index of first char of a date substring found in the string
            /// </summary>
            readonly public int IndexOfDate = -1;
            /// <summary>
            /// Length a date substring found in the string
            /// </summary>
            readonly public int LengthOfDate = -1;
            /// <summary>
            /// Index of first char of a time substring found in the string
            /// </summary>
            readonly public int IndexOfTime = -1;
            /// <summary>
            /// Length of a time substring found in the string
            /// </summary>
            readonly public int LengthOfTime = -1;
            /// <summary>
            /// DateTime found in the string
            /// </summary>
            readonly public DateTime DateTime;
            /// <summary>
            /// True if a date was found within the string
            /// </summary>
            readonly public bool IsDateFound;
            /// <summary>
            /// True if a time was found within the string
            /// </summary>
            readonly public bool IsTimeFound;

            internal ParsedDateTime(int index_of_date, int length_of_date, int index_of_time, int length_of_time, DateTime date_time)
            {
                IndexOfDate = index_of_date;
                LengthOfDate = length_of_date;
                IndexOfTime = index_of_time;
                LengthOfTime = length_of_time;
                DateTime = date_time;
                IsDateFound = index_of_date > -1;
                IsTimeFound = index_of_time > -1;
            }
        }

        /// <summary>
        /// Date that is accepted in the following cases:
        /// - no date was parsed by TryParseDateOrTime();
        /// - no year was found by TryParseDate();
        /// It is ignored if DefaultDateIsNow = true was set after DefaultDate
        /// </summary>
        public static DateTime DefaultDate
        {
            set
            {
                _DefaultDate = value;
                DefaultDateIsNow = false;
            }
            get
            {
                if (DefaultDateIsNow)
                    return DateTime.Now;
                else
                    return _DefaultDate;
            }
        }
        static DateTime _DefaultDate = DateTime.Now;

        /// <summary>
        /// If true then DefaultDate property is ignored and DefaultDate is always DateTime.Now
        /// </summary>
        public static bool DefaultDateIsNow = true;

        /// <summary>
        /// Defines default date-time format.
        /// </summary>
        public enum DateTimeFormat
        {
            /// <summary>
            /// month number goes before day number
            /// </summary>
            USA_DATE,
            /// <summary>
            /// day number goes before month number
            /// </summary>
            UK_DATE,
            ///// <summary>
            ///// time is specifed through AM or PM
            ///// </summary>
            //USA_TIME,
        }

        #endregion

        #region parsing derived methods for DateTime output

        /// <summary>
        /// Tries to find date and time within the passed string and return it as DateTime structure.
        /// </summary>
        /// <param name="str">string that contains date and/or time</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="date_time">parsed date-time output</param>
        /// <returns>true if both date and time were found, else false</returns>
        static public bool TryParseDateTime(string str, DateTimeFormat default_format, out DateTime date_time)
        {
            ParsedDateTime parsed_date_time;
            if (!TryParseDateTime(str, default_format, out parsed_date_time))
            {
                date_time = new DateTime(1, 1, 1);
                return false;
            }
            date_time = parsed_date_time.DateTime;
            return true;
        }

        /// <summary>
        /// Tries to find date and/or time within the passed string and return it as DateTime structure.
        /// If only date was found, time in the returned DateTime is always 0:0:0.
        /// If only time was found, date in the returned DateTime is DefaultDate.
        /// </summary>
        /// <param name="str">string that contains date and(or) time</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="date_time">parsed date-time output</param>
        /// <returns>true if date and/or time was found, else false</returns>
        static public bool TryParseDateOrTime(string str, DateTimeFormat default_format, out DateTime date_time)
        {
            ParsedDateTime parsed_date_time;
            if (!TryParseDateOrTime(str, default_format, out parsed_date_time))
            {
                date_time = new DateTime(1, 1, 1);
                return false;
            }
            date_time = parsed_date_time.DateTime;
            return true;
        }

        /// <summary>
        /// Tries to find time within the passed string and return it as DateTime structure.
        /// It recognizes only time while ignoring date, so date in the returned DateTime is always 1/1/1.
        /// </summary>
        /// <param name="str">string that contains time</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="time">parsed time output</param>
        /// <returns>true if time was found, else false</returns>
        public static bool TryParseTime(string str, DateTimeFormat default_format, out DateTime time)
        {
            ParsedDateTime parsed_time;
            if (!TryParseTime(str, default_format, out parsed_time, null))
            {
                time = new DateTime(1, 1, 1);
                return false;
            }
            time = parsed_time.DateTime;
            return true;
        }

        /// <summary>
        /// Tries to find date within the passed string and return it as DateTime structure.
        /// It recognizes only date while ignoring time, so time in the returned DateTime is always 0:0:0.
        /// If year of the date was not found then it accepts the current year.
        /// </summary>
        /// <param name="str">string that contains date</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="date">parsed date output</param>
        /// <returns>true if date was found, else false</returns>
        static public bool TryParseDate(string str, DateTimeFormat default_format, out DateTime date)
        {
            ParsedDateTime parsed_date;
            if (!TryParseDate(str, default_format, out parsed_date))
            {
                date = new DateTime(1, 1, 1);
                return false;
            }
            date = parsed_date.DateTime;
            return true;
        }

        #endregion

        #region parsing derived methods for ParsedDateTime output

        /// <summary>
        /// Tries to find date and time within the passed string and return it as ParsedDateTime object.
        /// </summary>
        /// <param name="str">string that contains date-time</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="parsed_date_time">parsed date-time output</param>
        /// <returns>true if both date and time were found, else false</returns>
        static public bool TryParseDateTime(string str, DateTimeFormat default_format, out ParsedDateTime parsed_date_time)
        {
            if (DateTimeRoutines.TryParseDateOrTime(str, default_format, out parsed_date_time)
                && parsed_date_time.IsDateFound
                && parsed_date_time.IsTimeFound
                )
                return true;

            parsed_date_time = null;
            return false;
        }

        /// <summary>
        /// Tries to find time within the passed string and return it as ParsedDateTime object.
        /// It recognizes only time while ignoring date, so date in the returned ParsedDateTime is always 1/1/1
        /// </summary>
        /// <param name="str">string that contains date-time</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="parsed_time">parsed date-time output</param>
        /// <returns>true if time was found, else false</returns>
        static public bool TryParseTime(string str, DateTimeFormat default_format, out ParsedDateTime parsed_time)
        {
            return TryParseTime(str, default_format, out parsed_time, null);
        }

        /// <summary>
        /// Tries to find date and/or time within the passed string and return it as ParsedDateTime object.
        /// If only date was found, time in the returned ParsedDateTime is always 0:0:0.
        /// If only time was found, date in the returned ParsedDateTime is DefaultDate.
        /// </summary>
        /// <param name="str">string that contains date-time</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="parsed_date_time">parsed date-time output</param>
        /// <returns>true if date or time was found, else false</returns>
        static public bool TryParseDateOrTime(string str, DateTimeFormat default_format, out ParsedDateTime parsed_date_time)
        {
            parsed_date_time = null;

            ParsedDateTime parsed_date;
            ParsedDateTime parsed_time;
            if (!TryParseDate(str, default_format, out parsed_date))
            {
                if (!TryParseTime(str, default_format, out parsed_time, null))
                    return false;

                DateTime date_time = new DateTime(DefaultDate.Year, DefaultDate.Month, DefaultDate.Day, parsed_time.DateTime.Hour, parsed_time.DateTime.Minute, parsed_time.DateTime.Second);
                parsed_date_time = new ParsedDateTime(-1, -1, parsed_time.IndexOfTime, parsed_time.LengthOfTime, date_time);
            }
            else
            {
                if (!TryParseTime(str, default_format, out parsed_time, parsed_date))
                {
                    DateTime date_time = new DateTime(parsed_date.DateTime.Year, parsed_date.DateTime.Month, parsed_date.DateTime.Day, 0, 0, 0);
                    parsed_date_time = new ParsedDateTime(parsed_date.IndexOfDate, parsed_date.LengthOfDate, -1, -1, date_time);
                }
                else
                {
                    DateTime date_time = new DateTime(parsed_date.DateTime.Year, parsed_date.DateTime.Month, parsed_date.DateTime.Day, parsed_time.DateTime.Hour, parsed_time.DateTime.Minute, parsed_time.DateTime.Second);
                    parsed_date_time = new ParsedDateTime(parsed_date.IndexOfDate, parsed_date.LengthOfDate, parsed_time.IndexOfTime, parsed_time.LengthOfTime, date_time);
                }
            }

            return true;
        }

        #endregion

        #region parsing base methods

        /// <summary>
        /// Tries to find time within the passed string (relatively to the passed parsed_date if any) and return it as ParsedDateTime object.
        /// It recognizes only time while ignoring date, so date in the returned ParsedDateTime is always 1/1/1
        /// </summary>
        /// <param name="str">string that contains date</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="parsed_time">parsed date-time output</param>
        /// <param name="parsed_date">ParsedDateTime object if the date was found within this string, else NULL</param>
        /// <returns>true if time was found, else false</returns>
        public static bool TryParseTime(string str, DateTimeFormat default_format, out ParsedDateTime parsed_time, ParsedDateTime parsed_date)
        {
            parsed_time = null;

            Match m;
            if (parsed_date != null && parsed_date.IndexOfDate > -1)
            {//look around the found date
                //look for <date> [h]h:mm[:ss] [PM/AM]
                m = Regex.Match(str.Substring(parsed_date.IndexOfDate + parsed_date.LengthOfDate), @"(?<=^\s*,?\s+|^\s*at\s*|^\s*[T\-]\s*)(?'hour'\d{1,2})\s*:\s*(?'minute'\d{2})\s*(?::\s*(?'second'\d{2}))?(?:\s*(?'ampm'AM|am|PM|pm))?(?=$|[^\d\w])", RegexOptions.Compiled);
                if (!m.Success)
                    //look for [h]h:mm:ss <date>
                    m = Regex.Match(str.Substring(0, parsed_date.IndexOfDate), @"(?<=^|[^\d])(?'hour'\d{1,2})\s*:\s*(?'minute'\d{2})\s*(?::\s*(?'second'\d{2}))?(?:\s*(?'ampm'AM|am|PM|pm))?(?=$|[\s,]+)", RegexOptions.Compiled);
            }
            else//look anywere within string
                //look for [h]h:mm[:ss] [PM/AM]
                m = Regex.Match(str, @"(?<=^|\s+|\s*T\s*)(?'hour'\d{1,2})\s*:\s*(?'minute'\d{2})\s*(?::\s*(?'second'\d{2}))?(?:\s*(?'ampm'AM|am|PM|pm))?(?=$|[^\d\w])", RegexOptions.Compiled);

            if (m.Success)
            {
                try
                {
                    int hour = int.Parse(m.Groups["hour"].Value);
                    if (hour < 0 || hour > 23)
                        return false;

                    int minute = int.Parse(m.Groups["minute"].Value);
                    if (minute < 0 || minute > 59)
                        return false;

                    int second = 0;
                    if (!string.IsNullOrEmpty(m.Groups["second"].Value))
                    {
                        second = int.Parse(m.Groups["second"].Value);
                        if (second < 0 || second > 59)
                            return false;
                    }

                    if (string.Compare(m.Groups["ampm"].Value, "PM", true) == 0)
                        hour += 12;

                    DateTime date_time = new DateTime(1, 1, 1, hour, minute, second);
                    parsed_time = new ParsedDateTime(-1, -1, m.Index, m.Length, date_time);
                }
                catch
                {
                    return false;
                }
                return true;
            }

            return false;
        }

        /// <summary>
        /// Tries to find date within the passed string and return it as ParsedDateTime object.
        /// It recognizes only date while ignoring time, so time in the returned ParsedDateTime is always 0:0:0.
        /// If year of the date was not found then it accepts the current year.
        /// </summary>
        /// <param name="str">string that contains date</param>
        /// <param name="default_format">format to be used preferably in ambivalent instances</param>
        /// <param name="parsed_date">parsed date output</param>
        /// <returns>true if date was found, else false</returns>
        static public bool TryParseDate(string str, DateTimeFormat default_format, out ParsedDateTime parsed_date)
        {
            parsed_date = null;

            if (string.IsNullOrEmpty(str))
                return false;

            //look for dd/mm/yy
            Match m = Regex.Match(str, @"(?<=^|[^\d])(?'day'\d{1,2})\s*(?'separator'[\\/\.])+\s*(?'month'\d{1,2})\s*\'separator'+\s*(?'year'\d{2}|\d{4})(?=$|[^\d])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            if (m.Success)
            {
                DateTime date;
                if ((default_format ^ DateTimeFormat.USA_DATE) == DateTimeFormat.USA_DATE)
                {
                    if (!convert_to_date(int.Parse(m.Groups["year"].Value), int.Parse(m.Groups["day"].Value), int.Parse(m.Groups["month"].Value), out date))
                        return false;
                }
                else
                {
                    if (!convert_to_date(int.Parse(m.Groups["year"].Value), int.Parse(m.Groups["month"].Value), int.Parse(m.Groups["day"].Value), out date))
                        return false;
                }
                parsed_date = new ParsedDateTime(m.Index, m.Length, -1, -1, date);
                return true;
            }

            //look for [yy]yy-mm-dd
            m = Regex.Match(str, @"(?<=^|[^\d])(?'year'\d{2}|\d{4})\s*(?'separator'[\-])\s*(?'month'\d{1,2})\s*\'separator'+\s*(?'day'\d{1,2})(?=$|[^\d])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            if (m.Success)
            {
                DateTime date;
                if (!convert_to_date(int.Parse(m.Groups["year"].Value), int.Parse(m.Groups["month"].Value), int.Parse(m.Groups["day"].Value), out date))
                    return false;
                parsed_date = new ParsedDateTime(m.Index, m.Length, -1, -1, date);
                return true;
            }

            //look for month dd yyyy
            m = Regex.Match(str, @"(?:^|[^\d\w])(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*\s+(?'day'\d{1,2})(?:-?st|-?th|-?rd|-?nd)?\s*,?\s*(?'year'\d{4})(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            if (!m.Success)
                //look for dd month [yy]yy
                m = Regex.Match(str, @"(?:^|[^\d\w:])(?'day'\d{1,2})(?:-?st\s+|-?th\s+|-?rd\s+|-?nd\s+|-|\s+)(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*(?:\s*,?\s*|-)'?(?'year'\d{2}|\d{4})(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            if (!m.Success)
                //look for yyyy month dd
                m = Regex.Match(str, @"(?:^|[^\d\w])(?'year'\d{4})\s+(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*\s+(?'day'\d{1,2})(?:-?st|-?th|-?rd|-?nd)?(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            if (!m.Success)
                //look for  month dd [yyyy]
                m = Regex.Match(str, @"(?:^|[^\d\w])(?'month'Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[uarychilestmbro]*\s+(?'day'\d{1,2})(?:-?st|-?th|-?rd|-?nd)?(?:\s*,?\s*(?'year'\d{4}))?(?=$|[^\d\w])", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            if (m.Success)
            {
                int month = -1;
                int index_of_date = m.Index;
                int length_of_date = m.Length;

                switch (m.Groups["month"].Value)
                {
                    case "Jan":
                    case "JAN":
                        month = 1;
                        break;
                    case "Feb":
                    case "FEB":
                        month = 2;
                        break;
                    case "Mar":
                    case "MAR":
                        month = 3;
                        break;
                    case "Apr":
                    case "APR":
                        month = 4;
                        break;
                    case "May":
                    case "MAY":
                        month = 5;
                        break;
                    case "Jun":
                    case "JUN":
                        month = 6;
                        break;
                    case "Jul":
                        month = 7;
                        break;
                    case "Aug":
                    case "AUG":
                        month = 8;
                        break;
                    case "Sep":
                    case "SEP":
                        month = 9;
                        break;
                    case "Oct":
                    case "OCT":
                        month = 10;
                        break;
                    case "Nov":
                    case "NOV":
                        month = 11;
                        break;
                    case "Dec":
                    case "DEC":
                        month = 12;
                        break;
                }

                int year;
                if (!string.IsNullOrEmpty(m.Groups["year"].Value))
                    year = int.Parse(m.Groups["year"].Value);
                else
                    year = DefaultDate.Year;

                DateTime date;
                if (!convert_to_date(year, month, int.Parse(m.Groups["day"].Value), out date))
                    return false;
                parsed_date = new ParsedDateTime(index_of_date, length_of_date, -1, -1, date);
                return true;
            }

            return false;
        }

        static bool convert_to_date(int year, int month, int day, out DateTime date)
        {
            if (year >= 100)
            {
                if (year < 1000)
                {
                    date = new DateTime(1, 1, 1);
                    return false;
                }
            }
            else
                if (year > 30)
                    year += 1900;
                else
                    year += 2000;

            try
            {
                date = new DateTime(year, month, day);
            }
            catch
            {
                date = new DateTime(1, 1, 1);
                return false;
            }
            return true;
        }

        #endregion
    }
}