コード例 #1
0
		internal void MergeInDbProperties(PwDatabase pwSource, PwMergeMethod mm)
		{
			if(pwSource == null) { Debug.Assert(false); return; }
			if((mm == PwMergeMethod.KeepExisting) || (mm == PwMergeMethod.None))
				return;

			bool bForce = (mm == PwMergeMethod.OverwriteExisting);

			if(bForce || (pwSource.m_dtNameChanged > m_dtNameChanged))
			{
				m_strName = pwSource.m_strName;
				m_dtNameChanged = pwSource.m_dtNameChanged;
			}

			if(bForce || (pwSource.m_dtDescChanged > m_dtDescChanged))
			{
				m_strDesc = pwSource.m_strDesc;
				m_dtDescChanged = pwSource.m_dtDescChanged;
			}

			if(bForce || (pwSource.m_dtDefaultUserChanged > m_dtDefaultUserChanged))
			{
				m_strDefaultUserName = pwSource.m_strDefaultUserName;
				m_dtDefaultUserChanged = pwSource.m_dtDefaultUserChanged;
			}

			PwUuid pwPrefBin = m_pwRecycleBin, pwAltBin = pwSource.m_pwRecycleBin;
			if(bForce || (pwSource.m_dtRecycleBinChanged > m_dtRecycleBinChanged))
			{
				pwPrefBin = pwSource.m_pwRecycleBin;
				pwAltBin = m_pwRecycleBin;
				m_bUseRecycleBin = pwSource.m_bUseRecycleBin;
				m_dtRecycleBinChanged = pwSource.m_dtRecycleBinChanged;
			}
			if(m_pgRootGroup.FindGroup(pwPrefBin, true) != null)
				m_pwRecycleBin = pwPrefBin;
			else if(m_pgRootGroup.FindGroup(pwAltBin, true) != null)
				m_pwRecycleBin = pwAltBin;
			else m_pwRecycleBin = PwUuid.Zero; // Debug.Assert(false);

			PwUuid pwPrefTmp = m_pwEntryTemplatesGroup, pwAltTmp = pwSource.m_pwEntryTemplatesGroup;
			if(bForce || (pwSource.m_dtEntryTemplatesChanged > m_dtEntryTemplatesChanged))
			{
				pwPrefTmp = pwSource.m_pwEntryTemplatesGroup;
				pwAltTmp = m_pwEntryTemplatesGroup;
				m_dtEntryTemplatesChanged = pwSource.m_dtEntryTemplatesChanged;
			}
			if(m_pgRootGroup.FindGroup(pwPrefTmp, true) != null)
				m_pwEntryTemplatesGroup = pwPrefTmp;
			else if(m_pgRootGroup.FindGroup(pwAltTmp, true) != null)
				m_pwEntryTemplatesGroup = pwAltTmp;
			else m_pwEntryTemplatesGroup = PwUuid.Zero; // Debug.Assert(false);
		}
コード例 #2
0
 private void OnBtnOK(object sender, EventArgs e)
 {
     if(m_radioCreateNew.Checked)
         m_mmSelected = PwMergeMethod.CreateNewUuids;
     else if(m_radioKeepExisting.Checked)
         m_mmSelected = PwMergeMethod.KeepExisting;
     else if(m_radioOverwrite.Checked)
         m_mmSelected = PwMergeMethod.OverwriteExisting;
     else if(m_radioOverwriteIfNewer.Checked)
         m_mmSelected = PwMergeMethod.OverwriteIfNewer;
     else if(m_radioSynchronize.Checked)
         m_mmSelected = PwMergeMethod.Synchronize;
 }
