dev
cfig 3 weeks ago
parent 43078016d4
commit 1ba97938ff

@ -525,23 +525,46 @@ class Common {
} }
} }
fun createWorkspaceIni(fileName: String) { fun createWorkspaceIni(fileName: String, iniFileName: String = "workspace.ini", prefix: String? = null) {
//create workspace file log.trace("create workspace file")
val workspaceFile = File(Helper.prop("workDir"), "workspace.ini").canonicalPath val workDir = Helper.prop("workDir")
val workspaceFile = File(workDir, iniFileName)
try { try {
FileOutputStream(workspaceFile).use { output -> if (prefix.isNullOrBlank()) {
Properties().also { // override existing file entirely when prefix is null or empty
it.setProperty("file", fileName) val props = Properties().apply {
it.setProperty("workDir", Helper.prop("workDir")) setProperty("file", fileName)
it.setProperty("role", File(fileName).name) setProperty("workDir", workDir)
it.store(output, "unpackInternal configuration") setProperty("role", File(fileName).name)
}
FileOutputStream(workspaceFile).use { out ->
props.store(out, "unpackInternal configuration (overridden)")
}
log.info("workspace file overridden: ${workspaceFile.canonicalPath}")
} else {
// merge into existing (or create new) with prefixed keys
val props = Properties().apply {
if (workspaceFile.exists()) {
FileInputStream(workspaceFile).use { load(it) }
}
} }
log.info("workspace file created: $workspaceFile")
fun key(name: String) = "${prefix.trim()}.$name"
props.setProperty(key("file"), fileName)
props.setProperty(key("workDir"), workDir)
props.setProperty(key("role"), File(fileName).name)
FileOutputStream(workspaceFile).use { out ->
props.store(out, "unpackInternal configuration (with prefix='$prefix')")
}
log.info("workspace file created/updated with prefix '$prefix': ${workspaceFile.canonicalPath}")
} }
} catch (e: IOException) { } catch (e: IOException) {
log.error("error writing workspace file: ${e.message}") log.error("error writing workspace file: ${e.message}")
} }
//create workspace file done
log.trace("create workspace file done")
} }
} }
} }

