Source

KeePassTrueCryptMount / src / KeepassTrueCryptMount / TrueCryptInfo.cs

Full commit
/*
  Plugin for KeePass Password Safe - The Open-Source Password Manager
  KeePassTrueCryptMount
  Copyright (C) 2010-2013 Patrick Schaller

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

namespace KeePassTrueCryptMount
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.Security;
    using System.Security.AccessControl;
    using System.Text;
    using System.Text.RegularExpressions;

    using KeePass.Plugins;

    using Microsoft.Win32;
    
    public static class TrueCryptInfo
    {
        /*
         *  The complete description of the file path regex pattern
         *  Thanks to FailedDev -> http://stackoverflow.com/users/880096/faileddev
        @"
        (                             # Match the regular expression below and capture its match into backreference number 1
           (                             # Match the regular expression below and capture its match into backreference number 2
              |                             # Match either the regular expression below (attempting the next alternative only if this one fails)
                 [a-zA-Z]                      # Match a single character in the range between “a” and “z”
                 :                             # Match the character “:” literally
              |                             # Or match regular expression number 2 below (the entire group fails if this one fails to match)
                 \\                            # Match the character “\” literally
                 \\                            # Match the character “\” literally
                 [a-z0-9_.$]                   # Match a single character present in the list below
                                                  # A character in the range between “a” and “z”
                                                  # A character in the range between “0” and “9”
                                                  # One of the characters “_.$”
                    +                             # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
                 \\                            # Match the character “\” literally
                 [a-z0-9_.$]                   # Match a single character present in the list below
                                                  # A character in the range between “a” and “z”
                                                  # A character in the range between “0” and “9”
                                                  # One of the characters “_.$”
                    +                             # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
           )?                            # Between zero and one times, as many times as possible, giving back as needed (greedy)
           (                             # Match the regular expression below and capture its match into backreference number 3
              \\                            # Match the character “\” literally
                 ?                             # Between zero and one times, as many times as possible, giving back as needed (greedy)
              (?:                           # Match the regular expression below
                 [^\\/:*?""<>|\r\n]             # Match a single character NOT present in the list below
                                                  # A \ character
                                                  # One of the characters “/:*?""<>|”
                                                  # A carriage return character
                                                  # A line feed character
                    +                             # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
                 \\                            # Match the character “\” literally
              )+                            # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
           )
           [^\\/:*?""<>|\r\n]             # Match a single character NOT present in the list below
                                            # A \ character
                                            # One of the characters “/:*?""<>|”
                                            # A carriage return character
                                            # A line feed character
              +                             # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
        )
        "
        */

        private static Regex FilePathRegex = new Regex(@"(([a-zA-Z]:|\\\\[a-z0-9_.$]+\\[a-z0-9_.$]+)?(\\?(?:[^\\/:*?""<>|\r\n]+\\)+)[^\\/:*?""<>|\r\n]+)", RegexOptions.Compiled);

        public static bool ExecutableExists(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                return false;
            }

            try
            {
                return File.Exists(filePath);
            }
            catch(Exception ex)
            {
                Debug.WriteLine("KeePassTrueCryptMount: Unknown error at check file exists: {0}", ex.Message);
            }

            return false;
        }

        public static string ResolveExecutableFromRegistry()
        {
            string fileName = string.Empty;

            try
            {
                // try to load from registry key
                using (var locationRegKey = Registry.ClassesRoot.OpenSubKey("TrueCryptVolume\\Shell\\open\\command", RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey))
                {
                    var locationRegValue = locationRegKey.GetValue(string.Empty).ToString();

                    var match = FilePathRegex.Match(locationRegValue);

                    if (match.Success)
                    {
                        fileName = match.Value;
                    }
                }
            }
            catch (SecurityException)
            {
                Debug.WriteLine("KeePassTrueCryptMount: Unable to get read only access to the registry.");
            }
            catch (UnauthorizedAccessException)
            {
                Debug.WriteLine("KeePassTrueCryptMount: Unable to read from registry value.");
            }
            catch (Exception ex)
            {
                Debug.WriteLine(string.Format("KeePassTrueCryptMount: Unable to determine true crypt executable from registry for unknown reason: {0}", ex.Message));
            }
            
            return fileName;
        }
    }
}