@@ -172,6 +172,8 @@ public class PxDatabase : PwDatabase
172172 public PwGroup CurrentGroup
173173 {
174174 get {
175+ if ( ! IsOpen ) { return null ; }
176+
175177 if ( RootGroup . Uuid == LastSelectedGroup || LastSelectedGroup . Equals ( PwUuid . Zero ) )
176178 {
177179 LastSelectedGroup = RootGroup . Uuid ;
@@ -203,9 +205,9 @@ public PwGroup CurrentGroup
203205 public string CurrentPath
204206 {
205207 get {
206- if ( CurrentGroup == null )
208+ if ( CurrentGroup == null )
207209 {
208- return null ;
210+ return string . Empty ;
209211 }
210212 else
211213 {
@@ -262,9 +264,9 @@ public PxDatabase() : base()
262264 /// <param name="password">The password of data file</param>
263265 public void Open ( string filename , string password )
264266 {
265- if ( filename == null || filename == String . Empty )
267+ if ( filename == null || filename == String . Empty )
266268 { Debug . Assert ( false ) ; throw new ArgumentNullException ( "filename" ) ; }
267- if ( password == null || password == String . Empty )
269+ if ( password == null || password == String . Empty )
268270 { Debug . Assert ( false ) ; throw new ArgumentNullException ( "password" ) ; }
269271
270272 var logger = new KPCLibLogger ( ) ;
@@ -302,6 +304,8 @@ public void Open(PassXYZLib.User user)
302304 {
303305 if ( user == null )
304306 { Debug . Assert ( false ) ; throw new ArgumentNullException ( "PassXYZLib.User" ) ; }
307+ if ( user . Password == null || user . Password == String . Empty )
308+ { Debug . Assert ( false ) ; throw new ArgumentNullException ( "Password" ) ; }
305309
306310 var logger = new KPCLibLogger ( ) ;
307311
@@ -328,7 +332,7 @@ public void Open(PassXYZLib.User user)
328332 }
329333 catch ( PassXYZ . Services . InvalidDeviceLockException ex )
330334 {
331- try { cmpKey . AddUserKey ( new KcpKeyFile ( user . KeFilePath ) ) ; }
335+ try { cmpKey . AddUserKey ( new KcpKeyFile ( user . KeyFilePath ) ) ; }
332336 catch ( Exception exFile )
333337 {
334338 Debug . Write ( $ "{ exFile } in { ex } ") ;
@@ -392,7 +396,7 @@ public bool ChangeMasterPassword(string newPassword, PassXYZLib.User user)
392396 }
393397 catch ( PassXYZ . Services . InvalidDeviceLockException ex )
394398 {
395- try { cmpKey . AddUserKey ( new KcpKeyFile ( user . KeFilePath ) ) ; }
399+ try { cmpKey . AddUserKey ( new KcpKeyFile ( user . KeyFilePath ) ) ; }
396400 catch ( Exception exFile )
397401 {
398402 Debug . Write ( $ "{ exFile } in { ex } ") ;
@@ -527,6 +531,34 @@ private void EnsureRecycleBin(ref PwGroup pgRecycleBin)
527531 else { Debug . Assert ( pgRecycleBin . Uuid . Equals ( this . RecycleBinUuid ) ) ; }
528532 }
529533
534+ /// <summary>
535+ /// Remove RecycleBin before merge. RecycleBin should be kept locally and should not be merged.
536+ /// </summary>
537+ /// <param name="pwDb"></param>
538+ /// <returns></returns>
539+ private bool DeleteRecycleBin ( PwDatabase pwDb )
540+ {
541+ if ( pwDb == null ) { return false ; }
542+
543+ PwGroup pgRecycleBin = pwDb . RootGroup . FindGroup ( pwDb . RecycleBinUuid , true ) ;
544+
545+ if ( pgRecycleBin != null )
546+ {
547+ pwDb . RootGroup . Groups . Remove ( pgRecycleBin ) ;
548+ pgRecycleBin . DeleteAllObjects ( pwDb ) ;
549+ PwDeletedObject pdo = new PwDeletedObject ( pgRecycleBin . Uuid , DateTime . UtcNow ) ;
550+ pwDb . DeletedObjects . Add ( pdo ) ;
551+ Debug . WriteLine ( "DeleteRecycleBin successfully." ) ;
552+ return true ;
553+ }
554+ else
555+ {
556+ Debug . WriteLine ( "DeleteRecycleBin failure." ) ;
557+ return false ;
558+ }
559+ }
560+
561+
530562 /// <summary>
531563 /// Find an entry or a group.
532564 /// </summary>
@@ -962,6 +994,58 @@ orderby e.LastModificationTime descending
962994 return resultsList ;
963995 }
964996
997+ public bool Merge ( string path , PwMergeMethod mm )
998+ {
999+ var pwImp = new PwDatabase ( ) ;
1000+ var ioInfo = IOConnectionInfo . FromPath ( path ) ;
1001+
1002+ var compositeKey = MasterKey ;
1003+
1004+ KPCLibLogger swLogger = new KPCLibLogger ( ) ;
1005+ try
1006+ {
1007+ swLogger . StartLogging ( "Merge: Opening database ..." , true ) ;
1008+ pwImp . Open ( ioInfo , compositeKey , swLogger ) ;
1009+ swLogger . EndLogging ( ) ;
1010+ }
1011+ catch ( Exception e )
1012+ {
1013+ Debug . WriteLine ( $ "$Failed to open database: { e . Message } .") ;
1014+ return false ;
1015+ }
1016+
1017+ // We only merge, if these are the same database with different versions.
1018+ if ( RootGroup . EqualsGroup ( pwImp . RootGroup , ( PwCompareOptions . IgnoreLastBackup |
1019+ PwCompareOptions . IgnoreHistory | PwCompareOptions . IgnoreParentGroup |
1020+ PwCompareOptions . IgnoreTimes | PwCompareOptions . PropertiesOnly ) , MemProtCmpMode . None ) )
1021+ {
1022+ Debug . WriteLine ( $ "Merge: Root group are the same. Merge method is { mm } .") ;
1023+ }
1024+ else
1025+ {
1026+ Debug . WriteLine ( $ "Merge: Root group are different DBase={ RootGroup } , pwImp={ pwImp . RootGroup } .") ;
1027+ pwImp . Close ( ) ;
1028+ return false ;
1029+ }
1030+
1031+ try
1032+ {
1033+ // Need to remove RecycleBin first before merge.
1034+ DeleteRecycleBin ( pwImp ) ;
1035+
1036+ MergeIn ( pwImp , mm , swLogger ) ;
1037+ DescriptionChanged = DateTime . UtcNow ;
1038+ Save ( swLogger ) ;
1039+ pwImp . Close ( ) ;
1040+ }
1041+ catch ( Exception exMerge )
1042+ {
1043+ Debug . WriteLine ( $ "Merge failed { exMerge } ") ;
1044+ return false ;
1045+ }
1046+ return true ;
1047+ }
1048+
9651049 // The end of PxDatabase
9661050 }
9671051
0 commit comments