Example #1
0
        public void Create_CreateFileSystemAndReadFile_Success()
        {
            // The minimum number of clusters for Fat32 is 65525.
            const int amountOfClusters = 65525;

            using (MemoryStream disk = new MemoryStream())
            {
                BootSector boot = new BootSector();
                boot.FatSize = (uint)Math.Ceiling(amountOfClusters / (double)boot.BytesPerSector);
                boot.Sectors = (uint)boot.SectorsPerCluster * amountOfClusters + boot.ReservedSectors + boot.FatSize;

                Fat32FileSystem.Create(disk, boot);

                byte[] bytes  = new byte[4600]; // Use multiple clusters.
                Random random = new Random();
                random.NextBytes(bytes);

                using (MemoryStream expected = new MemoryStream(bytes))
                {
                    Fat32FileSystem system = new Fat32FileSystem(disk);
                    system.Create("Data.bin");

                    using (Stream file = system.Open("Data.bin"))
                    {
                        expected.CopyTo(file);
                        file.Flush();
                    }

                    using (Stream file = system.Open("Data.bin"))
                        FileAssert.AreEqual(expected, file);
                }
            }
        }
Example #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Fat32FileSystem"/> class.
        /// </summary>
        /// <param name="stream">The stream containing the image of the file system.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="stream"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// <paramref name="stream"/> cannot be read or written or seeked.
        /// </exception>
        public Fat32FileSystem(Stream stream) : base(stream)
        {
            boot = ReadStructure <BootSector>(0);
            info = ReadStructure <FileSystemInfo>(boot.FileSystemInfoSector * boot.BytesPerSector);

            if (!info.IsFileSystemInfo)
            {
                throw new ArgumentException("File System Info is corrupted.", nameof(stream));
            }
        }
Example #3
0
        /// <summary>
        /// Creates Fat32 file system on the <paramref name="stream"/>.
        /// </summary>
        /// <param name="stream">The stream the file system is written on.</param>
        /// <param name="boot">The boot sector of the file system.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="stream"/> or <paramref name="boot"/> is null.
        /// </exception>
        public static void Create(Stream stream, BootSector boot)
        {
            if (stream == null)
            {
                throw new ArgumentNullException(nameof(stream));
            }
            if (boot == null)
            {
                throw new ArgumentNullException(nameof(boot));
            }

            if (boot.Fats != 1)
            {
                throw new ArgumentOutOfRangeException(nameof(boot), "This must be 1.");
            }

            byte[] bytes = Structures.ToBytes(boot);
            stream.Position = 0;
            stream.Write(bytes, 0, bytes.Length);

            bytes           = Structures.ToBytes(new FileSystemInfo());
            stream.Position = boot.FileSystemInfoSector * boot.BytesPerSector;
            stream.Write(bytes, 0, bytes.Length);

            FileEntry volume = new FileEntry();

            volume.ShortName  = "SD Card";
            volume.Attributes = FileAttributes.VolumeId;

            uint firstDataSector        = boot.ReservedSectors + (boot.Fats * boot.FatSize);
            uint firstByteOfRootCluster = ((boot.RootCluster - 2) * boot.SectorsPerCluster) + firstDataSector;

            bytes           = Structures.ToBytes(volume);
            stream.Position = firstByteOfRootCluster;
            stream.Write(bytes, 0, bytes.Length);

            // Allocate the root cluster.
            bytes           = BitConverter.GetBytes(0xFFFFFFFF);
            stream.Position = boot.ReservedSectors * boot.BytesPerSector + boot.RootCluster * 4;
            stream.Write(bytes, 0, bytes.Length);

            // Place signature.
            bytes           = BitConverter.GetBytes((ushort)0xAA55);
            stream.Position = 510;
            stream.Write(bytes, 0, bytes.Length);

            // Reach the end of the disk to allocated it.
            stream.Position = boot.Sectors * boot.BytesPerSector;
            stream.WriteByte(0);
        }