Example #1
0
        private string GetPasswordSHA()
        {
            using (var sha1 = new SHA1CryptoServiceProvider())
            {
                var context  = new SprContext(PasswordEntry, Host.Database, SprCompileFlags.All);
                var password = SprEngine.Compile(PasswordEntry.Strings.GetSafe(PwDefs.PasswordField).ReadString(), context);

                var pwdShaBytes = sha1.ComputeHash(Encoding.UTF8.GetBytes(password));
                var sb          = new StringBuilder(2 * pwdShaBytes.Length);

                foreach (var b in pwdShaBytes)
                {
                    sb.AppendFormat("{0:X2}", b);
                }

                return(sb.ToString());
            }
        }
Example #2
0
        public static string GetParamString(List <string> vParams, int iIndex,
                                            bool bSprCompile, bool bSprForCommandLine)
        {
            string str = GetParamString(vParams, iIndex, string.Empty);

            if (bSprCompile && !string.IsNullOrEmpty(str))
            {
                PwEntry pe = null;
                try { pe = Program.MainForm.GetSelectedEntry(false); }
                catch (Exception) { Debug.Assert(false); }

                PwDatabase pd = Program.MainForm.DocumentManager.SafeFindContainerOf(pe);

                str = SprEngine.Compile(str, new SprContext(pe, pd,
                                                            SprCompileFlags.All, false, bSprForCommandLine));
            }

            return(str);
        }
Example #3
0
        public static string GetCacheRoot()
        {
            if (Program.Config.Application.PluginCachePath.Length > 0)
            {
                string strRoot = SprEngine.Compile(Program.Config.Application.PluginCachePath,
                                                   false, null, null, false, false);
                if (!string.IsNullOrEmpty(strRoot))
                {
                    if (strRoot.EndsWith(new string(Path.DirectorySeparatorChar, 1)))
                    {
                        strRoot = strRoot.Substring(0, strRoot.Length - 1);
                    }
                    return(strRoot);
                }
            }

            return(AppConfigSerializer.AppDataDirectory +
                   Path.DirectorySeparatorChar + CacheDirName);
        }
Example #4
0
        private IEnumerable <KeyValuePair <string, string> > GetFields(ConfigOpt configOpt, PwEntryDatabase entryDatabase)
        {
            SprContext ctx = new SprContext(entryDatabase.entry, entryDatabase.database, SprCompileFlags.All, false, false);

            List <KeyValuePair <string, string> > fields = null;

            if (configOpt.ReturnStringFields)
            {
                fields = new List <KeyValuePair <string, string> >();
                foreach (var sf in entryDatabase.entry.Strings)
                {
                    var sfValue = entryDatabase.entry.Strings.ReadSafe(sf.Key);

                    // follow references
                    sfValue = SprEngine.Compile(sfValue, ctx);

                    if (configOpt.ReturnStringFieldsWithKphOnly)
                    {
                        if (sf.Key.StartsWith("KPH: "))
                        {
                            fields.Add(new KeyValuePair <string, string>(sf.Key.Substring(5), sfValue));
                        }
                    }
                    else
                    {
                        fields.Add(new KeyValuePair <string, string>(sf.Key, sfValue));
                    }
                }

                if (fields.Count > 0)
                {
                    var sorted = from e2 in fields orderby e2.Key ascending select e2;
                    fields = sorted.ToList();
                }
                else
                {
                    fields = null;
                }
            }

            return(fields);
        }
        protected ToolStripMenuItem CreateMenuItemFromPwEntry(PwEntry entry, PwDatabase pwDatabase)
        {
            var context       = new SprContext(entry, pwDatabase, SprCompileFlags.All, false, false);
            var entryTitle    = entry.Strings.ReadSafe(PwDefs.TitleField);
            var entryUsername = SprEngine.Compile(entry.Strings.ReadSafe(PwDefs.UserNameField), context);

            string trayTitle = TrimMenuItemTitleIfNecessary(entryTitle, entryUsername);

            var validEntry = Plugin.TOTPEntryValidator.SettingsValidate(entry);
            var menuItem   = new ToolStripMenuItem(trayTitle)
            {
                Tag     = entry,
                Image   = validEntry ? GetEntryImage(entry, pwDatabase) : Resources.TOTP_Error,
                Enabled = validEntry,
            };

            menuItem.Click += OnNotifyMenuTOTPClick;

            return(menuItem);
        }
Example #6
0
        public static string GetParamString(List <string> vParams, int iIndex,
                                            bool bSprCompile)
        {
            string str = GetParamString(vParams, iIndex, string.Empty);

            if (bSprCompile && !string.IsNullOrEmpty(str))
            {
                PwDatabase pd = null;
                try { pd = Program.MainForm.ActiveDatabase; }
                catch (Exception) { Debug.Assert(false); }

                PwEntry pe = null;
                try { pe = Program.MainForm.GetSelectedEntry(false); }
                catch (Exception) { Debug.Assert(false); }

                str = SprEngine.Compile(str, false, pe, pd, false, false);
            }

            return(str);
        }
Example #7
0
        public static bool Copy(ProtectedString psToCopy, bool bIsEntryInfo,
                                PwEntry peEntryInfo, PwDatabase pwReferenceSource)
        {
            Debug.Assert(psToCopy != null);
            if (psToCopy == null)
            {
                throw new ArgumentNullException("psToCopy");
            }

            if (bIsEntryInfo && !AppPolicy.Try(AppPolicyId.CopyToClipboard))
            {
                return(false);
            }

            string strData = SprEngine.Compile(psToCopy.ReadString(), false,
                                               peEntryInfo, pwReferenceSource, false, false);

            try
            {
                ClipboardUtil.Clear();

                DataObject doData = CreateProtectedDataObject(strData);
                Clipboard.SetDataObject(doData);

                m_pbDataHash32 = HashClipboard();
                m_strFormat    = null;

                RaiseCopyEvent(bIsEntryInfo, strData);
            }
            catch (Exception) { Debug.Assert(false); return(false); }

            if (peEntryInfo != null)
            {
                peEntryInfo.Touch(false);
            }

            // SprEngine.Compile might have modified the database
            Program.MainForm.UpdateUI(false, null, false, null, false, null, false);

            return(true);
        }
        public static ProtectedString GetFieldWRef(PwEntry entry, PwDatabase sourceDb, string fieldName)
        //Had to implement this fuction here, since Exporter is private
        {
            SprContext ctx = new SprContext(entry, sourceDb,
                                            SprCompileFlags.All, false, false);

            return(ProtectedString.EmptyEx.Insert(0, SprEngine.Compile(
                                                      entry.Strings.ReadSafe(fieldName), ctx)));

            /* This next code is borrowed from KeePassHttps, I don't know what it does:
             * var f = (MethodInvoker)delegate
             * {
             *  // apparently, SprEngine.Compile might modify the database
             *  host.MainWindow.UpdateUI(false, null, false, null, false, null, false);
             * };
             * if (host.MainWindow.InvokeRequired)
             *  host.MainWindow.Invoke(f);
             * else
             *  f.Invoke();
             */
        }
