Пример #1
0
        /// <summary>
        /// 写回空闲表
        /// </summary>
        /// <param name="drivename"></param>
        /// <param name="volumeInfo"></param>
        /// <param name="freetable"></param>
        /// <returns></returns>
        public static ErrorCode SetFreeBlock(string drivename, ref VolumeInfo volumeInfo, byte[] freetable)
        {
            var res = DiskRW.write(drivename, volumeInfo.FreeTableStart, freetable);

            if (res)
            {
                return(ErrorCode.Success);
            }
            return(ErrorCode.Fail);
        }
Пример #2
0
        /// <summary>
        /// 写入某个簇内容
        /// </summary>
        /// <param name="drivename">驱动器</param>
        /// <param name="volumeinfo">卷信息结构体</param>
        /// <param name="cluster">要写入的簇号</param>
        /// <param name="content">写入内容</param>
        /// <returns></returns>
        public static ErrorCode WriteIn(string drivename, VolumeInfo volumeinfo, UInt32 cluster, byte[] content)
        {
            if (content.Length != volumeinfo.Cluster)
            {
                return(ErrorCode.ErrorClusterLength);
            }
            var res = DiskRW.write(drivename, transfer(volumeinfo.SectorStart, cluster, volumeinfo.Cluster), content);

            if (res)
            {
                return(ErrorCode.Success);
            }
            return(ErrorCode.Fail);
        }
Пример #3
0
        public static ErrorCode SetFileInfo(string drivename, FileInfo fat)
        {
            byte[] buffer = DiskRW.read(drivename, fat.Location);

            //name
            for (int i = 0; i < 63; i++)
            {
                buffer[i] = 0;
            }
            byte[] name = Encoding.Unicode.GetBytes(fat.Name);
            name.CopyTo(buffer, 0);

            name = Encoding.Unicode.GetBytes(fat.Extension);
            name.CopyTo(buffer, 64);

            //文件号 权限号 权限标记
            buffer[77] = fat.Type;
            buffer[78] = fat.AccessCode;
            buffer[79] = fat.AccessMode;

            //作者
            name = Encoding.Unicode.GetBytes(fat.Author);
            name.CopyTo(buffer, 80);
            //最后修改人
            name = Encoding.Unicode.GetBytes(fat.LastEditor);
            name.CopyTo(buffer, 112);

            //创建日期
            buffer[144] = (byte)(fat.CreateTime);
            buffer[145] = (byte)(fat.CreateTime >> 8);
            buffer[146] = (byte)(fat.CreateTime >> 16);
            buffer[147] = (byte)(fat.CreateTime >> 24);
            //修改日期
            buffer[148] = (byte)(fat.LastEditTime);
            buffer[149] = (byte)(fat.LastEditTime >> 8);
            buffer[150] = (byte)(fat.LastEditTime >> 16);
            buffer[151] = (byte)(fat.LastEditTime >> 24);

            //尾字节长
            buffer[152] = (byte)fat.Rest;
            buffer[153] = (byte)(fat.Rest >> 8);

            bool res = DiskRW.write(drivename, fat.Location, buffer);

            if (!res)
            {
                return(ErrorCode.Fail);
            }
            return(ErrorCode.Success);
        }
Пример #4
0
        /// <summary>
        /// 写回卷信息
        /// </summary>
        /// <param name="drivename">驱动器名</param>
        /// <param name="volumeInfo">卷信息结构体</param>
        /// <returns>错误代码</returns>
        static public ErrorCode SetVolumeInfo(string drivename, VolumeInfo volumeInfo)
        {
            var header = new byte[512];

            byte[] name = Encoding.Unicode.GetBytes("新加卷");
            name.CopyTo(header, 0);

            //起始簇扇区
            header[32] = (byte)volumeInfo.SectorStart;
            header[33] = (byte)(volumeInfo.SectorStart >> 8);
            header[34] = (byte)(volumeInfo.SectorStart >> 16);
            header[35] = (byte)(volumeInfo.SectorStart >> 24);

            //分区长度
            header[36] = (byte)(volumeInfo.SectorCount);
            header[37] = (byte)(volumeInfo.SectorCount >> 8);
            header[38] = (byte)(volumeInfo.SectorCount >> 16);
            header[39] = (byte)(volumeInfo.SectorCount >> 24);

            //分配单元大小 512B 的倍数
            header[40] = (byte)(volumeInfo.Cluster >> 9);

            //卷标 预留为空 ascii编码
            header[41] = volumeInfo.VolumeLabel;

            //空闲闲表头
            header[42] = (byte)(volumeInfo.FreeTableStart);
            header[43] = (byte)(volumeInfo.FreeTableStart >> 8);
            header[44] = (byte)(volumeInfo.FreeTableStart >> 16);
            header[45] = (byte)(volumeInfo.FreeTableStart >> 24);

            //加密方式 0 不加密
            header[48] = volumeInfo.EncryptionType;

            bool res = DiskRW.write(drivename, volumeInfo.SectorStart, header);

            if (!res)
            {
                return(ErrorCode.Fail);
            }
            return(ErrorCode.Success);
        }
