Example #1
0
        public MBR(BlockDevice device)
        {
            var aMBR = device.NewBlockArray(1);

            device.ReadBlock(0, 1, ref aMBR);

            ParsePartition(aMBR, 446);
            ParsePartition(aMBR, 462);
            ParsePartition(aMBR, 478);
            ParsePartition(aMBR, 494);
        }
Example #2
0
        public List<System.FileSystem.Listing.Base> GetRoot()
        {
            var xResult = new List<System.FileSystem.Listing.Base>();

            byte[] xData;
            if (FatType == FatTypeEnum.Fat32)
            {
                xData = NewClusterArray();
                ReadCluster(RootCluster, xData);
            }
            else
            {
                xData = mDevice.NewBlockArray(RootSectorCount);
                mDevice.ReadBlock(RootSector, RootSectorCount, xData);
            }
            //TODO: Change xLongName to StringBuilder
            string xLongName = "";
            for (UInt32 i = 0; i < xData.Length; i = i + 32)
            {
                byte xAttrib = xData[i + 11];
                if (xAttrib == Attribs.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.
                        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;
                        //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)
                    {
                        string xName;
                        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);
                            }
                        }
                        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;
                            }
                        }

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

                        var xTest = xAttrib & (Attribs.Directory | Attribs.VolumeID);
                        if (xTest == 0)
                        {
                            UInt32 xSize = xData.ToUInt32(i + 28);
                            xResult.Add(new Listing.FatFile(this, xName, xSize, xFirstCluster));
                        }
                        else if (xTest == Attribs.VolumeID)
                        {
                            //
                        }
                        else if (xTest == Attribs.Directory)
                        {
                            xResult.Add(new Listing.FatDirectory(this, xName));
                        }
                        xLongName = "";
                    }
                }
            }

            return xResult;
        }
Example #3
0
        public FatFileSystem(BlockDevice aDevice)
        {

            mDevice = aDevice;
            byte[] xBPB = mDevice.NewBlockArray(1);

            mDevice.ReadBlock(0UL, 1U, xBPB);

            UInt16 xSig = xBPB.ToUInt16(510);
            if (xSig != 0xAA55)
            {
                throw new Exception("FAT signature not found.");
            }

            BytesPerSector = xBPB.ToUInt16(11);
            SectorsPerCluster = xBPB[13];
            BytesPerCluster = BytesPerSector * SectorsPerCluster;
            ReservedSectorCount = xBPB.ToUInt16(14);
            NumberOfFATs = xBPB[16];
            RootEntryCount = xBPB.ToUInt16(17);

            TotalSectorCount = xBPB.ToUInt16(19);
            if (TotalSectorCount == 0)
            {
                TotalSectorCount = xBPB.ToUInt32(32);
            }

            // FATSz
            FatSectorCount = xBPB.ToUInt16(22);
            if (FatSectorCount == 0)
            {
                FatSectorCount = xBPB.ToUInt32(36);
            }
            //Global.Dbg.Send("FAT Sector Count: " + FatSectorCount);

            DataSectorCount = TotalSectorCount - (ReservedSectorCount + (NumberOfFATs * FatSectorCount) + ReservedSectorCount);

            // Computation rounds down.
            ClusterCount = DataSectorCount / SectorsPerCluster;
            // Determine the FAT type. Do not use another method - this IS the official and
            // proper way to determine FAT type.
            // Comparisons are purposefully < and not <=
            // FAT16 starts at 4085, FAT32 starts at 65525
            if (ClusterCount < 4085)
            {
                FatType = FatTypeEnum.Fat12;
            }
            else if (ClusterCount < 65525)
            {
                FatType = FatTypeEnum.Fat16;
            }
            else
            {
                FatType = FatTypeEnum.Fat32;
            }

            if (FatType == FatTypeEnum.Fat32)
            {
                RootCluster = xBPB.ToUInt32(44);
            }
            else
            {
                RootSector = ReservedSectorCount + (NumberOfFATs * FatSectorCount);
                RootSectorCount = (RootEntryCount * 32 + (BytesPerSector - 1)) / BytesPerSector;
            }
            DataSector = ReservedSectorCount + (NumberOfFATs * FatSectorCount) + RootSectorCount;

        }
Example #4
0
        public FatFileSystem(Cosmos.HAL.BlockDevice.BlockDevice aDevice)
        {

            mDevice = aDevice;
            byte[] xBPB = mDevice.NewBlockArray(1);

            mDevice.ReadBlock(0UL, 1U, xBPB);

            UInt16 xSig = xBPB.ToUInt16(510);
            if (xSig != 0xAA55)
            {
                throw new Exception("FAT signature not found.");
            }

            BytesPerSector = xBPB.ToUInt16(11);
            SectorsPerCluster = xBPB[13];
            BytesPerCluster = BytesPerSector * SectorsPerCluster;
            ReservedSectorCount = xBPB.ToUInt16(14);
            NumberOfFATs = xBPB[16];
            RootEntryCount = xBPB.ToUInt16(17);

            TotalSectorCount = xBPB.ToUInt16(19);
            if (TotalSectorCount == 0)
            {
                TotalSectorCount = xBPB.ToUInt32(32);
            }

            // FATSz
            FatSectorCount = xBPB.ToUInt16(22);
            if (FatSectorCount == 0)
            {
                FatSectorCount = xBPB.ToUInt32(36);
            }
            //Global.Dbg.Send("FAT Sector Count: " + FatSectorCount);

            DataSectorCount = TotalSectorCount - (ReservedSectorCount + (NumberOfFATs * FatSectorCount) + ReservedSectorCount);

            // Computation rounds down. 
            ClusterCount = DataSectorCount / SectorsPerCluster;
            // Determine the FAT type. Do not use another method - this IS the official and
            // proper way to determine FAT type.
            // Comparisons are purposefully < and not <=
            // FAT16 starts at 4085, FAT32 starts at 65525 
            if (ClusterCount < 4085)
            {
                FatType = FatTypeEnum.Fat12;
            }
            else if (ClusterCount < 65525)
            {
                FatType = FatTypeEnum.Fat16;
            }
            else
            {
                FatType = FatTypeEnum.Fat32;
            }

            if (FatType == FatTypeEnum.Fat32)
            {
                RootCluster = xBPB.ToUInt32(44);
            }
            else
            {
                RootSector = ReservedSectorCount + (NumberOfFATs * FatSectorCount);
                RootSectorCount = (RootEntryCount * 32 + (BytesPerSector - 1)) / BytesPerSector;
            }
            DataSector = ReservedSectorCount + (NumberOfFATs * FatSectorCount) + RootSectorCount;

        }