Exemple #1
0
        private void OnFormLoad(object sender, EventArgs e)
        {
            this.Icon = Properties.Resources.KeePass;

            if (!string.IsNullOrEmpty(m_strTitle))
            {
                this.Text = m_strTitle;
            }
            else
            {
                m_strTitle = PwDefs.ShortProductName;
            }

            m_lvEntries.Columns.Add(KPRes.Title);
            m_lvEntries.Columns.Add(KPRes.UserName);
            m_lvEntries.Columns.Add(string.Empty);

            ListViewGroup lvg = new ListViewGroup(m_pgDataSource.GetFullPath(
                                                      " - ", true));

            m_lvEntries.Groups.Add(lvg);

            GroupHandler gh = delegate(PwGroup pg)
            {
                if (pg.Entries.UCount != 0)
                {
                    lvg = new ListViewGroup(pg.GetFullPath(" - ", true));
                    m_lvEntries.Groups.Add(lvg);
                }

                return(true);
            };

            EntryHandler eh = delegate(PwEntry pe)
            {
                ListViewItem lvi = new ListViewItem(pe.Strings.ReadSafe(PwDefs.TitleField));

                lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.UserNameField));
                lvi.SubItems.Add(string.Empty);

                m_lvEntries.Items.Add(lvi);
                lvg.Items.Add(lvi);
                return(true);
            };

            m_pgDataSource.TraverseTree(TraversalMethod.PreOrder, gh, eh);

            UIUtil.ResizeColumns(m_lvEntries, new int[] { 2, 1, 2 }, true);
        }
Exemple #2
0
        private static string FillGroupPlh(string strData, string strPlhPrefix,
                                           PwGroup pg, SprContext ctx, uint uRecursionLevel)
        {
            Debug.Assert(strPlhPrefix.StartsWith("{"));
            Debug.Assert(!strPlhPrefix.EndsWith("_"));
            Debug.Assert(!strPlhPrefix.EndsWith("}"));

            string str = strData;

            str = Fill(str, strPlhPrefix + @"}", pg.Name, ctx, uRecursionLevel);

            string strGroupPath = pg.GetFullPath();

            str = Fill(str, strPlhPrefix + @"_PATH}", strGroupPath,
                       ctx, uRecursionLevel);
            str = Fill(str, strPlhPrefix + @"PATH}", strGroupPath,
                       ctx, uRecursionLevel);          // Obsolete; for backward compatibility

            str = Fill(str, strPlhPrefix + @"_NOTES}", pg.Notes, ctx, uRecursionLevel);

            return(str);
        }