Example #9
0
        private static string GeneratePassword(string strProfile, SprContext ctx)
        {
            PwProfile prf = Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile;

            if (!string.IsNullOrEmpty(strProfile))
            {
                if (strProfile == @"~")
                {
                    prf = PwProfile.DeriveFromPassword(ctx.Entry.Strings.GetSafe(
                                                           PwDefs.PasswordField));
                }
                else
                {
                    List <PwProfile> lPrf = PwGeneratorUtil.GetAllProfiles(false);
                    foreach (PwProfile p in lPrf)
                    {
                        if (strProfile.Equals(p.Name, StrUtil.CaseIgnoreCmp))
                        {
                            prf = p;
                            break;
                        }
                    }
                }
            }

            ProtectedString ps;
            PwgError        e = PwGenerator.Generate(out ps, prf, null,
                                                     Program.PwGeneratorPool);

            if ((e != PwgError.Success) || (ps == null))
            {
                return(string.Empty);
            }

            string strGen = ps.ReadString();

            strGen = SprEngine.TransformContent(strGen, ctx);
            return(strGen);
        }
Example #10
0
        /// <summary>
        /// Resolves any references in the field value and returns it. If there were no references,
        /// returns null (to avoid duplicate searching - it is assumed that the unresolved value has already been searched)
        /// </summary>
        private string ResolveReferences(PwDatabase context, PwEntry entry, string fieldValue)
        {
            if (fieldValue.IndexOf('{') < 0)
            {
                // Can't contain any references
                return(null);
            }

            var sprContext = new SprContext(entry, context, SprCompileFlags.Deref)
            {
                ForcePlainTextPasswords = false
            };

            var result = SprEngine.Compile(fieldValue, sprContext);

            if (CultureInfo.CurrentCulture.CompareInfo.Compare(result, fieldValue, mStringComparison) == 0)
            {
                return(null);
            }

            return(result);
        }
Example #11
0
        internal string[] GetUserPass(PwEntry entry)
        {
            // follow references
            string user = SprEngine.Compile(entry.Strings.ReadSafe(PwDefs.UserNameField), false, entry, host.Database, false, false);
            string pass = SprEngine.Compile(entry.Strings.ReadSafe(PwDefs.PasswordField), false, entry, host.Database, false, false);
            var    f    = (MethodInvoker) delegate
            {
                // apparently, SprEngine.Compile might modify the database
                host.MainWindow.UpdateUI(false, null, false, null, false, null, false);
            };

            if (host.MainWindow.InvokeRequired)
            {
                host.MainWindow.Invoke(f);
            }
            else
            {
                f.Invoke();
            }

            return(new string[] { user, pass });
        }
Example #12
0
        public static string GetParamString(List <string> vParams, int iIndex,
                                            bool bSprCompile, bool bSprForCommandLine)
        {
            string str = GetParamString(vParams, iIndex, string.Empty);

            if (bSprCompile && !string.IsNullOrEmpty(str))
            {
                PwEntry pe = null;
                try { pe = Program.MainForm.GetSelectedEntry(false); }
                catch (Exception) { Debug.Assert(false); }

                PwDatabase pd = Program.MainForm.DocumentManager.SafeFindContainerOf(pe);

                // The trigger system does not update the UI itself,
                // thus ignore state-changing placeholders
                str = SprEngine.Compile(str, new SprContext(pe, pd,
                                                            (SprCompileFlags.All & ~SprCompileFlags.StateChanging),
                                                            false, bSprForCommandLine));
            }

            return(str);
        }
Example #13
0
        /*
         * protected override void SetFieldValueInternal(RowObject rowObject, ProtectedString newValue)
         * {
         *      if (newValue.ReadString() != rowObject.Value.ReadString())
         *      {
         *              CreateHistoryEntry();
         *
         *              Entry.Strings.Set(rowObject.FieldName, newValue);
         *              rowObject.Value = newValue;
         *
         *              OnModified(EventArgs.Empty);
         *      }
         * }
         */

        protected override void SetFieldValueInternal(RowObject rowObject, ProtectedString newValue)
        {
            if (newValue.ReadString() != rowObject.Value.ReadString())
            {
                CreateHistoryEntry();
                string val = newValue.ReadString();
                if (val.StartsWith("="))
                {
                    SprContext ctx = new SprContext(Entry, Database, SprCompileFlags.All, false, false);
                    val = SprEngine.Compile(val.Substring(1), ctx);
                    ProtectedString psval = new ProtectedString(newValue.IsProtected, val);
                    Entry.Strings.Set(rowObject.FieldName, psval);
                    rowObject.Value = psval;
                }
                else
                {
                    Entry.Strings.Set(rowObject.FieldName, newValue);
                    rowObject.Value = newValue;
                }
                OnModified(EventArgs.Empty);
            }
        }
