Quantcast
Channel: Reading MFT
Viewing all articles
Browse latest Browse all 444

Reading MFT

$
0
0

Here are my ideas for the public interface for a UsnJournal object.

I want to hide the complexity of dealing with the Usn Journal as much as possible without hiding too much.

I can write the code so that all of the errors calling DeviceIoControl are handled within the object.  I'd rather not throw exceptions.  Instead, I would return success/error codes.

So the only error codes that makes sense to the user are

        public enum UsnJournalReturnCode
        {
            USN_JOURNAL_SUCCESS = 0,
            USN_JOURNAL_INVALID = 1,
            USN_JOURNAL_NOT_ACTIVE = 2,
            VOLUME_NOT_NTFS = 3
        }

I've thought about calling the object a 'Volume'.  The other alternative is calling it UsnJournal.  I'm only dealing with one kind of volume, NTFS.  The only added value 'Volume' would bring is the data in the DriveInfo object, name, available freespace, total freespace, format, total size, and volume label.  I can expose all the DriveInfo fields by making it the DriveInfo object a member variable of UsnJournal.

Here is the class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using PInvoke;

namespace ConsoleUSNJournalProject
{
    class NtfsUsnJournal
    {
        #region enum(s)
        public enum UsnJournalReturnCode
        {
            USN_JOURNAL_SUCCESS = 0,
            USN_JOURNAL_INVALID = 1,
            USN_JOURNAL_NOT_ACTIVE = 2,
            VOLUME_NOT_NTFS = 3
        }
        #endregion

        #region private member variables

        private DriveInfo _driveInfo = null;
        private UInt64 _usnJournalId = 0;

        #endregion

        #region properties

        public string VolumeName
        {
            get { return _driveInfo.Name; }
        }

        public long AvailableFreeSpace
        {
            get { return _driveInfo.AvailableFreeSpace; }
        }

        public long TotalFreeSpace
        {
            get { return _driveInfo.TotalFreeSpace; }
        }

        public string Format
        {
            get { return _driveInfo.DriveFormat; }
        }

        public DirectoryInfo RootDirectory
        {
            get { return _driveInfo.RootDirectory; }
        }

        public long TotalSize
        {
            get { return _driveInfo.TotalSize; }
        }

        public string VolumeLabel
        {
            get { return _driveInfo.VolumeLabel; }
        }

        #endregion

        #region constructor(s)

        public NtfsUsnJournal(DriveInfo driveInfo)
        {
            _driveInfo = driveInfo;
        }

        #endregion

        #region public methods

        public UsnJournalReturnCode CreateUsnJournal(int maxSize, int allocationDelta)
        {
            //
            // caller should be able to change the size and allocation delta...
            //
        }

        public UsnJournalReturnCode DeleteUsnJournal()
        {
            //
            // I'm not sure about this one -- what do you think?
            // My take is if they can create it, they should be able to delete it.
            //
        }

        public bool IsUsnJournalValid()
        {
        }

        public bool IsUsnJournalActive()
        {
        }

        public UsnJournalReturnCode GetUsnJournalState(out Win32Api.USN_JOURNAL_DATA usnJournalState)
        {
        }

        public UsnJournalReturnCode GetChanges(Win32Api.USN_JOURNAL_DATA previousUsnState, out List<VolumeChangeEntry> changes, out Win32Api.USN_JOURNAL_DATA currentState)
        {
            //
            // each time the user calls for the changes it process usn journal entries from the 
            // previous state up to the current state.  So this info doesn't get misinterpreted
            // I think this should be one function rather than one function to get new files or 
            // directories, one function to get modified files, one function to get deleted 
            // files/directories.  
            //
            // this function would determine that the volume is NTFS,
            // it would read the current state,
            // that depending on the previousUsnState and the current state
            //   it would determine if the usn journal is valid
            // then it would process all the entries from the previous state to the current
            // state to load up the lists of new, modified, and deleted filesystem objects.
            //
            // I've thought about creating a UsnJournalEntry class that has the type of filesystem
            // object (file/folder), the change type (new, modified, deleted), etc., so that I could 
            // pass back one list, i.e. List<UsnJournalEntry>
            //
            // I'm leaning toward the three lists.
            //
        }

        #endregion

        #region private member functions

        #endregion
    }
}

 

If I returned one list of UsnJournalEntry's here is what that class might look like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;

namespace ConsoleUSNJournalProject
{
    public class UsnChangeEntry
    {
        #region enums

        public enum FolderOrFile
        {
            FOLDER = 0,
            FILE = 1
        }

        public enum NewChangedDeleted
        {
            NEW = 0,
            CHANGED = 1,
            DELETED = 2
        }

        #endregion

        #region properties

        private string _name;
        public string Name
        {
            get { return _name; }
        }

        private string _path;
        public string Path
        {
            get { return _path; }
        }

        public string FullyQualifiedPath
        {
            get { return System.IO.Path.Combine(_path, _name); }
        }

        private FolderOrFile _fileType;
        public FolderOrFile FileType
        {
            get { return _fileType; }
        }

        private NewChangedDeleted _changeType;
        public NewChangedDeleted ChangeType
        {
            get { return _changeType; }
        }

        #endregion

        #region private member variables
        #endregion

        #region constructor(s)
        #endregion

        #region public member functions
        #endregion

        #region private member functions
        #endregion
    }
}

 

Comments anyone? Suggestions, criticisms, alternatives?


StCroixSkipper

Viewing all articles
Browse latest Browse all 444

Trending Articles