Пример #5
0
        /// <summary>
        /// 获取空闲块 位示图
        /// </summary>
        /// <param name="drivename"></param>
        /// <param name="volumeInfo">卷信息的引用</param>
        /// <param name="count">所需空闲块个数</param>
        /// <returns>空闲簇列表</returns>
        public static List <UInt32> GetFreeBlock(string drivename, ref VolumeInfo volumeInfo, UInt32 count)
        {
            UInt32 clustercount = (UInt32)((volumeInfo.SectorCount - 1) / (volumeInfo.Cluster >> 9)); //簇总数
            UInt32 UseBytes     = (clustercount >> 3) + 1;                                            //用多少个字节存储
            UInt32 UseCluster   = UseBytes / volumeInfo.Cluster + 1;                                  //表大小(簇)

            //读取空闲表内容
            byte[] content = DiskRW.ReadA(drivename, volumeInfo.FreeTableStart, UseCluster * (UInt32)(volumeInfo.Cluster >> 9));
            //返回的空闲块号
            List <UInt32> ls = new List <uint>();

            //i为计数,j为簇索引值
            UInt32 i = 0;

            for (UInt32 j = 0; j < clustercount; j++)
            {
                if (!Test(j, content))
                {
                    ls.Add(j);
                    i++;
                }
                if (i == count)
                {
                    break;
                }
            }

            //磁盘已满或没有空间返回null;
            if (ls.Count < i)
            {
                return(null);
            }
            //写空闲表
            foreach (UInt32 item in ls)
            {
                Set(item, true, content);
            }
            //写回磁盘
            DiskRW.write(drivename, volumeInfo.FreeTableStart, content);
            return(ls);
        }
Пример #6
0
        /// <summary>
        /// 添加文件fat,文件为空
        /// </summary>
        /// <param name="current">当前目录信息</param>
        /// <param name="drivename">驱动器名</param>
        /// <param name="volumeinfo">当前卷信息</param>
        /// <returns>新文件簇号</returns>
        public static UInt32 AddDir(DirectInfo current, string drivename, VolumeInfo volumeinfo)
        {
            byte[] buffer = new byte[volumeinfo.Cluster];
            var    ls     = GetFreeBlock(drivename, ref volumeinfo, 1);//获取存放fat的簇

            //向现在目录加项
            var currentDir = DiskRW.ReadA(drivename, current.Location, (UInt16)(volumeinfo.Cluster >> 9));

            //检索当前的fat表
            for (int i = 164; i < volumeinfo.Cluster; i += 4)
            {
                if (mergeByte(currentDir[i], currentDir[i + 1], currentDir[i + 2], currentDir[i + 3]) == 0)
                {
                    currentDir[i]     = (byte)ls[0];
                    currentDir[i + 1] = (byte)(ls[0] >> 8);
                    currentDir[i + 2] = (byte)(ls[0] >> 16);
                    currentDir[i + 3] = (byte)(ls[0] >> 24);

                    //写回磁盘
                    DiskRW.write(drivename, current.Location, currentDir);
                    return(ls[0]);
                }
            }

            //fat满并且没有下个簇存放
            if (mergeByte(currentDir[160], currentDir[161], currentDir[162], currentDir[163]) == 0)
            {
                //添加下一索引块
                byte[] buffer2 = new byte[volumeinfo.Cluster];//写入内容缓存
                var    l2      = GetFreeBlock(drivename, ref volumeinfo, 1);
                //写入上个的索引表
                currentDir[160] = (byte)l2[0];
                currentDir[161] = (byte)(l2[0] >> 8);
                currentDir[162] = (byte)(l2[0] >> 16);
                currentDir[163] = (byte)(l2[0] >> 24);
                //下个
                buffer2[4] = (byte)ls[0];
                buffer2[5] = (byte)(ls[0] >> 8);
                buffer2[6] = (byte)(ls[0] >> 16);
                buffer2[7] = (byte)(ls[0] >> 24);
                //写入磁盘
                WriteIn(drivename, volumeinfo, l2[0], buffer2);
                DiskRW.write(drivename, current.Location, currentDir);
                return(ls[0]);
            }

            //寻找下一个索引表
            currentDir = ReadOut(drivename, volumeinfo, mergeByte(currentDir[160], currentDir[161], currentDir[162], currentDir[163]));
            while (true)
            {
                for (int i = 4; i < volumeinfo.Cluster; i += 4)
                {
                    if (mergeByte(currentDir[i], currentDir[i + 1], currentDir[i + 2], currentDir[i + 3]) == 0)
                    {
                        currentDir[i]     = (byte)ls[0];
                        currentDir[i + 1] = (byte)(ls[0] >> 8);
                        currentDir[i + 2] = (byte)(ls[0] >> 16);
                        currentDir[i + 3] = (byte)(ls[0] >> 24);
                        //写回磁盘
                        DiskRW.write(drivename, current.Location, currentDir);
                        return(ls[0]);
                    }
                    continue;
                }
                //索引表满并且没有下个簇存放
                if (mergeByte(currentDir[0], currentDir[1], currentDir[2], currentDir[3]) == 0)
                {
                    //添加下一索引块
                    byte[] buffer2 = new byte[volumeinfo.Cluster];//写入内容缓存
                    var    l2      = GetFreeBlock(drivename, ref volumeinfo, 1);
                    //写入上个的索引表
                    currentDir[0] = (byte)l2[0];
                    currentDir[1] = (byte)(l2[0] >> 8);
                    currentDir[2] = (byte)(l2[0] >> 16);
                    currentDir[3] = (byte)(l2[0] >> 24);
                    //下个
                    buffer2[4] = (byte)ls[0];
                    buffer2[5] = (byte)(ls[0] >> 8);
                    buffer2[6] = (byte)(ls[0] >> 16);
                    buffer2[7] = (byte)(ls[0] >> 24);
                    //写入磁盘
                    WriteIn(drivename, volumeinfo, l2[0], buffer2);
                    DiskRW.write(drivename, current.Location, currentDir);
                    return(ls[0]);
                }
                currentDir = ReadOut(drivename, volumeinfo, mergeByte(currentDir[0], currentDir[1], currentDir[2], currentDir[3]));
            }
        }
