void Discovery(string fullPath) { if (ComponentMode) { ExamineComponents(fullPath); } else { thisBackup.FreeWriterMetadata(); } thisSnap = new Snapshot(thisBackup); thisSnap.AddVolume(Path.GetPathRoot(fullPath)); }
void Discovery(string fullPath) { _backup.FreeWriterMetadata(); _set_id = _backup.StartSnapshotSet(); AddVolume(Path.GetPathRoot(fullPath)); }
public void SetupWriters(Guid[] includedWriters, Guid[] excludedWriters) { if (includedWriters != null && includedWriters.Length > 0) { _vssBackupComponents.EnableWriterClasses(includedWriters); } if (excludedWriters != null && excludedWriters.Length > 0) { _vssBackupComponents.DisableWriterClasses(excludedWriters); } try { _vssBackupComponents.GatherWriterMetadata(); } finally { _vssBackupComponents.FreeWriterMetadata(); } if (includedWriters == null) { return; } // check if writers got enabled foreach (var writerGUID in includedWriters) { if (!_vssBackupComponents.WriterMetadata.Any(o => o.WriterId.Equals(writerGUID))) { throw new Exception(string.Format("Writer with GUID {0} was not added to VSS writer set.", writerGUID.ToString())); } } }
private void Discovery(string fullPath) { if (ComponentMode) { // In component mode, we would need to enumerate through each component // and decide whether it should be added to our backup document. ExamineComponents(fullPath); } else { // Once we are finished with the writer metadata, we can dispose of it. _backup.FreeWriterMetadata(); } // Use our helper class to add the appropriate volume to the shadow copy set. _snapshot = new Snapshot(_backup); _snapshot.AddVolume(Path.GetPathRoot(fullPath)); }
/// <summary> /// This stage involes the requester (us, again) processing the /// information it received from writers on the system to find out /// which volumes - if any - must be shadow copied to perform a full /// backup. /// </summary> void Discovery(string fullPath) { if (ComponentMode) { // In component mode, we would need to enumerate through each // component and decide whether it should be added to our // backup document. ExamineComponents(fullPath); } else { // Once we are finished with the writer metadata, we can dispose // of it. If we were in component mode, we would want to keep it // around so that we could notify the writers of our success or // failure when we finish the backup. _backup.FreeWriterMetadata(); } // Now we use our helper class to add the appropriate volume to the // shadow copy set. _snap = new Snapshot(_backup); _snap.AddVolume(Path.GetPathRoot(fullPath)); }
/// <summary> /// Constructs a new backup snapshot, using all the required disks /// </summary> /// <param name="sourcepaths">The folders that are about to be backed up</param> /// <param name="options">A set of commandline options</param> public WindowsSnapshot(string[] sourcepaths, Dictionary <string, string> options) { try { //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC string alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss"); string alphadll = System.IO.Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll"); IVssImplementation vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation"); List <Guid> excludedWriters = new List <Guid>(); if (options.ContainsKey("vss-exclude-writers")) { foreach (string s in options["vss-exclude-writers"].Split(';')) { if (!string.IsNullOrEmpty(s) && s.Trim().Length > 0) { excludedWriters.Add(new Guid(s)); } } } //Check if we should map any drives bool useSubst = Utility.Utility.ParseBoolOption(options, "vss-use-mapping"); //Prepare the backup m_backup = vss.CreateVssBackupComponents(); m_backup.InitializeForBackup(null); if (excludedWriters.Count > 0) { m_backup.DisableWriterClasses(excludedWriters.ToArray()); } m_backup.StartSnapshotSet(); m_sourcepaths = new string[sourcepaths.Length]; for (int i = 0; i < m_sourcepaths.Length; i++) { m_sourcepaths[i] = System.IO.Directory.Exists(sourcepaths[i]) ? Utility.Utility.AppendDirSeparator(sourcepaths[i]) : sourcepaths[i]; } try { //Gather information on all Vss writers m_backup.GatherWriterMetadata(); m_backup.FreeWriterMetadata(); } catch { try { m_backup.FreeWriterMetadata(); } catch { } throw; } //Figure out which volumes are in the set m_volumes = new Dictionary <string, Guid>(StringComparer.InvariantCultureIgnoreCase); foreach (string s in m_sourcepaths) { string drive = Alphaleonis.Win32.Filesystem.Path.GetPathRoot(s); if (!m_volumes.ContainsKey(drive)) { if (!m_backup.IsVolumeSupported(drive)) { throw new VssVolumeNotSupportedException(drive); } m_volumes.Add(drive, m_backup.AddToSnapshotSet(drive)); } } //Signal that we want to do a backup m_backup.SetBackupState(false, true, VssBackupType.Full, false); //Make all writers aware that we are going to do the backup m_backup.PrepareForBackup(); //Create the shadow volumes m_backup.DoSnapshotSet(); //Make a little lookup table for faster translation m_volumeMap = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase); foreach (KeyValuePair <string, Guid> kvp in m_volumes) { m_volumeMap.Add(kvp.Key, m_backup.GetSnapshotProperties(kvp.Value).SnapshotDeviceObject); } //If we should map the drives, we do that now and update the volumeMap if (useSubst) { m_mappedDrives = new List <DefineDosDevice>(); foreach (string k in new List <string>(m_volumeMap.Keys)) { try { DefineDosDevice d; m_mappedDrives.Add(d = new DefineDosDevice(m_volumeMap[k])); m_volumeMap[k] = Utility.Utility.AppendDirSeparator(d.Drive); } catch { } } } } catch { //In case we fail in the constructor, we do not want a snapshot to be active try { Dispose(); } catch { } throw; } }
/// <summary> /// Constructs a new backup snapshot, using all the required disks /// </summary> /// <param name="sourcepaths">The folders that are about to be backed up</param> /// <param name="options">A set of commandline options</param> public WindowsSnapshot(string[] sourcepaths, Dictionary <string, string> options) { try { //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC string alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss"); string alphadll = System.IO.Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll"); IVssImplementation vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation"); var excludedWriters = new Guid[0]; if (options.ContainsKey("vss-exclude-writers")) { excludedWriters = options["vss-exclude-writers"].Split(';').Where(x => !string.IsNullOrWhiteSpace(x) && x.Trim().Length > 0).Select(x => new Guid(x)).ToArray(); } //Check if we should map any drives bool useSubst = Utility.Utility.ParseBoolOption(options, "vss-use-mapping"); //Prepare the backup m_backup = vss.CreateVssBackupComponents(); m_backup.InitializeForBackup(null); m_backup.SetContext(VssSnapshotContext.Backup); m_backup.SetBackupState(false, true, VssBackupType.Full, false); if (excludedWriters.Length > 0) { m_backup.DisableWriterClasses(excludedWriters.ToArray()); } m_sourcepaths = sourcepaths.Select(x => Directory.Exists(x) ? Utility.Utility.AppendDirSeparator(x) : x).ToList(); List <string> hypervPaths; try { m_backup.GatherWriterMetadata(); hypervPaths = PrepareHyperVBackup(options, m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(HyperVWriterGuid))); } finally { m_backup.FreeWriterMetadata(); } if (hypervPaths != null) { m_sourcepaths.AddRange(hypervPaths); } //Sanity check for duplicate files/folders var pathDuplicates = m_sourcepaths.GroupBy(x => x, Utility.Utility.ClientFilenameStringComparer) .Where(g => g.Count() > 1).Select(y => y.Key).ToList(); foreach (var pathDuplicate in pathDuplicates) { Logging.Log.WriteMessage(string.Format("Removing duplicate source: {0}", pathDuplicate), Logging.LogMessageType.Information); } if (pathDuplicates.Count > 0) { m_sourcepaths = m_sourcepaths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList(); } //Sanity check for multiple inclusions of the same files/folders var pathIncludedPaths = m_sourcepaths.Where(x => m_sourcepaths.Where(y => y != x).Any(z => x.StartsWith(z, Utility.Utility.ClientFilenameStringComparision))).ToList(); foreach (var pathIncluded in pathIncludedPaths) { Logging.Log.WriteMessage(string.Format("Removing already included source: {0}", pathIncluded), Logging.LogMessageType.Information); } if (pathIncludedPaths.Count > 0) { m_sourcepaths = m_sourcepaths.Except(pathIncludedPaths, Utility.Utility.ClientFilenameStringComparer).ToList(); } m_backup.StartSnapshotSet(); //Figure out which volumes are in the set m_volumes = new Dictionary <string, Guid>(StringComparer.InvariantCultureIgnoreCase); foreach (string s in m_sourcepaths) { string drive = Alphaleonis.Win32.Filesystem.Path.GetPathRoot(s); if (!m_volumes.ContainsKey(drive)) { if (!m_backup.IsVolumeSupported(drive)) { throw new VssVolumeNotSupportedException(drive); } m_volumes.Add(drive, m_backup.AddToSnapshotSet(drive)); } } //Make all writers aware that we are going to do the backup m_backup.PrepareForBackup(); //Create the shadow volumes m_backup.DoSnapshotSet(); //Make a little lookup table for faster translation m_volumeMap = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase); foreach (KeyValuePair <string, Guid> kvp in m_volumes) { m_volumeMap.Add(kvp.Key, m_backup.GetSnapshotProperties(kvp.Value).SnapshotDeviceObject); } //If we should map the drives, we do that now and update the volumeMap if (useSubst) { m_mappedDrives = new List <DefineDosDevice>(); foreach (string k in new List <string>(m_volumeMap.Keys)) { try { DefineDosDevice d; m_mappedDrives.Add(d = new DefineDosDevice(m_volumeMap[k])); m_volumeMap[k] = Utility.Utility.AppendDirSeparator(d.Drive); } catch { } } } } catch { //In case we fail in the constructor, we do not want a snapshot to be active try { Dispose(); } catch { } throw; } }
/// <summary> /// Constructs a new backup snapshot, using all the required disks /// </summary> /// <param name="sources">Sources to determine which volumes to include in snapshot</param> /// <param name="options">A set of commandline options</param> public WindowsSnapshot(IEnumerable <string> sources, IDictionary <string, string> options) { try { // Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC var assemblyLocation = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); if (assemblyLocation == null) { throw new InvalidOperationException(); } var alphadir = Path.Combine(assemblyLocation, "alphavss"); var alphadll = Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll"); var vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation"); if (vss == null) { throw new InvalidOperationException(); } var excludedWriters = new Guid[0]; if (options.ContainsKey("vss-exclude-writers")) { excludedWriters = options["vss-exclude-writers"].Split(';').Where(x => !string.IsNullOrWhiteSpace(x) && x.Trim().Length > 0).Select(x => new Guid(x)).ToArray(); } //Check if we should map any drives var useSubst = Utility.Utility.ParseBoolOption(options, "vss-use-mapping"); //Prepare the backup m_backup = vss.CreateVssBackupComponents(); m_backup.InitializeForBackup(null); m_backup.SetContext(VssSnapshotContext.Backup); m_backup.SetBackupState(false, true, VssBackupType.Full, false); if (excludedWriters.Length > 0) { m_backup.DisableWriterClasses(excludedWriters.ToArray()); } try { m_backup.GatherWriterMetadata(); } finally { m_backup.FreeWriterMetadata(); } m_backup.StartSnapshotSet(); //Figure out which volumes are in the set m_volumes = new Dictionary <string, Guid>(StringComparer.OrdinalIgnoreCase); foreach (var s in sources) { var drive = AlphaFS.Path.GetPathRoot(s); if (!m_volumes.ContainsKey(drive)) { //TODO: that seems a bit harsh... we could fall-back to not using VSS for that volume only if (!m_backup.IsVolumeSupported(drive)) { throw new VssVolumeNotSupportedException(drive); } m_volumes.Add(drive, m_backup.AddToSnapshotSet(drive)); } } //Make all writers aware that we are going to do the backup m_backup.PrepareForBackup(); //Create the shadow volumes m_backup.DoSnapshotSet(); //Make a little lookup table for faster translation m_volumeMap = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (var kvp in m_volumes) { m_volumeMap.Add(kvp.Key, m_backup.GetSnapshotProperties(kvp.Value).SnapshotDeviceObject); } m_volumeReverseMap = m_volumeMap.ToDictionary(x => x.Value, x => x.Key); //If we should map the drives, we do that now and update the volumeMap if (useSubst) { m_mappedDrives = new List <DefineDosDevice>(); foreach (var k in new List <string>(m_volumeMap.Keys)) { try { DefineDosDevice d; m_mappedDrives.Add(d = new DefineDosDevice(m_volumeMap[k])); m_volumeMap[k] = Utility.Utility.AppendDirSeparator(d.Drive); } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "SubstMappingfailed", ex, "Failed to map VSS path {0} to drive", k); } } } } catch { //In case we fail in the constructor, we do not want a snapshot to be active try { Dispose(); } catch (Exception ex) { Logging.Log.WriteVerboseMessage(LOGTAG, "VSSCleanupOnError", ex, "Failed during VSS error cleanup"); } throw; } }
/// <summary> /// Constructs a new backup snapshot, using all the required disks /// </summary> /// <param name="sourcepaths">The folders that are about to be backed up</param> /// <param name="options">A set of commandline options</param> public WindowsSnapshot(string[] sourcepaths, Dictionary<string, string> options) { try { //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC string alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss"); string alphadll = System.IO.Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyName().Name + ".dll"); IVssImplementation vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation"); List<Guid> excludedWriters = new List<Guid>(); if (options.ContainsKey("vss-exclude-writers")) { foreach (string s in options["vss-exclude-writers"].Split(';')) if (!string.IsNullOrEmpty(s) && s.Trim().Length > 0) excludedWriters.Add(new Guid(s)); } //Check if we should map any drives bool useSubst = Utility.Utility.ParseBoolOption(options, "vss-use-mapping"); //Prepare the backup m_backup = vss.CreateVssBackupComponents(); m_backup.InitializeForBackup(null); if (excludedWriters.Count > 0) m_backup.DisableWriterClasses(excludedWriters.ToArray()); m_snapshotId = m_backup.StartSnapshotSet(); m_sourcepaths = new string[sourcepaths.Length]; for(int i = 0; i < m_sourcepaths.Length; i++) m_sourcepaths[i] = Utility.Utility.AppendDirSeparator(sourcepaths[i]); try { //Gather information on all Vss writers using (IVssAsync async = m_backup.GatherWriterMetadata()) async.Wait(); m_backup.FreeWriterMetadata(); } catch { try { m_backup.FreeWriterMetadata(); } catch { } throw; } //Figure out which volumes are in the set m_volumes = new Dictionary<string, Guid>(StringComparer.InvariantCultureIgnoreCase); foreach (string s in m_sourcepaths) { string drive = Alphaleonis.Win32.Filesystem.Path.GetPathRoot(s); if (!m_volumes.ContainsKey(drive)) { if (!m_backup.IsVolumeSupported(drive)) throw new VssVolumeNotSupportedException(drive); m_volumes.Add(drive, m_backup.AddToSnapshotSet(drive)); } } //Signal that we want to do a backup m_backup.SetBackupState(false, true, VssBackupType.Full, false); //Make all writers aware that we are going to do the backup using (IVssAsync async = m_backup.PrepareForBackup()) async.Wait(); //Create the shadow volumes using (IVssAsync async = m_backup.DoSnapshotSet()) async.Wait(); //Make a little lookup table for faster translation m_volumeMap = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase); foreach(KeyValuePair<string, Guid> kvp in m_volumes) m_volumeMap.Add(kvp.Key, m_backup.GetSnapshotProperties(kvp.Value).SnapshotDeviceObject); //If we should map the drives, we do that now and update the volumeMap if (useSubst) { m_mappedDrives = new List<DefineDosDevice>(); foreach (string k in new List<string>(m_volumeMap.Keys)) { try { DefineDosDevice d; m_mappedDrives.Add(d = new DefineDosDevice(m_volumeMap[k])); m_volumeMap[k] = Utility.Utility.AppendDirSeparator(d.Drive); } catch { } } } } catch { //In case we fail in the constructor, we do not want a snapshot to be active try { Dispose(); } catch { } throw; } }
public void SetItems(List <string> spoPaths) { foreach (IVssExamineWriterMetadata writer in backup.WriterMetadata) { foreach (string spo in spoPaths) { try{ Logger.Append(Severity.TRIVIA, "Searching writer and/or component matching " + spo + ", current writer=" + writer.InstanceName); int index = spo.IndexOf(writer.WriterName); if (index < 0 && spo != "*") { continue; } bool found = false; // First we check that the writer's status is OK, else we don't add it to avoid failure of complete snapshot if it's not bool writerOk = false; foreach (VssWriterStatusInfo status in backup.WriterStatus) { if (status.Name == writer.WriterName) { if (status.State == VssWriterState.Stable) { // if we get there it means that we are ready to add the wanted component to VSS set writerOk = true; Metadata.Metadata.Add(writer.WriterName, writer.SaveAsXml()); } else { Logger.Append(Severity.ERROR, "***Cannot add writer " + status.Name + " to snapshot set," + " status=" + status.State.ToString() + ". Backup data managed by this writer may not be consistent. Restore will be hazardous."); if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003)) { backup.DisableWriterClasses(new Guid[] { writer.WriterId }); } } } } bool addAllComponents = false; if (spo.Length == index + writer.WriterName.Length || spo == "*" || spo == "" + writer.WriterName + @"\*") { addAllComponents = true; } // exclude items indicated by writer foreach (VssWMFileDescription file in writer.ExcludeFiles) { BasePath bp = new BasePath(); bp.Type = "FS"; bp.Path = file.Path; bp.ExcludePolicy.Add(file.FileSpecification); //bp.ExcludedPaths = writer.E bp.Recursive = file.IsRecursive; BasePaths.Add(bp); } foreach (IVssWMComponent component in writer.Components) { found = false; Console.WriteLine("***createvolsnapshot : current component is :" + component.LogicalPath + @"\" + component.ComponentName); if ((!addAllComponents) && spo.IndexOf(component.LogicalPath + @"\" + component.ComponentName) < 0) { continue; } Logger.Append(Severity.TRIVIA, "***Asked to recursively select all '" + writer.WriterName + "' writer's components"); if (OperatingSystemInfo.IsAtLeast(OSVersionName.WindowsServer2003)) { foreach (VssWMDependency dep in component.Dependencies) { Logger.Append(Severity.TRIVIA, "***Component " + component.ComponentName + " depends on component " + dep.ComponentName + " TODO TODO TODO add it automatically"); } } if (component.Selectable) { backup.AddComponent(writer.InstanceId, writer.WriterId, component.Type, component.LogicalPath, component.ComponentName); } //Logger.Append (Severity.INFO, "***Added writer '"+writer.WriterName+"' component "+component.ComponentName); this.ExplodedComponents.Add(writer.WriterName + @"\" + component.LogicalPath + @"\" + component.ComponentName); found = true; // Second we need to find every drive containing files necessary for writer's backup // and add them to drives list, in case they weren't explicitely selected as part of backuppaths List <VssWMFileDescription> componentFiles = new List <VssWMFileDescription>(); componentFiles.AddRange(component.Files); componentFiles.AddRange(component.DatabaseFiles); componentFiles.AddRange(component.DatabaseLogFiles); foreach (VssWMFileDescription file in componentFiles) { if (string.IsNullOrEmpty(file.Path)) { continue; } //Console.WriteLine ("***component file path="+file.Path+", alt backuplocation="+file.AlternateLocation // +", backuptypemask="+file.BackupTypeMask.ToString()+", spec="+file.FileSpecification+", recursive="+file.IsRecursive); BasePath bp = new BasePath(); bp.Path = file.Path; bp.Type = "FS"; //BasePath.PathType.FS; bp.IncludePolicy.Add(file.FileSpecification); bp.Recursive = file.IsRecursive; BasePaths.Add(bp); } //backup.SetBackupSucceeded(writer.InstanceId, writer.WriterId, component.Type, component.LogicalPath, component.ComponentName, false); //Logger.Append(Severity.TRIVIA, "Added writer/component "+spo); //break; } //metadata.Metadata.Add(writer.SaveAsXml()); // Retrieve Backup Components Document //Metadata.Metadata.Add("bcd", backup.SaveAsXml()); if (found == false) { Logger.Append(Severity.WARNING, "Could not find VSS component " + spo + " which was part of backup paths"); } } catch (Exception e) { Console.WriteLine(" *** SetItems() : error " + e.Message); } } } //backup.BackupComplete(); backup.FreeWriterStatus(); backup.FreeWriterMetadata(); backup.AbortBackup(); backup.Dispose(); }
/// <summary> /// For all Hyper-V guests it enumerate all associated paths using VSS data /// </summary> /// <returns>A collection of VMs and paths</returns> private Dictionary <string, List <string> > GetAllVMsPathsVSS() { IVssBackupComponents m_backup = null; var ret = new Dictionary <string, List <string> >(); try { //Substitute for calling VssUtils.LoadImplementation(), as we have the dlls outside the GAC string alphadir = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "alphavss"); string alphadll = System.IO.Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll"); IVssImplementation vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation"); m_backup = vss.CreateVssBackupComponents(); m_backup.InitializeForBackup(null); m_backup.SetContext(VssSnapshotContext.Backup); m_backup.SetBackupState(false, true, VssBackupType.Full, false); m_backup.EnableWriterClasses(new Guid[] { HyperVWriterGuid }); try { m_backup.GatherWriterMetadata(); var writerMetaData = m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(HyperVWriterGuid)); if (writerMetaData == null) { throw new Exception("Microsoft Hyper-V VSS Writer not found - cannot backup Hyper-V machines."); } foreach (var component in writerMetaData.Components) { var paths = new List <string>(); foreach (var file in component.Files) { if (file.FileSpecification.Contains("*")) { if (Directory.Exists(Utility.Utility.AppendDirSeparator(file.Path))) { paths.Add(Utility.Utility.AppendDirSeparator(file.Path)); } } else { if (File.Exists(Path.Combine(file.Path, file.FileSpecification))) { paths.Add(Path.Combine(file.Path, file.FileSpecification)); } } } ret.Add(component.ComponentName, paths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList()); } } finally { m_backup.FreeWriterMetadata(); } } finally { try { if (m_backup != null) { m_backup.Dispose(); } } catch { } } return(ret); }