Exemple #3
0
        private static string FillGroupPlh(string strData, string strPlhPrefix,
                                           PwGroup pg, SprContext ctx, uint uRecursionLevel)
        {
            Debug.Assert(strPlhPrefix.StartsWith("{"));
            Debug.Assert(!strPlhPrefix.EndsWith("_"));
            Debug.Assert(!strPlhPrefix.EndsWith("}"));

            string str = strData;

            str = SprEngine.FillIfExists(str, strPlhPrefix + @"}",
                                         new ProtectedString(false, pg.Name), ctx, uRecursionLevel);

            ProtectedString psGroupPath = new ProtectedString(false, pg.GetFullPath());

            str = SprEngine.FillIfExists(str, strPlhPrefix + @"_PATH}", psGroupPath,
                                         ctx, uRecursionLevel);
            str = SprEngine.FillIfExists(str, strPlhPrefix + @"PATH}", psGroupPath,
                                         ctx, uRecursionLevel); // Obsolete; for backward compatibility

            str = SprEngine.FillIfExists(str, strPlhPrefix + @"_NOTES}",
                                         new ProtectedString(false, pg.Notes), ctx, uRecursionLevel);

            return(str);
        }
        private void ShowExpiringEntriesMultiDB()
        {
            if ((m_host.Database == null) || !m_host.Database.IsOpen)
            {
                return;
            }
            DateTime dtSoon = DateTime.Now.AddDays(Program.Config.Application.ExpirySoonDays);

            List <DBExpiringEntries> lExpiring = new List <DBExpiringEntries>();

            foreach (PwDatabase db in m_host.MainWindow.DocumentManager.GetOpenDatabases())
            {
                lExpiring.Add(new DBExpiringEntries(db, GetExpiringEntries(db, dtSoon)));
            }
            if (lExpiring.Find(x => x.EntryCount > 0) == null)
            {
                Tools.ShowInfo(PluginTranslate.NoEntries);
                return;
            }

            Action <ListView> fInit = delegate(ListView lv)
            {
                int w  = lv.ClientSize.Width - UIUtil.GetVScrollBarWidth();
                int wf = w / 4;
                int di = Math.Min(UIUtil.GetSmallIconSize().Width, wf);

                lv.Columns.Add(KeePass.Resources.KPRes.Database, wf + di);
                lv.Columns.Add(KeePass.Resources.KPRes.Title, wf);
                lv.Columns.Add(KeePass.Resources.KPRes.UserName, wf);
                lv.Columns.Add(KeePass.Resources.KPRes.ExpiryTime, wf - di);

                UIUtil.SetDisplayIndices(lv, new int[] { 0, 1, 2, 3 });
            };

            List <object> lEntries = new List <object>();

            //Prepare ImageList (CustomIcons can be different per database)
            ImageList il  = new ImageList();
            ImageList il2 = (ImageList)Tools.GetField("m_ilCurrentIcons", m_host.MainWindow);

            foreach (Image img in il2.Images)
            {
                il.Images.Add(img);
            }

            foreach (DBExpiringEntries dbe in lExpiring)
            {
                foreach (PwEntry pe in dbe.pg.GetEntries(true))
                {
                    PwGroup pge = pe.ParentGroup;
                    if (pge != null)
                    {
                        if (lEntries.Find(x => (x is ListViewGroup) && ((x as ListViewGroup).Tag == pge)) == null)
                        {
                            ListViewGroup lvg = new ListViewGroup(pge.GetFullPath(" - ", pge.ParentGroup == null));
                            lvg.Tag = pge;
                            lEntries.Add(lvg);
                        }
                    }

                    ListViewItem lvi = new ListViewItem(UrlUtil.GetFileName(dbe.db.IOConnectionInfo.Path));
                    lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.UserNameField));
                    lvi.SubItems.Add(pe.Strings.ReadSafe(PwDefs.TitleField));
                    lvi.SubItems.Add(pe.ExpiryTime.ToLocalTime().ToString());
                    lvi.ImageIndex = (int)pe.IconId;
                    if (!pe.CustomIconUuid.Equals(PwUuid.Zero))
                    {
                        il.Images.Add(dbe.db.GetCustomIcon(pe.CustomIconUuid, DpiUtil.ScaleIntX(16), DpiUtil.ScaleIntY(16)));
                        lvi.ImageIndex = il.Images.Count - 1;
                    }
                    lvi.Tag = pe;
                    lEntries.Add(lvi);
                }
            }

            KeePass.Forms.ListViewForm lvf = new KeePass.Forms.ListViewForm();
            lvf.InitEx(PluginTranslate.PluginName, PluginTranslate.SoonExpiring, null, SmallIcon, lEntries, il, fInit);

            UIUtil.ShowDialogAndDestroy(lvf);
            il.Dispose();
            if (lvf.DialogResult != DialogResult.OK)
            {
                return;
            }

            PwEntry peSelected = lvf.ResultItem as PwEntry;

            if (peSelected == null)
            {
                return;
            }
            DBExpiringEntries dbeSelected = lExpiring.Find(x => x.pg.FindEntry(peSelected.Uuid, true) != null);

            if (dbeSelected == null)
            {
                return;
            }

            m_host.MainWindow.UpdateUI(false, m_host.MainWindow.DocumentManager.FindDocument(dbeSelected.db), true, dbeSelected.pg, true, dbeSelected.pg, false);
            m_host.MainWindow.SelectEntries(new PwObjectList <PwEntry>()
            {
                peSelected
            }, true, true);
        }