コード例 #3
0
        public static bool?Import(PwDatabase pd, FileFormatProvider fmtImp,
                                  IOConnectionInfo iocImp, PwMergeMethod mm, CompositeKey cmpKey)
        {
            if (pd == null)
            {
                Debug.Assert(false); return(false);
            }
            if (fmtImp == null)
            {
                Debug.Assert(false); return(false);
            }
            if (iocImp == null)
            {
                Debug.Assert(false); return(false);
            }
            if (cmpKey == null)
            {
                cmpKey = new CompositeKey();
            }

            if (!AppPolicy.Try(AppPolicyId.Import))
            {
                return(false);
            }
            if (!fmtImp.TryBeginImport())
            {
                return(false);
            }

            PwDatabase pdImp = new PwDatabase();

            pdImp.New(new IOConnectionInfo(), cmpKey);
            pdImp.MemoryProtection = pd.MemoryProtection.CloneDeep();

            Stream s = IOConnection.OpenRead(iocImp);

            if (s == null)
            {
                throw new FileNotFoundException(iocImp.GetDisplayName() +
                                                MessageService.NewLine + KPRes.FileNotFoundError);
            }

            try { fmtImp.Import(pdImp, s, null); }
            finally { s.Close(); }

            pd.MergeIn(pdImp, mm);
            return(true);
        }
コード例 #4
0
		internal void MergeEntryHistory(PwEntry pe, PwEntry peSource,
			PwMergeMethod mm)
		{
			if(!pe.Uuid.EqualsValue(peSource.Uuid)) { Debug.Assert(false); return; }

			if(pe.History.UCount == peSource.History.UCount)
			{
				bool bEqual = true;
				for(uint uEnum = 0; uEnum < pe.History.UCount; ++uEnum)
				{
					if(pe.History.GetAt(uEnum).LastModificationTime !=
						peSource.History.GetAt(uEnum).LastModificationTime)
					{
						bEqual = false;
						break;
					}
				}

				if(bEqual) return;
			}

			if((m_slStatus != null) && !m_slStatus.ContinueWork()) return;

			SortedList<DateTime, PwEntry> list = new SortedList<DateTime, PwEntry>();
			foreach(PwEntry peOrg in pe.History)
				list[peOrg.LastModificationTime] = peOrg;

			foreach(PwEntry peSrc in peSource.History)
			{
				DateTime dt = peSrc.LastModificationTime;
				if(list.ContainsKey(dt))
				{
					if(mm == PwMergeMethod.OverwriteExisting)
						list[dt] = peSrc.CloneDeep();
				}
				else list[dt] = peSrc.CloneDeep();
			}

			pe.History.Clear();
			foreach(KeyValuePair<DateTime, PwEntry> kvpCur in list)
			{
				Debug.Assert(kvpCur.Value.Uuid.EqualsValue(pe.Uuid));
				Debug.Assert(kvpCur.Value.History.UCount == 0);
				pe.History.Add(kvpCur.Value);
			}
		}
コード例 #5
0
            private void OTPDB_Synchronize(PwDatabase targetdb, FileFormatProvider fmtImp, byte[] bDecrypted, string text)
            {
                IStatusLogger dlgStatus = new OnDemandStatusDialog(true, Program.MainForm);

                dlgStatus.StartLogging(text, false);
                try
                {
                    dlgStatus.SetText(text, LogStatusType.Info);

                    PwDatabase pwImp;
                    pwImp = new PwDatabase();
                    pwImp.New(new IOConnectionInfo(), targetdb.MasterKey);
                    pwImp.MemoryProtection = targetdb.MemoryProtection.CloneDeep();
                    pwImp.MasterKey        = targetdb.MasterKey;

                    dlgStatus.SetText(text, LogStatusType.Info);

                    using (var s = new MemoryStream(bDecrypted))
                    {
                        fmtImp.Import(pwImp, s, null);
                    }
                    targetdb.KdfParameters   = pwImp.KdfParameters;
                    targetdb.DataCipherUuid  = pwImp.DataCipherUuid;
                    targetdb.HistoryMaxItems = pwImp.HistoryMaxItems;
                    targetdb.HistoryMaxSize  = pwImp.HistoryMaxSize;

                    PwMergeMethod mm = PwMergeMethod.Synchronize;

                    targetdb.RootGroup.Uuid = pwImp.RootGroup.Uuid;
                    targetdb.MergeIn(pwImp, mm, dlgStatus);
                    CleanupSyncedDB(targetdb);
                }
                catch (Exception ex)
                {
                    PluginDebug.AddError("Error loading OTP db", 0, ex.Message);
                    throw ex;
                }
                finally { dlgStatus.EndLogging(); }
            }
