/// <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); }
/// <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); }
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); }
/// <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); }
/// <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); }
/// <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])); } }
/// <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); }