Example #14
0
        private static string CompileText(string strText, PfOptions p, bool bToHtml,
                                          bool bNbsp)
        {
            string str = strText;

            if (g_strCodeItS == null)
            {
                g_strCodeItS = (new PwUuid(true)).ToHexString();
                g_strCodeItE = (new PwUuid(true)).ToHexString();
            }

            if ((p.SprMode != 0) && (p.SprContext != null))
            {
                string strPre = str;
                str = SprEngine.Compile(str, p.SprContext);

                if ((p.SprMode == 2) && (str != strPre))
                {
                    if (bToHtml)
                    {
                        str += " - " + g_strCodeItS + strPre + g_strCodeItE;
                    }
                    else
                    {
                        str += " - " + strPre;
                    }
                }
            }

            if (bToHtml)
            {
                str = StrUtil.StringToHtml(str, bNbsp);
            }

            str = str.Replace(g_strCodeItS, "<i>");
            str = str.Replace(g_strCodeItE, "</i>");
            return(str);
        }
        public void OnShowQRCode(object sender, DynamicMenuEventArgs e)
        {
            var key = e.Tag as string;

            if (key == null)
            {
                return;
            }

            var pe = host.MainWindow.GetSelectedEntry(true);

            if (pe == null)
            {
                return;
            }

            var context = new SprContext(pe, host.Database, SprCompileFlags.All);
            var value   = SprEngine.Compile(pe.Strings.GetSafe(key).ReadString(), context);

            try
            {
                var data = new QRCodeGenerator().CreateQrCode(value, QRCodeGenerator.ECCLevel.L);
                if (data != null)
                {
                    var form = new ShowQRCodeForm(
                        host,
                        data.GetBitmap(10, Color.Black, Color.White),
                        SprEngine.Compile(pe.Strings.GetSafe(PwDefs.TitleField).ReadString(), context),
                        TryTranslateKey(key)
                        );
                    form.ShowDialog();
                }
            }
            catch
            {
                MessageBox.Show("The data can't be displayed as a QR Code.");
            }
        }
Example #16
0
        private static void RunBuildCommand(string strCmd, string strTmpDir,
                                            string strCacheDir)
        {
            if (string.IsNullOrEmpty(strCmd))
            {
                return;                                          // No assert
            }
            string str = strCmd;

            if (strTmpDir != null)
            {
                str = StrUtil.ReplaceCaseInsensitive(str, @"{PLGX_TEMP_DIR}",
                                                     SprEncoding.EncodeForCommandLine(strTmpDir));
            }
            if (strCacheDir != null)
            {
                str = StrUtil.ReplaceCaseInsensitive(str, @"{PLGX_CACHE_DIR}",
                                                     SprEncoding.EncodeForCommandLine(strCacheDir));
            }

            // str = UrlUtil.ConvertSeparators(str); // Would convert args
            str = SprEngine.Compile(str, new SprContext(null, null,
                                                        SprCompileFlags.NonActive, false, true));

            string strApp, strArgs;

            StrUtil.SplitCommandLine(str, out strApp, out strArgs);

            try { NativeLib.StartProcess(strApp, strArgs); }
            catch (Exception ex)
            {
                if (Program.CommandLineArgs[AppDefs.CommandLineOptions.Debug] != null)
                {
                    throw new PlgxException(ex.Message);
                }
                throw;
            }
        }
Example #17
0
        internal static string SprCompileFn(string strText, PwListItem li)
        {
            string strCmp = null;

            while (strCmp == null)
            {
                try
                {
                    strCmp = SprEngine.Compile(strText, MainForm.GetEntryListSprContext(
                                                   li.Entry, Program.MainForm.DocumentManager.SafeFindContainerOf(
                                                       li.Entry)));
                }
                catch (InvalidOperationException) { }             // Probably collection changed
                catch (NullReferenceException) { }                // Objects disposed already
                catch (Exception) { Debug.Assert(false); }
            }

            if (strCmp == strText)
            {
                return(strText);
            }
            return(strCmp + " - " + strText);
        }
Example #18
0
        public static string FillPlaceholders(string strText, PwEntry pe,
                                              SprContentFlags cf)
        {
            if (pe == null)
            {
                return(strText);
            }

            string str = strText;

            if (str.ToUpper().IndexOf(@"{PICKPASSWORDCHARS}") >= 0)
            {
                ProtectedString ps = pe.Strings.Get(PwDefs.PasswordField);
                if (ps != null)
                {
                    byte[] pb        = ps.ReadUtf8();
                    bool   bNotEmpty = (pb.Length > 0);
                    Array.Clear(pb, 0, pb.Length);

                    if (bNotEmpty)
                    {
                        CharPickerForm cpf = new CharPickerForm();
                        cpf.InitEx(ps, true, true);

                        if (cpf.ShowDialog() == DialogResult.OK)
                        {
                            str = StrUtil.ReplaceCaseInsensitive(str, @"{PICKPASSWORDCHARS}",
                                                                 SprEngine.TransformContent(cpf.SelectedCharacters.ReadString(), cf));
                        }
                    }
                }

                str = StrUtil.ReplaceCaseInsensitive(str, @"{PICKPASSWORDCHARS}", string.Empty);
            }

            return(str);
        }
Example #19
0
        private static string ReplaceNewPasswordPlaceholder(string strText,
                                                            SprContext ctx)
        {
            PwEntry    pe = ctx.Entry;
            PwDatabase pd = ctx.Database;

            if ((pe == null) || (pd == null))
            {
                return(strText);
            }

            string str = strText;

            const string strNewPwPlh = @"{NEWPASSWORD}";

            if (str.IndexOf(strNewPwPlh, StrUtil.CaseIgnoreCmp) >= 0)
            {
                ProtectedString psAutoGen;
                PwgError        e = PwGenerator.Generate(out psAutoGen,
                                                         Program.Config.PasswordGenerator.AutoGeneratedPasswordsProfile,
                                                         null, Program.PwGeneratorPool);
                psAutoGen = psAutoGen.WithProtection(pd.MemoryProtection.ProtectPassword);

                if (e == PwgError.Success)
                {
                    pe.CreateBackup(pd);
                    pe.Strings.Set(PwDefs.PasswordField, psAutoGen);
                    pe.Touch(true, false);
                    pd.Modified = true;

                    string strIns = SprEngine.TransformContent(psAutoGen.ReadString(), ctx);
                    str = StrUtil.ReplaceCaseInsensitive(str, strNewPwPlh, strIns);
                }
            }

            return(str);
        }