Exemple #5
0
        /*
         * public static void ReorderEntriesAsInDatabase(PwObjectList<PwEntry> v,
            PwDatabase pd)
        {
            if((v == null) || (pd == null)) { Debug.Assert(false); return; }

            PwObjectList<PwEntry> vRem = v.CloneShallow();
            v.Clear();

            EntryHandler eh = delegate(PwEntry pe)
            {
                int p = vRem.IndexOf(pe);
                if(p >= 0)
                {
                    v.Add(pe);
                    vRem.RemoveAt((uint)p);
                }

                return true;
            };

            pd.RootGroup.TraverseTree(TraversalMethod.PreOrder, null, eh);

            foreach(PwEntry peRem in vRem) v.Add(peRem); // Entries not found
        }
         * */
        private Group GetGroupFromPwGroup(PwGroup pwg)
        {
            //Debug.Indent();
            //Stopwatch sw = Stopwatch.StartNew();

            string imageData = iconToBase64(pwg.CustomIconUuid, pwg.IconId);

            Group kpg = new Group(pwg.Name, KeePassLib.Utility.MemUtil.ByteArrayToHexString(pwg.Uuid.UuidBytes), imageData, pwg.GetFullPath("/", false));

            //sw.Stop();
            //Debug.WriteLine("GetGroupFromPwGroup execution time: " + sw.Elapsed);
            //Debug.Unindent();
            return kpg;
        }
