public static UsnJrnl[] GetInstances(string volume)
        {
            // Check for valid Volume name
            NativeMethods.getVolumeName(ref volume);

            // Set up FileStream to read volume
            IntPtr     hVolume      = NativeMethods.getHandle(volume);
            FileStream streamToRead = NativeMethods.getFileStream(hVolume);

            // Get VolumeBootRecord object for logical addressing
            VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

            // Get the $J Data attribute (contains UsnJrnl details
            NonResident J = UsnJrnl.GetJStream(UsnJrnl.GetFileRecord(volume));

            List <UsnJrnl> usnList = new List <UsnJrnl>();

            for (int i = 0; i < J.DataRun.Length; i++)
            {
                if (!(J.DataRun[i].Sparse))
                {
                    long clusterCount = J.DataRun[i].ClusterLength;

                    byte[] fragmentBytes = NativeMethods.readDrive(streamToRead, ((ulong)J.DataRun[i].StartCluster * VBR.BytesPerCluster), ((ulong)clusterCount * VBR.BytesPerCluster));

                    byte[] clusterBytes = new byte[VBR.BytesPerCluster];

                    for (long j = 0; j < clusterCount; j++)
                    {
                        Array.Copy(fragmentBytes, ((long)j * VBR.BytesPerCluster), clusterBytes, 0, clusterBytes.Length);

                        int offset = 0;

                        do
                        {
                            if (clusterBytes[offset] == 0)
                            {
                                break;
                            }

                            try
                            {
                                UsnJrnl usn = new UsnJrnl(clusterBytes, volume, ref offset);
                                if (usn.Version > USN40Version)
                                {
                                    break;
                                }
                                usnList.Add(usn);
                            }
                            catch
                            {
                                break;
                            }
                        } while (offset >= 0 && offset < clusterBytes.Length);
                    }
                }
            }
            return(usnList.ToArray());
        }
 public UsnJrnl GetUsnJrnl()
 {
     foreach (Attr attr in this.Attribute)
     {
         if (attr.Name == Attr.ATTR_TYPE.STANDARD_INFORMATION)
         {
             StandardInformation stdInfo = attr as StandardInformation;
             return(UsnJrnl.Get(this.VolumePath, stdInfo.UpdateSequenceNumber));
         }
     }
     throw new Exception("No $STANDARD_INFORMATION Attirbute found");
 }
        public static UsnJrnl Get(string volume, ulong usn)
        {
            // Check for valid Volume name
            NativeMethods.getVolumeName(ref volume);

            // Set up FileStream to read volume
            IntPtr     hVolume      = NativeMethods.getHandle(volume);
            FileStream streamToRead = NativeMethods.getFileStream(hVolume);

            // Get VolumeBootRecord object for logical addressing
            VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

            // Get the $J Data attribute (contains UsnJrnl details
            NonResident J = UsnJrnl.GetJStream(UsnJrnl.GetFileRecord(volume));

            // Determine the length of the initial sparse pages
            ulong SparseLength = (ulong)J.DataRun[0].ClusterLength * VBR.BytesPerCluster;
            // Subtract length of sparse data from desired usn offset
            ulong usnOffset = usn - SparseLength;

            // Iterate through each data run
            for (int i = 1; i < J.DataRun.Length; i++)
            {
                // Determine length of current DataRun
                ulong dataRunLength = (ulong)J.DataRun[i].ClusterLength * VBR.BytesPerCluster;

                // Check if usnOffset resides in current DataRun
                if (dataRunLength <= usnOffset)
                {
                    // If not, subtract length of DataRun from usnOffset
                    usnOffset -= dataRunLength;
                }

                // If usnOffset resides within DataRun, parse associated UsnJrnl Entry
                else
                {
                    // Read DataRun from disk
                    byte[] fragmentBytes = NativeMethods.readDrive(streamToRead, ((ulong)J.DataRun[i].StartCluster * VBR.BytesPerCluster), ((ulong)J.DataRun[i].ClusterLength * VBR.BytesPerCluster));

                    // Instatiate a byte array that is the size of a single cluster
                    byte[] clusterBytes = new byte[VBR.BytesPerCluster];

                    // Iterate through the clusters in the DataRun
                    for (long j = 0; j < J.DataRun[i].ClusterLength; j++)
                    {
                        // If usnOffset is not in current cluster, then subtract cluster size from offset and iterate
                        if (VBR.BytesPerCluster <= usnOffset)
                        {
                            usnOffset -= VBR.BytesPerCluster;
                        }
                        // Else if usnOffset is in current cluster
                        else
                        {
                            // Copy current cluster bytes to clusterBytes variable
                            Array.Copy(fragmentBytes, ((long)j * VBR.BytesPerCluster), clusterBytes, 0, clusterBytes.Length);

                            // Parse desired UsnJrnl entry from cluster
                            int offset = (int)usnOffset;
                            return(new UsnJrnl(clusterBytes, volume, ref offset));
                        }
                    }
                }
            }
            return(null);
        }
        public static UsnJrnl[] GetInstances(string volume)
        {
            // Check for valid Volume name
            NativeMethods.getVolumeName(ref volume);

            // Set up FileStream to read volume
            IntPtr hVolume = NativeMethods.getHandle(volume);
            FileStream streamToRead = NativeMethods.getFileStream(hVolume);

            // Get VolumeBootRecord object for logical addressing
            VolumeBootRecord VBR = VolumeBootRecord.Get(streamToRead);

            // Get the $J Data attribute (contains UsnJrnl details
            NonResident J = UsnJrnl.GetJStream(UsnJrnl.GetFileRecord(volume));

            List<UsnJrnl> usnList = new List<UsnJrnl>();

            for (int i = 0; i < J.DataRun.Length; i++)
            {
                if (!(J.DataRun[i].Sparse))
                {
                    long clusterCount = J.DataRun[i].ClusterLength;

                    byte[] fragmentBytes = NativeMethods.readDrive(streamToRead, ((ulong)J.DataRun[i].StartCluster * VBR.BytesPerCluster), ((ulong)clusterCount * VBR.BytesPerCluster));

                    byte[] clusterBytes = new byte[VBR.BytesPerCluster];

                    for (long j = 0; j < clusterCount; j++)
                    {
                        Array.Copy(fragmentBytes, ((long)j * VBR.BytesPerCluster), clusterBytes, 0, clusterBytes.Length);

                        int offset = 0;

                        do
                        {
                            if (clusterBytes[offset] == 0)
                            {
                                break;
                            }

                            try
                            {
                                UsnJrnl usn = new UsnJrnl(clusterBytes, volume, ref offset);
                                if (usn.Version > USN40Version)
                                {
                                    break;
                                }
                                usnList.Add(usn);
                            }
                            catch
                            {
                                break;
                            }

                        } while (offset >= 0 && offset < clusterBytes.Length);
                    }
                }
            }
            return usnList.ToArray();
        }