Example #20
0
        /*
         * protected override void SetFieldValueInternal(RowObject rowObject, ProtectedString newValue)
         * {
         *      var allEntries = Entries.ToArray();
         *      if (!IsMultiValuedField(rowObject) || // No need to confirm to change the value of a field that isn't multi-valued
         *              ConfirmOperationOnAllEntries(String.Format(Properties.Resources.MultipleEntryFieldSetValueQuestion, rowObject.DisplayName), Properties.Resources.MultpleEntryFieldSetValueCommand, allEntries))
         *      {
         *              var createBackups = AllowCreateHistoryNow;
         *              foreach (var entry in allEntries)
         *              {
         *                      if (createBackups)
         *                      {
         *                              entry.CreateBackup(Database);
         *                      }
         *
         *                      entry.Strings.Set(rowObject.FieldName, newValue); // ProtectedStrings are immutable, so OK to assign the same one to all entries
         *              }
         *              rowObject.Value = newValue;
         *
         *              OnModified(EventArgs.Empty);
         *      }
         * }
         */
        protected override void SetFieldValueInternal(RowObject rowObject, ProtectedString newValue)
        {
            var allEntries = Entries.ToArray();

            if (!IsMultiValuedField(rowObject) ||             // No need to confirm to change the value of a field that isn't multi-valued
                ConfirmOperationOnAllEntries(String.Format(Properties.Resources.MultipleEntryFieldSetValueQuestion, rowObject.DisplayName), Properties.Resources.MultpleEntryFieldSetValueCommand, allEntries))
            {
                var    createBackups = AllowCreateHistoryNow;
                string val           = newValue.ReadString();
                if (createBackups)
                {
                    foreach (var entry in allEntries)
                    {
                        entry.CreateBackup(Database);
                    }
                }
                if (val.StartsWith("="))
                {
                    foreach (var entry in allEntries)
                    {
                        SprContext ctx = new SprContext(entry, Database, SprCompileFlags.All, false, false);
                        entry.Strings.Set(rowObject.FieldName,
                                          new ProtectedString(newValue.IsProtected, SprEngine.Compile(val.Substring(1), ctx)));
                    }
                    OnEntriesChanged(EventArgs.Empty);
                }
                else
                {
                    foreach (var entry in allEntries)
                    {
                        entry.Strings.Set(rowObject.FieldName, newValue);                         // ProtectedStrings are immutable, so OK to assign the same one to all entries
                        rowObject.Value = newValue;
                    }
                }
                OnModified(EventArgs.Empty);
            }
        }
Example #21
0
        internal string GetTotpSettings(PwEntry entry)
        {
            PwEntryDatabase entryDatabase = new PwEntryDatabase(entry, HostInstance.Database);
            SprContext      ctx           = new SprContext(entryDatabase.entry, entryDatabase.database,
                                                           SprCompileFlags.All, false, false);

            string settings = SprEngine.Compile(entryDatabase.entry.Strings.ReadSafe("otp"), ctx);
            var    f        = (MethodInvoker) delegate
            {
                // apparently, SprEngine.Compile might modify the database
                HostInstance.MainWindow.UpdateUI(false, null, false, null, false, null, false);
            };

            if (HostInstance.MainWindow.InvokeRequired)
            {
                HostInstance.MainWindow.Invoke(f);
            }
            else
            {
                f.Invoke();
            }

            return(settings);
        }
Example #22
0
        private static void ExportEntry(PwEntry pe, string strDir, PwExportInfo pxi)
        {
            PwDatabase pd  = ((pxi != null) ? pxi.ContextDatabase : null);
            SprContext ctx = new SprContext(pe, pd, SprCompileFlags.NonActive, false, false);

            KeyValuePair <string, string>?okvpCmd = null;
            string strUrl = SprEngine.Compile(pe.Strings.ReadSafe(PwDefs.UrlField), ctx);

            if (WinUtil.IsCommandLineUrl(strUrl))
            {
                strUrl = WinUtil.GetCommandLineFromUrl(strUrl);

                if (!NativeLib.IsUnix())                // LNKs only supported on Windows
                {
                    string strApp, strArgs;
                    StrUtil.SplitCommandLine(strUrl, out strApp, out strArgs);

                    if (!string.IsNullOrEmpty(strApp))
                    {
                        okvpCmd = new KeyValuePair <string, string>(strApp, strArgs);
                    }
                }
            }
            if (string.IsNullOrEmpty(strUrl))
            {
                return;
            }
            bool bLnk = okvpCmd.HasValue;

            string strTitleCmp = SprEngine.Compile(pe.Strings.ReadSafe(PwDefs.TitleField), ctx);

            if (string.IsNullOrEmpty(strTitleCmp))
            {
                strTitleCmp = KPRes.Entry;
            }
            string strTitle = Program.Config.Defaults.WinFavsFileNamePrefix + strTitleCmp;

            string strSuffix = Program.Config.Defaults.WinFavsFileNameSuffix +
                               (bLnk ? ".lnk" : ".url");

            strSuffix = UrlUtil.FilterFileName(strSuffix);

            string strFileBase = (UrlUtil.EnsureTerminatingSeparator(strDir,
                                                                     false) + UrlUtil.FilterFileName(strTitle));
            string strFile = strFileBase + strSuffix;
            int    iFind   = 2;

            while (File.Exists(strFile))
            {
                strFile = strFileBase + " (" + iFind.ToString() + ")" + strSuffix;
                ++iFind;
            }

            if (!Directory.Exists(strDir))
            {
                try { Directory.CreateDirectory(strDir); }
                catch (Exception exDir)
                {
                    throw new Exception(strDir + MessageService.NewParagraph + exDir.Message);
                }

                WaitForDirCommit(strDir, true);
            }

            try
            {
                if (bLnk)
                {
                    int    ccMaxDesc = NativeMethods.INFOTIPSIZE - 1 - LnkDescSuffix.Length;
                    string strDesc   = StrUtil.CompactString3Dots(strUrl, ccMaxDesc) +
                                       LnkDescSuffix;

                    ShellLinkEx sl = new ShellLinkEx(okvpCmd.Value.Key,
                                                     okvpCmd.Value.Value, strDesc);
                    sl.Save(strFile);
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine(@"[InternetShortcut]");
                    sb.AppendLine(@"URL=" + strUrl);                     // No additional line break
                    sb.AppendLine(@"[" + PwDefs.ShortProductName + @"]");
                    sb.AppendLine(IniTypeKey + @"=" + IniTypeValue);
                    // Terminating line break is important

                    File.WriteAllText(strFile, sb.ToString(), Encoding.Default);
                }
            }
            catch (Exception exWrite)
            {
                throw new Exception(strFile + MessageService.NewParagraph + exWrite.Message);
            }
        }