Exemple #6
0
            // Ported from KeePass Mainform_functions SetListEntry
            internal static ListViewItem InsertListEntryOLD(PwEntry pe, int iIndex)
            {
                // Adapted variables
                DateTime      m_dtCachedNow       = DateTime.Now;
                Font          m_fontExpired       = FontUtil.CreateFont(m_lvEntries.Font, FontStyle.Strikeout);
                bool          m_bEntryGrouping    = m_lvEntries.ShowGroups;
                bool          m_bShowTanIndices   = Program.Config.MainWindow.TanView.ShowIndices;
                bool          bSubEntries         = Program.Config.MainWindow.ShowEntriesOfSubGroups;
                ListViewGroup m_lvgLastEntryGroup = null;

                foreach (ListViewGroup lvg in m_lvEntries.Groups)
                {
                    if ((lvg.Tag as PwGroup) == pe.ParentGroup)
                    {
                        m_lvgLastEntryGroup = lvg;
                    }
                }
                PwGroup pg = (Program.MainForm.GetSelectedGroup());
                PwObjectList <PwEntry> pwlSource = ((pg != null) ? pg.GetEntries(bSubEntries) : new PwObjectList <PwEntry>());
                bool m_bOnlyTans = ListContainsOnlyTans(pwlSource);

                ListViewItem lviTarget = null;
                Color        m_clrAlternateItemBgColor = UIUtil.GetAlternateColor(m_lvEntries.BackColor);

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

                ListViewItem lvi = (lviTarget ?? new ListViewItem());
                PwListItem   pli = new PwListItem(pe);

                lvi.Tag = pli;

                //lvi.BeginUpdate();

                if (pe.Expires && (pe.ExpiryTime <= m_dtCachedNow))
                {
                    lvi.ImageIndex = (int)PwIcon.Expired;
                    if (m_fontExpired != null)
                    {
                        lvi.Font = m_fontExpired;
                    }
                }
                else // Not expired
                {
                    // Reset font, if item was expired previously (i.e. has expired font)
                    if ((lviTarget != null) && (lvi.ImageIndex == (int)PwIcon.Expired))
                    {
                        lvi.Font = m_lvEntries.Font;
                    }

                    if (pe.CustomIconUuid.EqualsValue(PwUuid.Zero))
                    {
                        lvi.ImageIndex = (int)pe.IconId;
                    }
                    else
                    {
                        lvi.ImageIndex = (int)PwIcon.Count +
                                         m_host.MainWindow.DocumentManager.ActiveDatabase.GetCustomIconIndex(pe.CustomIconUuid);
                    }
                }

                if (m_bEntryGrouping && (lviTarget == null))
                {
                    PwGroup pgContainer = pe.ParentGroup;
                    PwGroup pgLast      = ((m_lvgLastEntryGroup != null) ?
                                           (PwGroup)m_lvgLastEntryGroup.Tag : null);

                    Debug.Assert(pgContainer != null);
                    if (pgContainer != null)
                    {
                        if (pgContainer != pgLast)
                        {
                            m_lvgLastEntryGroup = new ListViewGroup(
                                pgContainer.GetFullPath());
                            m_lvgLastEntryGroup.Tag = pgContainer;

                            m_lvEntries.Groups.Add(m_lvgLastEntryGroup);
                        }

                        lvi.Group = m_lvgLastEntryGroup;
                    }
                }

                if (!pe.ForegroundColor.IsEmpty)
                {
                    lvi.ForeColor = pe.ForegroundColor;
                }
                else if (lviTarget != null)
                {
                    lvi.ForeColor = m_lvEntries.ForeColor;
                }
                else
                {
                    Debug.Assert(UIUtil.ColorsEqual(lvi.ForeColor, m_lvEntries.ForeColor));
                }

                if (!pe.BackgroundColor.IsEmpty)
                {
                    lvi.BackColor = pe.BackgroundColor;
                }
                // else if(Program.Config.MainWindow.EntryListAlternatingBgColors &&
                //	((m_lvEntries.Items.Count & 1) == 1))
                //	lvi.BackColor = m_clrAlternateItemBgColor;
                else if (lviTarget != null)
                {
                    lvi.BackColor = m_lvEntries.BackColor;
                }
                else
                {
                    Debug.Assert(UIUtil.ColorsEqual(lvi.BackColor, m_lvEntries.BackColor));
                }

                // m_bOnlyTans &= PwDefs.IsTanEntry(pe);
                if (m_bShowTanIndices && m_bOnlyTans)
                {
                    string strIndex = pe.Strings.ReadSafe(PwDefs.TanIndexField);

                    if (strIndex.Length > 0)
                    {
                        lvi.Text = strIndex;
                    }
                    else
                    {
                        lvi.Text = PwDefs.TanTitle;
                    }
                }
                else
                {
                    lvi.Text = GetEntryFieldEx(pe, 0, true);
                }

                int nColumns = m_lvEntries.Columns.Count;

                if (lviTarget == null)
                {
                    for (int iColumn = 1; iColumn < nColumns; ++iColumn)
                    {
                        lvi.SubItems.Add(GetEntryFieldEx(pe, iColumn, true));
                    }
                }
                else
                {
                    int nSubItems = lvi.SubItems.Count;
                    for (int iColumn = 1; iColumn < nColumns; ++iColumn)
                    {
                        string strSub = GetEntryFieldEx(pe, iColumn, true);
                        if (iColumn < nSubItems)
                        {
                            lvi.SubItems[iColumn].Text = strSub;
                        }
                        else
                        {
                            lvi.SubItems.Add(strSub);
                        }
                    }

                    Debug.Assert(lvi.SubItems.Count == nColumns);
                }

                //if (lviTarget == null) m_lvEntries.Items.Add(lvi);
                if (lviTarget == null)
                {
                    m_lvEntries.Items.Insert(iIndex, lvi);
                }

                UIUtil.SetAlternatingBgColors(m_lvEntries, m_clrAlternateItemBgColor,
                                              Program.Config.MainWindow.EntryListAlternatingBgColors);

                //lvi.EndUpdate();

                return(lvi);
            }
