Esempio n. 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="volumeName"></param>
        /// <param name="fileName"></param>
        /// <param name="nodeNumber"></param>
        /// <returns></returns>
        internal static Node Get(string volumeName, string fileName, uint nodeNumber)
        {
            VolumeHeader volHeader = VolumeHeader.Get(volumeName);

            Node headerNode = null;

            switch (fileName)
            {
            case "Catalog":
                headerNode = CatalogFile.GetHeaderNode(volumeName);
                break;

            case "Attributes":
                headerNode = AttributesFile.GetHeaderNode(volumeName);
                break;

            case "ExtentsOverflow":
                headerNode = ExtentsOverflowFile.GetHeaderNode(volumeName);
                break;
            }

            HeaderRecord headerRecord = headerNode.Records[0] as HeaderRecord;

            return(Get(GetBytes(volumeName, fileName, nodeNumber), volumeName, fileName, nodeNumber));
        }
Esempio n. 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="volumeName"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private static byte[] GetHeaderBytes(string volumeName, string fileName)
        {
            VolumeHeader volHeader = VolumeHeader.Get(volumeName);

            ExtentDescriptor extent = null;

            switch (fileName)
            {
            case "Catalog":
                extent = volHeader.CatalogFile.Extents[0];
                break;

            case "Attributes":
                extent = volHeader.AttributesFile.Extents[0];
                break;

            case "ExtentsOverflow":
                extent = volHeader.ExtentsOverflowFile.Extents[0];
                break;
            }

            // Read the smallest possible amount of bytes
            byte[] firstSectorBytes = Helper.readDrive(volumeName, extent.StartBlock * volHeader.BlockSize, 0x200);
            // Parse HeaderRecord to determine NodeSize
            HeaderRecord headerRecord = HeaderRecord.Get(firstSectorBytes, 0x0E, volumeName, fileName);

            // Read the full Header Node
            return(Helper.readDrive(volumeName, extent.StartBlock * volHeader.BlockSize, headerRecord.NodeSize));
        }
Esempio n. 3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="volumeName"></param>
        /// <param name="fileName"></param>
        /// <param name="nodeNumber"></param>
        /// <returns></returns>
        internal static byte[] GetBytes(string volumeName, string fileName, uint nodeNumber)
        {
            VolumeHeader volHeader = VolumeHeader.Get(volumeName);

            ExtentDescriptor[] extents = null;

            switch (fileName)
            {
            case "Catalog":
                extents = volHeader.CatalogFile.Extents;
                break;

            case "Attributes":
                extents = volHeader.AttributesFile.Extents;
                break;

            case "ExtentsOverflow":
                extents = volHeader.ExtentsOverflowFile.Extents;
                break;
            }

            Node         headerNode   = GetHeaderNode(volumeName, fileName);
            HeaderRecord headerRecord = headerNode.Records[0] as HeaderRecord;

            // Determine which blocks contain desired node's bytes
            uint blockNumber = nodeNumber * (headerRecord.NodeSize / volHeader.BlockSize);

            // Starting Position within the extents
            uint extentPosition = 0;

            // Iterate through extents to determine which extent conatians the Node
            foreach (ExtentDescriptor extent in extents)
            {
                uint relBlock = blockNumber - extentPosition;

                if (relBlock < extent.BlockCount)
                {
                    return(Helper.readDrive(volumeName, (long)(extent.StartBlock + relBlock) * volHeader.BlockSize, headerRecord.NodeSize));
                }
                else
                {
                    extentPosition += extent.BlockCount;
                }
            }

            // Need to throw an "Invalid Node Number" error
            return(null);
        }
Esempio n. 4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="volumeName"></param>
        /// <param name="blockNumber"></param>
        /// <returns></returns>
        public static bool IsAllocationBlockUsed(string volumeName, uint blockNumber)
        {
            // Get VolumeHeader
            VolumeHeader volHeader = VolumeHeader.Get(volumeName);

            // Detemine which byte to look at
            uint bytePosition = blockNumber / 0x8;

            // Determine which of AllocationFile's blocks the byte belongs to
            uint fileBlock = bytePosition / volHeader.BlockSize;

            uint relativeBlock = 0;

            byte[] blockBytes = null;

            foreach (ExtentDescriptor extent in volHeader.AllocationFile.Extents)
            {
                if (fileBlock < relativeBlock + extent.BlockCount)
                {
                    uint blockToRead = fileBlock - relativeBlock + extent.StartBlock;
                    blockBytes = Helper.readDrive(volumeName, (blockToRead * volHeader.BlockSize), volHeader.BlockSize);
                    break;
                }
                else
                {
                    relativeBlock += extent.BlockCount;
                }
            }

            // Pick the right byte from the Sector
            byte byteToCheck = blockBytes[(blockNumber / 8) % volHeader.BlockSize];
            byte position    = (byte)(blockNumber % 8);

            // Need to come back and ensure this is correct (it appears to be opposite of what i'd expect)
            return((byteToCheck & (1 >> (position))) != 0);
        }