Example #23
0
        public static void OpenUrl(string strUrlToOpen, PwEntry peDataSource,
                                   bool bAllowOverride, string strBaseRaw)
        {
            // If URL is null, return, do not throw exception.
            Debug.Assert(strUrlToOpen != null); if (strUrlToOpen == null)
            {
                return;
            }

            string strPrevWorkDir = WinUtil.GetWorkingDirectory();
            string strThisExe     = WinUtil.GetExecutable();

            string strExeDir = UrlUtil.GetFileDirectory(strThisExe, false, true);

            WinUtil.SetWorkingDirectory(strExeDir);

            string strUrlFlt = strUrlToOpen;

            strUrlFlt = strUrlFlt.TrimStart(new char[] { ' ', '\t', '\r', '\n' });

            PwDatabase pwDatabase = null;

            try
            {
                pwDatabase = Program.MainForm.DocumentManager.SafeFindContainerOf(
                    peDataSource);
            }
            catch (Exception) { Debug.Assert(false); }

            bool bCmdQuotes = WinUtil.IsCommandLineUrl(strUrlFlt);

            SprContext ctx = new SprContext(peDataSource, pwDatabase,
                                            SprCompileFlags.All, false, bCmdQuotes);

            ctx.Base          = strBaseRaw;
            ctx.BaseIsEncoded = false;

            string strUrl = SprEngine.Compile(strUrlFlt, ctx);

            string strOvr = Program.Config.Integration.UrlSchemeOverrides.GetOverrideForUrl(
                strUrl);

            if (!bAllowOverride)
            {
                strOvr = null;
            }
            if (strOvr != null)
            {
                bool bCmdQuotesOvr = WinUtil.IsCommandLineUrl(strOvr);

                SprContext ctxOvr = new SprContext(peDataSource, pwDatabase,
                                                   SprCompileFlags.All, false, bCmdQuotesOvr);
                ctxOvr.Base          = strUrl;
                ctxOvr.BaseIsEncoded = bCmdQuotes;

                strUrl = SprEngine.Compile(strOvr, ctxOvr);
            }

            if (WinUtil.IsCommandLineUrl(strUrl))
            {
                string strApp, strArgs;
                StrUtil.SplitCommandLine(WinUtil.GetCommandLineFromUrl(strUrl),
                                         out strApp, out strArgs);

                try
                {
                    if ((strArgs != null) && (strArgs.Length > 0))
                    {
                        Process.Start(strApp, strArgs);
                    }
                    else
                    {
                        Process.Start(strApp);
                    }
                }
                catch (Win32Exception)
                {
                    StartWithoutShellExecute(strApp, strArgs);
                }
                catch (Exception exCmd)
                {
                    string strInf = KPRes.FileOrUrl + ": " + strApp;
                    if ((strArgs != null) && (strArgs.Length > 0))
                    {
                        strInf += MessageService.NewParagraph +
                                  KPRes.Arguments + ": " + strArgs;
                    }

                    MessageService.ShowWarning(strInf, exCmd);
                }
            }
            else             // Standard URL
            {
                try { Process.Start(strUrl); }
                catch (Exception exUrl)
                {
                    MessageService.ShowWarning(strUrl, exUrl);
                }
            }

            // Restore previous working directory
            WinUtil.SetWorkingDirectory(strPrevWorkDir);

            // SprEngine.Compile might have modified the database
            Program.MainForm.UpdateUI(false, null, false, null, false, null, false);
        }
Example #24
0
        public static bool Copy(string strToCopy, bool bSprCompile, bool bIsEntryInfo,
                                PwEntry peEntryInfo, PwDatabase pwReferenceSource, IntPtr hOwner)
        {
            if (strToCopy == null)
            {
                throw new ArgumentNullException("strToCopy");
            }

            if (bIsEntryInfo && !AppPolicy.Try(AppPolicyId.CopyToClipboard))
            {
                return(false);
            }

            string strData = (bSprCompile ? SprEngine.Compile(strToCopy,
                                                              new SprContext(peEntryInfo, pwReferenceSource,
                                                                             SprCompileFlags.All)) : strToCopy);

            try
            {
                if (!NativeLib.IsUnix())                // Windows
                {
                    if (!OpenW(hOwner, true))
                    {
                        throw new InvalidOperationException();
                    }

                    bool bFailed = false;
                    if (!AttachIgnoreFormatW())
                    {
                        bFailed = true;
                    }
                    if (!SetDataW(null, strData, null))
                    {
                        bFailed = true;
                    }
                    CloseW();

                    if (bFailed)
                    {
                        return(false);
                    }
                }
                else if (NativeLib.GetPlatformID() == PlatformID.MacOSX)
                {
                    SetStringM(strData);
                }
                else if (NativeLib.IsUnix())
                {
                    SetStringU(strData);
                }
                // else // Managed
                // {
                //	Clear();
                //	DataObject doData = CreateProtectedDataObject(strData);
                //	Clipboard.SetDataObject(doData);
                // }
            }
            catch (Exception) { Debug.Assert(false); return(false); }

            m_strFormat = null;

            byte[]        pbUtf8 = StrUtil.Utf8.GetBytes(strData);
            SHA256Managed sha256 = new SHA256Managed();

            m_pbDataHash32 = sha256.ComputeHash(pbUtf8);

            RaiseCopyEvent(bIsEntryInfo, strData);

            if (peEntryInfo != null)
            {
                peEntryInfo.Touch(false);
            }

            // SprEngine.Compile might have modified the database
            Program.MainForm.UpdateUI(false, null, false, null, false, null, false);

            return(true);
        }