コード例 #6
0
 private void OnBtnOK(object sender, EventArgs e)
 {
     if (m_radioCreateNew.Checked)
     {
         m_mmSelected = PwMergeMethod.CreateNewUuids;
     }
     else if (m_radioKeepExisting.Checked)
     {
         m_mmSelected = PwMergeMethod.KeepExisting;
     }
     else if (m_radioOverwrite.Checked)
     {
         m_mmSelected = PwMergeMethod.OverwriteExisting;
     }
     else if (m_radioOverwriteIfNewer.Checked)
     {
         m_mmSelected = PwMergeMethod.OverwriteIfNewer;
     }
     else if (m_radioSynchronize.Checked)
     {
         m_mmSelected = PwMergeMethod.Synchronize;
     }
 }
コード例 #7
0
		/// <summary>
		/// Synchronize the current database with another one.
		/// </summary>
		/// <param name="pwSource">Input database to synchronize with. This input
		/// database is used to update the current one, but is not modified! You
		/// must copy the current object if you want a second instance of the
		/// synchronized database. The input database must not be seen as valid
		/// database any more after calling <c>Synchronize</c>.</param>
		/// <param name="mm">Merge method.</param>
		/// <param name="slStatus">Logger to report status messages to.
		/// May be <c>null</c>.</param>
		public void MergeIn(PwDatabase pwSource, PwMergeMethod mm,
			IStatusLogger slStatus)
		{
			if(pwSource == null) throw new ArgumentNullException("pwSource");

			PwGroup pgOrgStructure = m_pgRootGroup.CloneStructure();
			PwGroup pgSrcStructure = pwSource.m_pgRootGroup.CloneStructure();

			if(mm == PwMergeMethod.CreateNewUuids)
				pwSource.RootGroup.CreateNewItemUuids(true, true, true);

			GroupHandler gh = delegate(PwGroup pg)
			{
				if(pg == pwSource.m_pgRootGroup) return true;

				PwGroup pgLocal = m_pgRootGroup.FindGroup(pg.Uuid, true);
				if(pgLocal == null)
				{
					PwGroup pgSourceParent = pg.ParentGroup;
					PwGroup pgLocalContainer;
					if(pgSourceParent == pwSource.m_pgRootGroup)
						pgLocalContainer = m_pgRootGroup;
					else
						pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
					Debug.Assert(pgLocalContainer != null);
					if(pgLocalContainer == null) pgLocalContainer = m_pgRootGroup;

					PwGroup pgNew = new PwGroup(false, false);
					pgNew.Uuid = pg.Uuid;
					pgNew.AssignProperties(pg, false, true);
					pgLocalContainer.AddGroup(pgNew, true);
				}
				else // pgLocal != null
				{
					Debug.Assert(mm != PwMergeMethod.CreateNewUuids);

					if(mm == PwMergeMethod.OverwriteExisting)
						pgLocal.AssignProperties(pg, false, false);
					else if((mm == PwMergeMethod.OverwriteIfNewer) ||
						(mm == PwMergeMethod.Synchronize))
					{
						pgLocal.AssignProperties(pg, true, false);
					}
					// else if(mm == PwMergeMethod.KeepExisting) ...
				}

				return ((slStatus != null) ? slStatus.ContinueWork() : true);
			};

			EntryHandler eh = delegate(PwEntry pe)
			{
				PwEntry peLocal = m_pgRootGroup.FindEntry(pe.Uuid, true);
				if(peLocal == null)
				{
					PwGroup pgSourceParent = pe.ParentGroup;
					PwGroup pgLocalContainer;
					if(pgSourceParent == pwSource.m_pgRootGroup)
						pgLocalContainer = m_pgRootGroup;
					else
						pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
					Debug.Assert(pgLocalContainer != null);
					if(pgLocalContainer == null) pgLocalContainer = m_pgRootGroup;

					PwEntry peNew = new PwEntry(false, false);
					peNew.Uuid = pe.Uuid;
					peNew.AssignProperties(pe, false, true, true);
					pgLocalContainer.AddEntry(peNew, true);
				}
				else // peLocal != null
				{
					Debug.Assert(mm != PwMergeMethod.CreateNewUuids);

					bool bEquals = peLocal.EqualsEntry(pe, true, false, true,
						true, false);

					bool bOrgBackup = !bEquals;
					if(mm != PwMergeMethod.OverwriteExisting)
						bOrgBackup &= (pe.LastModificationTime > peLocal.LastModificationTime);
					bOrgBackup &= !pe.HasBackupOfData(peLocal, false, true);
					if(bOrgBackup) peLocal.CreateBackup();

					bool bSrcBackup = !bEquals && (mm != PwMergeMethod.OverwriteExisting);
					bSrcBackup &= (peLocal.LastModificationTime > pe.LastModificationTime);
					bSrcBackup &= !peLocal.HasBackupOfData(pe, false, true);
					if(bSrcBackup) pe.CreateBackup();

					if(mm == PwMergeMethod.OverwriteExisting)
						peLocal.AssignProperties(pe, false, false, false);
					else if((mm == PwMergeMethod.OverwriteIfNewer) ||
						(mm == PwMergeMethod.Synchronize))
					{
						peLocal.AssignProperties(pe, true, false, false);
					}
					// else if(mm == PwMergeMethod.KeepExisting) ...

					MergeEntryHistory(peLocal, pe, mm);
				}

				return ((slStatus != null) ? slStatus.ContinueWork() : true);
			};

			if(!pwSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh))
				throw new InvalidOperationException();

			IStatusLogger slPrevStatus = m_slStatus;
			m_slStatus = slStatus;

			if(mm == PwMergeMethod.Synchronize)
			{
				ApplyDeletions(pwSource.m_vDeletedObjects, true);
				ApplyDeletions(m_vDeletedObjects, false);

				PwObjectPool ppOrgGroups = PwObjectPool.FromGroupRecursive(
					pgOrgStructure, false);
				PwObjectPool ppSrcGroups = PwObjectPool.FromGroupRecursive(
					pgSrcStructure, false);
				PwObjectPool ppOrgEntries = PwObjectPool.FromGroupRecursive(
					pgOrgStructure, true);
				PwObjectPool ppSrcEntries = PwObjectPool.FromGroupRecursive(
					pgSrcStructure, true);

				RelocateGroups(ppOrgGroups, ppSrcGroups);
				ReorderGroups(ppOrgGroups, ppSrcGroups);
				RelocateEntries(ppOrgEntries, ppSrcEntries);
				ReorderEntries(ppOrgEntries, ppSrcEntries);
				Debug.Assert(ValidateUuidUniqueness());
			}

			// Must be called *after* merging groups, because group UUIDs
			// are required for recycle bin and entry template UUIDs
			MergeInDbProperties(pwSource, mm);

			MergeInCustomIcons(pwSource);

			m_slStatus = slPrevStatus;
		}
