コード例 #1
0
 /// <summary>
 /// Put the background worker to work
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 void bgWorker_DoWork(object sender, DoWorkEventArgs e)
 {
     try
     {
         // We're off and running:
         resultStatus = ResultStatus.Running;
         // What we do depends on what mode we're in.  In single-file mode, start hashing
         // the specified file:
         if (singleMode)
         {
             e.Result = HashEngine.HashFile(hashAlgorithm, files[0], bgWorker, e, outputType);
         }
         // Otherwise, start comparing the hashes of the files in the list:
         else
         {
             e.Result = HashEngine.CompareHashes(hashAlgorithm, files, bgWorker, e);
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK,
                         MessageBoxIcon.Error);
         resultStatus = ResultStatus.Error;
         e.Cancel     = true;
         // Close is commented out here, because if this occurs, we'll be closing the dialog
         // from the background worker thread, not the GUI thread, and that throws an
         // exception.
         //Close();
     }
 }
コード例 #2
0
        public LoginUserDTO AuthenticateUser(LoginUserDTO user)
        {
            LoginRepository loginRepository   = new LoginRepository();
            LoginUserDTO    authenticatedUser = new LoginUserDTO();
            HashEngine      createHash        = new HashEngine();

            user.Password     = createHash.GeneratePasswordHash(user.Password);
            authenticatedUser = loginRepository.AuthenticateUser(user);
            return(authenticatedUser);
        }
コード例 #3
0
ファイル: ResultDialog.cs プロジェクト: willianma/winhasher
 /// <summary>
 /// The ResultDialog constructor
 /// </summary>
 /// <param name="result">A <see cref="String"/> containing the hash produced by the
 /// <see cref="HashEngine"/></param>
 /// <param name="hash">A <see cref="Hashes"/> enum value indicating which hashing
 /// algorithm was used</param>
 /// <param name="outputType">A <see cref="OutputType"/> enum value indicating which
 /// output encoding type was used</param>
 public ResultDialog(string result, Hashes hash, OutputType outputType)
 {
     // Do the usual initialization:
     InitializeComponent();
     // Put the hash text in the result box:
     txtResult.Text = result;
     // Build the hash type label:
     string labelText = HashEngine.GetHashName(hash) + " / " +
         HashEngine.GetOutputTypeName(outputType) + ":";
     // Hold onto the output type for comparison later:
     this.outputType = outputType;
 }
コード例 #4
0
 /// <summary>
 /// Constructor
 /// </summary>
 public OptionsDialog()
 {
     try
     {
         InitializeComponent();
         // The state of the Disable Update Checks checkbox should get set by setting the DisableUpdateCheck property.
         // For the rest, we'll need to do some digging.  The Send To shortcuts only make sense on Windows, so just in
         // case, make sure we're currently running on a Windows box before proceeding here.
         if (Environment.OSVersion.Platform == PlatformID.Win32NT ||
             Environment.OSVersion.Platform == PlatformID.Win32Windows)
         {
             // Convert the path to the Send To folder to a string for our convenience:
             sendToPath = Environment.GetFolderPath(Environment.SpecialFolder.SendTo);
             // Set up the output types drop-down.  This is pretty simple, and mimics what we did on the main form.
             // However, we don't know the current state of any existing shortcuts, so we'll default the output type
             // drop-down to the default value.
             comboOutputTypes.Items.Clear();
             foreach (OutputType otTemp in Enum.GetValues(typeof(OutputType)))
             {
                 comboOutputTypes.Items.Add(HashEngine.GetOutputTypeName(otTemp));
             }
             comboOutputTypes.SelectedItem = HashEngine.GetOutputTypeName(HashEngine.DefaultOutputType);
             // Set up the list of shortcuts as a checkbox list box.  What we'll do is loop through the available hash
             // algorithms and, for each one, determine whether or not a shortcut already exists for it.  That will decide
             // whether or not the checkbox will be checked initially.  Once we know that, create an item in the list for
             // that hash and set its initial checked state.
             listSentToShortcuts.Items.Clear();
             foreach (Hashes hashTemp in Enum.GetValues(typeof(Hashes)))
             {
                 string shortcutFile = sendToPath + Path.DirectorySeparatorChar.ToString() + HashEngine.GetHashName(hashTemp) + ".lnk";
                 bool   isChecked    = System.IO.File.Exists(shortcutFile);
                 listSentToShortcuts.Items.Add(HashEngine.GetHashName(hashTemp), isChecked);
             }
         }
         // If we're not running on Windows, disable the Send To shortcut controls so the user can't do anything
         // with them:
         else
         {
             listSentToShortcuts.Enabled = false;
             comboOutputTypes.Enabled    = false;
             toolTip1.SetToolTip(listSentToShortcuts, "Send To shortcuts are not supported on your operating system.");
             toolTip1.SetToolTip(comboOutputTypes, "Send To shortcuts are not supported on your operating system.");
         }
         // If enabled, make our tooltips look like nifty balloons:
         toolTip1.IsBalloon = true;
     }
     catch (Exception ex)
     {
         MessageBox.Show("There was a problem trying to build the options dialog box.\n" + ex.Message, "Error",
                         MessageBoxButtons.OK, MessageBoxIcon.Error);
     }
 }