Example #25
0
        // Multiple calls of this method are wrapped in
        // GetSequencesForWindowBegin and GetSequencesForWindowEnd
        private static List <string> GetSequencesForWindow(PwEntry pwe,
                                                           IntPtr hWnd, string strWindow, PwDatabase pdContext, int iEventID)
        {
            List <string> l = new List <string>();

            if (pwe == null)
            {
                Debug.Assert(false); return(l);
            }
            if (strWindow == null)
            {
                Debug.Assert(false); return(l);
            }                                                                    // May be empty

            if (!pwe.GetAutoTypeEnabled())
            {
                return(l);
            }

            SprContext sprCtx = new SprContext(pwe, pdContext,
                                               SprCompileFlags.NonActive);

            RaiseSequenceQueryEvent(AutoType.SequenceQueryPre, iEventID,
                                    hWnd, strWindow, pwe, pdContext, l);

            // Specifically defined sequences must match before the title,
            // in order to allow selecting the first item as default one
            foreach (AutoTypeAssociation a in pwe.AutoType.Associations)
            {
                string strWndSpec = a.WindowName;
                if (strWndSpec == null)
                {
                    Debug.Assert(false); continue;
                }

                strWndSpec = SprEngine.Compile(strWndSpec.Trim(), sprCtx);

                if (MatchWindows(strWndSpec, strWindow))
                {
                    string strSeq = a.Sequence;
                    if (string.IsNullOrEmpty(strSeq))
                    {
                        strSeq = pwe.GetAutoTypeSequence();
                    }
                    AddSequence(l, strSeq);
                }
            }

            RaiseSequenceQueryEvent(AutoType.SequenceQuery, iEventID,
                                    hWnd, strWindow, pwe, pdContext, l);

            if (Program.Config.Integration.AutoTypeMatchByTitle)
            {
                string strTitle = SprEngine.Compile(pwe.Strings.ReadSafe(
                                                        PwDefs.TitleField).Trim(), sprCtx);
                if ((strTitle.Length > 0) && (strWindow.IndexOf(strTitle,
                                                                StrUtil.CaseIgnoreCmp) >= 0))
                {
                    AddSequence(l, pwe.GetAutoTypeSequence());
                }
            }

            string strCmpUrl = null;             // To cache compiled URL

            if (Program.Config.Integration.AutoTypeMatchByUrlInTitle)
            {
                strCmpUrl = SprEngine.Compile(pwe.Strings.ReadSafe(
                                                  PwDefs.UrlField).Trim(), sprCtx);
                if ((strCmpUrl.Length > 0) && (strWindow.IndexOf(strCmpUrl,
                                                                 StrUtil.CaseIgnoreCmp) >= 0))
                {
                    AddSequence(l, pwe.GetAutoTypeSequence());
                }
            }

            if (Program.Config.Integration.AutoTypeMatchByUrlHostInTitle)
            {
                if (strCmpUrl == null)
                {
                    strCmpUrl = SprEngine.Compile(pwe.Strings.ReadSafe(
                                                      PwDefs.UrlField).Trim(), sprCtx);
                }

                string strCleanUrl = StrUtil.RemovePlaceholders(strCmpUrl);
                string strHost     = UrlUtil.GetHost(strCleanUrl);

                if (strHost.StartsWith("www.", StrUtil.CaseIgnoreCmp) &&
                    (strCleanUrl.StartsWith("http:", StrUtil.CaseIgnoreCmp) ||
                     strCleanUrl.StartsWith("https:", StrUtil.CaseIgnoreCmp)))
                {
                    strHost = strHost.Substring(4);
                }

                if ((strHost.Length > 0) && (strWindow.IndexOf(strHost,
                                                               StrUtil.CaseIgnoreCmp) >= 0))
                {
                    AddSequence(l, pwe.GetAutoTypeSequence());
                }
            }

            if (Program.Config.Integration.AutoTypeMatchByTagInTitle)
            {
                foreach (string strTag in pwe.Tags)
                {
                    if (string.IsNullOrEmpty(strTag))
                    {
                        Debug.Assert(false); continue;
                    }

                    if (strWindow.IndexOf(strTag, StrUtil.CaseIgnoreCmp) >= 0)
                    {
                        AddSequence(l, pwe.GetAutoTypeSequence());
                        break;
                    }
                }
            }

            RaiseSequenceQueryEvent(AutoType.SequenceQueryPost, iEventID,
                                    hWnd, strWindow, pwe, pdContext, l);

            return(l);
        }