Пример #7
0
        /// <summary>
        /// 向某个空文件添加内容块列表
        /// </summary>
        /// <param name="drivename">驱动器</param>
        /// <param name="fat">实体文件FAT</param>
        /// <param name="blocks">内容块</param>
        /// <returns></returns>
        private static ErrorCode AppendBlock(string drivename, VolumeInfo volumeinfo, FileInfo fat, List <UInt32> blocks)
        {
            var    content = new byte[volumeinfo.Cluster];
            UInt16 i1      = (ushort)(volumeinfo.Cluster - 163);//fat簇内可存放多少簇索引

            ///<summary>
            ///总共两种情况
            ///1.fat表即可放入所有索引
            ///2.fat表和额外的索引表放入
            ///</summary>

            //第一种情况 已测试
            if (blocks.Count <= i1)
            {
                //下一索引表为0
                content[160] = 0;
                content[161] = 0;
                content[162] = 0;
                content[163] = 0;

                //i是list的索引,j是content的索引
                for (int i = 0, j = 164; j < volumeinfo.Cluster; j += 4)
                {
                    content[j]     = (byte)blocks[i];
                    content[j + 1] = (byte)(blocks[i] >> 8);
                    content[j + 2] = (byte)(blocks[i] >> 16);
                    content[j + 3] = (byte)(blocks[i] >> 24);

                    i++;
                    if (i == blocks.Count)
                    {
                        break;                   //写完
                    }
                }
                var res = DiskRW.write(drivename, fat.Location, content);
                if (res == false)
                {
                    return(ErrorCode.Fail);
                }
                return(ErrorCode.Success);
            }

            //第二种情况
            int i2 = 0;//list索引

            for (int j = 164; j < volumeinfo.Cluster; i2++, j += 4)
            {
                content[j]     = (byte)blocks[i2];
                content[j + 1] = (byte)(blocks[i2] >> 8);
                content[j + 2] = (byte)(blocks[i2] >> 16);
                content[j + 3] = (byte)(blocks[i2] >> 24);
            }
            //获取的空闲块列表
            var blocklist = GetFreeBlock(drivename, ref volumeinfo, 1);

            content[160] = (byte)blocklist[0];
            content[161] = (byte)(blocklist[0] >> 8);
            content[162] = (byte)(blocklist[0] >> 16);
            content[163] = (byte)(blocklist[0] >> 24);

            DiskRW.write(drivename, fat.Location, content);

            //var blocklist = GetFreeBlock(drivename, ref volumeinfo, 1);
            while (true)
            {
                content = new byte[volumeinfo.Cluster];
                for (int j = 4; j < volumeinfo.Cluster; j += 4)
                {
                    content[j]     = (byte)blocks[i2];
                    content[j + 1] = (byte)(blocks[i2] >> 8);
                    content[j + 2] = (byte)(blocks[i2] >> 16);
                    content[j + 3] = (byte)(blocks[i2] >> 24);

                    i2++;
                    if (i2 == blocks.Count)
                    {
                        break;
                    }
                }
                if (i2 == blocks.Count)
                {
                    break;
                }

                var tmp = blocklist[0];//暂存目前块地址
                blocklist  = GetFreeBlock(drivename, ref volumeinfo, 1);
                content[0] = (byte)blocklist[0];
                content[1] = (byte)(blocklist[0] >> 8);
                content[2] = (byte)(blocklist[0] >> 16);
                content[3] = (byte)(blocklist[0] >> 24);
                WriteIn(drivename, volumeinfo, tmp, content);
            }

            WriteIn(drivename, volumeinfo, blocklist[0], content);
            return(ErrorCode.Success);
        }