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); } // slf.SetText(KPRes.MergingData, LogStatusType.Info); try { pwDatabase.MergeIn(pwImp, mm, dlgStatus); } catch(Exception exMerge) { MessageService.ShowWarning(iocIn.GetDisplayName(), KPRes.ImportFailed, exMerge); bAllSuccess = false; continue; } } } dlgStatus.EndLogging(); if(bSynchronize && bAllSuccess) { Debug.Assert(uiOps != null); if(uiOps == null) throw new ArgumentNullException("uiOps"); if(uiOps.UIFileSave(bForceSave)) { foreach(IOConnectionInfo ioc in vConnections) { try { 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) Program.MainForm.FileMruList.AddItem(ioc.GetDisplayName(), ioc.CloneDeep(), true); } 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; } } 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; }