@ -300,8 +300,8 @@ data class BootV2(
"verify fail" "verify fail"
} }
Avb.getJsonFileName(info.output).let { jsonFile -> Avb.getJsonFileName(info.output).let { jsonFile ->
it.addRow("AVB info [$verifyStatus]", jsonFile) it.addRow("AVB info [$verifyStatus]", shortenPath(jsonFile))
prints.add(Pair("AVB info [$verifyStatus]", jsonFile)) prints.add(Pair("AVB info [$verifyStatus]", shortenPath(jsonFile)))
if (File(jsonFile).exists()) { if (File(jsonFile).exists()) {
mapper.readValue(File(jsonFile), AVBInfo::class.java).let { ai -> mapper.readValue(File(jsonFile), AVBInfo::class.java).let { ai ->
val inspectRet = Avb.inspectKey(ai) val inspectRet = Avb.inspectKey(ai)
@ -362,11 +362,11 @@ data class BootV2(
if (theDtb.size > 0) { if (theDtb.size > 0) {
val dtbCount = this.dtb!!.dtbList.size val dtbCount = this.dtb!!.dtbList.size
it.addRule() it.addRule()
it.addRow("dtb", theDtb.file) it.addRow("dtb", theDtb.file?.let { fullPath -> shortenPath(fullPath) })
prints.add(Pair("dtb", theDtb.file.toString())) prints.add(Pair("dtb", shortenPath(theDtb.file.toString())))
if (File(theDtb.file + ".0.${dtsSuffix}").exists()) { if (File(theDtb.file + ".0.${dtsSuffix}").exists()) {
it.addRow("\\-- decompiled dts [$dtbCount]", theDtb.file + ".*.${dtsSuffix}") it.addRow("\\-- decompiled dts [$dtbCount]", shortenPath(theDtb.file + ".*.${dtsSuffix}"))
prints.add(Pair("\\-- decompiled dts [$dtbCount]", theDtb.file + ".*.${dtsSuffix}")) prints.add(Pair("\\-- decompiled dts [$dtbCount]", shortenPath(theDtb.file + ".*.${dtsSuffix}")))
} }
} }
} }
@ -377,8 +377,8 @@ data class BootV2(
val tabVBMeta = AsciiTable().let { val tabVBMeta = AsciiTable().let {
if (File("vbmeta.img").exists()) { if (File("vbmeta.img").exists()) {
it.addRule() it.addRule()
it.addRow("vbmeta.img", Avb.getJsonFileName("vbmeta.img")) it.addRow("vbmeta.img", shortenPath(Avb.getJsonFileName("vbmeta.img")))
prints.add(Pair("vbmeta.img", Avb.getJsonFileName("vbmeta.img"))) prints.add(Pair("vbmeta.img", shortenPath(Avb.getJsonFileName("vbmeta.img"))))
it.addRule() it.addRule()
"\n" + it.render() "\n" + it.render()
} else { } else {

@ -341,7 +341,9 @@ data class VendorBoot(
} }
fun postCopy(outFile: String): VendorBoot { fun postCopy(outFile: String): VendorBoot {
val signedFile = Helper.joinPath(Helper.prop("intermediateDir")!!, this.info.role + ".signed") val dir = Helper.prop("intermediateDir")!!
val signedFile = Helper.joinPath(dir, "${info.role}.signed").takeIf { File(it).exists() }
?: Helper.joinPath(dir, "${info.role}.clear")
log.info("COPY $signedFile -> $outFile") log.info("COPY $signedFile -> $outFile")
File(signedFile).copyTo(File(outFile), overwrite = true) File(signedFile).copyTo(File(outFile), overwrite = true)
return this return this

@ -1,6 +1,7 @@
package packable package packable
import cfig.bootimg.Common import cfig.bootimg.Common
import cfig.bootimg.v3.VendorBoot
import cfig.helper.Helper import cfig.helper.Helper
import cfig.helper.Helper.Companion.check_call import cfig.helper.Helper.Companion.check_call
import cfig.helper.Helper.Companion.check_output import cfig.helper.Helper.Companion.check_output
@ -15,13 +16,24 @@ class DeviceTreeParser : IPackable {
override fun capabilities(): List<String> { override fun capabilities(): List<String> {
return listOf("^.*\\.dtb$") return listOf("^.*\\.dtb$")
} }
override val loopNo: Int override val loopNo: Int
get() = 1 get() = 1
override fun unpack(fileName: String) { override fun unpack(fileName: String) {
super.clear() unpackInternal(fileName, Helper.prop("workDir")!!)
log.info("unpacking $fileName") }
val outFile = workDir + fileName.removeSuffix(".dtb") + "." + Helper.prop("config.dts_suffix")
fun unpackInternal(fileName: String, unpackDir: String) {
//set workdir
log.info("unpackInternal(fileName: $fileName, unpackDir: $unpackDir)")
Helper.setProp("workDir", unpackDir)
clear()
//create workspace file
Common.createWorkspaceIni(fileName)
//create workspace file done
val outFile = File(workDir, File(fileName).nameWithoutExtension + "." + Helper.prop("config.dts_suffix")).path
DTC().decompile(fileName, outFile) DTC().decompile(fileName, outFile)
//print summary //print summary
@ -32,15 +44,26 @@ class DeviceTreeParser : IPackable {
} }
override fun pack(fileName: String) { override fun pack(fileName: String) {
log.info("packing $fileName") packInternal(Helper.prop("workDir")!!, fileName)
val outFile = workDir + fileName.removeSuffix(".dtb") + "." + Helper.prop("config.dts_suffix") }
check(DTC().compile(outFile, "$fileName.new")) { "fail to compile dts" }
fun packInternal(workspace: String, outFileName: String) {
log.info("packInternal($workspace, $outFileName)")
Helper.setProp("workDir", workspace)
//workspace+cfg
val iniRole = Common.loadProperties(File(workspace, "workspace.ini").canonicalPath).getProperty("role")
val dtsSrc = File(workDir, File(iniRole).nameWithoutExtension + "." + Helper.prop("config.dts_suffix")).path
val origFile = File(workDir, File(outFileName).name + ".orig").path
log.info("COPY $outFileName -> $origFile")
File(outFileName).copyTo(File(origFile), overwrite = true)
check(DTC().compile(dtsSrc, outFileName)) { "fail to compile dts" }
//print summary //print summary
val prints: MutableList<Pair<String, String>> = mutableListOf() val prints: MutableList<Pair<String, String>> = mutableListOf()
prints.add(Pair("DTS", outFile)) prints.add(Pair("DTS", dtsSrc))
prints.add(Pair("updated DTB", "$fileName.new")) prints.add(Pair("updated DTB", outFileName))
log.info("\n\t\t\tPack Summary of {}\n{}\n", fileName, Common.table2String(prints)) log.info("\n\t\t\tPack Summary of {}\n{}\n", outFileName, Common.table2String(prints))
} }
fun pull(fileName: String) { fun pull(fileName: String) {

@ -53,8 +53,9 @@ class VBMetaParser : IPackable {
it.mkdirs() it.mkdirs()
} }
} }
//workspace.ini
log.info("workspace set to $unpackDir") log.info("workspace set to $unpackDir")
Common.createWorkspaceIni(fileName) Common.createWorkspaceIni(fileName, prefix = "vbmeta")
val ai = AVBInfo.parseFrom(Dumpling(fileName)).dumpDefault(fileName) val ai = AVBInfo.parseFrom(Dumpling(fileName)).dumpDefault(fileName)
log.info("Signing Key: " + Avb.inspectKey(ai)) log.info("Signing Key: " + Avb.inspectKey(ai))
@ -66,9 +67,9 @@ class VBMetaParser : IPackable {
// called via reflection // called via reflection
fun packInternal(workspace: String, outFileName: String) { fun packInternal(workspace: String, outFileName: String) {
log.info("packInternal(workspace: $workspace)") log.info("packInternal(workspace: $workspace, $outFileName)")
Helper.setProp("workDir", workspace) Helper.setProp("workDir", workspace)
val iniRole = Common.loadProperties(File(workspace, "workspace.ini").canonicalPath).getProperty("role") val iniRole = Common.loadProperties(File(workspace, "workspace.ini").canonicalPath).getProperty("vbmeta.role")
val blob = ObjectMapper().readValue(File(Avb.getJsonFileName(iniRole)), AVBInfo::class.java).encodePadded() val blob = ObjectMapper().readValue(File(Avb.getJsonFileName(iniRole)), AVBInfo::class.java).encodePadded()
log.info("Writing padded vbmeta to file: $outFileName.signed") log.info("Writing padded vbmeta to file: $outFileName.signed")
Files.write(Paths.get("$outFileName.signed"), blob, StandardOpenOption.CREATE) Files.write(Paths.get("$outFileName.signed"), blob, StandardOpenOption.CREATE)

@ -36,6 +36,7 @@ class VendorBootParser : IPackable {
} }
fun unpackInternal(fileName: String, unpackDir: String) { fun unpackInternal(fileName: String, unpackDir: String) {
//set workdir
log.info("unpackInternal(fileName: $fileName, unpackDir: $unpackDir)") log.info("unpackInternal(fileName: $fileName, unpackDir: $unpackDir)")
Helper.setProp("workDir", unpackDir) Helper.setProp("workDir", unpackDir)
clear() clear()

@ -147,29 +147,32 @@ data class SparseImage(var info: SparseInfo = SparseInfo()) {
val ret = SparseImage() val ret = SparseImage()
ret.info.json = File(fileName).name.removeSuffix(".img") + ".json" ret.info.json = File(fileName).name.removeSuffix(".img") + ".json"
ret.info.output = fileName ret.info.output = fileName
ret.info.pulp = workDir + fileName ret.info.pulp = File(Helper.prop("workDir")!!, File(fileName).nameWithoutExtension).path
log.info(ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(ret.info))
if (isSparse(fileName)) { if (isSparse(fileName)) {
val tempFile = UUID.randomUUID().toString() val tempFile = UUID.randomUUID().toString()
ret.info.outerFsType = "sparse" ret.info.outerFsType = "sparse"
val rawFile = "${workDir}${File(fileName).nameWithoutExtension}"
simg2img(fileName, tempFile) simg2img(fileName, tempFile)
ret.info.pulp = if (isExt4(tempFile)) { ret.info.pulp = if (isExt4(tempFile)) {
ret.info.innerFsType = "ext4" ret.info.innerFsType = "ext4"
"$rawFile.ext4" ret.info.pulp + ".ext4"
} else if (isErofs(tempFile)) { } else if (isErofs(tempFile)) {
ret.info.innerFsType = "erofs" ret.info.innerFsType = "erofs"
"$rawFile.erofs" ret.info.pulp + ".erofs"
} else { } else {
"$rawFile.raw" ret.info.pulp + ".raw"
} }
Files.move(Path(tempFile), Path(ret.info.pulp)) Files.move(Path(tempFile), Path(ret.info.pulp))
} else if (isExt4(fileName)) { } else if (isExt4(fileName)) {
ret.info.outerFsType = "ext4" ret.info.outerFsType = "ext4"
ret.info.innerFsType = "ext4" ret.info.innerFsType = "ext4"
ret.info.pulp = ret.info.pulp + ".ext4"
log.info("COPY $fileName -> ${ret.info.pulp}")
File(fileName).copyTo(File(ret.info.pulp)) File(fileName).copyTo(File(ret.info.pulp))
} else if (isErofs(fileName)) { } else if (isErofs(fileName)) {
ret.info.outerFsType = "erofs" ret.info.outerFsType = "erofs"
ret.info.innerFsType = "erofs" ret.info.innerFsType = "erofs"
ret.info.pulp = ret.info.pulp + ".erofs"
File(fileName).copyTo(File(ret.info.pulp)) File(fileName).copyTo(File(ret.info.pulp))
} }
when (ret.info.innerFsType) { when (ret.info.innerFsType) {

@ -15,6 +15,7 @@
package rom.sparse package rom.sparse
import avb.blob.Footer import avb.blob.Footer
import cfig.bootimg.Common
import cfig.helper.Helper import cfig.helper.Helper
import cfig.packable.IPackable import cfig.packable.IPackable
import cfig.packable.VBMetaParser import cfig.packable.VBMetaParser
@ -38,12 +39,24 @@ class SparseImgParser : IPackable {
} }
override fun unpack(fileName: String) { override fun unpack(fileName: String) {
log.info("unpack(fileName: $fileName)")
unpackInternal(fileName, Helper.prop("workDir")!!)
}
fun unpackInternal(fileName: String, unpackDir: String) {
//set workdir
log.info("unpackInternal(fileName: $fileName, unpackDir: $unpackDir)")
Helper.setProp("workDir", unpackDir)
clear() clear()
//create workspace file
Common.createWorkspaceIni(fileName)
//create workspace file done
SparseImage SparseImage
.parse(fileName) .parse(fileName)
.printSummary(fileName) .printSummary(fileName)
} }
override fun pack(fileName: String) { override fun pack(fileName: String) {
//TODO("not implemented: refer to https://github.com/cfig/Android_boot_image_editor/issues/133") //TODO("not implemented: refer to https://github.com/cfig/Android_boot_image_editor/issues/133")
val cfgFile = outDir + fileName.removeSuffix(".img") + ".json" val cfgFile = outDir + fileName.removeSuffix(".img") + ".json"
@ -54,6 +67,24 @@ class SparseImgParser : IPackable {
.unwrap() .unwrap()
} }
fun packInternal(workspace: String, outFileName: String) {
log.info("packInternal($workspace, $outFileName)")
Helper.setProp("workDir", workspace)
//intermediate
Helper.joinPath(workspace, "intermediate").also { intermediateDir ->
File(intermediateDir).let {
if (!it.exists()) {
it.mkdir()
}
}
Helper.setProp("intermediateDir", intermediateDir)
}
//workspace+cfg
val iniRole = Common.loadProperties(File(workspace, "workspace.ini").canonicalPath).getProperty("role")
val cfgFile = File(workspace, iniRole.removeSuffix(".img") + ".json").canonicalPath
log.info("Loading config from $cfgFile")
}
// invoked solely by reflection // invoked solely by reflection
fun `@footer`(fileName: String) { fun `@footer`(fileName: String) {
FileInputStream(fileName).use { fis -> FileInputStream(fileName).use { fis ->

Loading…
Cancel
Save