コード例 #5
0
        internal void BeginTask(Object threadContext)
        {
            Thread.CurrentThread.Name = string.Format("Task{0}", threadContext);
            //Console.WriteLine("i am doing something at {0}", (int)threadContext);
            //while(processList.NotProcessedCount > 0 && !HALT)
            {
                //while(this.HasSubTasks() && !HALT)
                {
                    //if(THREAD_COUNT < MAX_THREAD_COUNT)
                    {
                        try{
                            TaskItem subtask = TaskAvailable();
                            //this.subEvents.Insert(this.THREAD_INDEX, new ManualResetEvent(false));
                            //Console.WriteLine("Starting searchengine to find {0} in '{1}'", this.names.Value, subtask.Name);
                            //HashEngine search = new HashEngine(subtask, name, this.subEvents[(int)this.ProcessedCount-1]);
                            HashEngine search = new HashEngine(subtask, names);

                            //map events.
                            search.SearchCompleted += new TaskCompletedHandler(SearchCompleted);
                            search.DirectoryPolled += new DirectoryPolledHandler(DirectorySeen);
                            search.FilePolled      += new FilePolledHandler(FilePolled);


                            /*if(ThreadPool.QueueUserWorkItem(search.BeginSearch, THREAD_INDEX))
                             * {
                             ++THREAD_COUNT;
                             ++THREAD_INDEX;
                             * }*/
                            search.BeginSearch();
                        }
                        catch (System.Exception e)
                        {
                            Console.WriteLine(e);
                        }
                    }
                    //wait to ensure to avoid race conditions.
                    //Thread.Sleep(2000);
                }
            }
            //if(subEvents != null && subEvents.Count > 0)
            //	WaitHandle.WaitAll(subEvents.ToArray());

            SetComplete((int)threadContext);
        }
コード例 #6
0
        public bool RegisterUser(AppUserDTO appUser, byte[] profileImage)
        {
            RegistrationRepository registrationRepository = new RegistrationRepository();
            HashEngine             createHash             = new HashEngine();

            //Convert the profile image byte array to base 64 string
            string profileInBase64String = Convert.ToBase64String(profileImage, 0, profileImage.Length);

            //Insert base 64 image string to appUser DTO
            appUser.ProfilePicture = "data:image/jpeg;base64, " + profileInBase64String;

            //Generate user name for the user
            appUser.UserName = GenerateUserName(appUser.EmailAddress);

            //convert the password to password hash
            appUser.Password = createHash.GeneratePasswordHash(appUser.Password);

            return(registrationRepository.RegisterUser(appUser));
        }
コード例 #7
0
        private AppSettings()
        {
            this.SDEmuSetting = new SDEmuSetting();

            this.LocalAppSettingsPath =
                string.Format("{0}\\{1}\\{2}",
                              Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                              Application.CompanyName,
                              Application.ProductName);

            this.CurrentAppSettingsPath =
                string.Format("{0}\\{1}.sdemu",
                              this.LocalAppSettingsPath,
                              HashEngine.MD5Hash("current-sdemu-setting"));

            if (!Directory.Exists(LocalAppSettingsPath))
            {
                Directory.CreateDirectory(LocalAppSettingsPath);
            }
        }
