Exemplo n.º 1
0
        public FatDirectoryEntry(
            FatFileSystem aFileSystem,
            FatDirectoryEntry aParent,
            string aFullPath,
            string aName,
            uint aFirstCluster)
            : base(aFileSystem, aParent, aFullPath, aName, 0, DirectoryEntryTypeEnum.Directory)
        {
            if (aFirstCluster < aFileSystem.RootCluster)
            {
                throw new ArgumentOutOfRangeException(nameof(aFirstCluster));
            }

            mFirstClusterNum       = aFirstCluster;
            mEntryHeaderDataOffset = 0;
        }
Exemplo n.º 2
0
        public FatDirectoryEntry AddDirectoryEntry(string aName, DirectoryEntryTypeEnum aType)
        {
            if ((aType == DirectoryEntryTypeEnum.Directory) || (aType == DirectoryEntryTypeEnum.File))
            {
                string xFullPath              = Path.Combine(mFullPath, aName);
                uint   xFirstCluster          = ((FatFileSystem)mFileSystem).GetFat(0).GetNextUnallocatedFatEntry();
                uint   xEntryHeaderDataOffset = GetNextUnallocatedDirectoryEntry();

                var xNewEntry = new FatDirectoryEntry((FatFileSystem)mFileSystem, this, xFullPath, aName, 0, xFirstCluster, xEntryHeaderDataOffset, aType);

                xNewEntry.AllocateDirectoryEntry();

                return(xNewEntry);
            }

            throw new ArgumentOutOfRangeException(nameof(aType), "Unknown directory entry type.");
        }
Exemplo n.º 3
0
        public FatStream(FatDirectoryEntry aEntry)
        {
            if (aEntry == null)
            {
                throw new ArgumentNullException(nameof(aEntry));
            }

            mDirectoryEntry = aEntry;
            mFS             = aEntry.GetFileSystem();
            mFatTable       = aEntry.GetFatTable();
            mSize           = aEntry.mSize;

            if (mFatTable == null)
            {
                throw new Exception("The fat chain returned for the directory entry was null.");
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Retrieves a <see cref="List{T}"/> of <see cref="FatDirectoryEntry"/> objects that represent the Directory Entries inside this Directory
        /// </summary>
        /// <returns>Returns a <see cref="List{T}"/> of the Directory Entries inside this Directory</returns>
        public List <FatDirectoryEntry> ReadDirectoryContents()
        {
            var xData   = GetDirectoryEntryData();
            var xResult = new List <FatDirectoryEntry>();
            FatDirectoryEntry xParent = (FatDirectoryEntry)(mParent ?? mFileSystem.GetRootDirectory());

            //TODO: Change xLongName to StringBuilder
            string xLongName = "";
            string xName     = "";

            for (uint i = 0; i < xData.Length; i = i + 32)
            {
                byte xAttrib = xData[i + 11];
                byte xStatus = xData[i];

                if (xAttrib == FatDirectoryEntryAttributeConsts.LongName)
                {
                    byte xType = xData[i + 12];

                    if (xStatus == FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry)
                    {
                        continue;
                    }

                    if (xType == 0)
                    {
                        if ((xStatus & 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.
                        string xLongPart = xData.GetUtf16String(i + 1, 5);

                        // 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 determin
                        // this by also looking at the length. Since we short circuit the or, the length
                        // is rarely evaluated.
                        if (xData.ToUInt16(i + 14) != 0xFFFF || xLongPart.Length == 5)
                        {
                            xLongPart = xLongPart + xData.GetUtf16String(i + 14, 6);

                            if (xData.ToUInt16(i + 28) != 0xFFFF || xLongPart.Length == 11)
                            {
                                xLongPart = xLongPart + xData.GetUtf16String(i + 28, 2);
                            }
                        }

                        xLongName = xLongPart + xLongName;
                        xLongPart = null;
                        //TODO: LDIR_Chksum
                    }
                }
                else
                {
                    xName = xLongName;

                    if (xStatus == 0x00)
                    {
                        break;
                    }

                    switch (xStatus)
                    {
                    case 0x05:
                        // Japanese characters - We dont handle these
                        break;

                    case FatDirectoryEntryAttributeConsts.UnusedOrDeletedEntry:
                        // Empty slot, skip it
                        continue;

                    default:
                        if (xStatus >= 0x20)
                        {
                            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.
                                // As per spec, ignore trailing periods
                                xName = xLongName.Trim();

                                //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 > 0; nameIndex--)
                                    {
                                        if (xName[nameIndex] != '.')
                                        {
                                            break;
                                        }
                                    }
                                    //Substring to remove the periods
                                    xName = xName.Substring(0, nameIndex + 1);
                                }

                                xLongName = "";
                            }
                            else
                            {
                                string xEntry = xData.GetAsciiString(i, 11);
                                xName = xEntry.Substring(0, 8).TrimEnd();
                                string xExt = xEntry.Substring(8, 3).TrimEnd();

                                if (xExt.Length > 0)
                                {
                                    xName = xName + "." + xExt;
                                }
                            }
                        }
                        break;
                    }
                }

                uint xFirstCluster = (uint)(xData.ToUInt16(i + 20) << 16 | xData.ToUInt16(i + 26));

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

                if (xAttrib == FatDirectoryEntryAttributeConsts.LongName)
                {
                    // skip adding, as it's a LongFileName entry, meaning the next normal entry is the item with the name.
                    ////Global.mFileSystemDebugger.SendInternal($"Entry was a Long FileName entry. Current LongName = '{xLongName}'");
                }
                else if (xTest == 0)
                {
                    uint xSize = xData.ToUInt32(i + 28);

                    if (xSize == 0 && xName.Length == 0)
                    {
                        continue;
                    }

                    string xFullPath = Path.Combine(mFullPath, xName);
                    var    xEntry    = new FatDirectoryEntry(((FatFileSystem)mFileSystem), xParent, xFullPath, xName, xSize, xFirstCluster, i, DirectoryEntryTypeEnum.File);
                    xResult.Add(xEntry);
                }
                else if (xTest == FatDirectoryEntryAttributeConsts.Directory)
                {
                    string xFullPath = Path.Combine(mFullPath, xName);
                    uint   xSize     = xData.ToUInt32(i + 28);
                    var    xEntry    = new FatDirectoryEntry(((FatFileSystem)mFileSystem), xParent, xFullPath, xName, xSize, xFirstCluster, i, DirectoryEntryTypeEnum.Directory);
                    xResult.Add(xEntry);
                }
                else if (xTest == FatDirectoryEntryAttributeConsts.VolumeID)
                {
                    ////Global.mFileSystemDebugger.SendInternal("<VOLUME ID> : Attrib = " + xAttrib + ", Status = " + xStatus);
                }
                else
                {
                    ////Global.mFileSystemDebugger.SendInternal("<INVALID ENTRY> : Attrib = " + xAttrib + ", Status = " + xStatus);
                }
            }

            return(xResult);
        }
Exemplo n.º 5
0
        public override DirectoryEntry GetRootDirectory()
        {
            var xRootEntry = new FatDirectoryEntry(this, null, mRootPath, mRootPath, RootCluster);

            return(xRootEntry);
        }