コード例 #8
0
		public void MergeIn(PwDatabase pwSource, PwMergeMethod mm)
		{
			MergeIn(pwSource, mm, null);
		}
コード例 #9
0
        private static void ImportIntoCurrentDatabase(EcasAction a, EcasContext ctx)
        {
            PwDatabase pd = Program.MainForm.ActiveDatabase;

            if ((pd == null) || !pd.IsOpen)
            {
                return;
            }

            string strPath = EcasUtil.GetParamString(a.Parameters, 0, true);

            if (string.IsNullOrEmpty(strPath))
            {
                return;
            }
            IOConnectionInfo ioc = IOConnectionInfo.FromPath(strPath);

            string strFormat = EcasUtil.GetParamString(a.Parameters, 1, true);

            if (string.IsNullOrEmpty(strFormat))
            {
                return;
            }
            FileFormatProvider ff = Program.FileFormatPool.Find(strFormat);

            if (ff == null)
            {
                throw new Exception(KPRes.Unknown + ": " + strFormat);
            }

            uint          uMethod = EcasUtil.GetParamUInt(a.Parameters, 2);
            Type          tMM     = Enum.GetUnderlyingType(typeof(PwMergeMethod));
            object        oMethod = Convert.ChangeType(uMethod, tMM);
            PwMergeMethod mm      = PwMergeMethod.None;

            if (Enum.IsDefined(typeof(PwMergeMethod), oMethod))
            {
                mm = (PwMergeMethod)oMethod;
            }
            else
            {
                Debug.Assert(false);
            }
            if (mm == PwMergeMethod.None)
            {
                mm = PwMergeMethod.CreateNewUuids;
            }

            CompositeKey cmpKey = KeyFromParams(a, 3, 4, 5);

            if ((cmpKey == null) && ff.RequiresKey)
            {
                KeyPromptForm kpf = new KeyPromptForm();
                kpf.InitEx(ioc, false, true);

                if (UIUtil.ShowDialogNotValue(kpf, DialogResult.OK))
                {
                    return;
                }

                cmpKey = kpf.CompositeKey;
                UIUtil.DestroyForm(kpf);
            }

            bool?b = true;

            try { b = ImportUtil.Import(pd, ff, ioc, mm, cmpKey); }
            finally
            {
                if (b.GetValueOrDefault(false))
                {
                    Program.MainForm.UpdateUI(false, null, true, null, true, null, true);
                }
            }
        }