Example #26
0
        private static bool Execute(AutoTypeCtx ctx)
        {
            if (ctx == null)
            {
                Debug.Assert(false); return(false);
            }

            string  strSeq  = ctx.Sequence;
            PwEntry pweData = ctx.Entry;

            if (pweData == null)
            {
                Debug.Assert(false); return(false);
            }

            if (!pweData.GetAutoTypeEnabled())
            {
                return(false);
            }
            if (!AppPolicy.Try(AppPolicyId.AutoType))
            {
                return(false);
            }

            if (NativeLib.IsUnix())
            {
                if (!NativeMethods.TryXDoTool() && !NativeLib.IsWayland())
                {
                    MessageService.ShowWarning(KPRes.AutoTypeXDoToolRequired,
                                               KPRes.PackageInstallHint);
                    return(false);
                }
            }

            PwDatabase pwDatabase = ctx.Database;

            bool bObfuscate = (pweData.AutoType.ObfuscationOptions !=
                               AutoTypeObfuscationOptions.None);
            AutoTypeEventArgs args = new AutoTypeEventArgs(strSeq, bObfuscate,
                                                           pweData, pwDatabase);

            if (AutoType.FilterCompilePre != null)
            {
                AutoType.FilterCompilePre(null, args);
            }

            args.Sequence = SprEngine.Compile(args.Sequence, new SprContext(
                                                  pweData, pwDatabase, SprCompileFlags.All, true, false));

            // string strError = ValidateAutoTypeSequence(args.Sequence);
            // if(!string.IsNullOrEmpty(strError))
            // {
            //	MessageService.ShowWarning(args.Sequence +
            //		MessageService.NewParagraph + strError);
            //	return false;
            // }

            Application.DoEvents();

            if (AutoType.FilterSendPre != null)
            {
                AutoType.FilterSendPre(null, args);
            }
            if (AutoType.FilterSend != null)
            {
                AutoType.FilterSend(null, args);
            }

            if (args.Sequence.Length > 0)
            {
                string strError = null;
                try { SendInputEx.SendKeysWait(args.Sequence, args.SendObfuscated); }
                catch (SecurityException exSec) { strError = exSec.Message; }
                catch (Exception ex)
                {
                    strError = args.Sequence + MessageService.NewParagraph +
                               ex.Message;
                }

                if (AutoType.SendPost != null)
                {
                    AutoType.SendPost(null, args);
                }

                if (!string.IsNullOrEmpty(strError))
                {
                    try
                    {
                        MainForm mfP = Program.MainForm;
                        if (mfP != null)
                        {
                            mfP.EnsureVisibleForegroundWindow(false, false);
                        }
                    }
                    catch (Exception) { Debug.Assert(false); }

                    MessageService.ShowWarning(strError);
                }
            }

            pweData.Touch(false);
            EntryUtil.ExpireTanEntryIfOption(pweData, pwDatabase);

            MainForm mf = Program.MainForm;

            if (mf != null)
            {
                // Always refresh entry list (e.g. {NEWPASSWORD} might
                // have changed data)
                mf.RefreshEntriesList();

                // SprEngine.Compile might have modified the database;
                // pd.Modified is set by SprEngine
                mf.UpdateUI(false, null, false, null, false, null, false);

                if (Program.Config.MainWindow.MinimizeAfterAutoType &&
                    mf.IsCommandTypeInvokable(null, MainForm.AppCommandType.Window))
                {
                    UIUtil.SetWindowState(mf, FormWindowState.Minimized);
                }
            }

            return(true);
        }
        private void UpdateUI()
        {
            if ((m_uBlockUIUpdate > 0) || m_bInitializing)
            {
                return;
            }
            ++m_uBlockUIUpdate;

            ulong uFlags = 0;

            if (m_fParent is KeyCreationForm)
            {
                uFlags = Program.Config.UI.KeyCreationFlags;
            }

            byte[] pbUtf8 = m_secPassword.ToUtf8();
            string str    = StrUtil.Utf8.GetString(pbUtf8);

#if DEBUG
            byte[] pbTest = StrUtil.Utf8.GetBytes(str);
            Debug.Assert(MemUtil.ArraysEqual(pbUtf8, pbTest));
#endif

            m_tbPassword.Enabled = m_bEnabled;
            m_cbHide.Enabled     = (m_bEnabled && ((uFlags &
                                                    (ulong)AceKeyUIFlags.DisableHidePassword) == 0));

            if ((uFlags & (ulong)AceKeyUIFlags.CheckHidePassword) != 0)
            {
                ++m_uPrgmCheck;
                m_cbHide.Checked = true;
                --m_uPrgmCheck;
            }
            if ((uFlags & (ulong)AceKeyUIFlags.UncheckHidePassword) != 0)
            {
                ++m_uPrgmCheck;
                m_cbHide.Checked = false;
                --m_uPrgmCheck;
            }

            bool bAutoRepeat = this.AutoRepeat;
            if (bAutoRepeat && (m_secRepeat.TextLength > 0))
            {
                m_secRepeat.SetPassword(MemUtil.EmptyByteArray);
            }

            byte[] pbRepeat = m_secRepeat.ToUtf8();
            if (!MemUtil.ArraysEqual(pbUtf8, pbRepeat) && !bAutoRepeat)
            {
                m_tbRepeat.BackColor = AppDefs.ColorEditError;
            }
            else
            {
                m_tbRepeat.ResetBackColor();
            }

            bool bRepeatEnable = (m_bEnabled && !bAutoRepeat);
            m_lblRepeat.Enabled = bRepeatEnable;
            m_tbRepeat.Enabled  = bRepeatEnable;

            bool bQuality = m_bEnabled;
            if (m_bSprVar && bQuality)
            {
                if (SprEngine.MightChange(str))                // Perf. opt.
                {
                    // {S:...} and {REF:...} may reference the entry that
                    // is currently being edited and SprEngine will not see
                    // the current data entered in the dialog; thus we
                    // disable quality estimation for all strings containing
                    // one of these placeholders
                    if ((str.IndexOf(@"{S:", StrUtil.CaseIgnoreCmp) >= 0) ||
                        (str.IndexOf(@"{REF:", StrUtil.CaseIgnoreCmp) >= 0))
                    {
                        bQuality = false;
                    }
                    else
                    {
                        SprContext ctx = new SprContext(m_ctxEntry, m_ctxDatabase,
                                                        SprCompileFlags.NonActive, false, false);
                        string strCmp = SprEngine.Compile(str, ctx);
                        if (strCmp != str)
                        {
                            bQuality = false;
                        }
                    }
                }
#if DEBUG
                else
                {
                    SprContext ctx = new SprContext(m_ctxEntry, m_ctxDatabase,
                                                    SprCompileFlags.NonActive, false, false);
                    string strCmp = SprEngine.Compile(str, ctx);
                    Debug.Assert(strCmp == str);
                }
#endif
            }

            m_lblQualityPrompt.Enabled = bQuality;
            m_pbQuality.Enabled        = bQuality;
            m_lblQualityInfo.Enabled   = bQuality;

            if ((Program.Config.UI.UIFlags & (ulong)AceUIFlags.HidePwQuality) != 0)
            {
                m_lblQualityPrompt.Visible = false;
                m_pbQuality.Visible        = false;
                m_lblQualityInfo.Visible   = false;
            }
            else if (bQuality || !m_bSprVar)
            {
                UpdateQualityInfo(str);
            }
            else
            {
                UqiShowQuality(0, 0);
            }

            // MemUtil.ZeroByteArray(pbUtf8);
            // MemUtil.ZeroByteArray(pbRepeat);
            --m_uBlockUIUpdate;
        }
        /// <summary>
        /// Notify Icon Context Menu Opening.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnNotifyMenuOpening(object sender, CancelEventArgs e)
        {
            foreach (var Menu in niMenuList)
            {
                m_host.MainWindow.TrayContextMenu.Items.Remove(Menu);
            }
            niMenuList.Clear();
            if (m_host.CustomConfig.GetBool(setname_bool_NotifyContext_Visible, true))
            {
                niMenuTitle.Visible     = true;
                niMenuSeperator.Visible = true;
                if (m_host.MainWindow.ActiveDatabase.IsOpen)
                {
                    var trimTrayText = m_host.CustomConfig.GetBool(KeeTrayTOTPExt.setname_bool_TrimTrayText, false);
                    foreach (PwEntry Entry in m_host.MainWindow.ActiveDatabase.RootGroup.GetEntries(true))
                    {
                        if (SettingsCheck(Entry) && SeedCheck(Entry))
                        {
                            var entryTitle = Entry.Strings.ReadSafe(PwDefs.TitleField);

                            var    context       = new SprContext(Entry, m_host.MainWindow.ActiveDatabase, SprCompileFlags.All, false, false);
                            var    entryUsername = SprEngine.Compile(Entry.Strings.ReadSafe(PwDefs.UserNameField), context);
                            string trayTitle;
                            if (trimTrayText && entryTitle.Length + entryUsername.Length > setstat_trim_text_length)
                            {
                                trayTitle = entryTitle.ExtWithSpaceAfter();
                            }
                            else
                            {
                                trayTitle = entryTitle.ExtWithSpaceAfter() + entryUsername.ExtWithParenthesis();
                            }
                            m_host.CustomConfig.GetBool(KeeTrayTOTPExt.setname_bool_TrimTrayText, false);

                            var NewMenu = new ToolStripMenuItem(trayTitle, Properties.Resources.TOTP_Key, OnNotifyMenuTOTPClick);
                            NewMenu.Tag = Entry;
                            if (!SettingsValidate(Entry))
                            {
                                NewMenu.Enabled = false;
                                NewMenu.Image   = Properties.Resources.TOTP_Error;
                            }
                            niMenuList.Add(NewMenu);
                        }
                    }
                    if (niMenuList.Count > 0)
                    {
                        niMenuList.Sort((p1, p2) => string.Compare(p1.Text, p2.Text, true));
                        for (int i = 0; i <= niMenuList.Count - 1; i++)
                        {
                            m_host.MainWindow.TrayContextMenu.Items.Insert(i + 1, niMenuList[i]);
                        }
                    }
                    else
                    {
                        var NewMenu = new ToolStripMenuItem(TrayTOTP_Plugin_Localization.strNoTOTPFound);
                        NewMenu.Image = Properties.Resources.TOTP_None;
                        niMenuList.Add(NewMenu);
                        m_host.MainWindow.TrayContextMenu.Items.Insert(1, niMenuList[0]);
                    }
                }
                else
                {
                    if (m_host.MainWindow.IsFileLocked(null))
                    {
                        var NewMenu = new ToolStripMenuItem(TrayTOTP_Plugin_Localization.strDatabaseIsLocked);
                        NewMenu.Image = Properties.Resources.TOTP_Lock;
                        niMenuList.Add(NewMenu);
                        m_host.MainWindow.TrayContextMenu.Items.Insert(1, niMenuList[0]);
                    }
                    else
                    {
                        var NewMenu = new ToolStripMenuItem(TrayTOTP_Plugin_Localization.strDatabaseNotOpen);
                        NewMenu.Image = Properties.Resources.TOTP_Error;
                        niMenuList.Add(NewMenu);
                        m_host.MainWindow.TrayContextMenu.Items.Insert(1, niMenuList[0]);
                    }
                }
            }
            else
            {
                niMenuTitle.Visible     = false;
                niMenuSeperator.Visible = false;
            }
        }
