private byte[] CreatePatchedKernel() { SetStatus(Resources.BuildingCustom); if (Directory.Exists(tempDirectory)) { Directory.Delete(tempDirectory, true); } Directory.CreateDirectory(tempDirectory); Directory.CreateDirectory(kernelDirectory); Directory.CreateDirectory(ramfsDirectory); if (!ExecuteTool("unpackbootimg.exe", string.Format("-i \"{0}\" -o \"{1}\"", KernelDump, kernelDirectory))) { throw new Exception("Can't unpack kernel image"); } if (!ExecuteTool("lzop.exe", string.Format("-d \"{0}\" -o \"{1}\"", Path.Combine(kernelDirectory, "kernel.img-ramdisk.gz"), initramfs_cpio))) { throw new Exception("Can't unpack ramdisk"); } ExecuteTool("cpio.exe", string.Format("-imd --no-preserve-owner --quiet -I \"{0}\"", @"..\initramfs.cpio"), ramfsDirectory); if (!File.Exists(Path.Combine(ramfsDirectory, "init"))) // cpio.exe fails on Windows XP for some reason. But working! { throw new Exception("Can't unpack ramdisk 2"); } if (Directory.Exists(hakchiDirectory)) { Directory.Delete(hakchiDirectory, true); } NesMiniApplication.DirectoryCopy(Path.Combine(modsDirectory, Mod), ramfsDirectory, true); var ramfsFiles = Directory.GetFiles(ramfsDirectory, "*.*", SearchOption.AllDirectories); foreach (var file in ramfsFiles) { var fInfo = new FileInfo(file); if (fInfo.Length > 10 && fInfo.Length < 100 && ((fInfo.Attributes & FileAttributes.System) == 0) && (Encoding.ASCII.GetString(File.ReadAllBytes(file), 0, 10)) == "!<symlink>") { fInfo.Attributes |= FileAttributes.System; } } if (hmodsInstall != null && hmodsInstall.Count() > 0) { Directory.CreateDirectory(tempHmodsDirectory); foreach (var hmod in hmodsInstall) { var modName = hmod + ".hmod"; foreach (var dir in hmodDirectories) { if (Directory.Exists(Path.Combine(dir, modName))) { NesMiniApplication.DirectoryCopy(Path.Combine(dir, modName), Path.Combine(tempHmodsDirectory, modName), true); break; } if (File.Exists(Path.Combine(dir, modName))) { File.Copy(Path.Combine(dir, modName), Path.Combine(tempHmodsDirectory, modName)); break; } } } } if (hmodsUninstall != null && hmodsUninstall.Count() > 0) { Directory.CreateDirectory(tempHmodsDirectory); var mods = new StringBuilder(); foreach (var hmod in hmodsUninstall) { mods.AppendFormat("{0}.hmod\n", hmod); } File.WriteAllText(Path.Combine(tempHmodsDirectory, "uninstall"), mods.ToString()); } // Building image byte[] ramdisk; if (!ExecuteTool("mkbootfs.exe", string.Format("\"{0}\"", ramfsDirectory), out ramdisk)) { throw new Exception("Can't repack ramdisk"); } File.WriteAllBytes(initramfs_cpioPatched, ramdisk); var argCmdline = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-cmdline")).Trim(); var argBoard = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-board")).Trim(); var argBase = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-base")).Trim(); var argPagesize = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-pagesize")).Trim(); var argKerneloff = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-kerneloff")).Trim(); var argRamdiscoff = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-ramdiskoff")).Trim(); var argTagsoff = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-tagsoff")).Trim(); if (!ExecuteTool("lzop.exe", string.Format("--best -f -o \"{0}\" \"{1}\"", ramdiskPatched, initramfs_cpioPatched))) { throw new Exception("Can't repack ramdisk 2"); } if (!ExecuteTool("mkbootimg.exe", string.Format("--kernel \"{0}\" --ramdisk \"{1}\" --cmdline \"{2}\" --board \"{3}\" --base \"{4}\" --pagesize \"{5}\" --kernel_offset \"{6}\" --ramdisk_offset \"{7}\" --tags_offset \"{8}\" -o \"{9}\"", Path.Combine(kernelDirectory, "kernel.img-zImage"), ramdiskPatched, argCmdline, argBoard, argBase, argPagesize, argKerneloff, argRamdiscoff, argTagsoff, kernelPatched))) { throw new Exception("Can't rebuild kernel"); } var result = File.ReadAllBytes(kernelPatched); #if !DEBUG Directory.Delete(tempDirectory, true); #endif return(result); }
private byte[] CreatePatchedKernel(GamesTreeStats stats = null) { if (stats == null) { stats = new GamesTreeStats(); } bool first = stats.GamesProceed == 0; bool partial = stats.GamesProceed > 0; SetStatus(Resources.BuildingCustom); if (first) { if (Directory.Exists(tempDirectory)) { Directory.Delete(tempDirectory, true); } Directory.CreateDirectory(tempDirectory); Directory.CreateDirectory(kernelDirectory); Directory.CreateDirectory(ramfsDirectory); if (!ExecuteTool("unpackbootimg.exe", string.Format("-i \"{0}\" -o \"{1}\"", KernelDump, kernelDirectory))) { throw new Exception("Can't unpack kernel image"); } if (!ExecuteTool("lzop.exe", string.Format("-d \"{0}\" -o \"{1}\"", Path.Combine(kernelDirectory, "kernel.img-ramdisk.gz"), initramfs_cpio))) { throw new Exception("Can't unpack ramdisk"); } ExecuteTool("cpio.exe", string.Format("-imd --no-preserve-owner --quiet -I \"{0}\"", @"..\initramfs.cpio"), ramfsDirectory); if (!File.Exists(Path.Combine(ramfsDirectory, "init"))) // cpio.exe fails on Windows XP for some reason. But working! { throw new Exception("Can't unpack ramdisk 2"); } if (Directory.Exists(hakchiDirectory)) { Directory.Delete(hakchiDirectory, true); } NesMiniApplication.DirectoryCopy(Path.Combine(modsDirectory, Mod), ramfsDirectory, true); var ramfsFiles = Directory.GetFiles(ramfsDirectory, "*.*", SearchOption.AllDirectories); foreach (var file in ramfsFiles) { var fInfo = new FileInfo(file); if (fInfo.Length > 10 && fInfo.Length < 100 && ((fInfo.Attributes & FileAttributes.System) == 0) && (Encoding.ASCII.GetString(File.ReadAllBytes(file), 0, 10)) == "!<symlink>") { fInfo.Attributes |= FileAttributes.System; } } } if (!first && Directory.Exists(transferDirectory)) { Debug.WriteLine("Clearing transfer directory"); Directory.Delete(transferDirectory, true); } // Games! if (Games != null) { Directory.CreateDirectory(tempGamesDirectory); if (first) { File.WriteAllBytes(Path.Combine(tempGamesDirectory, "clear"), new byte[0]); Directory.CreateDirectory(originalGamesConfigDirectory); if (HiddenGames != null && HiddenGames.Length > 0) { StringBuilder h = new StringBuilder(); foreach (var game in HiddenGames) { h.Append(game + "\n"); } File.WriteAllText(hiddenPath, h.ToString()); } } stats.Next(); AddMenu(Games, stats); Debug.WriteLine(string.Format("Games copied: {0}/{1}, part size: {2}", stats.GamesProceed, stats.GamesTotal, stats.Size)); } bool last = stats.GamesProceed >= stats.GamesTotal; if (last && hmodsInstall != null && hmodsInstall.Count > 0) { Directory.CreateDirectory(tempHmodsDirectory); foreach (var hmod in hmodsInstall) { var modName = hmod + ".hmod"; foreach (var dir in hmodDirectories) { if (Directory.Exists(Path.Combine(dir, modName))) { NesMiniApplication.DirectoryCopy(Path.Combine(dir, modName), Path.Combine(tempHmodsDirectory, modName), true); break; } if (File.Exists(Path.Combine(dir, modName))) { File.Copy(Path.Combine(dir, modName), Path.Combine(tempHmodsDirectory, modName)); break; } } } } if (last && hmodsUninstall != null && hmodsUninstall.Count > 0) { Directory.CreateDirectory(tempHmodsDirectory); var mods = new StringBuilder(); foreach (var hmod in hmodsUninstall) { mods.AppendFormat("{0}.hmod\n", hmod); } File.WriteAllText(Path.Combine(tempHmodsDirectory, "uninstall"), mods.ToString()); } // Writing config if (Config != null && Config.Count > 0) { Directory.CreateDirectory(transferDirectory); var config = new StringBuilder(); foreach (var key in Config.Keys) { config.AppendFormat("cfg_{0}='{1}'\n", key, Config[key].Replace(@"'", @"\'")); } File.WriteAllText(configPath, config.ToString()); } // Building image if (first && Games != null && Games.Count > 0) // There is no reason to compress cryptsetup when we do not uploading games { ExecuteTool("upx.exe", "--best sbin\\cryptsetup", ramfsDirectory); } byte[] ramdisk; if (!ExecuteTool("mkbootfs.exe", string.Format("\"{0}\"", ramfsDirectory), out ramdisk)) { throw new Exception("Can't repack ramdisk"); } File.WriteAllBytes(initramfs_cpioPatched, ramdisk); var argCmdline = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-cmdline")).Trim(); var argBoard = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-board")).Trim(); var argBase = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-base")).Trim(); var argPagesize = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-pagesize")).Trim(); var argKerneloff = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-kerneloff")).Trim(); var argRamdiscoff = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-ramdiskoff")).Trim(); var argTagsoff = File.ReadAllText(Path.Combine(kernelDirectory, "kernel.img-tagsoff")).Trim(); if (!ExecuteTool("lzop.exe", string.Format("--best -f -o \"{0}\" \"{1}\"", ramdiskPatched, initramfs_cpioPatched))) { throw new Exception("Can't repack ramdisk 2"); } if (!ExecuteTool("mkbootimg.exe", string.Format("--kernel \"{0}\" --ramdisk \"{1}\" --cmdline \"{2}\" --board \"{3}\" --base \"{4}\" --pagesize \"{5}\" --kernel_offset \"{6}\" --ramdisk_offset \"{7}\" --tags_offset \"{8}\" -o \"{9}\"", Path.Combine(kernelDirectory, "kernel.img-zImage"), ramdiskPatched, argCmdline, argBoard, argBase, argPagesize, argKerneloff, argRamdiscoff, argTagsoff, kernelPatched))) { throw new Exception("Can't rebuild kernel"); } var result = File.ReadAllBytes(kernelPatched); #if !DEBUG if (last) { Directory.Delete(tempDirectory, true); } #endif if (result.Length > Fel.kernel_max_size) { throw new Exception("Kernel is too big"); } GC.Collect(); return(result); }