/// <summary> /// 编辑时间; /// </summary> /// <param name="fileStoken2"></param> /// <param name="extFileInfo"></param> private static void EditTime( FileStokenBase2 fileStoken2, ExtFileInfo extFileInfo) { if (fileStoken2 == null) { throw new ArgumentNullException(nameof(fileStoken2)); } if (extFileInfo == null) { throw new ArgumentNullException(nameof(extFileInfo)); } //编辑时间; if (extFileInfo.StExt4Inode == null) { LoggerService.WriteCallerLine($"{nameof(extFileInfo)} can't be null."); } extFileInfo.StExt4Inode.Value.GetMacTime(out var modifiedTime, out var accessedTime, out var createTime); fileStoken2.ModifiedTime = modifiedTime; fileStoken2.AccessedTime = accessedTime; fileStoken2.CreateTime = createTime; }
/// <summary> /// 应用本地文件系统信息至FileStoken; /// </summary> /// <param name="fsInfo"></param> /// <param name="stokenBase2"></param> private static void ApplyFileSystemInfoToStokenBase(FileSystemInfo fsInfo, FileStokenBase2 stokenBase2) { if (fsInfo == null) { throw new ArgumentNullException(nameof(fsInfo)); } if (stokenBase2 == null) { throw new ArgumentNullException(nameof(stokenBase2)); } stokenBase2.AccessedTime = fsInfo.LastAccessTime; stokenBase2.ModifiedTime = fsInfo.LastWriteTime; stokenBase2.CreateTime = fsInfo.CreationTime; stokenBase2.Name = fsInfo.Name; }
/// <summary> /// 编辑目录/文件/其它的时间,簇列表等值; /// </summary> /// <param name="fileStoken2"></param> private static void EditFileStoken2( FileStokenBase2 fileStoken2, ExtPartInfo partInfo, ExtFileInfo extFileInfo) { if (fileStoken2 == null) { throw new ArgumentNullException(nameof(fileStoken2)); } if (extFileInfo == null) { throw new ArgumentNullException(nameof(extFileInfo)); } if (extFileInfo.BlockListPtr == null) { throw new InvalidOperationException($"{nameof(extFileInfo.BlockListPtr)} of {nameof(ExtFileInfo)} can't be nullptr."); } if (partInfo == null) { throw new ArgumentNullException(nameof(partInfo)); } fileStoken2.SetInstance(extFileInfo, Constants.FileStokenTag_ExtFileInfo); fileStoken2.Name = extFileInfo.StExt4DirEntry?.Name; fileStoken2.Size = extFileInfo.StExt4Inode?.Size ?? 0; fileStoken2.Deleted = extFileInfo.StDirEntry?.bDel ?? false; EditTime(fileStoken2, extFileInfo); #if DEBUG //if (fileStoken2.Name.StartsWith(".journal")) { //} #endif EditBlockGroups(fileStoken2, partInfo, extFileInfo); }
/// <summary> /// 编辑块组; /// </summary> /// <param name="fileStoken2"></param> /// <param name="partInfo"></param> /// <param name="extFileInfo"></param> private static void EditBlockGroups( FileStokenBase2 fileStoken2, ExtPartInfo partInfo, ExtFileInfo extFileInfo) { if (fileStoken2 == null) { throw new ArgumentNullException(nameof(fileStoken2)); } if (extFileInfo == null) { throw new ArgumentNullException(nameof(extFileInfo)); } //if (extFileInfo.BlockListPtr == null) { // throw new InvalidOperationException($"{nameof(extFileInfo.BlockListPtr)} of {nameof(ExtFileInfo)} can't be nullptr."); //} if (partInfo == null) { throw new ArgumentNullException(nameof(partInfo)); } if (extFileInfo.BlockList == null) { //LoggerService.WriteCallerLine($"{nameof(extFileInfo.BlockList)} can't be null."); return; } var blocks = extFileInfo.BlockList; var blockSize = partInfo.SuperBlock.StructInstance.BlockSize; if (blocks == null) { return; } //遍历,粘合,将连续的簇列表并入为一个块组; StBlockList?lastBlock = null; long firstClusterLBA = 0; int blockCount = 0; ulong lastBlockNum = 0; //重置局部变量;参数为本次(循环)最新的独立头块; void Reset(StBlockList block) { lastBlock = block; blockCount = (int)block.count; lastBlockNum = block.address; firstClusterLBA = (long)block.address * blockSize; } //压栈; void PushBlockGroup() { if (lastBlock == null) { return; } fileStoken2.BlockGroups.Add( BlockGroupFactory.CreateNewBlockGroup((long)lastBlock.Value.address, blockCount, blockSize, firstClusterLBA) ); } try { foreach (var cluster in blocks) { if (lastBlock == null) { Reset(cluster); continue; } //如果是连续的簇号则+1; if (cluster.address == lastBlockNum + 1) { lastBlockNum = cluster.address; blockCount++; } //否则,构造BlockGroup,插入新建链表,并重置; else { PushBlockGroup(); Reset(cluster); } } if (lastBlock != null) { PushBlockGroup(); } } catch (Exception ex) { LoggerService.WriteCallerLine(ex.Message); } }
/// <summary> /// 处理子文件/目录/其它加载; /// </summary> /// <param name="haveFileCollection"></param> /// <param name="filePtr">非托管文件节点指针</param> /// <param name="ntfSzAct"></param> /// <param name="isCancel"></param> private static void DealWithFileNode( IHaveFileCollection haveFileCollection, ExtPartInfo partInfo, IntPtr filePtr, Action <long> ntfSzAct, Func <bool> isCancel) { while (filePtr != IntPtr.Zero) { IFile file = null; FileStokenBase2 fileStoken2 = null; var stDirEntry = filePtr.GetStructure <StDirEntry>(); //压栈;避免使用continue导致死循环以及冗余代码; void Push() { if (file != null) { haveFileCollection.Children.Add(file); } filePtr = stDirEntry.Next; } if (stDirEntry.DirInfo == IntPtr.Zero) { Push(); continue; } var stExtDirEntry = stDirEntry.DirInfo.GetStructure <StExt4DirEntry>(); var stExtINodePtr = ExtX_Get_InodeInfo(partInfo.ExtUnmanagedManager.ExtManagerPtr, stExtDirEntry.inode); if (stExtINodePtr == IntPtr.Zero) { LoggerService.WriteCallerLine($"{nameof(stExtINodePtr)} can't be nullptr."); Push(); continue; } var stExtINode = stExtINodePtr.GetStructure <StExt4Inode>(); var stBlockListPtr = ExtX_Get_BlockList(partInfo.ExtUnmanagedManager.ExtManagerPtr, stExtINodePtr); if (stBlockListPtr == IntPtr.Zero) { //LoggerService.WriteCallerLine($"{nameof(stBlockListPtr)} can't be nullptr."); Push(); continue; } var extFileInfo = new ExtFileInfo { StDirEntry = stDirEntry, StExt4DirEntry = stExtDirEntry, BlockListPtr = stBlockListPtr, StExt4Inode = stExtINode }; if (stExtDirEntry.file_type == Ext4FileType.Directory) { var dir = FileFactory.CreateDirectory(Constants.DirectoryKey_Ext); var dirStoken = dir.GetStoken(Constants.DirectoryKey_Ext); dirStoken.TypeGuid = Constants.DirectoryType_Ext; file = dir; fileStoken2 = dirStoken; EditFileStoken2(fileStoken2, partInfo, extFileInfo); //当目录名为".."或者"."时,跳过加载子文件; //且所加载目录不能被删除; if (stExtDirEntry._name[0] != '.' && !stDirEntry.bDel) { LoadDirectoryContent(dir, partInfo, ntfSzAct, isCancel); } else if (stExtDirEntry._name[1] == '.') { dirStoken.IsBack = true; } else { dirStoken.IsLocalBackUp = true; } } else if (stExtDirEntry.file_type == Ext4FileType.RegularFile) { var regFile = FileFactory.CreateRegularFile(Constants.RegularFileKey_Ext); var regFileStoken = regFile.GetStoken(Constants.RegularFileKey_Ext); regFileStoken.TypeGuid = Constants.RegularFileType_Ext; file = regFile; fileStoken2 = regFileStoken; EditFileStoken2(fileStoken2, partInfo, extFileInfo); ntfSzAct?.Invoke(fileStoken2.Size); } Push(); if (isCancel?.Invoke() ?? false) { return; } } }