Example #29
0
        private static string ReplaceNewPasswordPlaceholder(string strText,
                                                            SprContext ctx, uint uRecursionLevel)
        {
            PwEntry    pe = ctx.Entry;
            PwDatabase pd = ctx.Database;

            if ((pe == null) || (pd == null))
            {
                return(strText);
            }

            string str = strText;

            const string strNewPwStart = @"{NEWPASSWORD";

            if (str.IndexOf(strNewPwStart, StrUtil.CaseIgnoreCmp) < 0)
            {
                return(str);
            }

            string strGen = null;

            int           iStart;
            List <string> lParams;

            while (SprEngine.ParseAndRemovePlhWithParams(ref str, ctx, uRecursionLevel,
                                                         strNewPwStart + ":", out iStart, out lParams, true))
            {
                if (strGen == null)
                {
                    strGen = GeneratePassword((((lParams != null) &&
                                                (lParams.Count > 0)) ? lParams[0] : string.Empty), ctx);
                }

                string strIns = SprEngine.TransformContent(strGen, ctx);
                str = str.Insert(iStart, strIns);
            }

            const string strNewPwPlh = strNewPwStart + @"}";

            if (str.IndexOf(strNewPwPlh, StrUtil.CaseIgnoreCmp) >= 0)
            {
                if (strGen == null)
                {
                    strGen = GeneratePassword(null, ctx);
                }

                string strIns = SprEngine.TransformContent(strGen, ctx);
                str = StrUtil.ReplaceCaseInsensitive(str, strNewPwPlh, strIns);
            }

            if (strGen != null)
            {
                pe.CreateBackup(pd);

                ProtectedString psGen = new ProtectedString(
                    pd.MemoryProtection.ProtectPassword, strGen);
                pe.Strings.Set(PwDefs.PasswordField, psGen);

                pe.Touch(true, false);
                pd.Modified = true;
            }
            else
            {
                Debug.Assert(false);
            }

            return(str);
        }
Example #30
0
        public static void OpenUrl(string strUrlToOpen, PwEntry peDataSource)
        {
            // If URL is null, return false, do not throw exception.
            Debug.Assert(strUrlToOpen != null); if (strUrlToOpen == null)
            {
                return;
            }

            string strPrevWorkDir = Directory.GetCurrentDirectory();
            string strThisExe     = WinUtil.GetExecutable();

            string strExeDir = UrlUtil.GetFileDirectory(strThisExe, false);

            try { Directory.SetCurrentDirectory(strExeDir); }
            catch (Exception) { Debug.Assert(false); }

            string strUrl = strUrlToOpen;

            strUrl = strUrl.TrimStart(new char[] { ' ', '\t', '\r', '\n' });

            PwDatabase pwDatabase = null;

            try { pwDatabase = Program.MainForm.PluginHost.Database; }
            catch (Exception) { Debug.Assert(false); pwDatabase = null; }

            bool bCmdQuotes = WinUtil.IsCommandLineUrl(strUrl);

            strUrl = SprEngine.Compile(strUrl, false, peDataSource, pwDatabase,
                                       false, bCmdQuotes);

            if (WinUtil.IsCommandLineUrl(strUrl))
            {
                string strApp, strArgs;
                StrUtil.SplitCommandLine(WinUtil.GetCommandLineFromUrl(strUrl),
                                         out strApp, out strArgs);

                try
                {
                    if ((strArgs != null) && (strArgs.Length > 0))
                    {
                        Process.Start(strApp, strArgs);
                    }
                    else
                    {
                        Process.Start(strApp);
                    }
                }
                catch (Win32Exception)
                {
                    StartWithoutShellExecute(strApp, strArgs);
                }
                catch (Exception exCmd)
                {
                    string strInf = KPRes.FileOrUrl + ": " + strApp;
                    if ((strArgs != null) && (strArgs.Length > 0))
                    {
                        strInf += MessageService.NewParagraph +
                                  KPRes.Arguments + ": " + strArgs;
                    }

                    MessageService.ShowWarning(strInf, exCmd);
                }
            }
            else
            {
                try { Process.Start(strUrl); }
                catch (Exception exUrl)
                {
                    MessageService.ShowWarning(strUrl, exUrl);
                }
            }

            // Restore previous working directory
            try { Directory.SetCurrentDirectory(strPrevWorkDir); }
            catch (Exception) { Debug.Assert(false); }
        }