public static bool?Import(PwDatabase pwDatabase, FileFormatProvider fmtImp, IOConnectionInfo[] vConnections, bool bSynchronize, IUIOperations uiOps, bool bForceSave, Form fParent) { if (pwDatabase == null) { throw new ArgumentNullException("pwDatabase"); } if (!pwDatabase.IsOpen) { return(null); } if (fmtImp == null) { throw new ArgumentNullException("fmtImp"); } if (vConnections == null) { throw new ArgumentNullException("vConnections"); } if (!AppPolicy.Try(AppPolicyId.Import)) { return(false); } if (!fmtImp.TryBeginImport()) { return(false); } bool bUseTempDb = (fmtImp.SupportsUuids || fmtImp.RequiresKey); bool bAllSuccess = true; // if(bSynchronize) { Debug.Assert(vFiles.Length == 1); } IStatusLogger dlgStatus; if (Program.Config.UI.ShowImportStatusDialog) { dlgStatus = new OnDemandStatusDialog(false, fParent); } else { dlgStatus = new UIBlockerStatusLogger(fParent); } dlgStatus.StartLogging(PwDefs.ShortProductName + " - " + (bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg), false); dlgStatus.SetText(bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg, LogStatusType.Info); if (vConnections.Length == 0) { try { fmtImp.Import(pwDatabase, null, dlgStatus); } catch (Exception exSingular) { if ((exSingular.Message != null) && (exSingular.Message.Length > 0)) { // slf.SetText(exSingular.Message, LogStatusType.Warning); MessageService.ShowWarning(exSingular); } } dlgStatus.EndLogging(); return(true); } foreach (IOConnectionInfo iocIn in vConnections) { Stream s = null; try { s = IOConnection.OpenRead(iocIn); } catch (Exception exFile) { MessageService.ShowWarning(iocIn.GetDisplayName(), exFile); bAllSuccess = false; continue; } if (s == null) { Debug.Assert(false); bAllSuccess = false; continue; } PwDatabase pwImp; if (bUseTempDb) { pwImp = new PwDatabase(); pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey); pwImp.MemoryProtection = pwDatabase.MemoryProtection.CloneDeep(); } else { pwImp = pwDatabase; } if (fmtImp.RequiresKey && !bSynchronize) { KeyPromptForm kpf = new KeyPromptForm(); kpf.InitEx(iocIn, false, true); if (UIUtil.ShowDialogNotValue(kpf, DialogResult.OK)) { s.Close(); continue; } pwImp.MasterKey = kpf.CompositeKey; UIUtil.DestroyForm(kpf); } else if (bSynchronize) { pwImp.MasterKey = pwDatabase.MasterKey; } dlgStatus.SetText((bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg) + " (" + iocIn.GetDisplayName() + ")", LogStatusType.Info); try { fmtImp.Import(pwImp, s, dlgStatus); } catch (Exception excpFmt) { string strMsgEx = excpFmt.Message; if (bSynchronize && (excpFmt is InvalidCompositeKeyException)) { strMsgEx = KLRes.InvalidCompositeKey + MessageService.NewParagraph + KPRes.SynchronizingHint; } MessageService.ShowWarning(strMsgEx); s.Close(); bAllSuccess = false; continue; } s.Close(); if (bUseTempDb) { PwMergeMethod mm; if (!fmtImp.SupportsUuids) { mm = PwMergeMethod.CreateNewUuids; } else if (bSynchronize) { mm = PwMergeMethod.Synchronize; } else { ImportMethodForm imf = new ImportMethodForm(); if (UIUtil.ShowDialogNotValue(imf, DialogResult.OK)) { continue; } mm = imf.MergeMethod; UIUtil.DestroyForm(imf); } try { pwDatabase.MergeIn(pwImp, mm, dlgStatus); } catch (Exception exMerge) { MessageService.ShowWarning(iocIn.GetDisplayName(), KPRes.ImportFailed, exMerge); bAllSuccess = false; continue; } } } if (bSynchronize && bAllSuccess) { Debug.Assert(uiOps != null); if (uiOps == null) { throw new ArgumentNullException("uiOps"); } dlgStatus.SetText(KPRes.Synchronizing + " (" + KPRes.SavingDatabase + ")", LogStatusType.Info); MainForm mf = Program.MainForm; // Null for KPScript if (mf != null) { try { mf.DocumentManager.ActiveDatabase = pwDatabase; } catch (Exception) { Debug.Assert(false); } } if (uiOps.UIFileSave(bForceSave)) { foreach (IOConnectionInfo ioc in vConnections) { try { // dlgStatus.SetText(KPRes.Synchronizing + " (" + // KPRes.SavingDatabase + " " + ioc.GetDisplayName() + // ")", LogStatusType.Info); string strSource = pwDatabase.IOConnectionInfo.Path; if (ioc.Path != strSource) { bool bSaveAs = true; if (pwDatabase.IOConnectionInfo.IsLocalFile() && ioc.IsLocalFile()) { // Do not try to copy an encrypted file; // https://sourceforge.net/p/keepass/discussion/329220/thread/9c9eb989/ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa363851.aspx if ((long)(File.GetAttributes(strSource) & FileAttributes.Encrypted) == 0) { File.Copy(strSource, ioc.Path, true); bSaveAs = false; } } if (bSaveAs) { pwDatabase.SaveAs(ioc, false, null); } } // else { } // No assert (sync on save) if (mf != null) { mf.FileMruList.AddItem(ioc.GetDisplayName(), ioc.CloneDeep()); } } catch (Exception exSync) { MessageService.ShowWarning(KPRes.SyncFailed, pwDatabase.IOConnectionInfo.GetDisplayName() + MessageService.NewLine + ioc.GetDisplayName(), exSync); bAllSuccess = false; continue; } } } else { MessageService.ShowWarning(KPRes.SyncFailed, pwDatabase.IOConnectionInfo.GetDisplayName()); bAllSuccess = false; } } dlgStatus.EndLogging(); return(bAllSuccess); }
public static bool?Import(PwDatabase pwDatabase, FileFormatProvider fmtImp, IOConnectionInfo[] vConnections, bool bSynchronize, IUIOperations uiOps, bool bForceSave, Form fParent) { if (pwDatabase == null) { throw new ArgumentNullException("pwDatabase"); } if (!pwDatabase.IsOpen) { return(null); } if (fmtImp == null) { throw new ArgumentNullException("fmtImp"); } if (vConnections == null) { throw new ArgumentNullException("vConnections"); } if (!AppPolicy.Try(AppPolicyId.Import)) { return(false); } if (!fmtImp.TryBeginImport()) { return(false); } bool bUseTempDb = (fmtImp.SupportsUuids || fmtImp.RequiresKey); bool bAllSuccess = true; // if(bSynchronize) { Debug.Assert(vFiles.Length == 1); } IStatusLogger dlgStatus; if (Program.Config.UI.ShowImportStatusDialog) { dlgStatus = new OnDemandStatusDialog(false, fParent); } else { dlgStatus = new UIBlockerStatusLogger(fParent); } dlgStatus.StartLogging(PwDefs.ShortProductName + " - " + (bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg), false); dlgStatus.SetText(bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg, LogStatusType.Info); if (vConnections.Length == 0) { try { fmtImp.Import(pwDatabase, null, dlgStatus); } catch (Exception exSingular) { if ((exSingular.Message != null) && (exSingular.Message.Length > 0)) { // slf.SetText(exSingular.Message, LogStatusType.Warning); MessageService.ShowWarning(exSingular); } } dlgStatus.EndLogging(); return(true); } foreach (IOConnectionInfo iocIn in vConnections) { Stream s = null; try { s = IOConnection.OpenRead(iocIn); } catch (Exception exFile) { // Transacted-file operations can leave behind intact *.kdbx.tmp files when // the file rename doesn't get completed (can happen easily with slow/unreliable // remote collections. We check if that's the case here and fix the situation if // an kdbx file does *not* exist (to avoid possibly overwriting good data with bad // data (i.e. an interrupted kdbx.tmp write). // Make a copy of the IOC like FileTransactionEx.cs:Initialize does IOConnectionInfo iocTemp = iocIn.CloneDeep(); iocTemp.Path += FileTransactionEx.StrTempSuffix; if (IOConnection.FileExists(iocTemp) && !IOConnection.FileExists(iocIn)) { // Try and rename iocTemp to ioc.Path, then retry file opening. IOConnection.RenameFile(iocTemp, iocIn); try { s = IOConnection.OpenRead(iocIn); } catch (Exception nexFile) { MessageService.ShowWarning(iocIn.GetDisplayName(), nexFile); bAllSuccess = false; continue; } } else { MessageService.ShowWarning(iocIn.GetDisplayName(), exFile); bAllSuccess = false; continue; } } if (s == null) { Debug.Assert(false); bAllSuccess = false; continue; } PwDatabase pwImp; if (bUseTempDb) { pwImp = new PwDatabase(); pwImp.New(new IOConnectionInfo(), pwDatabase.MasterKey); pwImp.MemoryProtection = pwDatabase.MemoryProtection.CloneDeep(); } else { pwImp = pwDatabase; } if (fmtImp.RequiresKey && !bSynchronize) { KeyPromptForm kpf = new KeyPromptForm(); kpf.InitEx(iocIn, false, true); if (UIUtil.ShowDialogNotValue(kpf, DialogResult.OK)) { s.Close(); continue; } pwImp.MasterKey = kpf.CompositeKey; UIUtil.DestroyForm(kpf); } else if (bSynchronize) { pwImp.MasterKey = pwDatabase.MasterKey; } dlgStatus.SetText((bSynchronize ? KPRes.Synchronizing : KPRes.ImportingStatusMsg) + " (" + iocIn.GetDisplayName() + ")", LogStatusType.Info); try { fmtImp.Import(pwImp, s, dlgStatus); } catch (Exception excpFmt) { string strMsgEx = excpFmt.Message; if (bSynchronize && (excpFmt is InvalidCompositeKeyException)) { strMsgEx = KLRes.InvalidCompositeKey + MessageService.NewParagraph + KPRes.SynchronizingHint; } MessageService.ShowWarning(strMsgEx); s.Close(); bAllSuccess = false; continue; } s.Close(); if (bUseTempDb) { PwMergeMethod mm; if (!fmtImp.SupportsUuids) { mm = PwMergeMethod.CreateNewUuids; } else if (bSynchronize) { mm = PwMergeMethod.Synchronize; } else { ImportMethodForm imf = new ImportMethodForm(); if (UIUtil.ShowDialogNotValue(imf, DialogResult.OK)) { continue; } mm = imf.MergeMethod; UIUtil.DestroyForm(imf); } try { pwDatabase.MergeIn(pwImp, mm, dlgStatus); } catch (Exception exMerge) { MessageService.ShowWarning(iocIn.GetDisplayName(), KPRes.ImportFailed, exMerge); bAllSuccess = false; continue; } } } if (bSynchronize && bAllSuccess) { Debug.Assert(uiOps != null); if (uiOps == null) { throw new ArgumentNullException("uiOps"); } dlgStatus.SetText(KPRes.Synchronizing + " (" + KPRes.SavingDatabase + ")", LogStatusType.Info); MainForm mf = Program.MainForm; // Null for KPScript if (mf != null) { try { mf.DocumentManager.ActiveDatabase = pwDatabase; } catch (Exception) { Debug.Assert(false); } } if (uiOps.UIFileSave(bForceSave)) { foreach (IOConnectionInfo ioc in vConnections) { try { // dlgStatus.SetText(KPRes.Synchronizing + " (" + // KPRes.SavingDatabase + " " + ioc.GetDisplayName() + // ")", LogStatusType.Info); if (ioc.Path != pwDatabase.IOConnectionInfo.Path) { if (pwDatabase.IOConnectionInfo.IsLocalFile() && ioc.IsLocalFile()) { File.Copy(pwDatabase.IOConnectionInfo.Path, ioc.Path, true); } else { pwDatabase.SaveAs(ioc, false, null); } } // else { } // No assert (sync on save) if (mf != null) { mf.FileMruList.AddItem(ioc.GetDisplayName(), ioc.CloneDeep()); } } catch (Exception exSync) { MessageService.ShowWarning(KPRes.SyncFailed, pwDatabase.IOConnectionInfo.GetDisplayName() + MessageService.NewLine + ioc.GetDisplayName(), exSync); bAllSuccess = false; continue; } } } else { MessageService.ShowWarning(KPRes.SyncFailed, pwDatabase.IOConnectionInfo.GetDisplayName()); bAllSuccess = false; } } dlgStatus.EndLogging(); return(bAllSuccess); }