Exemple #1
0
 /// <summary>
 /// Initializes a new FAT directory.
 /// </summary>
 /// <param name="aFileSystem">The FAT file system to which the directory belongs.</param>
 /// <param name="parent">The FAT directory which is the parent of the directory. Null for the root directory.</param>
 /// <param name="aName">The name of the directory.</param>
 /// <param name="aFirstCluster">The first cluster number of the directory.</param>
 public FATDirectory(FATFileSystem aFileSystem, FATDirectory parent, FOS_System.String aName, UInt32 aFirstCluster)
     : base(aFileSystem, parent, aName)
 {
     _theFile = new FATFile(aFileSystem, parent, Name, 0, aFirstCluster)
     {
         IsDirectoryFile = true
     };
 }
Exemple #2
0
 /// <summary>
 /// Initializes a new FAT file.
 /// </summary>
 /// <param name="aFileSystem">The FAT file system to which the file belongs.</param>
 /// <param name="parent">The parent directory of the file.</param>
 /// <param name="aName">The name of the file.</param>
 /// <param name="aSize">The size of the file.</param>
 /// <param name="aFirstCluster">The first cluster number of the file.</param>
 /// <remarks>
 /// Size is UInt32 because FAT doesn't support bigger. Don't change to UInt64.
 /// </remarks>
 public FATFile(FATFileSystem aFileSystem, FATDirectory parent, FOS_System.String aName, UInt32 aSize, UInt32 aFirstCluster)
     : base(aFileSystem, parent, aName, aSize)
 {
     TheFATFileSystem = aFileSystem;
     FirstClusterNum  = aFirstCluster;
 }