コード例 #8
0
ファイル: CmdLineAppUtils.cs プロジェクト: qalasi/winhasher
 /// <summary>
 /// Perform the actual hash operation
 /// </summary>
 /// <param name="args">A <see cref="CmdLineAppArgs"/> object containing the parsed
 /// input parameters from the command line</param>
 /// <param name="overrideHash">If true, override the hash algorithm specified in
 /// args.Hash with the hash specified by hashToOverrideWith</param>
 /// <param name="hashToOverrideWith">If overrideHash is true, override the hash
 /// algorithm specified in args.Hash with this hash algorithm</param>
 /// <returns></returns>
 public static bool PerformHashes(CmdLineAppArgs args, bool overrideHash,
                                  Hashes hashToOverrideWith)
 {
     // If the arguments are null, return false to notify the caller that there's
     // nothing to do:
     if (args == null)
     {
         return(false);
     }
     // If we're being told to override the hash, check to make sure that the hash
     // specified in the arguments matches the hash we're supposed to override it
     // with.  If they don't match, print a warning to the user and override the
     // hash.  Otherwise, we'll let this quietly slip by.
     if (overrideHash && args.Hash != hashToOverrideWith)
     {
         Console.Error.WriteLine("WARNING: Can't override hash algorithm, " +
                                 GetHashSwitchString(args.Hash) + " switch ignored.");
         args.Hash = hashToOverrideWith;
     }
     // If the file list is empty and the input file parameter was not set, then
     // there's really not much for us to do.  Complain and exit out with a false
     // result.
     if ((args.Files == null || args.Files.Length == 0) &&
         String.IsNullOrEmpty(args.InputFile))
     {
         Console.Error.WriteLine("ERROR: No file list or input file specified. Nothing to do!");
         return(false);
     }
     // If the input file was specified but we also got a list of files on the
     // command line, we'll claim the input file overrides the list of files from
     // the arguments and null those out:
     if (!String.IsNullOrEmpty(args.InputFile) && args.Files != null &&
         args.Files.Length > 0)
     {
         Console.Error.WriteLine("WARNING: Input file specified. File list on command line will be ignored.");
         args.Files = null;
     }
     // Now that it looks like we're going to do something, put on our asbestos
     // underpants:
     try
     {
         // If an input file was specified, try to read in its contents:
         if (!String.IsNullOrEmpty(args.InputFile))
         {
             // Declare a list of strings to hold the intermediate values read
             // from the file:
             List <string> fileList = new List <string>();
             // Now try to open up the file for reading:
             StreamReader reader = new StreamReader(args.InputFile);
             // Loop through the lines in the file and examine each one:
             string line = null;
             while ((line = reader.ReadLine()) != null)
             {
                 // For the sake of data integrity, we'll ignore any empty lines
                 // or lines that consist entirely of white space.  As a convenience
                 // to the user, we'll also allow they to put in comments by starting
                 // a line with a hash/pound sign, which we'll also ignore.
                 if (line.Length == 0 || Regex.IsMatch(line, @"^\s*$") ||
                     Regex.IsMatch(line, @"^#"))
                 {
                     continue;
                 }
                 // If we pass that test, add the contents of the line to the list.
                 // Note that we'll strip any leading or trailing white space while
                 // we're at it.
                 fileList.Add(line.Trim());
             }
             // Close the reader:
             reader.Close();
             // If we got anything from the file, convert the list into a string
             // array and put that into the arguments:
             if (fileList.Count > 0)
             {
                 args.Files = fileList.ToArray();
             }
         }
         // We need to test again whether or not we have anything to do, because
         // reading the input file may have populated the file list where it was
         // empty before.  If no files are listed, bail:
         if (args.Files == null || args.Files.Length == 0)
         {
             Console.Error.WriteLine("ERROR: No file list specified or input file contained nothing useful. Nothing to do!");
             return(false);
         }
         // Now declare our output stream writer.  If an output file was specified,
         // try to open that file, using the append flag as well.  If no output file
         // was specified, the writer object will remain null, which will be our flag
         // below on where to send our output.
         StreamWriter writer = null;
         if (!String.IsNullOrEmpty(args.OutputFile))
         {
             writer = new StreamWriter(args.OutputFile, args.AppendOutput);
         }
         // Now to get to work.  First, we need to know what mode we're working in.
         // We'll handle compare mode first:
         if (args.CompareMode)
         {
             // Compare mode only makes sense if we've got more than one file to
             // compare.  If not, we need to complain:
             if (args.Files.Length == 1)
             {
                 Console.Error.WriteLine("ERROR: Cannot compare files unless two or more files are specified.");
                 return(false);
             }
             // Print out the initial status message like above:
             ConsoleStatusUpdater status = null;
             if (writer == null)
             {
                 status = new ConsoleStatusUpdater();
                 Console.WriteLine();
                 Console.Write("Comparing " + GetHashString(args.Hash) + " of " +
                               args.Files.Length + " files...   0%");
             }
             // Compute the hashes and compare the result.  Note that the
             // displayed status might be less than 100% if the comparisons
             // fail.
             bool isMatch = HashEngine.CompareHashes(args.Hash, args.Files, status);
             // Print the result to the appropriate place:
             string result = null;
             if (isMatch)
             {
                 result = "Congratulations!  All " + args.Files.Length + " files match!";
             }
             else
             {
                 result = "WARNING! One or more of these " + args.Files.Length + " files do not match!";
             }
             if (writer == null)
             {
                 Console.WriteLine();
                 Console.WriteLine(result);
             }
             else
             {
                 writer.WriteLine(result);
             }
         }
         // If we're not in compare mode, we must be hashing each file individually:
         else
         {
             // Loop through the file list:
             foreach (string file in args.Files)
             {
                 // We've already warned the user if they tried to use a redirection
                 // command, so ignore those here:
                 if (IsRedirectionCommand(file))
                 {
                     continue;
                 }
                 // Try to hash the file.  Note that our actual result here is to
                 // concatenate the result with the file name, giving us a similar
                 // output to md5sum, shasum, and their friends.
                 string result = HashEngine.HashFile(args.Hash, file, args.OutputType,
                                                     null) + "  " + file;
                 // Write the result to the appropriate output:
                 if (writer != null)
                 {
                     writer.WriteLine(result);
                 }
                 else
                 {
                     Console.WriteLine(result);
                 }
             }
         }
         // Once we're finished, close the file if necessary:
         if (writer != null)
         {
             writer.Close();
         }
         return(true);
     }
     // This needs to be prettied up, but for now just output the message from any
     // exception caught and return false to the caller to indicate an error:
     catch (Exception e)
     {
         Console.Error.WriteLine("ERROR: " + e.Message);
         return(false);
     }
 }
