Example #1
0
 /// <summary>
 /// Creates an instance of <see cref="DirectoryMembershipFingerprintResult"/>.
 /// </summary>
 public DirectoryMembershipFingerprintResult(
     DirectoryMembershipTrackingFingerprint fingerprint,
     PathExistence pathExistence,
     int memberCount)
 {
     Fingerprint   = fingerprint;
     PathExistence = pathExistence;
     MemberCount   = memberCount;
 }
Example #2
0
        /// <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));
        }