Exemple #3
0
        /// <summary>
        /// Parses the specified directory file data for its listings.
        /// </summary>
        /// <param name="xData">The directory data.</param>
        /// <param name="xDataLength">The directory data length.</param>
        /// <param name="thisDir">
        /// The FAT directory the FAT data is from. 
        /// Used when creating listings as the parent directory.
        /// </param>
        /// <returns>The directory listings.</returns>
        public List ParseDirectoryTable(byte[] xData, int xDataLength, FATDirectory thisDir)
        {
            List xResult = new List();

            //BasicConsole.WriteLine("Parsing listings...");

            FOS_System.String xLongName = "";
            for (UInt32 i = 0; i < xDataLength; i = i + 32)
            {
                byte xAttrib = xData[i + 11];
                if (xAttrib == ListingAttribs.LongName)
                {
                    byte xType = xData[i + 12];
                    if (xType == 0)
                    {
                        byte xOrd = xData[i];
                        if ((xOrd & 0x40) > 0)
                        {
                            xLongName = "";
                        }
                        //TODO: Check LDIR_Ord for ordering and throw exception
                        // if entries are found out of order.
                        // Also save buffer and only copy name if a end Ord marker is found.
                        FOS_System.String xLongPart = ByteConverter.GetASCIIStringFromUTF16(xData, i + 1, 5);
                        //BasicConsole.WriteLine("xLongPart1: " + xLongPart);
                        // We have to check the length because 0xFFFF is a valid Unicode codepoint.
                        // So we only want to stop if the 0xFFFF is AFTER a 0x0000. We can determine
                        // this by also looking at the length. Since we short circuit the or, the length
                        // is rarely evaluated.
                        if (xLongPart.length == 5)
                        {
                            xLongPart = xLongPart + ByteConverter.GetASCIIStringFromUTF16(xData, i + 14, 6);
                            //BasicConsole.WriteLine("xLongPart2: " + xLongPart);
                            if (xLongPart.length == 11)
                            {
                                xLongPart = xLongPart + ByteConverter.GetASCIIStringFromUTF16(xData, i + 28, 2);
                                //BasicConsole.WriteLine("xLongPart3: " + xLongPart);
                            }
                        }
                        xLongName = xLongPart + xLongName;
                        //BasicConsole.WriteLine("xLongName: " + xLongName);
                        //TODO: LDIR_Chksum 
                    }
                }
                else
                {
                    byte xStatus = xData[i];
                    if (xStatus == 0x00)
                    {
                        // Empty slot, and no more entries after this
                        break;
                    }
                    else if (xStatus == 0x05)
                    {
                        // Japanese characters - We dont handle these
                    }
                    else if (xStatus == 0xE5)
                    {
                        // Empty slot, skip it
                    }
                    else if (xStatus >= 0x20)
                    {
                        FOS_System.String xName;

                        int xTest = xAttrib & (ListingAttribs.Directory | ListingAttribs.VolumeID);

                        if (xLongName.length > 0)
                        {
                            // Leading and trailing spaces are to be ignored according to spec.
                            // Many programs (including Windows) pad trailing spaces although it 
                            // it is not required for long names.
                            xName = xLongName.Trim();

                            // As per spec, ignore trailing periods
                            //If there are trailing periods
                            int nameIndex = xName.length - 1;
                            if (xName[nameIndex] == '.')
                            {
                                //Search backwards till we find the first non-period character
                                for (; nameIndex > -1; nameIndex--)
                                {
                                    if (xName[nameIndex] != '.')
                                    {
                                        break;
                                    }
                                }
                                //Substring to remove the periods
                                xName = xName.Substring(0, nameIndex + 1);
                            }
                        }
                        else
                        {
                            FOS_System.String xEntry = ByteConverter.GetASCIIStringFromASCII(xData, i, 11);
                            //Volume ID does not have same format as file-name.
                            if (xTest == ListingAttribs.VolumeID)
                            {
                                xName = xEntry;
                            }
                            else
                            {
                                //Attempt to apply original spec:
                                // - 8 chars for filename
                                // - 3 chars for extension
                                if (xEntry.length >= 8)
                                {
                                    xName = xEntry.Substring(0, 8).TrimEnd();

                                    if (xEntry.length >= 11)
                                    {
                                        FOS_System.String xExt = xEntry.Substring(8, 3).TrimEnd();
                                        if (xExt.length > 0)
                                        {
                                            xName += "." + xExt;
                                        }
                                    }
                                }
                                else
                                {
                                    xName = xEntry;
                                }
                            }
                        }

                        UInt32 xFirstCluster = (UInt32)(ByteConverter.ToUInt16(xData, i + 20) << 16 | ByteConverter.ToUInt16(xData, i + 26));

                        xName = xName.ToUpper();

                        //TODO: Store attributes in the listings

                        if (xTest == 0)
                        {
                            if (xName[xName.length - 1] != '~')
                            {
                                UInt32 xSize = ByteConverter.ToUInt32(xData, i + 28);
                                xResult.Add(new FATFile(this, thisDir, xName, xSize, xFirstCluster));
                            }
                            else
                            {
                                //BasicConsole.WriteLine("Ignoring file: " + xName);
                            }
                        }
                        else if (xTest == ListingAttribs.VolumeID)
                        {
                            thePartition.VolumeID = xName;
                        }
                        else if (xTest == ListingAttribs.Directory)
                        {
                            xResult.Add(new FATDirectory(this, thisDir, xName, xFirstCluster));
                        }
                        xLongName = "";
                    }
                }
            }

            return xResult;
        }
Exemple #4
0
        /// <summary>
        /// Gets the root directory listings in the FAT file system.
        /// </summary>
        /// <returns>The root directory listings.</returns>
        public List GetRootDirectoryListings()
        {
            if (FATType == FATTypeEnum.FAT32)
            {
                if (_rootDirectoryFAT32 == null)
                {
                    _rootDirectoryFAT32 = new FATDirectory(this, null, "ROOT", RootCluster);
                }
                return _rootDirectoryFAT32.GetListings();
            }
            else
            {
                if (_rootDirectoryListings == null)
                {
                    byte[] xData = thePartition.TheDiskDevice.NewBlockArray(RootSectorCount);
                    thePartition.ReadBlock(RootSector, RootSectorCount, xData);

                    _rootDirectoryListings = ParseDirectoryTable(xData, xData.Length, null);
                }
                return _rootDirectoryListings;
            }
        }
