using Microsoft.VisualBasic; using System; using System.Collections.Generic; using System.IO; using System.Linq; using XboxToolkit; using XboxToolkit.Interface; namespace XboxToolkitTest { internal class Program { //public static bool GetSecuritySectorsFromXiso(ContainerReader input, bool compareMode, out HashSet securitySectors) //{ // securitySectors = new HashSet(); // var decoder = input.GetDecoder(); // var xgdInfo = decoder.GetXgdInfo(); // for (var j = 12544; j < 16640; j++) // { // if (decoder.TryReadSector(j, out var sectorData2) == false) // { // return false; // } // var isEmptySector = true; // for (var i = 0; i < sectorData2.Length; i++) // { // if (sectorData2[i] != 0) // { // isEmptySector = false; // break; // } // } // } // var flag = false; // var start = 0U; // var totalSectors = decoder.TotalSectors(); // for (uint sectorIndex = xgdInfo.BaseSector; sectorIndex <= totalSectors; sectorIndex++) // { // if (decoder.TryReadSector(sectorIndex, out var sectorData) == false) // { // return false; // } // var isEmptySector = true; // for (var i = 0; i < sectorData.Length; i++) // { // if (sectorData[i] != 0) // { // isEmptySector = false; // break; // } // } // var isDataSector = securitySectors.Contains(sectorIndex); // if (isEmptySector == true && flag == false && !isDataSector) // { // start = sectorIndex; // flag = true; // } // else if (isEmptySector == false && flag == true) // { // var end = sectorIndex - 1; // flag = false; // if (end - start == 0xFFF) // { // for (var i = start; i <= end; i++) // { // securitySectors.Add(i); // } // } // else if (compareMode && end - start > 0xFFF) // if more than 0xFFF, we "guess" this image is scrubbed so we stop // { // return true; // } // } // } // return true; //} public static void ProcessPngs() { //var input = @"J:\FailedXEX"; var input = @"J:\XEXDump\XEXDump"; var output = @"J:\XEXDump\PNGS"; var files = Directory.GetFiles(input, "*.xex"); foreach (var file in files) { try { var defaultData = File.ReadAllBytes(file); if (XexUtility.TryExtractXexMetaData(defaultData, out var metadata) == false) { File.Copy(file, $"J:\\FailedXEX\\{Path.GetFileName(file)}"); System.Diagnostics.Debug.Print($"Failed: {file}"); continue; } File.WriteAllBytes(Path.Combine(output, Path.GetFileNameWithoutExtension(file) + ".png"), metadata.Thumbnail); } catch (Exception ex) { File.Copy(file, $"J:\\FailedXEX\\{Path.GetFileName(file)}"); System.Diagnostics.Debug.Print(ex.ToString()); } } } static void MainOld() { ProcessPngs(); var z = ContainerUtility.TryAutoDetectContainerType(@"U:\Done\Gun (USA) (En,Fr,Es,It).cci", out var cc); { var m = cc.TryMount(); var n = cc.TryGetDefault(out var defaultData2, out var container); File.WriteAllBytes(@"J:\iso.xex", defaultData2); var qq = XexUtility.TryExtractXexMetaData(defaultData2, out var metadata); //XboxToolkit.ContainerUtility.ConvertContainerToCCI(cc, ProcessingOptions.All, @"J:\Army of Two (USA)\Army of Two (USA).cci", null); //var x = ContainerUtility.ConvertContainerToCCI(isoContainer, ProcessingOptions.All, @"G:\Xbox360\Test\Fifa.cci", p => //{ // Console.WriteLine(p.ToString()); //}); var filePath3 = @"G:\Xbox360\Test\Fifa.cci"; using var CCIContainer = new CCIContainerReader(filePath3); var q = CCIContainer.TryMount(); var xx = ContainerUtility.ExtractFilesFromContainer(CCIContainer, @"G:\Xbox360\Test3"); } // var x = ContainerUtility.ConvertContainerToCCI(isoContainer, ProcessingOptions.All, @"G:\Xbox360\far cry.cci"); ///3597756 //var cciContainer = new GODContainerReader(@"G:\Xbox360CCi's\Crysis.1.RF.X360-ZTM\45410968\00007000\801FA873A37D786F8DB0879D89FCEF5245"); // var cciContainer = new CCIContainerReader(@"G:\Xbox360\Crysis-trim.cci"); // var y = cciContainer.Mount(); // var q = cciContainer.TryGetDefault(out var d, out var xx); ////var x = ContainerUtility.ConvertContainerToISO(cciContainer, false, @"G:\Xbox360\Crysis.iso"); // var x = ContainerUtility.ConvertContainerToCCI(cciContainer, false, true, @"G:\Xbox360\Crysis-trim.cci"); //var isoContainer = new ISOContainerReader(@"G:\Xbox360\Crysis.iso"); //isoContainer.Mount(); //// var x = ContainerUtility.ConvertContainerToCCI(cciContainer, true, @"G:\Xbox360\Crysis.cci"); //isoContainer.TryGetDefault(out var xdefaultData, out var xcontainerType); var isoTest = true; var defaultData = Array.Empty(); var containerType = ContainerType.Unknown; if (isoTest) { //var filePath = @"G:\Xbox360\Crysis.1.RF.X360-ZTM\45410968\00007000\801FA873A37D786F8DB0879D89FCEF5245"; //var filePath = @"G:\Xbox360\MEMORICK - KNIGHTS APPRENT (USA-PAL).iso"; //var filePath = @"G:\Xbox360\Barbie Horse Adventures - Wild Horse Rescue (USA).iso"; //var filePath = @"G:\Xbox360\Far Cry 3 (USA, Europe) (En,Fr,De,Es,It,Nl,Pt,Sv,No,Da).iso"; //var filePath = @"G:\Xbox360\007 Legends (USA) (En,Fr,De).iso"; //var filePath = @"G:\Xbox360\MEMORICK - KNIGHTS APPRENT (USA-PAL).iso"; var filePath = @"G:\Xbox360\Burnout Paradise (USA).iso"; using var xisoContainerUtility = new ISOContainerReader(filePath); if (xisoContainerUtility.TryMount() == true && xisoContainerUtility.TryGetDefault(out defaultData, out containerType) == true) { //CCIUtility.ConvertContainerToCCI(xisoContainerUtility, false, @"G:\Xbox360\Burnout Paradise (USA)-noscrub.cci"); //CCIUtility.ConvertContainerToCCI(xisoContainerUtility, true, @"G:\Xbox360\Burnout Paradise (USA)-scrub.cci"); Console.WriteLine("Xiso format detected."); } else { using var godContainerUtility = new GODContainerReader(filePath); if (godContainerUtility.TryMount() == true && godContainerUtility.TryGetDefault(out defaultData, out containerType) == true) { Console.WriteLine("God format detected."); } else { Console.WriteLine("Unrecognized file format."); return; } } } else { defaultData = File.ReadAllBytes("default.xex"); } var result = XexUtility.TryExtractXexMetaData(defaultData, out var metaData); if (result == false) { Console.WriteLine("Failed."); return; } Console.WriteLine($"GameRegion: {metaData.GameRegion}"); Console.WriteLine(); Console.WriteLine($"TitleName: {metaData.TitleName}"); Console.WriteLine(); Console.WriteLine($"TitleId: {metaData.TitleId}"); Console.WriteLine(); Console.WriteLine($"MediaId: {metaData.MediaId}"); Console.WriteLine(); Console.WriteLine($"Version: {metaData.Version}"); Console.WriteLine(); Console.WriteLine($"BaseVersion: {metaData.BaseVersion}"); Console.WriteLine(); Console.WriteLine($"DiscNum: {metaData.DiscNum}"); Console.WriteLine(); Console.WriteLine($"DiscTotal: {metaData.DiscTotal}"); Console.WriteLine(); Console.WriteLine($"Description: {metaData.Description}"); Console.WriteLine(); Console.WriteLine($"Developer: {metaData.Developer}"); Console.WriteLine(); Console.WriteLine($"Genre: {metaData.Genre}"); Console.WriteLine(); Console.WriteLine($"ThumbnailLength: {metaData.Thumbnail.Length}"); Console.WriteLine(); File.WriteAllBytes("thumb.png", metaData.Thumbnail); Console.WriteLine("Success."); } static void Main() { // Skip directory structure test for now // DirectoryStructureTest.TestDirectoryStructure(); // Console.WriteLine(); // Console.WriteLine("Press any key to continue to ISO test..."); // Console.ReadKey(); // Console.WriteLine(); TestFolderToISO(); Console.WriteLine(); Console.WriteLine("Press any key to continue to CCI test..."); Console.ReadKey(); Console.WriteLine(); TestFolderToCCI(); } static void TestFolderToISO() { // Hardcoded folder path - change this to your test folder var sourceFolder = @"E:\isotest\game"; var isoOutputPath = @"E:\isotest\TestFolder.iso"; var extractOutputPath = @"E:\isotest\TestFolder_Extracted"; var comparisonOutputPath = @"E:\isotest\TestFolder_Comparison.txt"; Console.WriteLine("=== Xbox Original ISO Creation and Verification Test ==="); Console.WriteLine(); // Step 1: Create ISO from folder Console.WriteLine($"Step 1: Creating Xbox Original ISO from folder: {sourceFolder}"); if (!Directory.Exists(sourceFolder)) { Console.WriteLine($"ERROR: Source folder does not exist: {sourceFolder}"); return; } // Get file info before creating ISO var sourceFilesInfo = Directory.GetFiles(sourceFolder, "*", SearchOption.AllDirectories); var sourceDirsInfo = Directory.GetDirectories(sourceFolder, "*", SearchOption.AllDirectories); var totalSourceSize = sourceFilesInfo.Sum(f => new FileInfo(f).Length); Console.WriteLine($"Source folder contains:"); Console.WriteLine($" {sourceFilesInfo.Length} files"); Console.WriteLine($" {sourceDirsInfo.Length} directories"); Console.WriteLine($" Total size: {totalSourceSize / 1024.0 / 1024.0:F2} MB"); Console.WriteLine(); // List all files and directories for debugging Console.WriteLine("Source files:"); foreach (var file in sourceFilesInfo.OrderBy(f => f)) { var relPath = Path.GetRelativePath(sourceFolder, file).Replace('\\', '/'); Console.WriteLine($" {relPath}"); } Console.WriteLine(); Console.WriteLine("Source directories:"); foreach (var dir in sourceDirsInfo.OrderBy(d => d)) { var relPath = Path.GetRelativePath(sourceFolder, dir).Replace('\\', '/'); Console.WriteLine($" {relPath}/"); } Console.WriteLine(); var createSuccess = ContainerUtility.ConvertFolderToISO( sourceFolder, ISOFormat.XboxOriginal, isoOutputPath, 0, // No split point progress => Console.Write($"\rProgress: {progress:P2}") ); Console.WriteLine(); if (!createSuccess) { Console.WriteLine("ERROR: Failed to create ISO file."); return; } if (!File.Exists(isoOutputPath)) { Console.WriteLine("ERROR: ISO file was not created."); return; } var isoFileInfo = new FileInfo(isoOutputPath); Console.WriteLine($"SUCCESS: ISO created at: {isoOutputPath}"); Console.WriteLine($"ISO file size: {isoFileInfo.Length / 1024.0:F2} KB ({isoFileInfo.Length / 1024.0 / 1024.0:F2} MB)"); Console.WriteLine($"Expected size (approx): {totalSourceSize / 1024.0 / 1024.0:F2} MB + overhead"); Console.WriteLine(); // Step 2: Extract files from ISO Console.WriteLine($"Step 2: Extracting files from ISO to: {extractOutputPath}"); using var isoContainer = new ISOContainerReader(isoOutputPath); if (!isoContainer.TryMount()) { Console.WriteLine("ERROR: Failed to mount ISO container."); return; } var extractSuccess = ContainerUtility.ExtractFilesFromContainer(isoContainer, extractOutputPath); if (!extractSuccess) { Console.WriteLine("ERROR: Failed to extract files from ISO."); return; } Console.WriteLine($"SUCCESS: Files extracted to: {extractOutputPath}"); Console.WriteLine(); // List extracted files for debugging var extractedFilesInfo = Directory.GetFiles(extractOutputPath, "*", SearchOption.AllDirectories); var extractedDirsInfo = Directory.GetDirectories(extractOutputPath, "*", SearchOption.AllDirectories); Console.WriteLine($"Extracted folder contains:"); Console.WriteLine($" {extractedFilesInfo.Length} files"); Console.WriteLine($" {extractedDirsInfo.Length} directories"); Console.WriteLine(); Console.WriteLine("Extracted files:"); foreach (var file in extractedFilesInfo.OrderBy(f => f)) { var relPath = Path.GetRelativePath(extractOutputPath, file).Replace('\\', '/'); Console.WriteLine($" {relPath}"); } Console.WriteLine(); Console.WriteLine("Extracted directories:"); foreach (var dir in extractedDirsInfo.OrderBy(d => d)) { var relPath = Path.GetRelativePath(extractOutputPath, dir).Replace('\\', '/'); Console.WriteLine($" {relPath}/"); } Console.WriteLine(); // Step 3: Compare original and extracted files Console.WriteLine("Step 3: Comparing original and extracted files..."); var comparisonResults = new List(); var totalFiles = 0; var matchingFiles = 0; var mismatchedFiles = 0; var missingFiles = 0; var extraFiles = 0; // Get all files from source folder var sourceFilesList = Directory.GetFiles(sourceFolder, "*", SearchOption.AllDirectories) .Select(f => new { FullPath = f, RelativePath = Path.GetRelativePath(sourceFolder, f).Replace('\\', '/') }) .ToList(); // Get all files from extracted folder var extractedFiles = Directory.GetFiles(extractOutputPath, "*", SearchOption.AllDirectories) .Select(f => new { FullPath = f, RelativePath = Path.GetRelativePath(extractOutputPath, f).Replace('\\', '/') }) .ToDictionary(f => f.RelativePath, f => f.FullPath); // Compare each source file foreach (var sourceFile in sourceFilesList) { totalFiles++; var relativePath = sourceFile.RelativePath; if (!extractedFiles.ContainsKey(relativePath)) { missingFiles++; comparisonResults.Add($"MISSING: {relativePath} (exists in source but not in extracted)"); continue; } var extractedPath = extractedFiles[relativePath]; extractedFiles.Remove(relativePath); // Mark as found // Compare file contents var sourceBytes = File.ReadAllBytes(sourceFile.FullPath); var extractedBytes = File.ReadAllBytes(extractedPath); if (sourceBytes.Length != extractedBytes.Length) { mismatchedFiles++; comparisonResults.Add($"SIZE MISMATCH: {relativePath} (Source: {sourceBytes.Length} bytes, Extracted: {extractedBytes.Length} bytes)"); continue; } var bytesMatch = true; var firstMismatch = -1; for (var i = 0; i < sourceBytes.Length; i++) { if (sourceBytes[i] != extractedBytes[i]) { bytesMatch = false; firstMismatch = i; break; } } if (!bytesMatch) { mismatchedFiles++; comparisonResults.Add($"CONTENT MISMATCH: {relativePath} (First difference at byte offset: {firstMismatch})"); } else { matchingFiles++; } } // Check for extra files in extracted folder foreach (var extraFile in extractedFiles) { extraFiles++; comparisonResults.Add($"EXTRA: {extraFile.Key} (exists in extracted but not in source)"); } // Write comparison results using var writer = new StreamWriter(comparisonOutputPath); writer.WriteLine("=== File Comparison Results ==="); writer.WriteLine($"Total files in source: {totalFiles}"); writer.WriteLine($"Matching files: {matchingFiles}"); writer.WriteLine($"Mismatched files: {mismatchedFiles}"); writer.WriteLine($"Missing files: {missingFiles}"); writer.WriteLine($"Extra files: {extraFiles}"); writer.WriteLine(); if (comparisonResults.Count > 0) { writer.WriteLine("=== Detailed Results ==="); foreach (var result in comparisonResults) { writer.WriteLine(result); } } else { writer.WriteLine("All files match perfectly!"); } // Print summary to console Console.WriteLine($"Total files: {totalFiles}"); Console.WriteLine($"Matching: {matchingFiles}"); Console.WriteLine($"Mismatched: {mismatchedFiles}"); Console.WriteLine($"Missing: {missingFiles}"); Console.WriteLine($"Extra: {extraFiles}"); Console.WriteLine(); if (mismatchedFiles == 0 && missingFiles == 0 && extraFiles == 0) { Console.WriteLine("SUCCESS: All files match perfectly!"); } else { Console.WriteLine($"WARNING: Found {mismatchedFiles + missingFiles + extraFiles} issues. See {comparisonOutputPath} for details."); } Console.WriteLine($"Detailed results written to: {comparisonOutputPath}"); } static void TestFolderToCCI() { // Hardcoded folder path - change this to your test folder var sourceFolder = @"E:\isotest\game"; var cciOutputPath = @"E:\isotest\TestFolder.cci"; var extractOutputPath = @"E:\isotest\TestFolder_CCI_Extracted"; var comparisonOutputPath = @"E:\isotest\TestFolder_CCI_Comparison.txt"; Console.WriteLine("=== Xbox Original CCI Creation and Verification Test ==="); Console.WriteLine(); // Step 1: Create CCI from folder Console.WriteLine($"Step 1: Creating Xbox Original CCI from folder: {sourceFolder}"); if (!Directory.Exists(sourceFolder)) { Console.WriteLine($"ERROR: Source folder does not exist: {sourceFolder}"); return; } // Get file info before creating CCI var sourceFilesInfo = Directory.GetFiles(sourceFolder, "*", SearchOption.AllDirectories); var sourceDirsInfo = Directory.GetDirectories(sourceFolder, "*", SearchOption.AllDirectories); var totalSourceSize = sourceFilesInfo.Sum(f => new FileInfo(f).Length); Console.WriteLine($"Source folder contains:"); Console.WriteLine($" {sourceFilesInfo.Length} files"); Console.WriteLine($" {sourceDirsInfo.Length} directories"); Console.WriteLine($" Total size: {totalSourceSize / 1024.0 / 1024.0:F2} MB"); Console.WriteLine(); // List all files and directories for debugging Console.WriteLine("Source files:"); foreach (var file in sourceFilesInfo.OrderBy(f => f)) { var relPath = Path.GetRelativePath(sourceFolder, file).Replace('\\', '/'); Console.WriteLine($" {relPath}"); } Console.WriteLine(); Console.WriteLine("Source directories:"); foreach (var dir in sourceDirsInfo.OrderBy(d => d)) { var relPath = Path.GetRelativePath(sourceFolder, dir).Replace('\\', '/'); Console.WriteLine($" {relPath}/"); } Console.WriteLine(); var createSuccess = ContainerUtility.ConvertFolderToCCI( sourceFolder, ISOFormat.XboxOriginal, cciOutputPath, 0, // No split point progress => Console.Write($"\rProgress: {progress:P2}") ); Console.WriteLine(); if (!createSuccess) { Console.WriteLine("ERROR: Failed to create CCI file."); return; } if (!File.Exists(cciOutputPath)) { Console.WriteLine("ERROR: CCI file was not created."); return; } var cciFileInfo = new FileInfo(cciOutputPath); Console.WriteLine($"SUCCESS: CCI created at: {cciOutputPath}"); Console.WriteLine($"CCI file size: {cciFileInfo.Length / 1024.0:F2} KB ({cciFileInfo.Length / 1024.0 / 1024.0:F2} MB)"); Console.WriteLine($"Expected size (approx): {totalSourceSize / 1024.0 / 1024.0:F2} MB + overhead"); Console.WriteLine(); // Step 2: Extract files from CCI Console.WriteLine($"Step 2: Extracting files from CCI to: {extractOutputPath}"); using var cciContainer = new CCIContainerReader(cciOutputPath); if (!cciContainer.TryMount()) { Console.WriteLine("ERROR: Failed to mount CCI container."); return; } var extractSuccess = ContainerUtility.ExtractFilesFromContainer(cciContainer, extractOutputPath); if (!extractSuccess) { Console.WriteLine("ERROR: Failed to extract files from CCI."); return; } Console.WriteLine($"SUCCESS: Files extracted to: {extractOutputPath}"); Console.WriteLine(); // List extracted files for debugging var extractedFilesInfo = Directory.GetFiles(extractOutputPath, "*", SearchOption.AllDirectories); var extractedDirsInfo = Directory.GetDirectories(extractOutputPath, "*", SearchOption.AllDirectories); Console.WriteLine($"Extracted folder contains:"); Console.WriteLine($" {extractedFilesInfo.Length} files"); Console.WriteLine($" {extractedDirsInfo.Length} directories"); Console.WriteLine(); Console.WriteLine("Extracted files:"); foreach (var file in extractedFilesInfo.OrderBy(f => f)) { var relPath = Path.GetRelativePath(extractOutputPath, file).Replace('\\', '/'); Console.WriteLine($" {relPath}"); } Console.WriteLine(); Console.WriteLine("Extracted directories:"); foreach (var dir in extractedDirsInfo.OrderBy(d => d)) { var relPath = Path.GetRelativePath(extractOutputPath, dir).Replace('\\', '/'); Console.WriteLine($" {relPath}/"); } Console.WriteLine(); // Step 3: Compare original and extracted files Console.WriteLine("Step 3: Comparing original and extracted files..."); var comparisonResults = new List(); var totalFiles = 0; var matchingFiles = 0; var mismatchedFiles = 0; var missingFiles = 0; var extraFiles = 0; // Get all files from source folder var sourceFilesList = Directory.GetFiles(sourceFolder, "*", SearchOption.AllDirectories) .Select(f => new { FullPath = f, RelativePath = Path.GetRelativePath(sourceFolder, f).Replace('\\', '/') }) .ToList(); // Get all files from extracted folder var extractedFiles = Directory.GetFiles(extractOutputPath, "*", SearchOption.AllDirectories) .Select(f => new { FullPath = f, RelativePath = Path.GetRelativePath(extractOutputPath, f).Replace('\\', '/') }) .ToDictionary(f => f.RelativePath, f => f.FullPath); // Compare each source file foreach (var sourceFile in sourceFilesList) { totalFiles++; var relativePath = sourceFile.RelativePath; if (!extractedFiles.ContainsKey(relativePath)) { missingFiles++; comparisonResults.Add($"MISSING: {relativePath} (exists in source but not in extracted)"); continue; } var extractedPath = extractedFiles[relativePath]; extractedFiles.Remove(relativePath); // Mark as found // Compare file contents var sourceBytes = File.ReadAllBytes(sourceFile.FullPath); var extractedBytes = File.ReadAllBytes(extractedPath); if (sourceBytes.Length != extractedBytes.Length) { mismatchedFiles++; comparisonResults.Add($"SIZE MISMATCH: {relativePath} (Source: {sourceBytes.Length} bytes, Extracted: {extractedBytes.Length} bytes)"); continue; } var bytesMatch = true; var firstMismatch = -1; for (var i = 0; i < sourceBytes.Length; i++) { if (sourceBytes[i] != extractedBytes[i]) { bytesMatch = false; firstMismatch = i; break; } } if (!bytesMatch) { mismatchedFiles++; comparisonResults.Add($"CONTENT MISMATCH: {relativePath} (First difference at byte offset: {firstMismatch})"); } else { matchingFiles++; } } // Check for extra files in extracted folder foreach (var extraFile in extractedFiles) { extraFiles++; comparisonResults.Add($"EXTRA: {extraFile.Key} (exists in extracted but not in source)"); } // Write comparison results using var writer = new StreamWriter(comparisonOutputPath); writer.WriteLine("=== File Comparison Results ==="); writer.WriteLine($"Total files in source: {totalFiles}"); writer.WriteLine($"Matching files: {matchingFiles}"); writer.WriteLine($"Mismatched files: {mismatchedFiles}"); writer.WriteLine($"Missing files: {missingFiles}"); writer.WriteLine($"Extra files: {extraFiles}"); writer.WriteLine(); if (comparisonResults.Count > 0) { writer.WriteLine("=== Detailed Results ==="); foreach (var result in comparisonResults) { writer.WriteLine(result); } } else { writer.WriteLine("All files match perfectly!"); } // Print summary to console Console.WriteLine($"Total files: {totalFiles}"); Console.WriteLine($"Matching: {matchingFiles}"); Console.WriteLine($"Mismatched: {mismatchedFiles}"); Console.WriteLine($"Missing: {missingFiles}"); Console.WriteLine($"Extra: {extraFiles}"); Console.WriteLine(); if (mismatchedFiles == 0 && missingFiles == 0 && extraFiles == 0) { Console.WriteLine("SUCCESS: All files match perfectly!"); } else { Console.WriteLine($"WARNING: Found {mismatchedFiles + missingFiles + extraFiles} issues. See {comparisonOutputPath} for details."); } Console.WriteLine($"Detailed results written to: {comparisonOutputPath}"); } } }