internal static bool IsDirectoryAccessibleMountPoint(string path, out Exception exception) { if (!MountPointUtil.IsDirectoryMountPoint(path, out exception)) { return(false); } exception = null; try { Directory.GetDirectories(path); } catch (IOException ex) { exception = ex; } catch (UnauthorizedAccessException ex2) { exception = ex2; } catch (SecurityException ex3) { exception = ex3; } return(exception == null); }
public MountedFolderPath(string mountedFolderPath) : this() { if (!string.IsNullOrEmpty(mountedFolderPath)) { this.m_mountedFolderPathRaw = mountedFolderPath; this.m_mountedFolderPath = MountPointUtil.EnsurePathHasTrailingBackSlash(mountedFolderPath); } }
internal static NativeMethods.WIN32_FIND_DATA GetExtendedNonRootDirectoryInfo(string path, out Exception exception) { exception = null; NativeMethods.WIN32_FIND_DATA win32_FIND_DATA = default(NativeMethods.WIN32_FIND_DATA); DirectoryInfo di = null; exception = MountPointUtil.HandleIOExceptions(delegate { di = new DirectoryInfo(path); }); if (exception != null) { return(win32_FIND_DATA); } if (!di.Exists) { exception = new DirectoryNotFoundException(); return(win32_FIND_DATA); } if (di.Parent == null) { DiagCore.RetailAssert(false, "An invalid root path was passed in: {0}", new object[] { path }); exception = new IOException(string.Format("An invalid root path was passed in: {0}", path)); return(win32_FIND_DATA); } NativeMethods.WIN32_FIND_DATA result; using (DirectoryEnumerator dirEnum = new DirectoryEnumerator(di.Parent, false, false)) { bool foundNext = false; NativeMethods.WIN32_FIND_DATA tempFindData = default(NativeMethods.WIN32_FIND_DATA); string dirName; exception = MountPointUtil.HandleIOExceptions(delegate { foundNext = dirEnum.GetNextDirectoryExtendedInfo(di.Name, out dirName, out tempFindData); }); if (exception != null) { result = win32_FIND_DATA; } else if (!foundNext) { exception = new DirectoryNotFoundException(); result = win32_FIND_DATA; } else { exception = null; result = tempFindData; } } return(result); }
internal static bool IsDirectoryMountPoint(string path, out Exception exception) { exception = null; DirectoryInfo di = null; exception = MountPointUtil.HandleIOExceptions(delegate { di = new DirectoryInfo(path); }); if (exception != null) { return(false); } if (!di.Exists) { return(false); } if (!BitMasker.IsOn((int)di.Attributes, 1024)) { return(false); } if (di.Parent == null) { return(false); } using (DirectoryEnumerator dirEnum = new DirectoryEnumerator(di.Parent, false, false)) { NativeMethods.WIN32_FIND_DATA findData = default(NativeMethods.WIN32_FIND_DATA); bool foundNext = false; string dirName; exception = MountPointUtil.HandleIOExceptions(delegate { foundNext = dirEnum.GetNextDirectoryExtendedInfo(di.Name, out dirName, out findData); }); if (exception != null) { return(false); } if (!foundNext) { return(false); } if (findData.Reserved0 == 2684354563U) { return(true); } } return(false); }
public static string GetVolumeLabel(MountedFolderPath volumeName, out Exception exception) { MountPointUtil.Tracer.TraceDebug <string>(0L, "GetVolumeLabel(): Entering... [ volumeName= {0} ]", volumeName.Path); exception = null; int volumeNameSize = 1024; StringBuilder stringBuilder; exception = MountPointUtil.GetVolumeInformation(volumeName.Path, out stringBuilder, volumeNameSize); if (exception != null) { MountPointUtil.Tracer.TraceError <string, Exception>(0L, "GetVolumeLabel() for volumeName '{0}' failed with error: {1}", volumeName.Path, exception); return(null); } return(stringBuilder.ToString()); }
internal static bool IsDirectoryNonExistentOrEmpty(string directory, out Exception exception) { DirectoryInfo di = null; exception = MountPointUtil.HandleIOExceptions(delegate { di = new DirectoryInfo(directory); }); if (exception != null) { MountPointUtil.Tracer.TraceError <string, Exception>(0L, "IsDirectoryNonExistentOrEmpty(): Failed to construct DirectoryInfo for directory '{0}'. Exception: {1}", directory, exception); return(false); } if (!di.Exists) { MountPointUtil.Tracer.TraceDebug <string>(0L, "IsDirectoryNonExistentOrEmpty(): Directory '{0}' is not present. Returning true.", directory); return(true); } bool result; using (DirectoryEnumerator dirEnum = new DirectoryEnumerator(di, false, false)) { int count = 0; exception = MountPointUtil.HandleIOExceptions(delegate { count = dirEnum.EnumerateFilesAndDirectoriesExcludingHiddenAndSystem("*").Count <string>(); }); if (exception != null) { MountPointUtil.Tracer.TraceError <string, Exception>(0L, "IsDirectoryNonExistentOrEmpty(): Failed to enumerate files/directories for directory '{0}'. Exception: {1}", directory, exception); result = false; } else if (count > 0) { MountPointUtil.Tracer.TraceDebug <string, int>(0L, "IsDirectoryNonExistentOrEmpty(): Directory '{0}' has {1} files and/or directories. Returning false.", directory, count); result = false; } else { MountPointUtil.Tracer.TraceDebug <string, int>(0L, "IsDirectoryNonExistentOrEmpty(): Directory '{0}' has 0 files and/or directories. Returning true.", directory, count); result = true; } } return(result); }
internal static bool DoesContainAnyFiles(string directory, bool recurse, out Exception exception) { bool foundFiles = false; exception = MountPointUtil.HandleIOExceptions(delegate { DirectoryInfo path = new DirectoryInfo(directory); using (DirectoryEnumerator directoryEnumerator = new DirectoryEnumerator(path, recurse, false)) { IEnumerable <string> source = directoryEnumerator.EnumerateFiles("*", DirectoryEnumerator.ExcludeHiddenAndSystemFilter); if (source.Any <string>()) { foundFiles = true; } } }); return(foundFiles); }
internal static bool IsPathDirectlyUnderParentPath(string path, string parentPath, out Exception exception) { exception = null; DirectoryInfo di = null; exception = MountPointUtil.HandleIOExceptions(delegate { di = new DirectoryInfo(path); }); if (exception != null) { MountPointUtil.Tracer.TraceError <string, Exception>(0L, "IsPathDirectlyUnderParentPath() : DirectoryInfo..ctor() on path '{0}' failed with exception: {1}", path, exception); return(false); } if (di.Parent == null) { MountPointUtil.Tracer.TraceDebug <string>(0L, "IsPathDirectlyUnderParentPath() : Path '{0}' is a root path. Returning false.", path); return(false); } return(string.Equals(parentPath, di.Parent.FullName, StringComparison.OrdinalIgnoreCase)); }
// Token: 0x060015A9 RID: 5545 RVA: 0x0005610C File Offset: 0x0005430C public VolumeSpareStatus GetSpareStatus(out Exception exception) { exception = null; ExchangeVolume.Tracer.TraceDebug <MountedFolderPath>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Computing status of volume '{0}'.", this.VolumeName); if (!this.IsValid) { ExchangeVolume.Tracer.TraceError <DatabaseVolumeInfoException>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Returning Error because the ExchangeVolume instance is invalid. Error: {0}", this.LastException); exception = this.LastException; return(VolumeSpareStatus.Error); } if (!this.IsExchangeVolume || !this.IsAvailableAsSpare || this.DatabaseMountPoints.Length != 0) { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Returning Volume '{0}' is NotUsableAsSpare.", this.VolumeName); return(VolumeSpareStatus.NotUsableAsSpare); } ExchangeVolume.Tracer.TraceDebug((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Found a potential spare volume..."); MountedFolderPath exchangeVolumeMountPoint = this.ExchangeVolumeMountPoint; if (MountPointUtil.IsDirectoryNonExistentOrEmpty(exchangeVolumeMountPoint.Path, out exception)) { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Returning Volume '{0}' is EmptySpare.", this.VolumeName); bool flag = BitlockerUtil.IsVolumeMountedOnVirtualDisk(this.VolumeName.Path, out exception); if (exception != null) { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, Exception>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Exception finding whether Volume '{0}' is mounted on a virtual disk or not. Reason {1}", this.VolumeName, exception); } if (!flag) { bool flag2 = false; bool flag3 = false; exception = BitlockerUtil.IsVolumeEncryptedOrEncrypting(this.VolumeName.Path, out flag2, out flag3); if (exception != null) { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, Exception>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Exception finding whether Volume '{0}' is encrypting or not. Reason {1}", this.VolumeName, exception); } else { if (flag2) { return(VolumeSpareStatus.EncryptingEmptySpare); } if (flag3) { return(VolumeSpareStatus.EncryptedEmptySpare); } string arg; string arg2; bool flag4 = BitlockerUtil.IsEncryptionPausedDueToBadBlocks(this.VolumeName.Path, out exception, out arg, out arg2); if (exception != null) { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, Exception>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Exception finding whether Volume '{0}' has encryption paused due to bad blocks. Reason {1}", this.VolumeName, exception); return(VolumeSpareStatus.Error); } if (flag4) { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, string, string>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Returning Volume '{0}' is Qurantined due to encryption paused due to bad blocks. Mount point {1}. Event Xml {2}", this.VolumeName, arg, arg2); return(VolumeSpareStatus.Quarantined); } } } else { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Volume mounted on virtual disk. Not attempting to find bitlocker spare status", this.VolumeName); } return(VolumeSpareStatus.UnEncryptedEmptySpare); } int num = 0; if (exception == null || FileOperations.IsCorruptedIOException((IOException)exception, out num)) { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, string>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Returning Volume '{0}' is Quarantined because it has some files/directories under mountPath '{1}'.", this.VolumeName, exchangeVolumeMountPoint.Path); return(VolumeSpareStatus.Quarantined); } ExchangeVolume.Tracer.TraceError <string, Exception>((long)this.GetHashCode(), "ExchangeVolume.GetSpareStatus(): Returning Error because IsDirectoryNonExistentOrEmpty() returned exception for mountPath '{0}'. Exception: {1}", exchangeVolumeMountPoint.Path, exception); return(VolumeSpareStatus.Error); }
// Token: 0x060015A8 RID: 5544 RVA: 0x00055CBC File Offset: 0x00053EBC public void Refresh() { Exception ex = null; this.Init(); DriveType driveType = NativeMethods.GetDriveType(this.VolumeName.Path); this.DriveType = driveType; if (this.DriveType != DriveType.Fixed) { ExchangeVolume.Tracer.TraceError <MountedFolderPath, DriveType>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): Volume is not a Fixed DriveType. Actual: {1}", this.VolumeName, this.DriveType); this.IsValid = true; return; } string volumeLabel = MountPointUtil.GetVolumeLabel(this.VolumeName, out ex); if (ex != null) { ExchangeVolume.Tracer.TraceError <MountedFolderPath, Exception>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): Could not retrieve volume label. Error - ", this.VolumeName, ex); ex = null; } else { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, string>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): Volume has a label '{1}'.", this.VolumeName, volumeLabel); this.VolumeLabel = volumeLabel; } MountedFolderPath[] volumePathNamesForVolumeName = MountPointUtil.GetVolumePathNamesForVolumeName(this.VolumeName, out ex); if (ex != null) { ExchangeVolume.Tracer.TraceError <MountedFolderPath, Exception>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): GetVolumePathNamesForVolumeName() failed with error: {1}", this.VolumeName, ex); this.LastException = new ExchangeVolumeInfoInitException(this.VolumeName.Path, ex.Message, ex); return; } this.MountPoints = volumePathNamesForVolumeName; MountedFolderPath[] array = (from mp in volumePathNamesForVolumeName where MountPointUtil.IsPathDirectlyUnderParentPath(mp.Path, this.ExchangeVolumesRootPath, out ex) && ex == null select mp).ToArray <MountedFolderPath>(); if (ex != null) { ExchangeVolume.Tracer.TraceError <MountedFolderPath, Exception>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): IsPathDirectlyUnderParentPath() for ExchangeVolumeMountPoints failed with error: {1}", this.VolumeName, ex); this.LastException = new ExchangeVolumeInfoInitException(this.VolumeName.Path, ex.Message, ex); return; } int num = array.Length; if (num > 0) { this.IsExchangeVolume = true; this.ExchangeVolumeMountPoint = array[0]; if (num > 1) { string text = string.Join(", ", from mp in array select mp.Path); ExchangeVolume.Tracer.TraceError <MountedFolderPath, string, string>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): Multiple mount points found under '{1}': {2}", this.VolumeName, this.ExchangeVolumesRootPath, text); this.LastException = new ExchangeVolumeInfoMultipleExMountPointsException(this.VolumeName.Path, this.ExchangeVolumesRootPath, text); return; } } MountedFolderPath[] array2 = (from mp in volumePathNamesForVolumeName where MountPointUtil.IsPathDirectlyUnderParentPath(mp.Path, this.DatabasesRootPath, out ex) && ex == null orderby mp select mp).ToArray <MountedFolderPath>(); if (ex != null) { ExchangeVolume.Tracer.TraceError <MountedFolderPath, Exception>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): IsPathDirectlyUnderParentPath() for DatabaseMountPoints failed with error: {1}", this.VolumeName, ex); this.LastException = new ExchangeVolumeInfoInitException(this.VolumeName.Path, ex.Message, ex); return; } int num2 = array2.Length; if (num2 < this.NumDbsPerVolume) { if (this.IsExchangeVolume) { Exception ex2; VolumeSpareStatus spareStatus = this.GetSpareStatus(out ex2); if (spareStatus == VolumeSpareStatus.EncryptingEmptySpare && ex2 == null) { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, int, int>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): Volume has {1} Database mount points. It should have {2}. But volume is getting Encrypted. Not setting as spare.", this.VolumeName, num2, this.NumDbsPerVolume); this.IsAvailableAsSpare = false; } else { ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, int, int>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): Volume has {1} Database mount points. It should have {2}. Setting as spare.", this.VolumeName, num2, this.NumDbsPerVolume); this.IsAvailableAsSpare = true; } } } else { if (num2 > this.NumDbsPerVolume) { string text2 = string.Join(", ", from mp in array2 select mp.Path); ExchangeVolume.Tracer.TraceError((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): Volume has {1} Database mount points, but should only have MAX of {2}: {3}", new object[] { this.VolumeName, num2, this.NumDbsPerVolume, text2 }); this.LastException = new ExchangeVolumeInfoMultipleDbMountPointsException(this.VolumeName.Path, this.DatabasesRootPath, text2, this.NumDbsPerVolume); return; } ExchangeVolume.Tracer.TraceDebug <MountedFolderPath, int>((long)this.GetHashCode(), "ExchangeVolume.GetInstance( {0} ): Volume has expected {1} Database mount points.", this.VolumeName, num2); } this.DatabaseMountPoints = array2; this.IsValid = true; }
// Token: 0x06001589 RID: 5513 RVA: 0x00055818 File Offset: 0x00053A18 public static DatabaseVolumeInfo GetInstance(string edbPath, string logPath, string databaseName, string autoDagVolumesRootFolderPath, string autoDagDatabasesRootFolderPath, int autoDagDatabaseCopiesPerVolume) { Exception ex = null; DatabaseVolumeInfo databaseVolumeInfo = new DatabaseVolumeInfo(); MountedFolderPath volumePathName = MountPointUtil.GetVolumePathName(edbPath, out ex); if (ex != null) { DatabaseVolumeInfo.Tracer.TraceError <string, string, Exception>(0L, "DatabaseVolumeInfo.GetInstance( {0} ): GetVolumePathName() for EDB path '{1}' failed with error: {2}", databaseName, edbPath, ex); databaseVolumeInfo.LastException = new DatabaseVolumeInfoInitException(databaseName, ex.Message, ex); return(databaseVolumeInfo); } databaseVolumeInfo.DatabaseVolumeMountPoint = volumePathName; MountedFolderPath volumeNameForVolumeMountPoint = MountPointUtil.GetVolumeNameForVolumeMountPoint(volumePathName, out ex); if (ex != null) { DatabaseVolumeInfo.Tracer.TraceError <string, MountedFolderPath, Exception>(0L, "DatabaseVolumeInfo.GetInstance( {0} ): GetVolumeNameForVolumeMountPoint() for EDB mount point '{1}' failed with error: {2}", databaseName, volumePathName, ex); databaseVolumeInfo.LastException = new DatabaseVolumeInfoInitException(databaseName, ex.Message, ex); return(databaseVolumeInfo); } databaseVolumeInfo.DatabaseVolumeName = volumeNameForVolumeMountPoint; bool isDatabasePathOnMountedFolder = MountPointUtil.IsDirectoryMountPoint(volumePathName.Path, out ex); if (ex != null) { DatabaseVolumeInfo.Tracer.TraceError <string, MountedFolderPath, Exception>(0L, "DatabaseVolumeInfo.GetInstance( {0} ): IsDirectoryMountPoint() for EDB mount point '{1}' failed with error: {2}", databaseName, volumePathName, ex); databaseVolumeInfo.LastException = new DatabaseVolumeInfoInitException(databaseName, ex.Message, ex); return(databaseVolumeInfo); } databaseVolumeInfo.IsDatabasePathOnMountedFolder = isDatabasePathOnMountedFolder; MountedFolderPath volumePathName2 = MountPointUtil.GetVolumePathName(logPath, out ex); if (ex != null) { DatabaseVolumeInfo.Tracer.TraceError <string, string, Exception>(0L, "DatabaseVolumeInfo.GetInstance( {0} ): GetVolumePathName() for LOG path '{1}' failed with error: {2}", databaseName, logPath, ex); databaseVolumeInfo.LastException = new DatabaseVolumeInfoInitException(databaseName, ex.Message, ex); return(databaseVolumeInfo); } databaseVolumeInfo.LogVolumeMountPoint = volumePathName2; MountedFolderPath volumeNameForVolumeMountPoint2 = MountPointUtil.GetVolumeNameForVolumeMountPoint(volumePathName2, out ex); if (ex != null) { DatabaseVolumeInfo.Tracer.TraceError <string, MountedFolderPath, Exception>(0L, "DatabaseVolumeInfo.GetInstance( {0} ): GetVolumeNameForVolumeMountPoint() for LOG mount point '{1}' failed with error: {2}", databaseName, volumePathName2, ex); databaseVolumeInfo.LastException = new DatabaseVolumeInfoInitException(databaseName, ex.Message, ex); return(databaseVolumeInfo); } databaseVolumeInfo.LogVolumeName = volumeNameForVolumeMountPoint2; bool isLogPathOnMountedFolder = MountPointUtil.IsDirectoryMountPoint(volumePathName2.Path, out ex); if (ex != null) { DatabaseVolumeInfo.Tracer.TraceError <string, MountedFolderPath, Exception>(0L, "DatabaseVolumeInfo.GetInstance( {0} ): IsDirectoryMountPoint() for LOG mount point '{1}' failed with error: {2}", databaseName, volumePathName2, ex); databaseVolumeInfo.LastException = new DatabaseVolumeInfoInitException(databaseName, ex.Message, ex); return(databaseVolumeInfo); } databaseVolumeInfo.IsLogPathOnMountedFolder = isLogPathOnMountedFolder; if (!string.IsNullOrEmpty(autoDagVolumesRootFolderPath) && !string.IsNullOrEmpty(autoDagDatabasesRootFolderPath)) { ExchangeVolume instance = ExchangeVolume.GetInstance(volumeNameForVolumeMountPoint, autoDagVolumesRootFolderPath, autoDagDatabasesRootFolderPath, autoDagDatabaseCopiesPerVolume); if (instance.IsValid) { databaseVolumeInfo.ExchangeVolumeMountPoint = (instance.ExchangeVolumeMountPoint ?? MountedFolderPath.Empty); databaseVolumeInfo.IsExchangeVolumeMountPointValid = !MountedFolderPath.IsNullOrEmpty(databaseVolumeInfo.ExchangeVolumeMountPoint); } } databaseVolumeInfo.IsValid = true; return(databaseVolumeInfo); }
internal static DateTime GetLastWriteTimeUtcInDirectory(string directory, bool recurse, out string lastWriteTimePath, out Exception exception) { DateTime dateTime = DateTime.MaxValue; lastWriteTimePath = string.Empty; DirectoryInfo di = null; exception = MountPointUtil.HandleIOExceptions(delegate { di = new DirectoryInfo(directory); }); if (exception != null) { MountPointUtil.Tracer.TraceError <string, Exception>(0L, "GetLastWriteTimeUtcOfFilesInDirectory(): Failed to construct DirectoryInfo for directory '{0}'. Exception: {1}", directory, exception); return(dateTime); } if (!di.Exists) { MountPointUtil.Tracer.TraceError <string>(0L, "GetLastWriteTimeUtcOfFilesInDirectory(): Directory '{0}' is not present.", directory); return(dateTime); } string maxTimePath = string.Empty; DateTime maxTime = DateTime.MinValue; using (DirectoryEnumerator dirEnum = new DirectoryEnumerator(di, recurse, false)) { Exception tempEx = null; DateTime currentTime; exception = MountPointUtil.HandleIOExceptions(delegate { IEnumerable <string> enumerable = dirEnum.EnumerateFilesAndDirectoriesExcludingHiddenAndSystem("*"); foreach (string text in enumerable) { NativeMethods.WIN32_FILE_ATTRIBUTE_DATA fileAttributesEx = FileOperations.GetFileAttributesEx(text, out tempEx); if (tempEx != null) { MountPointUtil.Tracer.TraceError <string, Exception>(0L, "GetLastWriteTimeUtcOfFilesInDirectory(): GetFileAttributesEx() FAILED for '{0}'. Exception: {1}", text, tempEx); break; } currentTime = DateTimeHelper.FromFileTimeUtc(fileAttributesEx.LastWriteTime); if (currentTime > maxTime) { maxTime = currentTime; maxTimePath = text; } } }); if (exception == null) { exception = tempEx; } } if (exception != null) { MountPointUtil.Tracer.TraceError <string, Exception>(0L, "GetLastWriteTimeUtcOfFilesInDirectory(): FAILED for directory '{0}'. Exception: {1}", directory, exception); return(dateTime); } if (maxTime > DateTime.MinValue) { dateTime = maxTime; lastWriteTimePath = maxTimePath; } MountPointUtil.Tracer.TraceDebug <string, DateTime, string>(0L, "GetLastWriteTimeUtcOfFilesInDirectory() for directory '{0}' returning '{1}' for file '{2}'", directory, dateTime, lastWriteTimePath); return(dateTime); }