diff options
author | Kenneth Skovhede <kenneth@hexad.dk> | 2016-11-09 14:57:35 +0300 |
---|---|---|
committer | Kenneth Skovhede <kenneth@hexad.dk> | 2016-11-09 14:57:35 +0300 |
commit | aed97d5b4c004c76affec6feb592775230932f4f (patch) | |
tree | ea2f7c2460c8ed2c68b722bd2fd0135ed33b6382 | |
parent | f0d4babdb790a580da21632ee07b1340028154e8 (diff) |
Fixed an issue with Windows reporting an error if there are no MSSQL instances on the machine
-rw-r--r-- | Duplicati/Library/Snapshots/MSSQLUtility.cs | 319 | ||||
-rw-r--r-- | Duplicati/Server/WebServer/RESTMethods/HyperV.cs | 3 | ||||
-rw-r--r-- | Duplicati/Server/WebServer/RESTMethods/MSSQL.cs | 163 |
3 files changed, 252 insertions, 233 deletions
diff --git a/Duplicati/Library/Snapshots/MSSQLUtility.cs b/Duplicati/Library/Snapshots/MSSQLUtility.cs index 9bf57c610..8aaf57ca9 100644 --- a/Duplicati/Library/Snapshots/MSSQLUtility.cs +++ b/Duplicati/Library/Snapshots/MSSQLUtility.cs @@ -1,154 +1,167 @@ -using Alphaleonis.Win32.Vss; -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace Duplicati.Library.Snapshots -{ - public class MSSQLDB : IEquatable<MSSQLDB> - { - public string Name { get; } - public string ID { get; } - public List<string> DataPaths { get; } - - public MSSQLDB(string Name, string ID, List<string> DataPaths) - { - this.Name = Name; - this.ID = ID; - this.DataPaths = DataPaths; - } - - bool IEquatable<MSSQLDB>.Equals(MSSQLDB other) - { - return ID.Equals(other.ID); - } - - public override int GetHashCode() - { - return ID.GetHashCode(); - } - - public override bool Equals(object obj) - { - MSSQLDB db = obj as MSSQLDB; - if (db != null) - { - return Equals(db); - } - else - { - return false; - } - } - - public static bool operator ==(MSSQLDB db1, MSSQLDB db2) - { - if (object.ReferenceEquals(db1, db2)) return true; - if (object.ReferenceEquals(db1, null)) return false; - if (object.ReferenceEquals(db2, null)) return false; - - return db1.Equals(db2); - } - - public static bool operator !=(MSSQLDB db1, MSSQLDB db2) - { - if (object.ReferenceEquals(db1, db2)) return false; - if (object.ReferenceEquals(db1, null)) return true; - if (object.ReferenceEquals(db2, null)) return true; - - return !db1.Equals(db2); - } - } - - public class MSSQLUtility - { - /// <summary> - /// The MS SQL VSS Writer Guid - /// </summary> - public static readonly Guid MSSQLWriterGuid = new Guid("a65faa63-5ea8-4ebc-9dbd-a0c4db26912a"); - /// <summary> - /// MS SQL is supported only on Windows platform - /// </summary> - public bool IsMSSQLInstalled { get; } - /// <summary> - /// Enumerated MS SQL DBs - /// </summary> - public List<MSSQLDB> DBs { get { return m_DBs; } } - private List<MSSQLDB> m_DBs; - - public MSSQLUtility() - { - m_DBs = new List<MSSQLDB>(); - - if (!Utility.Utility.IsClientWindows) - { - IsMSSQLInstalled = false; - return; - } - - var arrInstalledInstances = (string [])Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server", "InstalledInstances", ""); - IsMSSQLInstalled = arrInstalledInstances == null ? false : arrInstalledInstances.Length > 0; - - if (!IsMSSQLInstalled) - Logging.Log.WriteMessage("Cannot find any MS SQL Server instance. MS SQL Server is probably not installed.", Logging.LogMessageType.Information); - } - - /// <summary> - /// For all MS SQL databases it enumerate all associated paths using VSS data - /// </summary> - /// <returns>A collection of DBs and paths</returns> - public void QueryDBsInfo() - { - if (!IsMSSQLInstalled) - return; - - m_DBs.Clear(); - - //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 = Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll"); - IVssImplementation vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation"); - - using (var 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[] { MSSQLWriterGuid }); - - try - { - m_backup.GatherWriterMetadata(); - var writerMetaData = m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(MSSQLWriterGuid)); - - if (writerMetaData == null) - throw new Exception("Microsoft SQL Server VSS Writer not found - cannot backup SQL databases."); - - 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)); - } - - m_DBs.Add(new MSSQLDB(component.ComponentName, component.LogicalPath + "\\" + component.ComponentName, paths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList())); - } - } - finally - { - m_backup.FreeWriterMetadata(); - } - } - } - } +using Alphaleonis.Win32.Vss;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace Duplicati.Library.Snapshots
+{
+ public class MSSQLDB : IEquatable<MSSQLDB>
+ {
+ public string Name { get; }
+ public string ID { get; }
+ public List<string> DataPaths { get; }
+
+ public MSSQLDB(string Name, string ID, List<string> DataPaths)
+ {
+ this.Name = Name;
+ this.ID = ID;
+ this.DataPaths = DataPaths;
+ }
+
+ bool IEquatable<MSSQLDB>.Equals(MSSQLDB other)
+ {
+ return ID.Equals(other.ID);
+ }
+
+ public override int GetHashCode()
+ {
+ return ID.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ MSSQLDB db = obj as MSSQLDB;
+ if (db != null)
+ {
+ return Equals(db);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ public static bool operator ==(MSSQLDB db1, MSSQLDB db2)
+ {
+ if (object.ReferenceEquals(db1, db2)) return true;
+ if (object.ReferenceEquals(db1, null)) return false;
+ if (object.ReferenceEquals(db2, null)) return false;
+
+ return db1.Equals(db2);
+ }
+
+ public static bool operator !=(MSSQLDB db1, MSSQLDB db2)
+ {
+ if (object.ReferenceEquals(db1, db2)) return false;
+ if (object.ReferenceEquals(db1, null)) return true;
+ if (object.ReferenceEquals(db2, null)) return true;
+
+ return !db1.Equals(db2);
+ }
+ }
+
+ public class MSSQLUtility
+ {
+ /// <summary>
+ /// The MS SQL VSS Writer Guid
+ /// </summary>
+ public static readonly Guid MSSQLWriterGuid = new Guid("a65faa63-5ea8-4ebc-9dbd-a0c4db26912a");
+ /// <summary>
+ /// MS SQL is supported only on Windows platform
+ /// </summary>
+ public bool IsMSSQLInstalled { get; }
+ /// <summary>
+ /// Enumerated MS SQL DBs
+ /// </summary>
+ public List<MSSQLDB> DBs { get { return m_DBs; } }
+ private List<MSSQLDB> m_DBs;
+
+ public MSSQLUtility()
+ {
+ m_DBs = new List<MSSQLDB>();
+
+ if (!Utility.Utility.IsClientWindows)
+ {
+ IsMSSQLInstalled = false;
+ return;
+ }
+
+ string[] arrInstalledInstances = null;
+
+ var installed = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server", "InstalledInstances", "");
+ if (installed is string)
+ {
+ if (!string.IsNullOrWhiteSpace(installed as string))
+ arrInstalledInstances = new string[] { installed as string };
+ }
+ else if (installed is string[])
+ arrInstalledInstances = (string[])installed;
+ else if (installed != null)
+ try { arrInstalledInstances = (string[])installed; }
+ catch { }
+
+ IsMSSQLInstalled = arrInstalledInstances == null ? false : arrInstalledInstances.Length > 0;
+
+ if (!IsMSSQLInstalled)
+ Logging.Log.WriteMessage("Cannot find any MS SQL Server instance. MS SQL Server is probably not installed.", Logging.LogMessageType.Information);
+ }
+
+ /// <summary>
+ /// For all MS SQL databases it enumerate all associated paths using VSS data
+ /// </summary>
+ /// <returns>A collection of DBs and paths</returns>
+ public void QueryDBsInfo()
+ {
+ if (!IsMSSQLInstalled)
+ return;
+
+ m_DBs.Clear();
+
+ //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 = Path.Combine(alphadir, VssUtils.GetPlatformSpecificAssemblyShortName() + ".dll");
+ IVssImplementation vss = (IVssImplementation)System.Reflection.Assembly.LoadFile(alphadll).CreateInstance("Alphaleonis.Win32.Vss.VssImplementation");
+
+ using (var 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[] { MSSQLWriterGuid });
+
+ try
+ {
+ m_backup.GatherWriterMetadata();
+ var writerMetaData = m_backup.WriterMetadata.FirstOrDefault(o => o.WriterId.Equals(MSSQLWriterGuid));
+
+ if (writerMetaData == null)
+ throw new Exception("Microsoft SQL Server VSS Writer not found - cannot backup SQL databases.");
+
+ 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));
+ }
+
+ m_DBs.Add(new MSSQLDB(component.ComponentName, component.LogicalPath + "\\" + component.ComponentName, paths.Distinct(Utility.Utility.ClientFilenameStringComparer).OrderBy(a => a).ToList()));
+ }
+ }
+ finally
+ {
+ m_backup.FreeWriterMetadata();
+ }
+ }
+ }
+ }
}
\ No newline at end of file diff --git a/Duplicati/Server/WebServer/RESTMethods/HyperV.cs b/Duplicati/Server/WebServer/RESTMethods/HyperV.cs index cbc1705c9..f1eeb2fd9 100644 --- a/Duplicati/Server/WebServer/RESTMethods/HyperV.cs +++ b/Duplicati/Server/WebServer/RESTMethods/HyperV.cs @@ -39,7 +39,10 @@ namespace Duplicati.Server.WebServer.RESTMethods var hypervUtility = new HyperVUtility();
if (!hypervUtility.IsHyperVInstalled)
+ {
info.OutputOK();
+ return;
+ }
try
{
diff --git a/Duplicati/Server/WebServer/RESTMethods/MSSQL.cs b/Duplicati/Server/WebServer/RESTMethods/MSSQL.cs index d82a1ede8..7ad9c6bfb 100644 --- a/Duplicati/Server/WebServer/RESTMethods/MSSQL.cs +++ b/Duplicati/Server/WebServer/RESTMethods/MSSQL.cs @@ -1,80 +1,83 @@ -// Copyright (C) 2015, The Duplicati Team -// http://www.duplicati.com, info@duplicati.com -// -// This library is free software; you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as -// published by the Free Software Foundation; either version 2.1 of the -// License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -using System; -using System.Collections.Generic; -using Duplicati.Library.Interface; -using System.Linq; -using Duplicati.Library.Snapshots; - -namespace Duplicati.Server.WebServer.RESTMethods -{ - public class MSSQL : IRESTMethodGET, IRESTMethodDocumented - { - public void GET(string key, RequestInfo info) - { - // Early exit in case we are non-windows to prevent attempting to load Windows-only components - if (Library.Utility.Utility.IsClientWindows) - RealGET(key, info); - } - - // Make sure the JIT does not attempt to inline this call and thus load - // referenced types from System.Management here - [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] - private void RealGET(string key, RequestInfo info) - { - var mssqlUtility = new MSSQLUtility(); - - if (!mssqlUtility.IsMSSQLInstalled) - info.OutputOK(); - - try - { - mssqlUtility.QueryDBsInfo(); - - if (string.IsNullOrEmpty(key)) - info.OutputOK(mssqlUtility.DBs.Select(x => new { id = x.ID, name = x.Name }).ToList()); - else - { - var foundDBs = mssqlUtility.DBs.FindAll(x => x.ID.Equals(key, StringComparison.OrdinalIgnoreCase)); - - if (foundDBs.Count == 1) - info.OutputOK(foundDBs[0].DataPaths.Select(x => new { text = x, id = x, cls = "folder", iconCls = "x-tree-icon-leaf", check = "false", leaf = "true" }).ToList()); - else - info.ReportClientError(string.Format("Cannot find DB with ID {0}.", key)); - } - } - catch (Exception ex) - { - info.ReportClientError("Failed to enumerate Microsoft SQL Server databases: " + ex.Message); - } - } - - public string Description { get { return "Return a list of Microsoft SQL Server databases"; } } - - public IEnumerable<KeyValuePair<string, Type>> Types - { - get - { - return new KeyValuePair<string, Type>[] { - new KeyValuePair<string, Type>(HttpServer.Method.Get, typeof(ICommandLineArgument[])) - }; - } - } - - } -} - +// Copyright (C) 2015, The Duplicati Team
+// http://www.duplicati.com, info@duplicati.com
+//
+// This library is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of the
+// License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+using System;
+using System.Collections.Generic;
+using Duplicati.Library.Interface;
+using System.Linq;
+using Duplicati.Library.Snapshots;
+
+namespace Duplicati.Server.WebServer.RESTMethods
+{
+ public class MSSQL : IRESTMethodGET, IRESTMethodDocumented
+ {
+ public void GET(string key, RequestInfo info)
+ {
+ // Early exit in case we are non-windows to prevent attempting to load Windows-only components
+ if (Library.Utility.Utility.IsClientWindows)
+ RealGET(key, info);
+ }
+
+ // Make sure the JIT does not attempt to inline this call and thus load
+ // referenced types from System.Management here
+ [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
+ private void RealGET(string key, RequestInfo info)
+ {
+ var mssqlUtility = new MSSQLUtility();
+
+ if (!mssqlUtility.IsMSSQLInstalled)
+ {
+ info.OutputOK();
+ return;
+ }
+
+ try
+ {
+ mssqlUtility.QueryDBsInfo();
+
+ if (string.IsNullOrEmpty(key))
+ info.OutputOK(mssqlUtility.DBs.Select(x => new { id = x.ID, name = x.Name }).ToList());
+ else
+ {
+ var foundDBs = mssqlUtility.DBs.FindAll(x => x.ID.Equals(key, StringComparison.OrdinalIgnoreCase));
+
+ if (foundDBs.Count == 1)
+ info.OutputOK(foundDBs[0].DataPaths.Select(x => new { text = x, id = x, cls = "folder", iconCls = "x-tree-icon-leaf", check = "false", leaf = "true" }).ToList());
+ else
+ info.ReportClientError(string.Format("Cannot find DB with ID {0}.", key));
+ }
+ }
+ catch (Exception ex)
+ {
+ info.ReportClientError("Failed to enumerate Microsoft SQL Server databases: " + ex.Message);
+ }
+ }
+
+ public string Description { get { return "Return a list of Microsoft SQL Server databases"; } }
+
+ public IEnumerable<KeyValuePair<string, Type>> Types
+ {
+ get
+ {
+ return new KeyValuePair<string, Type>[] {
+ new KeyValuePair<string, Type>(HttpServer.Method.Get, typeof(ICommandLineArgument[]))
+ };
+ }
+ }
+
+ }
+}
+
|