Exemple #1
0
 public void Delete(CompressedFileRecord objRecord)
 {
     if (objRecord != null)
     {
         if (SortedRecords.ContainsKey(objRecord) == true)
         {
             SortedRecords[objRecord] = CompressedFileRecordState.Deleted;
         }
     }
 }
Exemple #2
0
        public bool Exists(CompressedFileRecord objRecord)
        {
            bool blnExists = false;

            if (objRecord != null)
            {
                blnExists = SortedRecords.ContainsKey(objRecord);
            }

            return(blnExists);
        }
Exemple #3
0
        /// <summary>
        /// Calculates the full path of each entry in the USN table
        /// </summary>
        /// <param name="records">The list of records with local names</param>
        /// <returns>A list of USN entries with full path</returns>
        private List <Record> ResolveFullPaths(ICollection <Record> records)
        {
            // initialize file ref-nr (FRN) to path/parent-FRN look-up table
            var cache = new Dictionary <ulong, SortedRecords>();

            foreach (var rec in records)
            {
                if (rec.UsnRecord.FileAttributes.HasFlag(Win32USN.FileAttributes.Directory))
                {
                    if (!cache.TryGetValue(rec.UsnRecord.FileReferenceNumber, out var e))
                    {
                        e = new SortedRecords();
                        cache.Add(rec.UsnRecord.FileReferenceNumber, e);
                    }

                    e.Add(rec);
                }
            }

            // iterate through USN records
            var result = new List <Record>();

            foreach (var rec in records)
            {
                var pathList = new LinkedList <Record>();
                pathList.AddFirst(rec);

                // walk back up the chain as far as we can go
                var cur = rec;
                while (true)
                {
                    var parentRefNr = cur.UsnRecord.ParentFileReferenceNumber;
                    if (parentRefNr == m_volumeRootRefNumber)
                    {
                        break; // done
                    }
                    if (!cache.TryGetValue(parentRefNr, out var parents))
                    {
                        // parent FRN not found in look-up table, fetch it from change journal
                        var parentRecord = GetRecordByFileRef(parentRefNr);
                        parents = new SortedRecords(new List <Record> {
                            parentRecord
                        });
                        cache.Add(parentRefNr, parents);
                    }

                    // take parent entry having next smaller USN
                    var parent = parents.GetParentOf(cur);
                    if (parent == null)
                    {
                        throw new UsnJournalSoftFailureException(Strings.USNHelper.PathResolveError);
                    }

                    pathList.AddFirst(parent);

                    cur = parent;
                }

                // generate full path
                Debug.Assert(m_volume != null, nameof(m_volume) + " != null");
                var path = m_volume;
                foreach (var r in pathList)
                {
                    path = System.IO.Path.Combine(path, r.FileName);
                }

                if (rec.UsnRecord.FileAttributes.HasFlag(Win32USN.FileAttributes.Directory))
                {
                    path = Utility.Utility.AppendDirSeparator(path);
                }

                // set resolved path
                rec.FullPath = path;
                result.Add(rec);
            }

            return(result);
        }
Exemple #4
0
        /// <summary>
        /// Calculates the full path of each entry in the USN table
        /// </summary>
        /// <param name="records">The list of records with local names</param>
        /// <returns>A list of USN entries with full path</returns>
        private IReadOnlyCollection <Record> ResolveFullPaths(ICollection <Record> records)
        {
            // initialize file ref-nr (FRN) to path/parent-FRN look-up table
            var cache = new Dictionary <ulong, SortedRecords>();

            foreach (var rec in records)
            {
                if (rec.UsnRecord.FileAttributes.HasFlag(Win32USN.FileAttributes.Directory))
                {
                    if (!cache.TryGetValue(rec.UsnRecord.FileReferenceNumber, out var e))
                    {
                        e = new SortedRecords();
                        cache.Add(rec.UsnRecord.FileReferenceNumber, e);
                    }

                    e.Add(rec);
                }
            }

            // List of unresolved USN records, with FileReferenceNumber as a key
            Dictionary <ulong, List <Record> > recordsByFileRefNumber = new Dictionary <ulong, List <Record> >();

            // iterate through USN records
            var result = new Dictionary <string, Record>();

            foreach (var rec in records)
            {
                // Add entry to list of unresolved entries, and try to resolve them at the end of the scan
                if (!recordsByFileRefNumber.TryGetValue(rec.UsnRecord.FileReferenceNumber, out List <Record> fileRefHistory))
                {
                    fileRefHistory = new List <Record>();
                    recordsByFileRefNumber.Add(rec.UsnRecord.FileReferenceNumber, fileRefHistory);
                }
                fileRefHistory.Add(rec);

                var pathList = new LinkedList <Record>();
                pathList.AddFirst(rec);

                // walk back up the chain as far as we can go
                var cur = rec;
                while (true)
                {
                    var parentRefNr = cur.UsnRecord.ParentFileReferenceNumber;
                    if (parentRefNr == m_volumeRootRefNumber)
                    {
                        break; // done
                    }
                    if (!cache.TryGetValue(parentRefNr, out var parents))
                    {
                        // parent FRN not found in look-up table, fetch it from change journal
                        var parentRecord = GetRecordByFileRef(parentRefNr);

                        if (parentRecord == null)
                        {
                            pathList.Clear();
                            break;
                        }
                        else
                        {
                            parents = new SortedRecords(new List <Record> {
                                parentRecord
                            });
                            cache.Add(parentRefNr, parents);
                        }
                    }

                    // take parent entry having next smaller USN
                    var parent = parents.GetParentOf(cur);
                    if (parent == null)
                    {
                        throw new UsnJournalSoftFailureException(Strings.USNHelper.PathResolveError);
                    }

                    pathList.AddFirst(parent);

                    cur = parent;
                }

                if (pathList.Count > 0)
                {
                    // generate full path
                    Debug.Assert(m_volume != null, nameof(m_volume) + " != null");
                    var path = m_volume;
                    foreach (var r in pathList)
                    {
                        path = SystemIO.IO_WIN.PathCombine(path, r.FileName);
                    }

                    if (rec.UsnRecord.FileAttributes.HasFlag(Win32USN.FileAttributes.Directory))
                    {
                        path = Util.AppendDirSeparator(path);
                    }

                    // set resolved path
                    rec.FullPath = path;
                }
            }

            // parse all records
            foreach (var entry in recordsByFileRefNumber)
            {
                bool wasCreated  = false;
                var  tempRecords = new List <Record>();

                foreach (var rec in entry.Value)
                {
                    // add entry to intermediate result set
                    tempRecords.Add(rec);

                    var reason = rec.UsnRecord.Reason;

                    if (reason.HasFlag(Win32USN.USNReason.USN_REASON_FILE_CREATE) || reason.HasFlag(Win32USN.USNReason.USN_REASON_RENAME_NEW_NAME))
                    {
                        wasCreated = true;
                    }

                    if (reason.HasFlag(Win32USN.USNReason.USN_REASON_FILE_DELETE) || reason.HasFlag(Win32USN.USNReason.USN_REASON_RENAME_OLD_NAME))
                    {
                        if (!wasCreated)
                        {
                            FlushRecords(tempRecords, result);
                        }

                        tempRecords.Clear();
                        wasCreated = false;
                    }
                }

                FlushRecords(tempRecords, result);
            }

            return(result.Values);
        }