Exemple #5
0
        /// <summary>
        /// Creates a new directory within the file system.
        /// </summary>
        /// <param name="name">The name of the directory to create.</param>
        /// <param name="parent">The parent directory of the new directory.</param>
        /// <returns>The new directory listing.</returns>
        public override Directory NewDirectory(String name, Directory parent)
        {
            if (FATType != FATTypeEnum.FAT32)
            {
                ExceptionMethods.Throw(new Exceptions.NotSupportedException("FATFileSystem.NewDirectory for non-FAT32 not supported!"));
            }
            if (parent == null)
            {
                ExceptionMethods.Throw(new Exceptions.NullReferenceException());
            }
            if (!(parent is FATDirectory))
            {
                ExceptionMethods.Throw(new Exceptions.NotSupportedException("FATFileSystem.NewDirectory parent directory must be of type FATDirectory!"));
            }

            //BasicConsole.WriteLine("Getting listings...");
            List listings = parent.GetListings();

            //BasicConsole.WriteLine("Got listings. Converting name to upper...");
            name = name.ToUpper();

            //BasicConsole.WriteLine("Name converted. Checking listing exists...");
            bool exists = Directory.ListingExists(name, listings);
            //BasicConsole.WriteLine("Checked.");
            if (!exists)
            {
                //BasicConsole.WriteLine("Getting next free cluster...");
                UInt32 freeCluster = GetNextFreeCluster(2);
                //BasicConsole.WriteLine("Got next free. Clearing cluster...");
                WriteCluster(freeCluster, null);
                //BasicConsole.WriteLine("Cleared. Setting FAT entry...");
                SetFATEntryAndSave(freeCluster, GetFATEntryEOFValue(FATType));
                //BasicConsole.WriteLine("Set FAT entry. Creating new directory...");
                FATDirectory newDir = new FATDirectory(this, (FATDirectory)parent, name, freeCluster);
                //BasicConsole.WriteLine("Adding listing to parent...");
                parent.AddListing(newDir);
                //BasicConsole.WriteLine("Added listing. Writing listings...");
                parent.WriteListings();
                //BasicConsole.WriteLine("Written listings.");
                return newDir;
            }
            else
            {
                ExceptionMethods.Throw(new IOException("Listing (directory/file) with specified name already exists!"));
            }
            return null;
        }
Exemple #6
0
 /// <summary>
 /// Initializes a new FAT file.
 /// </summary>
 /// <param name="aFileSystem">The FAT file system to which the file belongs.</param>
 /// <param name="parent">The parent directory of the file.</param>
 /// <param name="aName">The name of the file.</param>
 /// <param name="aSize">The size of the file.</param>
 /// <param name="aFirstCluster">The first cluster number of the file.</param>
 /// <remarks>
 /// Size is UInt32 because FAT doesn't support bigger. Don't change to UInt64.
 /// </remarks>
 public FATFile(FATFileSystem aFileSystem, FATDirectory parent, FOS_System.String aName, UInt32 aSize, UInt32 aFirstCluster)
     : base(aFileSystem, parent, aName, aSize)
 {
     TheFATFileSystem = aFileSystem;
     FirstClusterNum = aFirstCluster;
 }
Exemple #7
0
 /// <summary>
 /// Initializes a new FAT directory.
 /// </summary>
 /// <param name="aFileSystem">The FAT file system to which the directory belongs.</param>
 /// <param name="parent">The FAT directory which is the parent of the directory. Null for the root directory.</param>
 /// <param name="aName">The name of the directory.</param>
 /// <param name="aFirstCluster">The first cluster number of the directory.</param>
 public FATDirectory(FATFileSystem aFileSystem, FATDirectory parent, FOS_System.String aName, UInt32 aFirstCluster)
     : base(aFileSystem, parent, aName)
 {
     _theFile = new FATFile(aFileSystem, parent, Name, 0, aFirstCluster) { IsDirectoryFile = true };
 }