コード例 #10
0
ファイル: ImportUtil.cs プロジェクト: riking/go-keepass2
		public static bool? Import(PwDatabase pd, FileFormatProvider fmtImp,
			IOConnectionInfo iocImp, PwMergeMethod mm, CompositeKey cmpKey)
		{
			if(pd == null) { Debug.Assert(false); return false; }
			if(fmtImp == null) { Debug.Assert(false); return false; }
			if(iocImp == null) { Debug.Assert(false); return false; }
			if(cmpKey == null) cmpKey = new CompositeKey();

			if(!AppPolicy.Try(AppPolicyId.Import)) return false;
			if(!fmtImp.TryBeginImport()) return false;

			PwDatabase pdImp = new PwDatabase();
			pdImp.New(new IOConnectionInfo(), cmpKey);
			pdImp.MemoryProtection = pd.MemoryProtection.CloneDeep();

			Stream s = IOConnection.OpenRead(iocImp);
			if(s == null)
				throw new FileNotFoundException(iocImp.GetDisplayName() +
					MessageService.NewLine + KPRes.FileNotFoundError);

			try { fmtImp.Import(pdImp, s, null); }
			finally { s.Close(); }

			pd.MergeIn(pdImp, mm);
			return true;
		}
コード例 #11
0
ファイル: PwDatabase.cs プロジェクト: jonbws/strengthreport
        /// <summary>
        /// Synchronize the current database with another one.
        /// </summary>
        /// <param name="pwSource">Input database to synchronize with. This input
        /// database is used to update the current one, but is not modified! You
        /// must copy the current object if you want a second instance of the
        /// synchronized database. The input database must not be seen as valid
        /// database any more after calling <c>Synchronize</c>.</param>
        /// <param name="mm">Merge method.</param>
        public void MergeIn(PwDatabase pwSource, PwMergeMethod mm)
        {
            if(mm == PwMergeMethod.CreateNewUuids)
            {
                pwSource.RootGroup.CreateNewItemUuids(true, true, true);
            }

            GroupHandler gh = delegate(PwGroup pg)
            {
                if(pg == pwSource.m_pgRootGroup) return true;

                PwGroup pgLocal = m_pgRootGroup.FindGroup(pg.Uuid, true);
                if(pgLocal == null)
                {
                    PwGroup pgSourceParent = pg.ParentGroup;
                    PwGroup pgLocalContainer;
                    if(pgSourceParent == pwSource.m_pgRootGroup)
                        pgLocalContainer = m_pgRootGroup;
                    else
                        pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
                    Debug.Assert(pgLocalContainer != null);

                    PwGroup pgNew = new PwGroup();
                    pgNew.Uuid = pg.Uuid;
                    pgNew.AssignProperties(pg, false);
                    pgLocalContainer.AddGroup(pgNew, true);
                }
                else // pgLocal != null
                {
                    Debug.Assert(mm != PwMergeMethod.CreateNewUuids);

                    if(mm == PwMergeMethod.OverwriteExisting)
                        pgLocal.AssignProperties(pg, false);
                    else if((mm == PwMergeMethod.OverwriteIfNewer) ||
                        (mm == PwMergeMethod.Synchronize))
                    {
                        pgLocal.AssignProperties(pg, true);
                    }
                    // else if(mm == PwMergeMethod.KeepExisting) ...
                }

                return true;
            };

            EntryHandler eh = delegate(PwEntry pe)
            {
                PwEntry peLocal = m_pgRootGroup.FindEntry(pe.Uuid, true);
                if(peLocal == null)
                {
                    PwGroup pgSourceParent = pe.ParentGroup;
                    PwGroup pgLocalContainer;
                    if(pgSourceParent == pwSource.m_pgRootGroup)
                        pgLocalContainer = m_pgRootGroup;
                    else
                        pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
                    Debug.Assert(pgLocalContainer != null);

                    PwEntry peNew = new PwEntry(false, false);
                    peNew.Uuid = pe.Uuid;
                    peNew.AssignProperties(pe, false, true);
                    pgLocalContainer.AddEntry(peNew, true);
                }
                else // peLocal == null
                {
                    Debug.Assert(mm != PwMergeMethod.CreateNewUuids);

                    if(mm == PwMergeMethod.OverwriteExisting)
                        peLocal.AssignProperties(pe, false, true);
                    else if((mm == PwMergeMethod.OverwriteIfNewer) ||
                        (mm == PwMergeMethod.Synchronize))
                    {
                        peLocal.AssignProperties(pe, true, true);
                    }
                    // else if(mm == PwMergeMethod.KeepExisting) ...
                }

                return true;
            };

            if(!pwSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh))
                throw new InvalidOperationException();

            if(mm == PwMergeMethod.Synchronize)
            {
                ApplyDeletions(pwSource.m_vDeletedObjects, true);
                ApplyDeletions(m_vDeletedObjects, false);
            }
        }
        private static bool PerformImport(PwDatabase pwDb, CommandLineArgs args)
        {
            string strFile = args["file"];

            if (string.IsNullOrEmpty(strFile))
            {
                KPScript.Program.WriteLineColored("E: No file specified to import!", ConsoleColor.Red);
                return(false);
            }
            IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);

            FileFormatProvider prov = GetFormatProv(args);

            if (prov == null)
            {
                return(false);
            }

            if (!prov.SupportsImport)
            {
                KPScript.Program.WriteLineColored("E: No import support for this format!",
                                                  ConsoleColor.Red);
                return(false);
            }

            if (!prov.TryBeginImport())
            {
                KPScript.Program.WriteLineColored("E: Format initialization failed!",
                                                  ConsoleColor.Red);
                return(false);
            }

            PwMergeMethod mm    = PwMergeMethod.CreateNewUuids;
            string        strMM = args["mm"];

            if (!string.IsNullOrEmpty(strMM))
            {
                if (strMM.Equals("CreateNewUuids", StrUtil.CaseIgnoreCmp))
                {
                    mm = PwMergeMethod.CreateNewUuids;
                }
                else if (strMM.Equals("KeepExisting", StrUtil.CaseIgnoreCmp))
                {
                    mm = PwMergeMethod.KeepExisting;
                }
                else if (strMM.Equals("OverwriteExisting", StrUtil.CaseIgnoreCmp))
                {
                    mm = PwMergeMethod.OverwriteExisting;
                }
                else if (strMM.Equals("OverwriteIfNewer", StrUtil.CaseIgnoreCmp))
                {
                    mm = PwMergeMethod.OverwriteIfNewer;
                }
                else if (strMM.Equals("Sync", StrUtil.CaseIgnoreCmp))
                {
                    mm = PwMergeMethod.Synchronize;
                }
            }

            CompositeKey cmpKey = KpsUtil.GetMasterKey(args, "imp_", ioc);

            if ((cmpKey == null) || (cmpKey.UserKeyCount == 0))
            {
                cmpKey = pwDb.MasterKey;
            }

            bool?  b        = false;
            string strError = "Import failed!";

            try { b = ImportUtil.Import(pwDb, prov, ioc, mm, cmpKey); }
            catch (Exception ex)
            {
                if ((ex != null) && !string.IsNullOrEmpty(ex.Message))
                {
                    strError = ex.Message;
                }
            }

            bool r = (b.HasValue && b.Value);

            if (r)
            {
                KPScript.Program.WriteLineColored("OK: Import succeeded!", ConsoleColor.Green);
            }
            else
            {
                KPScript.Program.WriteLineColored("E: " + strError, ConsoleColor.Red);
            }

            return(r);
        }