コード例 #9
0
        /// <summary>
        /// What to do when the OK button is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void okButton_Click(object sender, EventArgs e)
        {
            try
            {
                // The disable update checks setting will be passed through the DisableUpdateCheck property.  For the Send To
                // shortcuts, those only make sense if we're running on Windows:
                if (Environment.OSVersion.Platform == PlatformID.Win32NT ||
                    Environment.OSVersion.Platform == PlatformID.Win32Windows)
                {
                    // Determine the command-line flag for output types.  Get the current value of the drop-down and switch on
                    // it to determine which flag to add.
                    string outputType = null;
                    switch (HashEngine.GetOutputTypeFromName((string)comboOutputTypes.SelectedItem))
                    {
                    case OutputType.CapHex:
                        outputType = " -hexcaps";
                        break;

                    case OutputType.Base64:
                        outputType = " -base64";
                        break;

                    case OutputType.BubbleBabble:
                        outputType = " -bubbab";
                        break;

                    case OutputType.Hex:
                    default:
                        outputType = "";
                        break;
                    }
                    // Here's where things get funky.  For creating shortcuts, we'll need to dip into the Windows Shell,
                    // so create our interface to it first:
                    WshShellClass wsh = new WshShellClass();
                    // We're going have to look at every hash in the list, so we might as well do a for loop here:
                    for (int i = 0; i < listSentToShortcuts.Items.Count; i++)
                    {
                        // Get the name of the hash as a string, as well as the full path to the shortcut file we plan to
                        // create or delete:
                        string hash         = (string)listSentToShortcuts.Items[i];
                        string shortcutFile = sendToPath + Path.DirectorySeparatorChar.ToString() + hash + ".lnk";
                        // Always delete the existing shortcut if it exists.  The user may have changed the output type,
                        // and there's no good way to check for that.
                        if (System.IO.File.Exists(shortcutFile))
                        {
                            System.IO.File.Delete(shortcutFile);
                        }
                        // If the hash's checkbox was checked, we'll create the shortcut for that hash.  Most of this is
                        // pretty straightforward.  The funkiest part is probably the shortcut arguments, which is where we
                        // tell WinHasher which hash to use.  The command-line argument is usually the hash name in lower case
                        // minus any non-alphanumeric characters and with a UNIX-style dash ("-") on the front of it.  We'll tack
                        // the output type onto the end of that before we assign it to the Arguments property.  The WorkingDirectory
                        // is not really necessary as the Send To shortcut will send WinHasher the full path to the file, but we'll
                        // default it to My Documents, just in case.  One gotcha on the TargetPath:  If WinHasher is run through
                        // Visual Studio, this will point to the Visual Studio Hosting Process version of the file, not the final
                        // EXE.  This should work as intended whenever the program is run by itself.  The icon path should point
                        // to the WinHasher executable; in the Visual Studio Hosting Process scenario mentioned above, this means
                        // we won't get a nice icon on our shortcut, but it'll work otherwise.
                        if (listSentToShortcuts.GetItemChecked(i))
                        {
                            IWshShortcut shortcut = (IWshShortcut)(wsh.CreateShortcut(shortcutFile));
                            shortcut.TargetPath = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
                            string hashArg = "-" + Regex.Replace(hash.ToLower(), @"\W", "");
                            shortcut.Arguments        = hashArg + outputType;
                            shortcut.WindowStyle      = 1;
                            shortcut.Description      = "Compute the " + hash + " hash for the selected file(s)";
                            shortcut.WorkingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                            shortcut.IconLocation     = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
                            shortcut.Save();
                        }
                    }
                }
                // Let the caller know we clicked the OK button:
                DialogResult = System.Windows.Forms.DialogResult.OK;
            }
            // We should probably pretty up this erorr message, but for now we'll just include the exception information:
            catch (Exception ex)
            {
                MessageBox.Show("The Send To shortcuts could not be created.\n" + ex.Message,
                                "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            // Dispose of the form:
            Dispose();
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: willianma/winhasher
        static void Main(string[] args)
        {
            // Set up the usual GUI stuff first:
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            // If no command-line arguments are given, go ahead and run the program in
            // interactive GUI mode:
            if (args.Length == 0)
            {
                Application.Run(new MainForm());
            }
            // If we have one and only one command-line argument and it's the portable
            // flag, load the main application in portable mode (i.e. no writes to the
            // registry):
            else if (args.Length == 1 && args[0].ToLower() == "-portable")
            {
                Application.Run(new MainForm(true));
            }
            // Otherwise, assume we're going to process one or more files, show the results
            // in a dialog box, then exit:
            else
            {
                // Start off by declaring a string array to hold a copy of the command line
                // arguments.  We can't work with the argument array itself because we may
                // need to strip off the first one if it's a hash switch.
                string[] files = null;
                // Set our default hash and output type:
                Hashes     hash       = HashEngine.DefaultHash;
                string     hashString = HashEngine.GetHashName(hash);
                OutputType outputType = HashEngine.DefaultOutputType;
                // All our command switches come first, so step through them:
                while (args[0].StartsWith("-"))
                {
                    // Examine the switch:
                    switch (args[0].ToLower())
                    {
                    // Most of these determine which hash to use:
                    case "-md5":
                        hash = Hashes.MD5;
                        break;

                    case "-sha1":
                        hash = Hashes.SHA1;
                        break;

                    case "-sha224":
                        hash = Hashes.SHA224;
                        break;

                    case "-sha256":
                        hash = Hashes.SHA256;
                        break;

                    case "-sha384":
                        hash = Hashes.SHA384;
                        break;

                    case "-sha512":
                        hash = Hashes.SHA512;
                        break;

                    case "-ripemd128":
                        hash = Hashes.RIPEMD128;
                        break;

                    case "-ripemd160":
                        hash = Hashes.RIPEMD160;
                        break;

                    case "-ripemd256":
                        hash = Hashes.RIPEMD256;
                        break;

                    case "-ripemd320":
                        hash = Hashes.RIPEMD320;
                        break;

                    case "-whirlpool":
                        hash = Hashes.Whirlpool;
                        break;

                    case "-tiger":
                        hash = Hashes.Tiger;
                        break;

                    // But this switch enables Base64 hashing:
                    case "-base64":
                        outputType = OutputType.Base64;
                        break;

                    // And this puts us in all-caps hex mode:
                    case "-hexcaps":
                        outputType = OutputType.CapHex;
                        break;

                    // And this puts us in Bubble Babble mode:
                    case "-bubbab":
                        outputType = OutputType.BubbleBabble;
                        break;

                    // If we didn't get a valid hash switch, complain:
                    default:
                        MessageBox.Show("Invalid switch \"" + args[0] + "\"", "Error",
                                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                        break;
                    }
                    hashString = HashEngine.GetHashName(hash);
                    // Now shift the array down to the next argument.  I wish there was a better,
                    // more efficient way of doing this (like a Perl or PHP shift()), but this is
                    // all I know of using simple arrays:
                    string[] args2 = new string[args.Length - 1];
                    Array.Copy(args, 1, args2, 0, args.Length - 1);
                    args = args2;

                    //If there are no more arguments left, exit the loop
                    if (args.Length == 0)
                    {
                        break;
                    }
                }
                // By now, all our switches should be exhausted.  We should only have strings
                // not starting with hyphens, which we'll interpret as file path strings.
                // Only proceed if we have files to work with:
                files = args;
                if (files.Length > 0)
                {
                    // If we got one file, compute the hash and print it back:
                    if (files.Length == 1)
                    {
                        // We could throw some exceptions here, so ignore Yoda's advice and give
                        // it a try:
                        try
                        {
                            // Only do this if the file exists:
                            if (File.Exists(files[0]))
                            {
                                // Create a new progress dialog.  This does the actual work:
                                ProgressDialog pd = new ProgressDialog(files[0], hash, true,
                                                                       outputType);
                                pd.ShowDialog();
                                // If we got back a successful result, show the hash.  Otherwise,
                                // the error message should already be shown so do nothing.
                                if (pd.Result == ProgressDialog.ResultStatus.Success && pd.Hash != null)
                                {
                                    ResultDialog rd = new ResultDialog(pd.Hash, hash, outputType);
                                    rd.ShowDialog();
                                }
                            }
                            // The file didn't exist:
                            else
                            {
                                MessageBox.Show("Error: The specified file does not exist.", "Error",
                                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                        #region Catch Exceptions
                        // Our hash engine can throw its own exceptions, which usually are just other
                        // exceptions wrapped in our own message format.  We'll look for those first
                        // and foremost:
                        catch (HashEngineException hee)
                        {
                            MessageBox.Show("Error: " + hee.Message, "Error", MessageBoxButtons.OK,
                                            MessageBoxIcon.Error);
                        }
                        // Console.WriteLine() can throw this one:
                        catch (IOException)
                        {
                            MessageBox.Show("Error: An unknown I/O error has occured.", "Error",
                                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        // A catch-all to handle anything else:
                        catch (Exception ex)
                        {
                            MessageBox.Show("Error: " + ex.ToString(), "Error", MessageBoxButtons.OK,
                                            MessageBoxIcon.Error);
                        }
                        #endregion
                    }
                    // If we receive more than one argument, will treat each one as a file path and
                    // reach each one in turn, computing its hash.  The hash of each file is compared
                    // against the hash of the first file.  If all the hashes match, we'll print out
                    // a happy congratulatory message.  If just one of the hashes doesn't match the
                    // others, we say the whole batch fails.
                    else
                    {
                        try
                        {
                            // Create a new progress dialog and show it.  This is where the actual
                            // work will be done.  Note we don't care about the Base64 flag, since
                            // the actual hashes won't be displayed to the user.  (Whether we compare
                            // hex strings or Base64 strings doesn't really matter.)
                            ProgressDialog pd = new ProgressDialog(files, hash, true);
                            pd.ShowDialog();
                            // If we got a successful result, keep going.  Anything else should have
                            // already thrown an error message.
                            if (pd.Result == ProgressDialog.ResultStatus.Success)
                            {
                                // If the files matched, congratulate the user:
                                if (pd.FilesMatch)
                                {
                                    MessageBox.Show("Congratulations!  All " + files.Length +
                                                    " files match!", hashString + " Hash", MessageBoxButtons.OK,
                                                    MessageBoxIcon.Information);
                                }
                                // Otherwise, warn them:
                                else
                                {
                                    MessageBox.Show("WARNING! One or more of these " + files.Length +
                                                    " files do not match!", hashString + " Hash",
                                                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                                }
                            }
                        }
                        #region Catch Exceptions
                        // Same as above:
                        catch (HashEngineException hee)
                        {
                            MessageBox.Show("Error: " + hee.Message, "Error", MessageBoxButtons.OK,
                                            MessageBoxIcon.Error);
                        }
                        // Console.WriteLine() can throw this one:
                        catch (IOException)
                        {
                            MessageBox.Show("Error: An unknown I/O error has occured.", "Error",
                                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        // A catch-all to handle anything else:
                        catch (Exception ex)
                        {
                            MessageBox.Show("Error: " + ex.ToString(), "Error", MessageBoxButtons.OK,
                                            MessageBoxIcon.Error);
                        }
                        #endregion
                    }
                }
                // There were no files left in the list after the switches were exhausted:
                else
                {
                    MessageBox.Show("Error: No files specified", "Error", MessageBoxButtons.OK,
                                    MessageBoxIcon.Error);
                }
            }
        }