Exemple #7
0
        private static string FillGroupPlh(string strData, string strPlhPrefix,
			PwGroup pg, SprContext ctx, uint uRecursionLevel)
        {
            Debug.Assert(strPlhPrefix.StartsWith("{"));
            Debug.Assert(!strPlhPrefix.EndsWith("_"));
            Debug.Assert(!strPlhPrefix.EndsWith("}"));

            string str = strData;

            str = SprEngine.FillIfExists(str, strPlhPrefix + @"}",
                new ProtectedString(false, pg.Name), ctx, uRecursionLevel);

            ProtectedString psGroupPath = new ProtectedString(false, pg.GetFullPath());
            str = SprEngine.FillIfExists(str, strPlhPrefix + @"_PATH}", psGroupPath,
                ctx, uRecursionLevel);
            str = SprEngine.FillIfExists(str, strPlhPrefix + @"PATH}", psGroupPath,
                ctx, uRecursionLevel); // Obsolete; for backward compatibility

            str = SprEngine.FillIfExists(str, strPlhPrefix + @"_NOTES}",
                new ProtectedString(false, pg.Notes), ctx, uRecursionLevel);

            return str;
        }
Exemple #8
0
        private List <object> GetFoundEntriesList(PwGroup g, Dictionary <PwEntry, int> dEntryIconIndex)
        {
            List <Object> l = new List <object>();

            m_lEntryListColumns = new List <AceColumn>();
            List <AceColumn> lColumns = null;

            if (m_miGetEntryFieldEx != null)
            {
                lColumns = KeePass.Program.Config.MainWindow.EntryListColumns;
            }
            else             //add a basic set of columns
            {
                lColumns = new List <AceColumn>();
                AddColumn(lColumns, AceColumnType.Title, false);
                AddColumn(lColumns, AceColumnType.UserName, false);
                AddColumn(lColumns, AceColumnType.Password, true);
                AddColumn(lColumns, AceColumnType.Url, false);
                AddColumn(lColumns, AceColumnType.Notes, false);
            }
            foreach (PwEntry pe in g.Entries)
            {
                PwGroup pg = pe.ParentGroup;
                if (pg != null)
                {
                    if (l.Find(x => (x is ListViewGroup) && ((x as ListViewGroup).Tag == pg)) == null)
                    {
                        ListViewGroup lvg = new ListViewGroup(pg.GetFullPath(" - ", pg.ParentGroup == null));
                        lvg.Tag = pg;
                        l.Add(lvg);
                    }
                }
                ListViewItem lvi = new ListViewItem();
                lvi.Tag        = new object[] { pe, g };
                lvi.Text       = SearchHelp.GetDBName(pe);
                lvi.ImageIndex = dEntryIconIndex[pe];
                ListViewItem.ListViewSubItem lvsi = null;
                //Show all columns that are shown in the entry list view if possible
                if (m_miGetEntryFieldEx != null)
                {
                    for (int i = 0; i < lColumns.Count; i++)
                    {
                        lvsi      = new ListViewItem.ListViewSubItem();
                        lvsi.Text = (string)m_miGetEntryFieldEx.Invoke(m_host.MainWindow, new object[] { pe, i, true, null });
                        if (!m_lEntryListColumns.Contains(lColumns[i]))
                        {
                            m_lEntryListColumns.Add(lColumns[i]);
                        }
                        lvi.SubItems.Add(lvsi);
                    }
                }
                else                 //Show a basic set of columns
                {
                    foreach (AceColumn c in lColumns)
                    {
                        lvsi = new ListViewItem.ListViewSubItem();
                        if (c.Type == AceColumnType.Title)
                        {
                            lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.TitleField);
                        }
                        if (c.Type == AceColumnType.UserName)
                        {
                            lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.UserNameField);
                        }
                        if (c.Type == AceColumnType.Password)
                        {
                            lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.PasswordField);
                        }
                        if (c.Type == AceColumnType.Url)
                        {
                            lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : pe.Strings.ReadSafe(PwDefs.UrlField);
                        }
                        if (c.Type == AceColumnType.Notes)
                        {
                            lvsi.Text = c.HideWithAsterisks ? PwDefs.HiddenPassword : KeePassLib.Utility.StrUtil.MultiToSingleLine(pe.Strings.ReadSafe(PwDefs.NotesField));
                        }
                        //Deref data if required
                        lvsi.Text = DerefString(lvsi.Text, pe);
                        if (!m_lEntryListColumns.Contains(c))
                        {
                            m_lEntryListColumns.Add(c);
                        }
                        lvi.SubItems.Add(lvsi);
                    }
                    ;
                };
                l.Add(lvi);
            }
            return(l);
        }
