/// <summary> /// Gets link impact. /// </summary> internal static LinkImpact LinkImpact(this UsnChangeReasons reasons) { const UsnChangeReasons AllLinkChangeReasons = UsnChangeReasons.FileDelete | // Only caused by deletion of the last link, so let's be thrifty and claim 'all links' affected. UsnChangeReasons.DataExtend | UsnChangeReasons.DataOverwrite | UsnChangeReasons.DataTruncation | UsnChangeReasons.StreamChange | UsnChangeReasons.ReparsePointChange; const UsnChangeReasons SingleLinkChangeReasons = UsnChangeReasons.HardLinkChange | // This is a deletion or creation of a link (other than the last). UsnChangeReasons.RenameOldName; if ((reasons & AllLinkChangeReasons) != 0) { return(ChangeTracking.LinkImpact.AllLinks); } if ((reasons & SingleLinkChangeReasons) != 0) { return(ChangeTracking.LinkImpact.SingleLink); } return(ChangeTracking.LinkImpact.None); }
/// <summary> /// Creates a UsnRecord /// </summary> public UsnRecord(FileId file, FileId container, Usn usn, UsnChangeReasons reasons) { FileId = file; ContainerFileId = container; Usn = usn; Reason = reasons; }
private void ExpectChangesSinceUsn( UsnChangeReasons expectedChangeReasons, SafeFileHandle volumeHandle, Usn startUsn, FileId fileId, out Usn nextUsn, TimeSpan?timeLimit = default(TimeSpan?)) { const int DefaultTimeLimitForScanningInSecond = 30; // 30 sec for scanning. QueryUsnJournalData journalState = QueryJournal(volumeHandle); byte[] buffer = new byte[64 * 1024]; // 655 records per read. timeLimit = timeLimit.HasValue ? timeLimit : TimeSpan.FromSeconds(DefaultTimeLimitForScanningInSecond); var stopWatch = System.Diagnostics.Stopwatch.StartNew(); UsnChangeReasons foundChangeReasons = 0; nextUsn = startUsn; while (true) { if (stopWatch.ElapsedTicks > timeLimit.Value.Ticks) { break; } ReadUsnJournalResult result = FileUtilities.TryReadUsnJournal( volumeHandle, buffer, journalState.UsnJournalId, startUsn); nextUsn = result.NextUsn; if (!result.Succeeded) { break; } if (result.Records.Count == 0) { break; } foundChangeReasons |= UsnJournalUtilities.GetAggregateChangeReasons(fileId, result.Records); if (expectedChangeReasons == (foundChangeReasons & expectedChangeReasons)) { // Found all expected change reasons. return; } startUsn = result.NextUsn; } XAssert.AreEqual(expectedChangeReasons, foundChangeReasons & expectedChangeReasons); }
/// <summary> /// Gets membership impacts. /// </summary> internal static MembershipImpact MembershipImpact(this UsnChangeReasons reasons) { const UsnChangeReasons CreationReasons = UsnChangeReasons.FileCreate | UsnChangeReasons.RenameNewName | UsnChangeReasons.HardLinkChange; // Can be either a creation or deletion const UsnChangeReasons DeletionReasons = UsnChangeReasons.FileDelete | UsnChangeReasons.RenameOldName | UsnChangeReasons.HardLinkChange; // Can be either a creation or deletion return(((reasons & CreationReasons) != 0 ? ChangeTracking.MembershipImpact.Creation : ChangeTracking.MembershipImpact.None) | ((reasons & DeletionReasons) != 0 ? ChangeTracking.MembershipImpact.Deletion : ChangeTracking.MembershipImpact.None)); }
public static UsnChangeReasons GetAggregateChangeReasons( FileId fileFilter, IEnumerable <UsnRecord> records) { UsnChangeReasons reasons = default(UsnChangeReasons); foreach (UsnRecord record in records) { if (fileFilter == record.FileId) { reasons |= record.Reason; } } return(reasons); }
public void ReadChangesToFile() { string path = GetFullPath("File"); WithVolumeHandle( volumeHandle => { Usn initialUsn = QueryJournal(volumeHandle).NextUsn; FileId fileId; using (FileStream file = File.Create(path)) { fileId = FileUtilities.ReadFileUsnByHandle(file.SafeFileHandle).Value.FileId; file.WriteByte(1); } const UsnChangeReasons ExpectedCreationChangeReasons = UsnChangeReasons.FileCreate | UsnChangeReasons.DataExtend | UsnChangeReasons.Close; Usn nextUsn; ExpectChangesSinceUsn(ExpectedCreationChangeReasons, volumeHandle, initialUsn, fileId, out nextUsn); using (FileStream file = File.OpenWrite(path)) { file.WriteByte(1); } File.SetAttributes(path, FileAttributes.Normal | FileAttributes.ReadOnly); const UsnChangeReasons ExpectedModificationChangeReasons = UsnChangeReasons.DataOverwrite | UsnChangeReasons.BasicInfoChange | UsnChangeReasons.Close; ExpectChangesSinceUsn(ExpectedModificationChangeReasons, volumeHandle, nextUsn, fileId, out nextUsn); }); }