/// <summary> /// Initializes a new instance of a FileNode. /// </summary> /// <param name="fileInfo">A LfsFileInfo retrieved from an LTO Flash! device.</param> /// <remarks>This constructor is used to create a user interface to display the file system /// retrieved from a Locutus device.</remarks> protected FileNode(ILfsFileInfo fileInfo) : this() { _longName = fileInfo.LongName; if (string.Compare(fileInfo.LongName, fileInfo.ShortName, StringComparison.Ordinal) != 0) { _shortName = fileInfo.ShortName; } _color = fileInfo.Color; _globalFileNumber = fileInfo.GlobalFileNumber; }
/// <summary> /// Remove all the forks from a file. /// </summary> /// <param name="file">The file from which all forks are to be removed.</param> public static void RemoveForks(this ILfsFileInfo file) { if (file != null) { file.Rom = null; file.Manual = null; file.JlpFlash = null; file.Vignette = null; file.ReservedFork4 = null; file.ReservedFork5 = null; file.ReservedFork6 = null; } }
private static void SyncFileData(FileNode localFile, ILfsFileInfo deviceFile, bool updateOnly, Dictionary <ushort, ushort> forkNumberMap, Dictionary <ushort, string> forkSourceFileMap, FileSystemSyncErrors syncErrors) { localFile.Color = deviceFile.Color; localFile.LongName = deviceFile.LongName; localFile.ShortName = deviceFile.ShortName; System.Diagnostics.Debug.Assert(localFile.GlobalFileNumber == deviceFile.GlobalFileNumber, "Need to figure out how to set GFN"); System.Diagnostics.Debug.Assert(localFile.GlobalDirectoryNumber == deviceFile.GlobalDirectoryNumber, "Need to figure out how to set GDN"); switch (deviceFile.FileType) { case FileType.File: var program = (Program)localFile; var forks = new ushort[(int)ForkKind.NumberOfForkKinds]; for (int i = 0; i < forks.Length; ++i) { ushort forkNumber; if (!forkNumberMap.TryGetValue(deviceFile.ForkNumbers[i], out forkNumber)) { forkNumber = GlobalForkTable.InvalidForkNumber; } forks[i] = forkNumber; } program.SetForks(deviceFile.ForkNumbers); ProgramDescription description = null; SyncForkData(localFile.Rom, ForkKind.Program, forkSourceFileMap, (f, k) => ReportForkSyncError(f, k, localFile, syncErrors), ref description); if (description != null) { program.Description = description; } SyncForkData(localFile.Manual, ForkKind.Manual, forkSourceFileMap, (f, k) => ReportForkSyncError(f, k, localFile, syncErrors), ref description); SyncForkData(localFile.JlpFlash, ForkKind.JlpFlash, forkSourceFileMap, (f, k) => ReportForkSyncError(f, k, localFile, syncErrors), ref description); SyncForkData(localFile.Vignette, ForkKind.Vignette, forkSourceFileMap, (f, k) => ReportForkSyncError(f, k, localFile, syncErrors), ref description); SyncForkData(localFile.ReservedFork4, ForkKind.Reserved4, forkSourceFileMap, (f, k) => ReportForkSyncError(f, k, localFile, syncErrors), ref description); SyncForkData(localFile.ReservedFork5, ForkKind.Reserved5, forkSourceFileMap, (f, k) => ReportForkSyncError(f, k, localFile, syncErrors), ref description); SyncForkData(localFile.ReservedFork6, ForkKind.Reserved6, forkSourceFileMap, (f, k) => ReportForkSyncError(f, k, localFile, syncErrors), ref description); break; case FileType.Folder: for (var i = 0; i < deviceFile.ForkNumbers.Length; ++i) { ((Folder)localFile).ForkNumbers[i] = deviceFile.ForkNumbers[i]; } break; default: throw new System.InvalidOperationException(Resources.Strings.FileSystem_InvalidFileType); } }
/// <summary> /// Determines whether the given file entry is contained in the file add, update or delete differences. /// </summary> /// <param name="file">The file to search for.</param> /// <param name="operation">Which kind of operations to search for.</param> /// <returns><c>true</c> if the given file participates in any of the given operations.</returns> public bool Contains(ILfsFileInfo file, LfsOperations operation) { var isInDiff = false; if (operation.HasFlag(LfsOperations.Add)) { isInDiff |= FileDifferences.ToAdd.Any(f => f.GlobalFileNumber == file.GlobalFileNumber); } if (operation.HasFlag(LfsOperations.Update)) { isInDiff |= FileDifferences.ToUpdate.Any(f => f.GlobalFileNumber == file.GlobalFileNumber); } if (operation.HasFlag(LfsOperations.Remove)) { isInDiff |= FileDifferences.ToDelete.Contains(file.GlobalFileNumber); } return(isInDiff); }
/// <summary> /// Determines whether a file is using a particular Fork. /// </summary> /// <param name="file">The file whose Forks are being searched.</param> /// <param name="fork">The fork of interest.</param> /// <returns><c>true</c> if the file uses the given Fork.</returns> public static bool UsesFork(this ILfsFileInfo file, Fork fork) { bool usesFork = false; if (file != null && fork != null) { Fork[] forks = new Fork[(int)ForkKind.NumberOfForkKinds] { file.Rom, file.Manual, file.JlpFlash, file.Vignette, file.ReservedFork4, file.ReservedFork5, file.ReservedFork6, }; usesFork = forks.Contains(fork); } return(usesFork); }
private LfsOperationData(LfsOperations operation, ILfsFileInfo file) : this(operation, LfsEntityType.File, file) { FileSystemNumber = file.GlobalFileNumber; }
private static void ReportForkSyncError(Fork fork, ForkKind forkKind, ILfsFileInfo localFile, FileSystemSyncErrors syncErrors) { System.Diagnostics.Debug.WriteLine("What to do with " + forkKind + " for file number " + localFile.GlobalFileNumber + "??"); syncErrors.UnsupportedForks.Add(new Tuple <ILfsFileInfo, Fork>(localFile, fork)); }
private static string GetPathForFork(ExecuteDeviceCommandAsyncTaskData data, Fork fork, FileSystem deviceFileSystem, IEnumerable <ProgramDescription> roms, RomListConfiguration romsConfiguration, ref string destinationDir, out bool retrievalNecessary) { retrievalNecessary = false; string forkPath = null; var forkFileKind = ProgramFileKind.None; var crc = 0u; var cfgCrc = 0u; var errors = data.Result as FileSystemSyncErrors; // Determine what kind of fork this is. ILfsFileInfo fileContainingFork = null; var forkKind = deviceFileSystem.GetForkKind(fork, out fileContainingFork); switch (forkKind) { case ForkKind.Program: // Try to fetch LUIGI header from the fork. forkFileKind = ProgramFileKind.LuigiFile; forkPath = GetRomPathForForkFromRomList(data, fork, roms, romsConfiguration.RomsDirectory, out crc, out cfgCrc); if (forkPath == null) { forkPath = GetRomPathForForkFromCache(fork, romsConfiguration.RomsDirectory); } if ((forkPath == null) && string.IsNullOrEmpty(destinationDir)) { destinationDir = romsConfiguration.RomsDirectory; } break; case ForkKind.JlpFlash: if (string.IsNullOrEmpty(destinationDir)) { destinationDir = romsConfiguration.RomsDirectory; // seems sensible to keep save data file(s) next to the ROM } forkFileKind = ProgramFileKind.SaveData; break; case ForkKind.Manual: if (string.IsNullOrEmpty(destinationDir)) { destinationDir = romsConfiguration.ManualsDirectory; } forkFileKind = ProgramFileKind.ManualText; break; case ForkKind.Vignette: if (string.IsNullOrEmpty(destinationDir)) { destinationDir = Configuration.Instance.VignetteDataAreaPath; // keep next to ROM? } forkFileKind = ProgramFileKind.Vignette; break; case ForkKind.Reserved4: case ForkKind.Reserved5: case ForkKind.Reserved6: if (string.IsNullOrEmpty(destinationDir)) { destinationDir = Configuration.Instance.ReservedDataAreaPath; // keep next to ROM? } forkFileKind = ProgramFileKind.GenericSupportFile; errors.UnsupportedForks.Add(new Tuple <ILfsFileInfo, Fork>(fileContainingFork, fork)); ////throw new UnsupportedForkKindException(forkKind); break; case ForkKind.None: // An orphaned fork. Retrieve it, but we can't really do much with it. if (string.IsNullOrEmpty(destinationDir)) { destinationDir = Configuration.Instance.RecoveredDataAreaPath; // orphaned fork } forkFileKind = ProgramFileKind.None; errors.OrphanedForks.Add(fork); break; default: throw new UnsupportedForkKindException(forkKind); } if ((destinationDir != null) && (forkPath == null)) { retrievalNecessary = true; var forkFileBaseName = (fileContainingFork == null) ? Configuration.Instance.GetForkDataFileName(fork.GlobalForkNumber) : fileContainingFork.LongName.EnsureValidFileName(); var extension = forkFileKind.FileExtension(); // For the menu position fork, use the default extension; since it's in the manual fork slot, we want // to override the .txt extension. if (string.IsNullOrEmpty(extension) || (fork.Uid == Fork.MenuPositionForkUid)) { extension = Configuration.ForkExtension; } var forkFileName = System.IO.Path.ChangeExtension(forkFileBaseName, extension); var destFile = System.IO.Path.Combine(destinationDir, forkFileName); if (System.IO.File.Exists(destFile)) { var existingCrc = 0u; var existingCfgCrc = 0u; var luigiHeader = LuigiFileHeader.GetHeader(destFile); if ((luigiHeader != null) && (luigiHeader.Version > 0)) { existingCrc = luigiHeader.OriginalRomCrc32; existingCfgCrc = luigiHeader.OriginalCfgCrc32; } if (existingCrc == 0) { existingCrc = Crc32.OfFile(destFile); } if (existingCfgCrc == 0) { var destCfgFile = System.IO.Path.ChangeExtension(destFile, ProgramFileKind.CfgFile.FileExtension()); if (System.IO.File.Exists(destCfgFile)) { existingCfgCrc = Crc32.OfFile(destCfgFile); } } // This is the equivalent of RomComparerStrict: We skip retrieval only if both the ROM CRCs match and, if available, the .cfg CRCs match. if ((crc != 0) && (existingCrc == crc) && ((cfgCrc == 0) || (existingCfgCrc == cfgCrc))) { retrievalNecessary = false; forkPath = destFile; } else { forkPath = destFile.EnsureUniqueFileName(); } } else { forkPath = destFile; } } if (!string.IsNullOrEmpty(forkPath) && !System.IO.File.Exists(forkPath)) { retrievalNecessary = true; destinationDir = System.IO.Path.GetDirectoryName(forkPath); } return(forkPath); }