/// <summary> /// 删除实体文件 /// </summary> /// <param name="drivename"></param> /// <param name="volumeinfo"></param> /// <param name="fat"></param> /// <returns></returns> public static ErrorCode DeleteFile(string drivename, VolumeInfo volumeinfo, FileInfo fat) { var content = GetList(drivename, fat.Location, volumeinfo); UInt32 clustercount = (UInt32)((volumeinfo.SectorCount - 1) / (volumeinfo.Cluster >> 9)); //簇总数 UInt32 UseBytes = (clustercount >> 3) + 1; //用多少个字节存储 UInt32 UseCluster = UseBytes / volumeinfo.Cluster + 1; //表大小(簇) //读取空闲表内容 byte[] freetable = DiskRW.ReadA(drivename, volumeinfo.FreeTableStart, UseCluster * (UInt32)(volumeinfo.Cluster >> 9)); //将位置写回空闲表 foreach (UInt32 block in content) { Set(block, false, freetable); } //fat簇写回空闲表; Set(TransferInverse(volumeinfo.SectorStart, fat.Location, volumeinfo.Cluster), false, freetable); //保存空闲表 var res = SetFreeBlock(drivename, ref volumeinfo, freetable); if (res == ErrorCode.Fail) { return(ErrorCode.WriteFreeTableFail); } return(ErrorCode.Success); }
/// <summary> /// 删除目录中某项 /// </summary> /// <param name="drivename">驱动器名</param> /// <param name="volumeinfo">卷信息结构体</param> /// <param name="cluster">要删的扇区</param> /// <param name="dirinfo">目录</param> /// <returns></returns> public static ErrorCode DeleteInDir(string drivename, VolumeInfo volumeinfo, UInt32 sector, DirectInfo dirinfo) { var cluster = TransferInverse(volumeinfo.SectorStart, sector, volumeinfo.Cluster); byte[] content = DiskRW.ReadA(drivename, dirinfo.Location, (uint)(volumeinfo.Cluster >> 9)); UInt32 next = mergeByte(content[160], content[161], content[162], content[163]); for (UInt16 i = 164; i < content.Length; i += 4) { UInt32 s1 = mergeByte(content[i], content[i + 1], content[i + 2], content[i + 3]); if (s1 == cluster) { content[i] = 0; content[i + 1] = 0; content[i + 2] = 0; content[i + 3] = 0; DiskRW.write(drivename, dirinfo.Location, content); return(ErrorCode.Success); } } //没有下一个索引块,找不到该目录 if (next == 0) { return(ErrorCode.NoSuchFile); } //读取索引表 content = DiskRW.ReadA(drivename, transfer(volumeinfo.SectorStart, next, volumeinfo.Cluster), (uint)(volumeinfo.Cluster >> 9)); while (true) { for (UInt16 i = 4; i < content.Length; i += 4) { UInt32 s1 = mergeByte(content[i], content[i + 1], content[i + 2], content[i + 3]); if (s1 == cluster) { content[i] = 0; content[i + 1] = 0; content[i + 2] = 0; content[i + 3] = 0; DiskRW.write(drivename, next, content); return(ErrorCode.Success); } } next = mergeByte(content[0], content[1], content[2], content[3]); //下簇号 为零表示没有下一簇 if (next == 0) { return(ErrorCode.NoSuchFile); } content = ReadOut(drivename, volumeinfo, next); } }
/// <summary> /// 获取文件内容具体位置(簇号) /// </summary> /// <param name="drivename"></param> /// <param name="Location">扇区号</param> /// <param name="fileUnit"></param> /// <returns>位置表(簇号)</returns> public static List <UInt32> GetList(string drivename, UInt32 location, VolumeInfo volumeinfo) { var res = new List <UInt32>(); byte[] content = DiskRW.ReadA(drivename, location, (uint)(volumeinfo.Cluster >> 9)); UInt32 next = mergeByte(content[160], content[161], content[162], content[163]); for (UInt16 i = 164; i < content.Length; i += 4) { UInt32 s1 = mergeByte(content[i], content[i + 1], content[i + 2], content[i + 3]); if (s1 == 0) { continue; } res.Add(s1); } //没有下一个索引块 if (next == 0) { return(res); } //读取索引表 content = DiskRW.ReadA(drivename, transfer(volumeinfo.SectorStart, next, volumeinfo.Cluster), (uint)(volumeinfo.Cluster >> 9)); while (true) { for (UInt16 i = 4; i < content.Length; i += 4) { UInt32 s1 = mergeByte(content[i], content[i + 1], content[i + 2], content[i + 3]); if (s1 == 0) { continue; } res.Add(s1); } next = mergeByte(content[0], content[1], content[2], content[3]); //下簇号 为零表示没有下一簇 if (next == 0) { return(res); } content = ReadOut(drivename, volumeinfo, next); } }
/// <summary> /// 获取实体文件信息 /// </summary> /// <param name="drivename"></param> /// <param name="location"></param> /// <param name="fileUnit"></param> /// <returns></returns> public static FileInfo GetFileInfoA(string drivename, UInt32 location, UInt16 fileUnit) { byte[] content = DiskRW.ReadA(drivename, location, (uint)(fileUnit >> 9)); var file = new FileInfo(); byte[] tmp = new byte[64]; Array.Copy(content, tmp, 64); file.Name = Encoding.Unicode.GetString(tmp).Replace("\0", ""); //后缀名 tmp = new byte[13]; Array.Copy(content, 64, tmp, 0, 13); file.Extension = Encoding.ASCII.GetString(tmp).Replace("\0", ""); //类型 file.Type = content[77]; //权限号 file.AccessCode = content[78]; //权限标记 file.AccessMode = content[79]; //作者 tmp = new byte[32]; Array.Copy(content, 80, tmp, 0, 32); file.Author = Encoding.Unicode.GetString(tmp); //最后修改人 tmp = new byte[32]; Array.Copy(content, 112, tmp, 0, 32); file.LastEditor = Encoding.Unicode.GetString(tmp); //创建时间 file.CreateTime = mergeByte(content[144], content[145], content[146], content[147]); //最后修改时间 file.LastEditTime = mergeByte(content[148], content[149], content[150], content[151]); //尾字节 UInt16 s5 = content[152]; UInt16 s6 = content[153]; file.Rest = (UInt16)((s6 << 8) + s5); file.Location = location; return(file); }
/// <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> /// 从某个FAT节点读取文件信息,返回值要转换方可使用 /// </summary> /// <param name="drivename"></param> /// <param name="location">扇区</param> /// <param name="fileUnit"></param> /// <returns>返回目录信息或者文件信息</returns> public static FATInfo GetFileInfo(string drivename, UInt32 location, UInt16 fileUnit) { byte[] content = DiskRW.ReadA(drivename, location, (uint)(fileUnit >> 9)); if (content[77] == 0) //目录 { var dir = new DirectInfo(); byte[] tmp = new byte[64]; Array.Copy(content, tmp, 64); dir.Name = Encoding.Unicode.GetString(tmp).Replace("\0", ""); //类型 dir.Type = content[77]; //权限号 dir.AccessCode = content[78]; //权限标记 dir.AccessMode = content[79]; //作者 tmp = new byte[32]; Array.Copy(content, 80, tmp, 0, 32); dir.Author = Encoding.Unicode.GetString(tmp); //最后修改人 tmp = new byte[32]; Array.Copy(content, 112, tmp, 0, 32); dir.LastEditor = Encoding.Unicode.GetString(tmp); //创建时间 UInt32 s1 = content[144]; UInt32 s2 = content[145]; UInt32 s3 = content[146]; UInt32 s4 = content[147]; dir.CreateTime = (s4 << 24) + (s3 << 16) + (s2 << 8) + s1; //最后修改时间 s1 = content[148]; s2 = content[149]; s3 = content[150]; s4 = content[151]; dir.LastEditTime = (s4 << 24) + (s3 << 16) + (s2 << 8) + s1; dir.Location = location; return(dir); } else if (content[77] != 0) //实体文件 { var file = new FileInfo(); byte[] tmp = new byte[64]; Array.Copy(content, tmp, 64); file.Name = Encoding.Unicode.GetString(tmp).Replace("\0", ""); //后缀名 tmp = new byte[13]; Array.Copy(content, 64, tmp, 0, 13); file.Extension = Encoding.Unicode.GetString(tmp).Replace("\0", ""); //类型 file.Type = content[77]; //权限号 file.AccessCode = content[78]; //权限标记 file.AccessMode = content[79]; //作者 tmp = new byte[32]; Array.Copy(content, 80, tmp, 0, 32); file.Author = Encoding.Unicode.GetString(tmp); //最后修改人 tmp = new byte[32]; Array.Copy(content, 112, tmp, 0, 32); file.LastEditor = Encoding.Unicode.GetString(tmp); //创建时间 UInt32 s1 = content[144]; UInt32 s2 = content[145]; UInt32 s3 = content[146]; UInt32 s4 = content[147]; file.CreateTime = (s4 << 24) + (s3 << 16) + (s2 << 8) + s1; //最后修改时间 s1 = content[148]; s2 = content[149]; s3 = content[150]; s4 = content[151]; file.LastEditTime = (s4 << 24) + (s3 << 16) + (s2 << 8) + s1; //尾字节 UInt16 s5 = content[152]; UInt16 s6 = content[153]; file.Rest = (UInt16)((s6 << 8) + s5); file.Location = location; return(file); } return(null); }
/// <summary> /// 读取某簇内容 /// </summary> /// <param name="drivename">驱动器</param> /// <param name="volumeinfo">卷信息结构体</param> /// <param name="cluster">要读取的簇号</param> /// <returns>具体内容</returns> public static byte[] ReadOut(string drivename, VolumeInfo volumeinfo, UInt32 cluster) { var res = DiskRW.ReadA(drivename, transfer(volumeinfo.SectorStart, cluster, volumeinfo.Cluster), (UInt32)(volumeinfo.Cluster >> 9)); return(res); }