From 2c5d4afd4b29ae201fbe12f0a31cdc6a3b895bbd Mon Sep 17 00:00:00 2001 From: epbk Date: Tue, 30 Jan 2024 18:22:44 +0100 Subject: [PATCH] MP1-5196: Fix/Enhance UNC Root resolving (UNCTools) --- mediaportal/Core/Util/UNCTools.cs | 1158 +++++++++++++++-------------- 1 file changed, 587 insertions(+), 571 deletions(-) diff --git a/mediaportal/Core/Util/UNCTools.cs b/mediaportal/Core/Util/UNCTools.cs index 16f497ee706..4d93638a381 100644 --- a/mediaportal/Core/Util/UNCTools.cs +++ b/mediaportal/Core/Util/UNCTools.cs @@ -35,696 +35,712 @@ namespace MediaPortal.Util { + /// + /// A static class to help with resolving a mapped drive path to a UNC network path. + /// If a local drive path or a UNC network path are passed in, they will just be returned. + /// Also there is a File/Folder exists function which first pings the UNC server first, if it is not reachable it states that file not exitst. + /// This is usefull because there is no "long" timeout like on c# File.Exists Function. + /// + + public static class UNCTools + { + + #region Declarations + + [DllImport("wininet", CharSet = CharSet.Auto)] + static extern bool InternetGetConnectedState(ref ConnectionStatusEnum flags, int dw); + + static string HostDetectMethod = "Ping"; + /// - /// A static class to help with resolving a mapped drive path to a UNC network path. - /// If a local drive path or a UNC network path are passed in, they will just be returned. - /// Also there is a File/Folder exists function which first pings the UNC server first, if it is not reachable it states that file not exitst. - /// This is usefull because there is no "long" timeout like on c# File.Exists Function. + /// enum to hold the possible connection states /// - - public static class UNCTools + [Flags] + enum ConnectionStatusEnum : int { + INTERNET_CONNECTION_MODEM = 0x1, + INTERNET_CONNECTION_LAN = 0x2, + INTERNET_CONNECTION_PROXY = 0x4, + INTERNET_RAS_INSTALLED = 0x10, + INTERNET_CONNECTION_OFFLINE = 0x20, + INTERNET_CONNECTION_CONFIGURED = 0x40 + } - #region Declarations + #endregion - [DllImport("wininet", CharSet = CharSet.Auto)] - static extern bool InternetGetConnectedState(ref ConnectionStatusEnum flags, int dw); + static UNCTools() + { + using (Profile.Settings xmlreader = new Profile.MPSettings()) + { + HostDetectMethod = xmlreader.GetValueAsString("general", "HostDetectMethod", HostDetectMethod); + } + } - static string HostDetectMethod = "Ping"; - /// - /// enum to hold the possible connection states - /// - [Flags] - enum ConnectionStatusEnum : int - { - INTERNET_CONNECTION_MODEM = 0x1, - INTERNET_CONNECTION_LAN = 0x2, - INTERNET_CONNECTION_PROXY = 0x4, - INTERNET_RAS_INSTALLED = 0x10, - INTERNET_CONNECTION_OFFLINE = 0x20, - INTERNET_CONNECTION_CONFIGURED = 0x40 - } + #region Public functions - #endregion + /// + /// Resolves the given path to a full UNC path if the path is a mapped drive. + /// Otherwise, just returns the given path. + /// + /// The path to resolve. + /// + public static string ResolveToUNC(string path) + { + if (String.IsNullOrWhiteSpace(path)) + { + Log.Debug("UNCTools: ResolveToUNC: The path argument '{0}' was null or whitespace.", path); + } - static UNCTools() - { - using (Profile.Settings xmlreader = new Profile.MPSettings()) - { - HostDetectMethod = xmlreader.GetValueAsString("general", "HostDetectMethod", HostDetectMethod); - } - } + if (!Path.IsPathRooted(path)) + { + Log.Debug("UNCTools: ResolveToUNC: The path '{0}' was not a rooted path and ResolveToUNC does not support relative paths.", path); + } + // Is the path already in the UNC format? + if (path.StartsWith(@"\\")) + { + return path; + } - #region Public functions + string rootPath = ResolveToRootUNC(path); - /// - /// Resolves the given path to a full UNC path if the path is a mapped drive. - /// Otherwise, just returns the given path. - /// - /// The path to resolve. - /// - public static string ResolveToUNC(string path) - { - if (String.IsNullOrWhiteSpace(path)) - { - Log.Debug("UNCTools: ResolveToUNC: The path argument '{0}' was null or whitespace.", path); - } + if (string.IsNullOrWhiteSpace(rootPath)) + { + return string.Empty; + } + else if (path.StartsWith(rootPath)) + { + return path; // Local drive, no resolving occurred + } + else + { + return path.Replace(GetDriveLetter(path), rootPath); + } + } - if (!Path.IsPathRooted(path)) - { - Log.Debug("UNCTools: ResolveToUNC: The path '{0}' was not a rooted path and ResolveToUNC does not support relative paths.", path); - } + /// + /// Resolves the given path to a root UNC path if the path is a mapped drive. + /// Otherwise, just returns the given path. + /// + /// The path to resolve. + /// + public static string ResolveToRootUNC(string path) + { + if (String.IsNullOrWhiteSpace(path)) + { + Log.Debug("UNCTools: ResolveToRootUNC: The path argument was null or whitespace."); + } - // Is the path already in the UNC format? - if (path.StartsWith(@"\\")) - { - return path; - } + if (!Path.IsPathRooted(path)) + { + Log.Debug("UNCTools: ResolveToRootUNC: The path '{0}' was not a rooted path and ResolveToRootUNC does not support relative paths.", path); + } - string rootPath = ResolveToRootUNC(path); + if (path.StartsWith(@"\\")) + { + return Directory.GetDirectoryRoot(path); + } - if (path.StartsWith(rootPath)) - { - return path; // Local drive, no resolving occurred - } - else - { - return path.Replace(GetDriveLetter(path), rootPath); - } - } + // Get just the drive letter for WMI call + string driveletter = GetDriveLetter(path); - /// - /// Resolves the given path to a root UNC path if the path is a mapped drive. - /// Otherwise, just returns the given path. - /// - /// The path to resolve. - /// - public static string ResolveToRootUNC(string path) + // Query WMI if the drive letter is a network drive, and if so the UNC path for it + using (ManagementClass devs = new ManagementClass(@"Win32_LogicalDisk")) + { + foreach (ManagementObject mo in devs.GetInstances()) { - if (String.IsNullOrWhiteSpace(path)) - { - Log.Debug("UNCTools: ResolveToRootUNC: The path argument was null or whitespace."); - } + PropertyData propDevId = mo.Properties["DeviceID"]; - if (!Path.IsPathRooted(path)) - { - Log.Debug("UNCTools: ResolveToRootUNC: The path '{0}' was not a rooted path and ResolveToRootUNC does not support relative paths.", path); - } + if (((string)propDevId.Value).Equals(driveletter, StringComparison.OrdinalIgnoreCase)) + { + DriveType driveType = (DriveType)((uint)mo["DriveType"]); - if (path.StartsWith(@"\\")) - { - return Directory.GetDirectoryRoot(path); - } + if (driveType == DriveType.Network) + return Convert.ToString(mo["ProviderName"]); + else if (driveType == DriveType.CDRom && mo["volumename"] == null && mo["volumeserialnumber"] == null) + return string.Empty; //cdrom is not loaded + else + return driveletter + Path.DirectorySeparatorChar; + } + } + } - // Get just the drive letter for WMI call - string driveletter = GetDriveLetter(path); + //Not found + return string.Empty; + } - // Query WMI if the drive letter is a network drive, and if so the UNC path for it - using (System.Management.ManagementObject mo = new ManagementObject()) - { - mo.Path = new ManagementPath(string.Format("Win32_LogicalDisk='{0}'", driveletter)); + /// + /// Checks if the given path is a network drive. + /// + /// The path to check. + /// + public static bool isNetworkDrive(string path) + { + if (String.IsNullOrWhiteSpace(path)) + { + Log.Debug("UNCTools: isNetworkDrive: The path argument was null or whitespace."); + } - DriveType driveType = (DriveType)((uint)mo["DriveType"]); - string networkRoot = Convert.ToString(mo["ProviderName"]); + if (!Path.IsPathRooted(path)) + { + Log.Debug("UNCTools: isNetworkDrive: The path '{0}' was not a rooted path and ResolveToRootUNC does not support relative paths.", path); + } - if (driveType == DriveType.Network) - { - return networkRoot; - } - return driveletter + Path.DirectorySeparatorChar; - } - } + if (path.StartsWith(@"\\")) + { + return true; + } - /// - /// Checks if the given path is a network drive. - /// - /// The path to check. - /// - public static bool isNetworkDrive(string path) - { - if (String.IsNullOrWhiteSpace(path)) - { - Log.Debug("UNCTools: isNetworkDrive: The path argument was null or whitespace."); - } + // Get just the drive letter for WMI call + string driveletter = GetDriveLetter(path); - if (!Path.IsPathRooted(path)) - { - Log.Debug("UNCTools: isNetworkDrive: The path '{0}' was not a rooted path and ResolveToRootUNC does not support relative paths.", path); - } + // Query WMI if the drive letter is a network drive + using (ManagementObject mo = new ManagementObject()) + { + mo.Path = new ManagementPath(string.Format("Win32_LogicalDisk='{0}'", driveletter)); + DriveType driveType = (DriveType)((uint)mo["DriveType"]); + return driveType == DriveType.Network; + } + } - if (path.StartsWith(@"\\")) - { - return true; - } + /// + /// Given a path will extract just the drive letter with volume separator. + /// + /// + /// C: + public static string GetDriveLetter(string path) + { + if (String.IsNullOrWhiteSpace(path)) + { + Log.Debug("UNCTools: GetDriveLetter: The path argument was null or whitespace."); + } - // Get just the drive letter for WMI call - string driveletter = GetDriveLetter(path); + if (!Path.IsPathRooted(path)) + { + Log.Debug("UNCTools: GetDriveLetter: The path '{0}' was not a rooted path and GetDriveLetter does not support relative paths.", path); + } - // Query WMI if the drive letter is a network drive - using (ManagementObject mo = new ManagementObject()) - { - mo.Path = new ManagementPath(string.Format("Win32_LogicalDisk='{0}'", driveletter)); - DriveType driveType = (DriveType)((uint)mo["DriveType"]); - return driveType == DriveType.Network; - } - } + if (path.StartsWith(@"\\")) + { + Log.Debug("UNCTools: A UNC path was passed to GetDriveLetter, path '{0}'", path); + } - /// - /// Given a path will extract just the drive letter with volume separator. - /// - /// - /// C: - public static string GetDriveLetter(string path) - { - if (String.IsNullOrWhiteSpace(path)) - { - Log.Debug("UNCTools: GetDriveLetter: The path argument was null or whitespace."); - } + return Directory.GetDirectoryRoot(path).Replace(Path.DirectorySeparatorChar.ToString(), string.Empty); + } - if (!Path.IsPathRooted(path)) - { - Log.Debug("UNCTools: GetDriveLetter: The path '{0}' was not a rooted path and GetDriveLetter does not support relative paths.", path); - } + /// + /// Check if the host of an UNC file/folder is online and the given filesystem object exists (with user defined ping timeout) + /// On local files/folders (ex.: c:\temp\1.txt) will be returned true/// + /// ex.: bolRes = UNCFileFolderExists("\\MYSERVER\VIDEOS\1.MKV"); + /// ex.: bolRes = UNCFileFolderExists("\\MYSERVER\VIDEOS\");/// + /// + /// + /// BOOL + public static bool UNCFileFolderExists(string strFile) + { + return UNCFileFolderExists(strFile, "Default"); + } - if (path.StartsWith(@"\\")) - { - Log.Debug("UNCTools: A UNC path was passed to GetDriveLetter, path '{0}'", path); - } + /// + /// Check if the host of an UNC file/folder is online and the given filesystem object exists (with user defined ping timeout) + /// On local files/folders (ex.: c:\temp\1.txt) will be returned true/// + /// ex.: bolRes = UNCFileFolderExists("\\MYSERVER\VIDEOS\1.MKV"); + /// ex.: bolRes = UNCFileFolderExists("\\MYSERVER\VIDEOS\");/// + /// + /// + /// + /// BOOL + public static bool UNCFileFolderExists(string strFile, string hostDetectMethod) + { + // Check if UNC strFile was already tested avoid another check + if (VirtualDirectory.detectedItemsPath.Contains(strFile)) + { + return true; + } - return Directory.GetDirectoryRoot(path).Replace(Path.DirectorySeparatorChar.ToString(), string.Empty); - } + string strUNCPath; + bool bolExist = false; + string strType = string.Empty; - /// - /// Check if the host of an UNC file/folder is online and the given filesystem object exists (with user defined ping timeout) - /// On local files/folders (ex.: c:\temp\1.txt) will be returned true/// - /// ex.: bolRes = UNCFileFolderExists("\\MYSERVER\VIDEOS\1.MKV"); - /// ex.: bolRes = UNCFileFolderExists("\\MYSERVER\VIDEOS\");/// - /// - /// - /// BOOL - public static bool UNCFileFolderExists(string strFile) - { - return UNCFileFolderExists(strFile, "Default"); - } - - /// - /// Check if the host of an UNC file/folder is online and the given filesystem object exists (with user defined ping timeout) - /// On local files/folders (ex.: c:\temp\1.txt) will be returned true/// - /// ex.: bolRes = UNCFileFolderExists("\\MYSERVER\VIDEOS\1.MKV"); - /// ex.: bolRes = UNCFileFolderExists("\\MYSERVER\VIDEOS\");/// - /// - /// - /// - /// BOOL - public static bool UNCFileFolderExists(string strFile, string hostDetectMethod) - { - // Check if UNC strFile was already tested avoid another check - if (VirtualDirectory.detectedItemsPath.Contains(strFile)) + try + { + //Check if the host of the file/folder is online + strUNCPath = UNCFileFolderOnline(strFile, hostDetectMethod); + if (string.IsNullOrEmpty(strUNCPath)) { - return true; + return false; } - string strUNCPath; - bool bolExist = false; - string strType = string.Empty; + // get the file attributes for file or directory + FileAttributes attr = File.GetAttributes(strUNCPath); - try + //detect whether its a directory or file + if ((attr & FileAttributes.Directory) == FileAttributes.Directory) { - //Check if the host of the file/folder is online - strUNCPath = UNCFileFolderOnline(strFile, hostDetectMethod); - if (string.IsNullOrEmpty(strUNCPath)) - { - return false; - } - - // get the file attributes for file or directory - FileAttributes attr = File.GetAttributes(strUNCPath); - - //detect whether its a directory or file - if ((attr & FileAttributes.Directory) == FileAttributes.Directory) - { - //its a folder - bolExist = Directory.Exists(strUNCPath); //Does the folder exist? - strType = "Folder"; - } - else - { - //its a file - bolExist = File.Exists(strUNCPath); //Does the file exist? - strType = "File"; - } - - - if (bolExist) - { - //File/Folder exists - Log.Debug("UNCTools: UNCFileFolderExists: {0} '{1}' exists!", strType, strFile); - } - else - { - //File/Folder doesnt exist - Log.Info("UNCTools: UNCFileFolderExists: {0} '{1}' doesn't exists or isnt online!", strType, strFile); - } - + //its a folder + bolExist = Directory.Exists(strUNCPath); //Does the folder exist? + strType = "Folder"; } - catch (Exception ex) + else { - Log.Error("UNCTools: UNCFileFolderExists: {0} for {1}", ex.Message, strFile); + //its a file + bolExist = File.Exists(strUNCPath); //Does the file exist? + strType = "File"; } - if (!VirtualDirectory.detectedItemsPath.Contains(strFile)) + + if (bolExist) + { + //File/Folder exists + Log.Debug("UNCTools: UNCFileFolderExists: {0} '{1}' exists!", strType, strFile); + } + else { - VirtualDirectory.detectedItemsPath.Add(strFile); + //File/Folder doesnt exist + Log.Info("UNCTools: UNCFileFolderExists: {0} '{1}' doesn't exists or isnt online!", strType, strFile); } - //Return the flag - return bolExist; } - - /// - /// Check if the host of an UNC file/folder is online, (with user defined ping timeout) - /// On local files/folders (ex.: c:\temp\1.txt) will be returned true - /// ex.: strUNCPath = UNCFileFolderOnline("C:\mydir\myfile.ext"); - /// ex.: strUNCPath = UNCFileFolderOnline("C:\mydir\");/// - /// - /// - /// the converted UNC Path as string when the file/folder is online - /// empty string when the file/folder is offline - public static string UNCFileFolderOnline(string strFile) + catch (Exception ex) { - return UNCFileFolderOnline(strFile, "Default"); + Log.Error("UNCTools: UNCFileFolderExists: {0} for {1}", ex.Message, strFile); } - /// - /// Check if the host of an UNC file/folder is online, (with user defined ping timeout) - /// On local files/folders (ex.: c:\temp\1.txt) will be returned true - /// ex.: strUNCPath = UNCFileFolderOnline("C:\mydir\myfile.ext"); - /// ex.: strUNCPath = UNCFileFolderOnline("C:\mydir\");/// - /// - /// - /// - /// the converted UNC Path as string when the file/folder is online - /// empty string when the file/folder is offline - public static string UNCFileFolderOnline(string strFile, string hostDetectMethod) + if (!VirtualDirectory.detectedItemsPath.Contains(strFile)) { - string hostdetectmethod = (string.IsNullOrEmpty(hostDetectMethod) || hostDetectMethod == "Default") ? HostDetectMethod : hostDetectMethod; + VirtualDirectory.detectedItemsPath.Add(strFile); + } + + //Return the flag + return bolExist; + } - // Resolve given path to UNC - var strUNCPath = ResolveToUNC(strFile); - // Get Host name - var uri = new Uri(strUNCPath); + /// + /// Check if the host of an UNC file/folder is online, (with user defined ping timeout) + /// On local files/folders (ex.: c:\temp\1.txt) will be returned true + /// ex.: strUNCPath = UNCFileFolderOnline("C:\mydir\myfile.ext"); + /// ex.: strUNCPath = UNCFileFolderOnline("C:\mydir\");/// + /// + /// + /// the converted UNC Path as string when the file/folder is online + /// empty string when the file/folder is offline + public static string UNCFileFolderOnline(string strFile) + { + return UNCFileFolderOnline(strFile, "Default"); + } + + /// + /// Check if the host of an UNC file/folder is online, (with user defined ping timeout) + /// On local files/folders (ex.: c:\temp\1.txt) will be returned true + /// ex.: strUNCPath = UNCFileFolderOnline("C:\mydir\myfile.ext"); + /// ex.: strUNCPath = UNCFileFolderOnline("C:\mydir\");/// + /// + /// + /// + /// the converted UNC Path as string when the file/folder is online + /// empty string when the file/folder is offline + public static string UNCFileFolderOnline(string strFile, string hostDetectMethod) + { + string hostdetectmethod = (string.IsNullOrEmpty(hostDetectMethod) || hostDetectMethod == "Default") ? HostDetectMethod : hostDetectMethod; + + // Resolve given path to UNC + string strUNCPath = ResolveToUNC(strFile); + if (string.IsNullOrWhiteSpace(strUNCPath)) + return string.Empty; + + // Get Host name + var uri = new Uri(strUNCPath); - if (hostdetectmethod == "Ping") + if (hostdetectmethod == "Ping") + { + // Ping the Host + if (string.IsNullOrEmpty(uri.Host)) { - // Ping the Host - if (string.IsNullOrEmpty(uri.Host)) - { - return strUNCPath; - } - // We have an host -> try to ping it - var iPingAnswers = PingHost(uri.Host, 200, 2); - if (iPingAnswers != 0) - { - return strUNCPath; - } + return strUNCPath; } - else if (hostdetectmethod == "Samba") + // We have an host -> try to ping it + var iPingAnswers = PingHost(uri.Host, 200, 2); + if (iPingAnswers != 0) { - if (CheckNetworkHost(strFile, 139)) - { - return strUNCPath; - } + return strUNCPath; } - else + } + else if (hostdetectmethod == "Samba") + { + if (CheckNetworkHost(strFile, 139)) { - if (CheckNetworkPath(strFile)) - { - return strUNCPath; - } + return strUNCPath; } - - //We DONT have received an answer - Log.Debug("UNCTools: UNCFileFolderOnline: Host: '{0}' is not reachable!", uri.Host); - Log.Debug(" : Method: {0}/{1}", HostDetectMethod, hostdetectmethod); - Log.Debug(" : File/Folder: {0}", strFile); - return string.Empty; - - //UNC device is online or local file/folder } - - public static bool IsUNCFileFolderOnline(string strFile) + else { - return IsUNCFileFolderOnline(strFile, "Default"); + if (CheckNetworkPath(strFile)) + { + return strUNCPath; + } } - public static bool IsUNCFileFolderOnline(string strFile, string hostDetectMethod) - { - return !string.IsNullOrEmpty(UNCFileFolderOnline(strFile, hostDetectMethod)); - } + //We DONT have received an answer + Log.Debug("UNCTools: UNCFileFolderOnline: Host: '{0}' is not reachable!", uri.Host); + Log.Debug(" : Method: {0}/{1}", HostDetectMethod, hostdetectmethod); + Log.Debug(" : File/Folder: {0}", strFile); + return string.Empty; - [MethodImpl(MethodImplOptions.Synchronized)] - public static bool CheckNetworkPath(string path) - { - if (string.IsNullOrEmpty(path)) return false; - var pathRoot = Path.GetPathRoot(path); - if (string.IsNullOrEmpty(pathRoot)) return false; + //UNC device is online or local file/folder + } - // Part 1 : try to delete share - var pinfo = new ProcessStartInfo("net", "use " + "\"" + path + "\"" + " /DELETE") - { - CreateNoWindow = true, - RedirectStandardOutput = true, - UseShellExecute = false - }; - using (var p = Process.Start(pinfo)) - { - if (p != null) - { - p.WaitForExit(200); - Log.Debug("UNCTools: CheckNetworkPath: try to delete share : {0}", path); - } - } + public static bool IsUNCFileFolderOnline(string strFile) + { + return IsUNCFileFolderOnline(strFile, "Default"); + } - // Part 2 : try to add share - pinfo = new ProcessStartInfo("net", "use " + "\"" + path + "\"") - { - CreateNoWindow = true, - RedirectStandardOutput = true, - UseShellExecute = false - }; - using (var p = Process.Start(pinfo)) + public static bool IsUNCFileFolderOnline(string strFile, string hostDetectMethod) + { + return !string.IsNullOrEmpty(UNCFileFolderOnline(strFile, hostDetectMethod)); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + public static bool CheckNetworkPath(string path) + { + if (string.IsNullOrEmpty(path)) return false; + var pathRoot = Path.GetPathRoot(path); + if (string.IsNullOrEmpty(pathRoot)) return false; + + // Part 1 : try to delete share + var pinfo = new ProcessStartInfo("net", "use " + "\"" + path + "\"" + " /DELETE") + { + CreateNoWindow = true, + RedirectStandardOutput = true, + UseShellExecute = false + }; + using (var p = Process.Start(pinfo)) + { + if (p != null) { - if (p != null) - { - p.WaitForExit(200); - Log.Debug("UNCTools: CheckNetworkPath: try to connect share : {0}", path); - } + p.WaitForExit(200); + Log.Debug("UNCTools: CheckNetworkPath: try to delete share : {0}", path); } + } - // Part 3 : Analyse if share connected - pinfo = new ProcessStartInfo("net", "use") - { - CreateNoWindow = true, - RedirectStandardOutput = true, - UseShellExecute = false - }; - string output = null; - using (var p = Process.Start(pinfo)) + // Part 2 : try to add share + pinfo = new ProcessStartInfo("net", "use " + "\"" + path + "\"") + { + CreateNoWindow = true, + RedirectStandardOutput = true, + UseShellExecute = false + }; + using (var p = Process.Start(pinfo)) + { + if (p != null) { - if (p != null) - { - output = p.StandardOutput.ReadToEnd(); - p.WaitForExit(200); - } + p.WaitForExit(200); + Log.Debug("UNCTools: CheckNetworkPath: try to connect share : {0}", path); } - return output != null && output.Split('\n').Any(line => line.Contains(pathRoot) && line.StartsWith("OK")); } - //Method UNCCopyFile copies a remote file (strSourceFile) to the given strDestFile - public static void UNCCopyFile(string strSourceFile, string strDestFile) + // Part 3 : Analyse if share connected + pinfo = new ProcessStartInfo("net", "use") { - UNCCopyFile(strSourceFile, strDestFile, "Default"); + CreateNoWindow = true, + RedirectStandardOutput = true, + UseShellExecute = false + }; + string output = null; + using (var p = Process.Start(pinfo)) + { + if (p != null) + { + output = p.StandardOutput.ReadToEnd(); + p.WaitForExit(200); + } } + return output != null && output.Split('\n').Any(line => line.Contains(pathRoot) && line.StartsWith("OK")); + } - public static void UNCCopyFile(string strSourceFile, string strDestFile, string hostDetectMethod) + //Method UNCCopyFile copies a remote file (strSourceFile) to the given strDestFile + public static void UNCCopyFile(string strSourceFile, string strDestFile) + { + UNCCopyFile(strSourceFile, strDestFile, "Default"); + } + + public static void UNCCopyFile(string strSourceFile, string strDestFile, string hostDetectMethod) + { + // CopyDB + try { - // CopyDB - try + if (UNCFileFolderExists(strSourceFile, hostDetectMethod)) { - if (UNCFileFolderExists(strSourceFile, hostDetectMethod)) - { - //UNC host is online and file exists - File.Copy(strSourceFile, strDestFile, true); - Log.Info("UNCTools: UNCCopyFile: '{0}' to '{1}' ok!", strSourceFile, strDestFile); - } - else - { - //UNC host is offline or file doesnt exists - Log.Warn("UNCTools: UNCCopyFile: '{0}' DOESNT exists or host is offline! File copy skipped!", strSourceFile); - } + //UNC host is online and file exists + File.Copy(strSourceFile, strDestFile, true); + Log.Info("UNCTools: UNCCopyFile: '{0}' to '{1}' ok!", strSourceFile, strDestFile); } - catch (Exception ex) + else { - Log.Error("UNCTools: UNCCopyFile: exception on copy database: '{0}' to '{1}, ex:{2} stack:{3}", strSourceFile, - strDestFile, ex.Message, ex.StackTrace); + //UNC host is offline or file doesnt exists + Log.Warn("UNCTools: UNCCopyFile: '{0}' DOESNT exists or host is offline! File copy skipped!", strSourceFile); } } + catch (Exception ex) + { + Log.Error("UNCTools: UNCCopyFile: exception on copy database: '{0}' to '{1}, ex:{2} stack:{3}", strSourceFile, + strDestFile, ex.Message, ex.StackTrace); + } + } - #endregion + #endregion - #region Private functions + #region Private functions - /// - /// Pings an given hostname - /// - private static int PingHost(string strHost_or_IP, int iTimeoutMilliseonds, int iCount) - { - //int which returns the answered packages - int iAnswers = 0; + /// + /// Pings an given hostname + /// + private static int PingHost(string strHost_or_IP, int iTimeoutMilliseonds, int iCount) + { + //int which returns the answered packages + int iAnswers = 0; - //string to hold our return messge - string returnMessage = string.Empty; + //string to hold our return messge + string returnMessage = string.Empty; - //IPAddress instance for holding the returned host - IPAddress address = AsyncDNSReverseLookup(strHost_or_IP); + //IPAddress instance for holding the returned host + IPAddress address = AsyncDNSReverseLookup(strHost_or_IP); - //check if we have an ipaddress - if(string.IsNullOrEmpty(strHost_or_IP) || (address == null)) - { - Log.Debug("UNCTools: PingHost: Could not resolve/convert {0} to an IPAddress object!", strHost_or_IP); - return 0; - } + //check if we have an ipaddress + if (string.IsNullOrEmpty(strHost_or_IP) || (address == null)) + { + Log.Debug("UNCTools: PingHost: Could not resolve/convert {0} to an IPAddress object!", strHost_or_IP); + return 0; + } - //set the ping options, TTL 128 - PingOptions pingOptions = new PingOptions(128, true); + //set the ping options, TTL 128 + PingOptions pingOptions = new PingOptions(128, true); - //create a new ping instance - Ping ping = new Ping(); + //create a new ping instance + Ping ping = new Ping(); - //32 byte buffer (create empty) - byte[] buffer = new byte[32]; + //32 byte buffer (create empty) + byte[] buffer = new byte[32]; - //first make sure we actually have an internet connection - if (HasConnection()) + //first make sure we actually have an internet connection + if (HasConnection()) + { + //here we will ping the host 4 times (standard) + for (int i = 0; i < iCount; i++) + { + try + { + //send the ping 4 times to the host and record the returned data. + //The Send() method expects 4 items: + //1) The IPAddress we are pinging + //2) The timeout value + //3) A buffer (our byte array) + //4) PingOptions + PingReply pingReply = ping.Send(address, iTimeoutMilliseonds, buffer, pingOptions); + + //make sure we dont have a null reply + if (pingReply != null) { - //here we will ping the host 4 times (standard) - for (int i = 0; i < iCount; i++) - { - try - { - //send the ping 4 times to the host and record the returned data. - //The Send() method expects 4 items: - //1) The IPAddress we are pinging - //2) The timeout value - //3) A buffer (our byte array) - //4) PingOptions - PingReply pingReply = ping.Send(address, iTimeoutMilliseonds, buffer, pingOptions); - - //make sure we dont have a null reply - if (pingReply != null) - { - switch (pingReply.Status) - { - case IPStatus.Success: - //Log.Debug("UNCTools: PingHost: Reply from {0}: bytes={1} time={2}ms TTL={3}", pingReply.Address, pingReply.Buffer.Length, pingReply.RoundtripTime, pingReply.Options.Ttl); - iAnswers++; - break; - case IPStatus.TimedOut: - Log.Debug("UNCTools: PingHost: Connection has timed out..."); - break; - default: - Log.Debug("UNCTools: PingHost: Ping failed: {0}", pingReply.Status.ToString()); - break; - } - } - else - Log.Debug("UNCTools: PingHost: Connection failed for an unknown reason..."); - } - catch (PingException ex) - { - Log.Debug("UNCTools: PingHost: Connection Error: {0}", ex.Message); - } - catch (SocketException ex) - { - Log.Debug("UNCTools: PingHost: Connection Error: {0}", ex.Message); - } - } + switch (pingReply.Status) + { + case IPStatus.Success: + //Log.Debug("UNCTools: PingHost: Reply from {0}: bytes={1} time={2}ms TTL={3}", pingReply.Address, pingReply.Buffer.Length, pingReply.RoundtripTime, pingReply.Options.Ttl); + iAnswers++; + break; + case IPStatus.TimedOut: + Log.Debug("UNCTools: PingHost: Connection has timed out..."); + break; + default: + Log.Debug("UNCTools: PingHost: Ping failed: {0}", pingReply.Status.ToString()); + break; + } } else - Log.Debug("UNCTools: PingHost: No Internet connection found..."); - - //return the message - return iAnswers; + Log.Debug("UNCTools: PingHost: Connection failed for an unknown reason..."); + } + catch (PingException ex) + { + Log.Debug("UNCTools: PingHost: Connection Error: {0}", ex.Message); + } + catch (SocketException ex) + { + Log.Debug("UNCTools: PingHost: Connection Error: {0}", ex.Message); + } } + } + else + Log.Debug("UNCTools: PingHost: No Internet connection found..."); - /// - /// method for retrieving the IP address from the host/IP string provided - /// - /// the host/IP we need the IPAddress obj for - /// - private static IPAddress AsyncDNSReverseLookup(string strHost_or_IP) - { - var cts = new CancellationTokenSource(); - DateTime dt1; - double iTimeDiff = 0; + //return the message + return iAnswers; + } - //IPAddress instance for holding the returned host - IPAddress address = null; + /// + /// method for retrieving the IP address from the host/IP string provided + /// + /// the host/IP we need the IPAddress obj for + /// + private static IPAddress AsyncDNSReverseLookup(string strHost_or_IP) + { + var cts = new CancellationTokenSource(); + DateTime dt1; + double iTimeDiff = 0; - //try to get an ip address from the given string - if (!IPAddress.TryParse(strHost_or_IP, out address)) - { - //we have no IP address -> make an async dns reverse lookup - - //Start async dns reverse lookup - MP1-4967 TimeOut increased to 1500ms - try - { - var t1 = Task.Factory.StartNew(_ => DnsReverseLookup(strHost_or_IP), - TaskCreationOptions.AttachedToParent) - .TimeoutAfter(1500) - .ContinueWith(antecedent => - { - if (!(antecedent.IsCanceled || antecedent.IsFaulted)) - address = antecedent.Result; - } - , cts.Token); - - //Make Timestamp now - dt1 = DateTime.Now; - - t1.Wait(); - - //Calc needed milliseconds - iTimeDiff = (DateTime.Now - dt1).TotalMilliseconds; - } - catch (Exception ex) - { - Log.Debug("UNCTools: AsyncDNSReverseLookup: exception: {0}", ex.InnerException.Message); - } - } + //IPAddress instance for holding the returned host + IPAddress address = null; + //try to get an ip address from the given string + if (!IPAddress.TryParse(strHost_or_IP, out address)) + { + //we have no IP address -> make an async dns reverse lookup - //is the result ok? - if (address == null) - { - Log.Debug("UNCTools: AsyncDNSReverseLookup: dns reverse lookup timeout ({0} ms)!", iTimeDiff.ToString()); - } - else - { - Log.Debug("UNCTools: AsyncDNSReverseLookup: ip '{0}' resolved for host '{1}' in {2} ms", address.ToString(), strHost_or_IP, iTimeDiff.ToString()); - } - return address; + //Start async dns reverse lookup - MP1-4967 TimeOut increased to 1500ms + try + { + var t1 = Task.Factory.StartNew(_ => DnsReverseLookup(strHost_or_IP), + TaskCreationOptions.AttachedToParent) + .TimeoutAfter(1500) + .ContinueWith(antecedent => + { + if (!(antecedent.IsCanceled || antecedent.IsFaulted)) + address = antecedent.Result; + } + , cts.Token); + + //Make Timestamp now + dt1 = DateTime.Now; + + t1.Wait(); + + //Calc needed milliseconds + iTimeDiff = (DateTime.Now - dt1).TotalMilliseconds; } - - //DnsReverseLookup, makes a DnsReverseLookup, call this from a new task to make it faster - private static IPAddress DnsReverseLookup(string strHost) + catch (Exception ex) { - IPAddress ipAddressObj = null; - try - { - ipAddressObj = Dns.GetHostEntry(strHost).AddressList[0]; - } - catch - { - } - return ipAddressObj; + Log.Debug("UNCTools: AsyncDNSReverseLookup: exception: {0}", ex.InnerException.Message); } + } - /// - /// method to check the status of the pinging machines internet connection - /// - /// - private static bool HasConnection() - { - //instance of our ConnectionStatusEnum - ConnectionStatusEnum state = 0; - //call the API - InternetGetConnectedState(ref state, 0); + //is the result ok? + if (address == null) + { + Log.Debug("UNCTools: AsyncDNSReverseLookup: dns reverse lookup timeout ({0} ms)!", iTimeDiff.ToString()); + } + else + { + Log.Debug("UNCTools: AsyncDNSReverseLookup: ip '{0}' resolved for host '{1}' in {2} ms", address.ToString(), strHost_or_IP, iTimeDiff.ToString()); + } + return address; + } - //check the status, if not offline and the returned state - //isnt 0 then we have a connection - if (((int)ConnectionStatusEnum.INTERNET_CONNECTION_OFFLINE & (int)state) != 0) - { - //return true, we have a connection - return false; - } - //return false, no connection available - return true; - } + //DnsReverseLookup, makes a DnsReverseLookup, call this from a new task to make it faster + private static IPAddress DnsReverseLookup(string strHost) + { + IPAddress ipAddressObj = null; + try + { + ipAddressObj = Dns.GetHostEntry(strHost).AddressList[0]; + } + catch + { + } + return ipAddressObj; + } - private class IsPortOpen - { - public TcpClient Client { get; set; } - public bool Open { get; set; } - } + /// + /// method to check the status of the pinging machines internet connection + /// + /// + private static bool HasConnection() + { + //instance of our ConnectionStatusEnum + ConnectionStatusEnum state = 0; - private static void AsyncCallback(IAsyncResult asyncResult) - { - var state = (IsPortOpen)asyncResult.AsyncState; - TcpClient client = state.Client; + //call the API + InternetGetConnectedState(ref state, 0); - try - { - client.EndConnect(asyncResult); - } - catch - { - return; - } + //check the status, if not offline and the returned state + //isnt 0 then we have a connection + if (((int)ConnectionStatusEnum.INTERNET_CONNECTION_OFFLINE & (int)state) != 0) + { + //return true, we have a connection + return false; + } + //return false, no connection available + return true; + } - if (client.Connected && state.Open) - { - return; - } + private class IsPortOpen + { + public TcpClient Client { get; set; } + public bool Open { get; set; } + } - client.Close(); - } + private static void AsyncCallback(IAsyncResult asyncResult) + { + var state = (IsPortOpen)asyncResult.AsyncState; + TcpClient client = state.Client; - public static bool CheckNetworkHost(string hostname, int port, int timeout = 5000) - { - if (string.IsNullOrEmpty(hostname)) - { - return false; - } + try + { + client.EndConnect(asyncResult); + } + catch + { + return; + } - if (port == 0) - { - return false; - } + if (client.Connected && state.Open) + { + return; + } - try - { - Uri uri = new Uri(hostname); - IPHostEntry host = Dns.GetHostEntry(uri.Host); - IPAddress address = host.AddressList[0]; + client.Close(); + } - var state = new IsPortOpen - { - Client = new TcpClient(), - Open = true - }; + public static bool CheckNetworkHost(string hostname, int port, int timeout = 5000) + { + if (string.IsNullOrEmpty(hostname)) + { + return false; + } - IAsyncResult ar = state.Client.BeginConnect(address, port, AsyncCallback, state); - state.Open = ar.AsyncWaitHandle.WaitOne(timeout, false); + if (port == 0) + { + return false; + } - if (state.Open == false || state.Client.Connected == false) - { - Log.Debug("UNCTools: CheckNetworkHost: Connection {0}:{1} Error", hostname, port); - return false; - } - return true; - } - catch (Exception ex) - { - Log.Debug("UNCTools: CheckNetworkHost: Connection {0}:{1} Error: {2}", hostname, port, ex.Message); - } + try + { + Uri uri = new Uri(hostname); + IPHostEntry host = Dns.GetHostEntry(uri.Host); + IPAddress address = host.AddressList[0]; + + var state = new IsPortOpen + { + Client = new TcpClient(), + Open = true + }; + + IAsyncResult ar = state.Client.BeginConnect(address, port, AsyncCallback, state); + state.Open = ar.AsyncWaitHandle.WaitOne(timeout, false); + + if (state.Open == false || state.Client.Connected == false) + { + Log.Debug("UNCTools: CheckNetworkHost: Connection {0}:{1} Error", hostname, port); return false; } + return true; + } + catch (Exception ex) + { + Log.Debug("UNCTools: CheckNetworkHost: Connection {0}:{1} Error: {2}", hostname, port, ex.Message); + } + return false; + } - #endregion + #endregion - } -} + } +} \ No newline at end of file