/// <summary> /// Creates an instance of <see cref="DirectoryMembershipFingerprintResult"/>. /// </summary> public DirectoryMembershipFingerprintResult( DirectoryMembershipTrackingFingerprint fingerprint, PathExistence pathExistence, int memberCount) { Fingerprint = fingerprint; PathExistence = pathExistence; MemberCount = memberCount; }
/// <summary> /// Computes fingerprint. /// </summary> public static Possible <DirectoryMembershipFingerprintResult> ComputeFingerprint( string path, Action <string, FileAttributes> handleEntry = null, Func <string, FileAttributes, bool> shouldIncludeEntry = null) { Contract.Requires(!string.IsNullOrWhiteSpace(path)); var calculator = DirectoryMembershipTrackingFingerprint.CreateCalculator(); int memberCount = 0; EnumerateDirectoryResult enumResult = FileUtilities.EnumerateDirectoryEntries( path, (entryName, entryAttributes) => { if (shouldIncludeEntry?.Invoke(entryName, entryAttributes) ?? true) { calculator = calculator.Accumulate(entryName, entryAttributes); memberCount++; handleEntry?.Invoke(entryName, entryAttributes); } }); DirectoryMembershipTrackingFingerprint fingerprint = calculator.GetFingerprint(); var existence = PathExistence.Nonexistent; bool enumerationSucceeded = true; switch (enumResult.Status) { case EnumerateDirectoryStatus.Success: existence = PathExistence.ExistsAsDirectory; break; case EnumerateDirectoryStatus.CannotEnumerateFile: // We return an empty fingerprint for a path without children, even if that is because // the directory path was to a 'leaf' node (file). Contract.Assume(fingerprint == DirectoryMembershipTrackingFingerprint.Zero); existence = PathExistence.ExistsAsFile; break; case EnumerateDirectoryStatus.SearchDirectoryNotFound: // The directory is expected to exist because we have a handle. // But that handle may be for a symlink to a non-existent directory. // Thus, directory enumeration results in directory not found. var possibleExistence = HandleSearchDirectoryNotFoundOnDirectoryEnumerationForFingerprinting(path); if (possibleExistence.Succeeded) { existence = possibleExistence.Result; } fingerprint = DirectoryMembershipTrackingFingerprint.Absent; break; case EnumerateDirectoryStatus.AccessDenied: case EnumerateDirectoryStatus.UnknownError: enumerationSucceeded = false; break; default: throw Contract.AssertFailure("Unhandled EnumerateDirectoryStatus"); } if (!enumerationSucceeded) { return(new Failure <EnumerateDirectoryStatus>(enumResult.Status).Annotate( "Failed to enumerate a directory (unexpected since a read-access handle to it was just opened; was there a rename?)")); } return(new DirectoryMembershipFingerprintResult(fingerprint, existence, memberCount)); }