Click here to Skip to main content
15,894,460 members
Articles / Web Development / ASP.NET

Checksum Verification

Rate me:
Please Sign up or sign in to vote.
5.00/5 (3 votes)
22 Sep 2011CPOL3 min read 52.5K   1.4K   17  
Loop through all files in a folder/subfolders and run a checksum that is stored in a database. E-mail descrepancies and results.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using System.Diagnostics;
using System.Configuration;
using System.Data;
using MySql.Data.MySqlClient;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using ChecksumFiles.Utilities;


namespace ChecksumFiles
{
    class Program
    {
        // Public variables
        public static string m_results = Settings.Default.ResultFile.ToString();
        public static string m_errors = Settings.Default.ErrorFile.ToString();

        
        static void Main(string[] args)
        {

            #region Local variables

            string m_path = Settings.Default.DirectoryPath.ToString();
            string m_notification_title = Settings.Default.NotificationTitle.ToString();
            string m_notification_from = Settings.Default.NotificationFrom.ToString();
            string m_notification_to = Settings.Default.NotificationTo.ToString();
            string m_newfiles = Settings.Default.NewFiles.ToString();
            string m_changedfiles = Settings.Default.ChangedFiles.ToString();
            string m_filename = "";

            #endregion

            #region Database workload

            // Connect to database
            string m_conn = ConfigurationManager.ConnectionStrings["MySqlConnectionString"].ConnectionString;
            MySqlConnection conn = new MySqlConnection(m_conn);
            conn.Open();

            try
            {
                // Get the checksum and path for all files in directory. Use stored proc to insert data. Log results and errors.
                MySqlCommand cmd = new MySqlCommand("drmc.proc_checksum", conn);
                cmd.CommandType = CommandType.StoredProcedure;

                string[] m_files = Directory.GetFiles(m_path, "*.*", SearchOption.AllDirectories);

                foreach (string m_file in m_files)
                {
                    m_filename = Path.GetFileName(m_file);
                    cmd.Parameters.Clear();
                    cmd.Parameters.Add(new MySqlParameter(@"M_FILEPATH", MySqlDbType.VarChar) { Value = m_file.Replace("\\", "\\\\") });
                    cmd.Parameters.Add(new MySqlParameter(@"M_FILENAME", MySqlDbType.VarChar) { Value = m_filename });
                    cmd.Parameters.Add(new MySqlParameter(@"M_SHA256", MySqlDbType.VarChar) { Value = GetChecksum(m_file).ToString() });
                    cmd.ExecuteNonQuery();

                    using (StreamWriter sw = File.AppendText(m_results))
                    {
                        Logger.LogMessage("File " + m_file + " inserted in database.", sw);
                        sw.Close();
                    }
                }

                // Get number of total files
                MySqlCommand cmd_totalfiles = new MySqlCommand("drmc.proc_totalfiles", conn);
                cmd_totalfiles.CommandType = CommandType.StoredProcedure;
                cmd_totalfiles.Parameters.AddWithValue("@M_TOTALCOUNT", MySqlDbType.Int32);
                cmd_totalfiles.Parameters["@M_TOTALCOUNT"].Direction = ParameterDirection.Output;
                cmd_totalfiles.ExecuteNonQuery();

                Console.WriteLine("Total file count: " + cmd_totalfiles.Parameters["@M_TOTALCOUNT"].Value);
                Console.WriteLine("\r\n");

                string str_totalfiles = cmd_totalfiles.Parameters["@M_TOTALCOUNT"].Value.ToString();

                // Get number of files that have no changes
                MySqlCommand cmd_samefiles = new MySqlCommand("drmc.proc_samefiles", conn);
                cmd_samefiles.CommandType = CommandType.StoredProcedure;
                cmd_samefiles.Parameters.AddWithValue("@M_SAMECOUNT", MySqlDbType.Int32);
                cmd_samefiles.Parameters["@M_SAMECOUNT"].Direction = ParameterDirection.Output;
                cmd_samefiles.ExecuteNonQuery();

                Console.WriteLine("Files with no changes: " + cmd_samefiles.Parameters["@M_SAMECOUNT"].Value);
                Console.WriteLine("\r\n");

                string str_samefiles = cmd_samefiles.Parameters["@M_SAMECOUNT"].Value.ToString();

                // Get number and listing of new files
                MySqlCommand cmd_newfiles = new MySqlCommand("drmc.proc_newfiles", conn);
                cmd_newfiles.CommandType = CommandType.StoredProcedure;

                cmd_newfiles.Parameters.AddWithValue("@M_NEWCOUNT", MySqlDbType.Int32);
                cmd_newfiles.Parameters["@M_NEWCOUNT"].Direction = ParameterDirection.Output;
                cmd_newfiles.ExecuteNonQuery();

                Console.WriteLine("New files: " + cmd_newfiles.Parameters["@M_NEWCOUNT"].Value);
                Console.WriteLine("\r\n");

                string str_newfiles = cmd_newfiles.Parameters["@M_NEWCOUNT"].Value.ToString();

                MySqlDataAdapter sda_newfiles = new MySqlDataAdapter(cmd_newfiles);
                DataSet ds_newfiles = new DataSet();
                ds_newfiles.DataSetName = "New Files";
                sda_newfiles.Fill(ds_newfiles);
                sda_newfiles.Dispose();

                // Get number and listing of changed checksum files.  This is the core use case.
                MySqlCommand cmd_changedfiles = new MySqlCommand("drmc.proc_changedfiles", conn);
                cmd_changedfiles.CommandType = CommandType.StoredProcedure;

                cmd_changedfiles.Parameters.AddWithValue("@M_CHANGECOUNT", MySqlDbType.Int32);
                cmd_changedfiles.Parameters["@M_CHANGECOUNT"].Direction = ParameterDirection.Output;
                cmd_changedfiles.ExecuteNonQuery();

                Console.WriteLine("Changed files: " + cmd_changedfiles.Parameters["@M_CHANGECOUNT"].Value);
                Console.WriteLine("\r\n");

                string str_changedfiles = cmd_changedfiles.Parameters["@M_CHANGECOUNT"].Value.ToString();

                MySqlDataAdapter sda_changedfiles = new MySqlDataAdapter(cmd_changedfiles);
                DataSet ds_changedfiles = new DataSet();
                ds_changedfiles.DataSetName = "Changed Files";
                sda_changedfiles.Fill(ds_changedfiles);
                sda_changedfiles.Dispose();

                // Close db connection
                conn.Close();


                // Begin creating email content and attachments
                DataTable dt_newfiles = ds_newfiles.Tables[0];
                DataTable dt_changedfiles = ds_changedfiles.Tables[0];
                DataTable dt_changedfiles1 = ds_changedfiles.Tables[1];

                FileGenerator.CreateFile(dt_changedfiles, m_changedfiles).ToString();

                string m_emailbody = "This e-mail is a summary of checksum file integrity for files located here: \r\n\r\n" + m_path + "\r\n\r\n";
                m_emailbody = m_emailbody + "There are a total of " + str_totalfiles + " files. \r\n\r\n";
                m_emailbody = m_emailbody + "The file location, file name, and checksum are the same for " + str_samefiles + " files. \r\n\r\n";
                m_emailbody = m_emailbody + "There are " + str_newfiles + " new files. These are listed below, if any.  Detailed information is in the attached file checksum_new_files.csv\r\n\r\n";
                m_emailbody = m_emailbody + "There are " + str_changedfiles + " files where the CHECKSUM HAS BEEN CHANGED. The integrity of the file is in doubt, or it has been changed by a user.  The files are listed below, if any.  Detailed information is in the attached file checksum_changed_files.csv\r\n\r\n";

                string m_emailnewbody = "New Files: \r\n" + FileGenerator.CreateFile(dt_newfiles, m_newfiles).ToString();
                string m_emailchangedbody = "Changed Files: \r\n" + FileGenerator.CreateFile(dt_changedfiles1).ToString();

                m_emailbody = m_emailbody + m_emailnewbody + "\r\n" + m_emailchangedbody;

            #endregion

            #region Email configuration and send

                var client = new SmtpClient("smtp.gmail.com", 587)
                    {
                        Credentials = new NetworkCredential("gmailuserhere", "gmailpasswordhere"),
                        EnableSsl = true
                    };

                MailMessage m_message = new MailMessage(
               m_notification_to,
               m_notification_from,
               m_notification_title + DateTime.Today.ToShortDateString(),
               m_emailbody);

                // Create  the file attachment for new files.
                Attachment m_new_attachment = new Attachment(m_newfiles, MediaTypeNames.Application.Octet);
                m_new_attachment.Name = "checksum_new_files.csv";
                // Add time stamp information for the file.
                ContentDisposition m_new_disposition = m_new_attachment.ContentDisposition;
                m_new_disposition.CreationDate = System.IO.File.GetCreationTime(m_newfiles);
                m_new_disposition.ModificationDate = System.IO.File.GetLastWriteTime(m_newfiles);
                m_new_disposition.ReadDate = System.IO.File.GetLastAccessTime(m_newfiles);


                // Create  the file attachment for changed files.
                Attachment m_changed_attachment = new Attachment(m_changedfiles, MediaTypeNames.Application.Octet);
                m_changed_attachment.Name = "checksum_changed_files.csv";
                // Add time stamp information for the file.
                ContentDisposition m_changed_disposition = m_changed_attachment.ContentDisposition;
                m_changed_disposition.CreationDate = System.IO.File.GetCreationTime(m_changedfiles);
                m_changed_disposition.ModificationDate = System.IO.File.GetLastWriteTime(m_changedfiles);
                m_changed_disposition.ReadDate = System.IO.File.GetLastAccessTime(m_changedfiles);

                m_message.Attachments.Add(m_new_attachment);
                m_message.Attachments.Add(m_changed_attachment);

                client.Send(m_message);

            }
            catch (Exception ex)
            {
                using (StreamWriter swerr = File.AppendText(m_errors))
                {
                    Logger.LogMessage(ex.Message.ToString(), swerr);
                    swerr.Close();
                }

            }
        }

        #endregion

        #region Checksum

		/*  The checksum method below comes almost verbatim from Jeff Barnes, MS MVP, and his blog article posted here:

                http://jeffbarnes.net/blog/post/2007/01/12/File-Checksum-using-NET.aspx
        */
		
        private static string GetChecksum(string m_fileinput)
        {
            try
            {
                string m_checksum;
                using (FileStream stream = File.OpenRead(m_fileinput))
                {
                    SHA256Managed sha = new SHA256Managed();
                    byte[] checksum = sha.ComputeHash(stream);
                    m_checksum = BitConverter.ToString(checksum).Replace("-", String.Empty);
                }

                return m_checksum;

            }
            catch (Exception ex)
            {
                using (StreamWriter swerr = File.AppendText(m_errors))
                {
                    Logger.LogMessage(ex.Message.ToString(), swerr);
                    swerr.Close();
                }

                return "unable to retrieve checksum";

            }
        }

        #endregion

    }
}

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 Code Project Open License (CPOL)


Written By
Database Developer
United States United States
I am an MBA with a bunch of MS certifications. Technically, I am a DBA, but I do a good deal of sys admin work and web development using .NET. I like to focus on business intelligence, database design, messaging architectures, and web services.

Comments and Discussions