コード例 #13
0
        /// <summary>
        /// Synchronize the current database with another one.
        /// </summary>
        /// <param name="pwSource">Input database to synchronize with. This input
        /// database is used to update the current one, but is not modified! You
        /// must copy the current object if you want a second instance of the
        /// synchronized database. The input database must not be seen as valid
        /// database any more after calling <c>Synchronize</c>.</param>
        /// <param name="mm">Merge method.</param>
        public void MergeIn(PwDatabase pwSource, PwMergeMethod mm)
        {
            if (mm == PwMergeMethod.CreateNewUuids)
            {
                pwSource.RootGroup.CreateNewItemUuids(true, true, true);
            }

            GroupHandler gh = delegate(PwGroup pg)
            {
                if (pg == pwSource.m_pgRootGroup)
                {
                    return(true);
                }

                PwGroup pgLocal = m_pgRootGroup.FindGroup(pg.Uuid, true);
                if (pgLocal == null)
                {
                    PwGroup pgSourceParent = pg.ParentGroup;
                    PwGroup pgLocalContainer;
                    if (pgSourceParent == pwSource.m_pgRootGroup)
                    {
                        pgLocalContainer = m_pgRootGroup;
                    }
                    else
                    {
                        pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
                    }
                    Debug.Assert(pgLocalContainer != null);

                    PwGroup pgNew = new PwGroup();
                    pgNew.Uuid = pg.Uuid;
                    pgNew.AssignProperties(pg, false);
                    pgLocalContainer.AddGroup(pgNew, true);
                }
                else                 // pgLocal != null
                {
                    Debug.Assert(mm != PwMergeMethod.CreateNewUuids);

                    if (mm == PwMergeMethod.OverwriteExisting)
                    {
                        pgLocal.AssignProperties(pg, false);
                    }
                    else if ((mm == PwMergeMethod.OverwriteIfNewer) ||
                             (mm == PwMergeMethod.Synchronize))
                    {
                        pgLocal.AssignProperties(pg, true);
                    }
                    // else if(mm == PwMergeMethod.KeepExisting) ...
                }

                return(true);
            };

            EntryHandler eh = delegate(PwEntry pe)
            {
                PwEntry peLocal = m_pgRootGroup.FindEntry(pe.Uuid, true);
                if (peLocal == null)
                {
                    PwGroup pgSourceParent = pe.ParentGroup;
                    PwGroup pgLocalContainer;
                    if (pgSourceParent == pwSource.m_pgRootGroup)
                    {
                        pgLocalContainer = m_pgRootGroup;
                    }
                    else
                    {
                        pgLocalContainer = m_pgRootGroup.FindGroup(pgSourceParent.Uuid, true);
                    }
                    Debug.Assert(pgLocalContainer != null);

                    PwEntry peNew = new PwEntry(false, false);
                    peNew.Uuid = pe.Uuid;
                    peNew.AssignProperties(pe, false, true);
                    pgLocalContainer.AddEntry(peNew, true);
                }
                else                 // peLocal == null
                {
                    Debug.Assert(mm != PwMergeMethod.CreateNewUuids);

                    if (mm == PwMergeMethod.OverwriteExisting)
                    {
                        peLocal.AssignProperties(pe, false, true);
                    }
                    else if ((mm == PwMergeMethod.OverwriteIfNewer) ||
                             (mm == PwMergeMethod.Synchronize))
                    {
                        peLocal.AssignProperties(pe, true, true);
                    }
                    // else if(mm == PwMergeMethod.KeepExisting) ...
                }

                return(true);
            };

            if (!pwSource.RootGroup.TraverseTree(TraversalMethod.PreOrder, gh, eh))
            {
                throw new InvalidOperationException();
            }

            if (mm == PwMergeMethod.Synchronize)
            {
                ApplyDeletions(pwSource.m_vDeletedObjects, true);
                ApplyDeletions(m_vDeletedObjects, false);
            }
        }