Exemple #9
0
        private static string CompileInternal(string strText, SprContext ctx,
                                              uint uRecursionLevel)
        {
            if (strText == null)
            {
                Debug.Assert(false); return(string.Empty);
            }
            if (ctx == null)
            {
                Debug.Assert(false); ctx = new SprContext();
            }

            if (uRecursionLevel >= SprEngine.MaxRecursionDepth)
            {
                Debug.Assert(false);                 // Most likely a recursive reference
                return(string.Empty);                // Do not return strText (endless loop)
            }

            string str = strText;

            bool bExt = ((ctx.Flags & (SprCompileFlags.ExtActive |
                                       SprCompileFlags.ExtNonActive)) != SprCompileFlags.None);

            if (bExt && (SprEngine.FilterCompilePre != null))
            {
                SprEventArgs args = new SprEventArgs(str, ctx.Clone());
                SprEngine.FilterCompilePre(null, args);
                str = args.Text;
            }

            if ((ctx.Flags & SprCompileFlags.Comments) != SprCompileFlags.None)
            {
                str = RemoveComments(str);
            }

            if ((ctx.Flags & SprCompileFlags.TextTransforms) != SprCompileFlags.None)
            {
                str = PerformTextTransforms(str, ctx, uRecursionLevel);
            }

            if ((ctx.Flags & SprCompileFlags.AppPaths) != SprCompileFlags.None)
            {
                str = AppLocator.FillPlaceholders(str, ctx);
            }

            if (ctx.Entry != null)
            {
                if ((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None)
                {
                    str = ReplacePickPw(str, ctx, uRecursionLevel);
                }

                if ((ctx.Flags & SprCompileFlags.EntryStrings) != SprCompileFlags.None)
                {
                    str = FillEntryStrings(str, ctx, uRecursionLevel);
                }

                if ((ctx.Flags & SprCompileFlags.EntryStringsSpecial) != SprCompileFlags.None)
                {
                    // ctx.UrlRemoveSchemeOnce = true;
                    // str = SprEngine.FillIfExists(str, @"{URL:RMVSCM}",
                    //	ctx.Entry.Strings.GetSafe(PwDefs.UrlField), ctx, uRecursionLevel);
                    // Debug.Assert(!ctx.UrlRemoveSchemeOnce);

                    str = FillEntryStringsSpecial(str, ctx, uRecursionLevel);
                }

                if (((ctx.Flags & SprCompileFlags.PasswordEnc) != SprCompileFlags.None) &&
                    (str.IndexOf(@"{PASSWORD_ENC}", SprEngine.ScMethod) >= 0))
                {
                    string strPwCmp = SprEngine.FillIfExists(@"{PASSWORD}",
                                                             @"{PASSWORD}", ctx.Entry.Strings.GetSafe(PwDefs.PasswordField),
                                                             ctx.WithoutContentTransformations(), uRecursionLevel);

                    str = SprEngine.FillPlaceholder(str, @"{PASSWORD_ENC}",
                                                    StrUtil.EncryptString(strPwCmp), ctx);
                }

                PwGroup pg = ctx.Entry.ParentGroup;
                if (((ctx.Flags & SprCompileFlags.Group) != SprCompileFlags.None) &&
                    (pg != null))
                {
                    str = SprEngine.FillIfExists(str, @"{GROUP}", new ProtectedString(
                                                     false, pg.Name), ctx, uRecursionLevel);

                    ProtectedString psGroupPath = new ProtectedString(false,
                                                                      pg.GetFullPath());
                    str = SprEngine.FillIfExists(str, @"{GROUP_PATH}", psGroupPath,
                                                 ctx, uRecursionLevel);
                    str = SprEngine.FillIfExists(str, @"{GROUPPATH}", psGroupPath,
                                                 ctx, uRecursionLevel); // Obsolete; for backward compatibility

                    str = SprEngine.FillIfExists(str, @"{GROUP_NOTES}", new ProtectedString(
                                                     false, pg.Notes), ctx, uRecursionLevel);
                }
            }

            if ((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None)
            {
                str = SprEngine.FillIfExists(str, @"{APPDIR}", new ProtectedString(
                                                 false, UrlUtil.GetFileDirectory(m_strAppExePath, false, false)),
                                             ctx, uRecursionLevel);
            }

            if (ctx.Database != null)
            {
                if ((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None)
                {
                    // For backward compatibility only
                    str = SprEngine.FillIfExists(str, @"{DOCDIR}", new ProtectedString(
                                                     false, UrlUtil.GetFileDirectory(ctx.Database.IOConnectionInfo.Path,
                                                                                     false, false)), ctx, uRecursionLevel);

                    str = SprEngine.FillIfExists(str, @"{DB_PATH}", new ProtectedString(
                                                     false, ctx.Database.IOConnectionInfo.Path), ctx, uRecursionLevel);
                    str = SprEngine.FillIfExists(str, @"{DB_DIR}", new ProtectedString(
                                                     false, UrlUtil.GetFileDirectory(ctx.Database.IOConnectionInfo.Path,
                                                                                     false, false)), ctx, uRecursionLevel);
                    str = SprEngine.FillIfExists(str, @"{DB_NAME}", new ProtectedString(
                                                     false, UrlUtil.GetFileName(ctx.Database.IOConnectionInfo.Path)),
                                                 ctx, uRecursionLevel);
                    str = SprEngine.FillIfExists(str, @"{DB_BASENAME}", new ProtectedString(
                                                     false, UrlUtil.StripExtension(UrlUtil.GetFileName(
                                                                                       ctx.Database.IOConnectionInfo.Path))), ctx, uRecursionLevel);
                    str = SprEngine.FillIfExists(str, @"{DB_EXT}", new ProtectedString(
                                                     false, UrlUtil.GetExtension(ctx.Database.IOConnectionInfo.Path)),
                                                 ctx, uRecursionLevel);
                }
            }

            if ((ctx.Flags & SprCompileFlags.Paths) != SprCompileFlags.None)
            {
                str = SprEngine.FillIfExists(str, @"{ENV_DIRSEP}", new ProtectedString(
                                                 false, Path.DirectorySeparatorChar.ToString()), ctx, uRecursionLevel);

                string strPF86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)");
                if (string.IsNullOrEmpty(strPF86))
                {
                    strPF86 = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
                }
                if (strPF86 != null)
                {
                    str = SprEngine.FillIfExists(str, @"{ENV_PROGRAMFILES_X86}",
                                                 new ProtectedString(false, strPF86), ctx, uRecursionLevel);
                }
                else
                {
                    Debug.Assert(false);
                }
            }

            if ((ctx.Flags & SprCompileFlags.AutoType) != SprCompileFlags.None)
            {
                // Use Bksp instead of Del (in order to avoid Ctrl+Alt+Del);
                // https://sourceforge.net/p/keepass/discussion/329220/thread/4f1aa6b8/
                str = StrUtil.ReplaceCaseInsensitive(str, @"{CLEARFIELD}",
                                                     @"{HOME}+({END}){BKSP}{DELAY 50}");
            }

            if ((ctx.Flags & SprCompileFlags.DateTime) != SprCompileFlags.None)
            {
                DateTime dtNow = DateTime.Now;                 // Local time
                str = SprEngine.FillIfExists(str, @"{DT_YEAR}", new ProtectedString(
                                                 false, dtNow.Year.ToString("D4")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_MONTH}", new ProtectedString(
                                                 false, dtNow.Month.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_DAY}", new ProtectedString(
                                                 false, dtNow.Day.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_HOUR}", new ProtectedString(
                                                 false, dtNow.Hour.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_MINUTE}", new ProtectedString(
                                                 false, dtNow.Minute.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_SECOND}", new ProtectedString(
                                                 false, dtNow.Second.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_SIMPLE}", new ProtectedString(
                                                 false, dtNow.ToString("yyyyMMddHHmmss")), ctx, uRecursionLevel);

                dtNow = dtNow.ToUniversalTime();
                str   = SprEngine.FillIfExists(str, @"{DT_UTC_YEAR}", new ProtectedString(
                                                   false, dtNow.Year.ToString("D4")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_UTC_MONTH}", new ProtectedString(
                                                 false, dtNow.Month.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_UTC_DAY}", new ProtectedString(
                                                 false, dtNow.Day.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_UTC_HOUR}", new ProtectedString(
                                                 false, dtNow.Hour.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_UTC_MINUTE}", new ProtectedString(
                                                 false, dtNow.Minute.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_UTC_SECOND}", new ProtectedString(
                                                 false, dtNow.Second.ToString("D2")), ctx, uRecursionLevel);
                str = SprEngine.FillIfExists(str, @"{DT_UTC_SIMPLE}", new ProtectedString(
                                                 false, dtNow.ToString("yyyyMMddHHmmss")), ctx, uRecursionLevel);
            }

            if ((ctx.Flags & SprCompileFlags.References) != SprCompileFlags.None)
            {
                str = SprEngine.FillRefPlaceholders(str, ctx, uRecursionLevel);
            }

            if (((ctx.Flags & SprCompileFlags.EnvVars) != SprCompileFlags.None) &&
                (str.IndexOf('%') >= 0))
            {
                // Replace environment variables
                foreach (DictionaryEntry de in Environment.GetEnvironmentVariables())
                {
                    string strKey   = (de.Key as string);
                    string strValue = (de.Value as string);

                    if ((strKey != null) && (strValue != null))
                    {
                        str = SprEngine.FillIfExists(str, @"%" + strKey + @"%",
                                                     new ProtectedString(false, strValue), ctx, uRecursionLevel);
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
            }

            if ((ctx.Flags & SprCompileFlags.Env) != SprCompileFlags.None)
            {
                str = FillUriSpecial(str, ctx, @"{BASE", (ctx.Base ?? string.Empty),
                                     ctx.BaseIsEncoded, uRecursionLevel);
            }

            str = EntryUtil.FillPlaceholders(str, ctx, uRecursionLevel);

            if ((ctx.Flags & SprCompileFlags.PickChars) != SprCompileFlags.None)
            {
                str = ReplacePickChars(str, ctx, uRecursionLevel);
            }

            if (bExt && (SprEngine.FilterCompile != null))
            {
                SprEventArgs args = new SprEventArgs(str, ctx.Clone());
                SprEngine.FilterCompile(null, args);
                str = args.Text;
            }

            if (ctx.EncodeAsAutoTypeSequence)
            {
                str = StrUtil.NormalizeNewLines(str, false);
                str = str.Replace("\n", @"{ENTER}");
            }

            return(str);
        }