Fix Nissan ROM checksum processing issue #184

This commit is contained in:
Dale Schultz 2022-05-06 20:56:33 -04:00
parent 0b1c55de23
commit 253291373d
No known key found for this signature in database
GPG Key ID: EA2C8AD6CB5C2AF2
6 changed files with 94 additions and 103 deletions

View File

@ -11,7 +11,7 @@ CFGEDFSMENU = ECU definition files need to be configured before ROM images can b
RELEASENOTESFONT = Tahoma
RELEASENOTES = Release Notes
STATUSREADY = Ready ...
CHECKSUMSTATE = %d/%d Checksums are correct. Checksums will be updated when file is saved.
CHECKSUMSTATE = %d Checksums are correct. Checksums will be updated when file is saved.
OBSOLETEROM = A newer version of this ECU revision exists. Please visit the following link to download the latest revision:
DISPLAYMSG = Always display this message
ISOBSOLETE = ECU Revision is Obsolete

View File

@ -4,8 +4,8 @@ ECUDEFERROR = ECU Definition Error
TABLELOADERR = There was an error loading table {0}
YES = Yes
NO = No
CHECKSUMFIXED = %d/%d Checksums needed to be updated.
CHECKSUMFIXED = %d of %d Checksums updated.
CHKSUMINVALID = One or more ROM image Checksums is invalid. Calculate new Checksums?\n(NOTE: this will only fix the Checksums it will NOT repair a corrupt ROM image.
CHECKSUMFIX = Checksum Fix
INVLAIDCHKSUM = Checksum is invalid.\nThe ROM image may be corrupt or it has been hex edited manually.\nThe checksum can be corrected when the ROM is saved if your trust it is not corrupt.
INVLAIDCHKSUM = Checksum is invalid.\nThe ROM image may be corrupt or it has been hex edited manually.\nThe checksum can be corrected when the ROM is saved if you trust it is not corrupt.
CHKSUMFAIL = ERROR - Checksum Failed

View File

@ -1,6 +1,6 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2021 RomRaider.com
* Copyright (C) 2006-2022 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -56,11 +56,11 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
private final File inputFile;
private Rom rom;
private String finalStatus;
public OpenImageWorker(File inputFile) {
this.inputFile = inputFile;
}
private void loadRom(Rom rom, byte[] input) {
ECUEditor editor = ECUEditorManager.getECUEditor();
editor.getStatusPanel().setStatus(
@ -77,44 +77,44 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
editor.getStatusPanel().setStatus(
ECUEditor.rb.getString("DONELOAD"));
setProgress(95);
if(rom.getNumChecksumsManagers() == 0) {
finalStatus = ECUEditor.rb.getString("STATUSREADY");
}
else {
editor.getStatusPanel().setStatus(
ECUEditor.rb.getString("CHECKSUM"));
finalStatus = String.format(ECUEditor.rb.getString("CHECKSUMSTATE"),
rom.validateChecksum(), rom.getNumChecksumsManagers());
}
rom.validateChecksum());
}
this.rom = rom;
}
private Document createDocument(File f) throws Exception {
Document doc = null;
FileInputStream fileStream = null;
FileInputStream fileStream = null;
try {
fileStream = new FileInputStream(f);
fileStream = new FileInputStream(f);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
factory.setXIncludeAware(true);
DocumentBuilder docBuilder = factory.newDocumentBuilder();
//Check if definition is standard or
//if it has to be converted first
//if it has to be converted first
if(ConversionLayerFactory.requiresConversionLayer(f)) {
ConversionLayer l = ConversionLayerFactory.getConversionLayerForFile(f);
if(l != null)
doc = l.convertToDocumentTree(f);
if(doc == null)
if(l != null)
doc = l.convertToDocumentTree(f);
if(doc == null)
throw new SAXParseException(ECUEditor.rb.getString("UNREADABLEDEF"), null);
}
}
//Default case
else {
doc = docBuilder.parse(fileStream, f.getAbsolutePath());
@ -131,44 +131,44 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
e.printStackTrace();
}
}
return doc;
}
private void showExceptionPopup(Exception ex, File defFile) {
String errorMessage = defFile.getName() + ": " + (ex.getMessage() == null || ex.getMessage().isEmpty() ?
String errorMessage = defFile.getName() + ": " + (ex.getMessage() == null || ex.getMessage().isEmpty() ?
ECUEditor.rb.getString("LOADEXCEPTION") : ex.getMessage());
final String errorLoading = MessageFormat.format(
ECUEditor.rb.getString("ERRORFILE"),
inputFile.getName());
ECUEditor editor = ECUEditorManager.getECUEditor();
showMessageDialog(editor,
errorMessage,
errorLoading,
ERROR_MESSAGE);
if(ex instanceof SAXException)
LOGGER.error(errorMessage);
else
ex.printStackTrace();
}
private Rom openRomWithDefinition(File f, Node romNode, byte[] input) {
ECUEditor editor = ECUEditorManager.getECUEditor();
final String errorLoading = MessageFormat.format(
ECUEditor.rb.getString("ERRORFILE"),
inputFile.getName());
try {
try {
Document doc = createDocument(f);
Rom rom = new DOMRomUnmarshaller().unmarshallXMLDefinition(f, doc.getDocumentElement(), romNode,
input, editor.getStatusPanel());
rom.setDocument(doc);
loadRom(rom, input);
rom.setDocument(doc);
loadRom(rom, input);
} catch (StackOverflowError ex) {
ex.printStackTrace();
@ -188,17 +188,17 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
showExceptionPopup(ex, f);
return null;
}
return null;
}
@Override
protected Void doInBackground() throws Exception {
Thread.currentThread().setName("Open Image Thread");
ECUEditor editor = ECUEditorManager.getECUEditor();
Settings settings = SettingsManager.getSettings();
editor.getStatusPanel().setStatus(
ECUEditor.rb.getString("STATUSPARSING"));
setProgress(0);
@ -210,11 +210,11 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
setProgress(10);
boolean found = false;
// parse ecu definition files until result found
for (int i = 0; i < settings.getEcuDefinitionFiles().size(); i++) {
File f = settings.getEcuDefinitionFiles().get(i);
if (!f.exists()) {
showMessageDialog(editor,
MessageFormat.format(
@ -225,10 +225,10 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
settings.getEcuDefinitionFiles().get(i).getName()),
ERROR_MESSAGE);
continue;
}
}
Node romNode = null;
try {
Document doc = createDocument(f);
romNode = new DOMRomUnmarshaller().checkDefinitionMatch(doc.getDocumentElement(), input);
@ -236,22 +236,22 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
catch(Exception e) {
showExceptionPopup(e, f);
}
if(romNode != null) {
openRomWithDefinition(f, romNode, input);
found = true;
break;
}
}
if(!found) {
showNoDefinitionFoundPopup(input);
}
return null;
return null;
}
private void showNoDefinitionFoundPopup(byte[] input) {
private void showNoDefinitionFoundPopup(byte[] input) {
// no ECU definitions configured - let user choose one
Object[] options = {ECUEditor.rb.getString("YES"), ECUEditor.rb.getString("NO")};
int answer = showOptionDialog(null,
@ -262,7 +262,7 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
null,
options,
options[0]);
if (answer == 0) {
Settings settings = SettingsManager.getSettings();
JFileChooser fc = new JFileChooser(settings.getLastDefinitionDir());
@ -271,10 +271,10 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
settings.setLastDefinitionDir(file.getParentFile());
Node romNode;
Document doc = null;
try {
doc = createDocument(file);
romNode = new DOMRomUnmarshaller().checkDefinitionMatch(doc.getDocumentElement(), input);
@ -282,7 +282,7 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
showExceptionPopup(e, file);
return;
}
if(romNode == null) {
int answerForceLoad = showOptionDialog(null,
ECUEditor.rb.getString("DEFNOMATCH"),
@ -292,8 +292,8 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
null,
options,
options[0]);
if(answerForceLoad == 0) {
if(answerForceLoad == 0) {
Node n = DOMRomUnmarshaller.findFirstRomNode(doc.getDocumentElement());
openRomWithDefinition(file, n, input);
}
@ -317,16 +317,16 @@ public class OpenImageWorker extends SwingWorker<Void, Void> {
@Override
public void done() {
ECUEditor editor = ECUEditorManager.getECUEditor();
ECUEditor editor = ECUEditorManager.getECUEditor();
//Add the rom in the main thread
if(rom != null) {
editor.addRom(rom);
rom = null;
editor.getStatusPanel().update(finalStatus, 0);
rom = null;
editor.getStatusPanel().update(finalStatus, 0);
editor.setCursor(null);
editor.refreshAfterNewRom();
editor.refreshAfterNewRom();
}
else {
editor.getStatusPanel().update(ECUEditor.rb.getString("STATUSREADY"), 0);

View File

@ -169,12 +169,12 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
public Table getTableByName(String tableName) {
TableTreeNode node = getTableNodeByName(tableName);
if(node != null)
return node.getTable();
return null;
}
public TableTreeNode getTableNodeByName(String tableName) {
if(!tableNodes.containsKey(tableName.toLowerCase())) {
return null;
@ -511,7 +511,7 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
valid = false;
}
else {
correctChecksums+=localCorrectCs;
correctChecksums += localCorrectCs;
}
}
}
@ -530,7 +530,7 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
int updatedCs = 0;
for(ChecksumManager cm: checksumManagers) {
updatedCs+=cm.update(binData);
updatedCs += cm.update(binData);
}
ECUEditorManager.getECUEditor().getStatusPanel().setStatus(
@ -543,7 +543,7 @@ public class Rom extends DefaultMutableTreeNode implements Serializable {
int cs = 0;
for(ChecksumManager cm: checksumManagers) {
cs+=cm.getNumberOfChecksums();
cs += cm.getNumberOfChecksums();
}
return cs;

View File

@ -1,6 +1,6 @@
/*
* RomRaider Open-Source Tuning, Logging and Reflashing
* Copyright (C) 2006-2021 RomRaider.com
* Copyright (C) 2006-2022 RomRaider.com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -38,6 +38,7 @@ public final class ChecksumALT2 extends NissanChecksum {
calculator = new CalculateALT2();
}
@Override
public void configure(Map<String, String> vars) {
super.configure(vars);
if (vars.containsKey(SKIPLOC)) {
@ -48,36 +49,41 @@ public final class ChecksumALT2 extends NissanChecksum {
}
}
@Override
public int getNumberOfChecksums() {
return 4;
}
@Override
public int validate(byte[] binData) {
calculator.calculate(range, binData, results);
int valid = 0;
if(results.get(SUMT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(SUMLOC), 4, true)) {
valid++;
}
if(results.get(XORT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(XORLOC), 4, true)) {
valid++;
}
if(results.get(START) == (short)parseByteValue(binData, Settings.Endian.BIG, range.get(START), 2, false)) {
valid++;
}
if(results.get(SKIPLOC) == (short)parseByteValue(binData, Settings.Endian.BIG, range.get(SKIPLOC), 2, false)) {
valid++;
}
return valid;
}
@Override
public int update(byte[] binData) {
// SUMT & XORT are updated in super before START and SKIPLOC
super.update(binData);
int updateNeeded = getNumberOfChecksums();
System.arraycopy(parseIntegerValue(results.get(START), Settings.Endian.BIG, 2), 0, binData, range.get(START), 2);
System.arraycopy(parseIntegerValue(results.get(SKIPLOC), Settings.Endian.BIG, 2), 0, binData, range.get(SKIPLOC), 2);
return updateNeeded;
return getNumberOfChecksums();
}
}

View File

@ -22,7 +22,6 @@ package com.romraider.maps.checksum;
import static com.romraider.xml.RomAttributeParser.parseByteValue;
import static com.romraider.xml.RomAttributeParser.parseIntegerValue;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@ -30,7 +29,7 @@ import com.romraider.Settings;
import com.romraider.util.HexUtil;
/**
* This class provides common methods implemented by different
* This class provides common methods implemented by different
* checksum calculation type classes.
*/
abstract class NissanChecksum implements ChecksumManager {
@ -43,7 +42,7 @@ import com.romraider.util.HexUtil;
protected final Map<String, Integer> range = new HashMap<String, Integer>();
protected final Map<String, Integer> results = new HashMap<String, Integer>();
protected Calculator calculator;
@Override
public void configure(Map<String, String> vars) {
range.put(START, HexUtil.hexToInt(vars.get(START)));
@ -51,47 +50,33 @@ import com.romraider.util.HexUtil;
range.put(SUMLOC, HexUtil.hexToInt(vars.get(SUMLOC)));
range.put(XORLOC, HexUtil.hexToInt(vars.get(XORLOC)));
}
@Override
public int getNumberOfChecksums() {
return 2;
}
@Override
public int validate(byte[] binData) {
calculator.calculate(range, binData, results);
int valid = 0;
if(results.get(SUMT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(SUMLOC), 4, true)) {
valid++;
}
if((results.get(XORT) == (int)parseByteValue(binData, Settings.Endian.BIG, range.get(XORLOC), 4, true))) {
valid++;
}
return valid;
}
@Override
public int update(byte[] binData) {
calculator.calculate(range, binData, results);
int updateNeeded = getNumberOfChecksums();
if(!Arrays.equals(parseIntegerValue(results.get(SUMT), Settings.Endian.BIG, 4),
Arrays.copyOfRange(binData, range.get(SUMLOC), 4))){
updateNeeded++;
}
if(!Arrays.equals(parseIntegerValue(results.get(XORT), Settings.Endian.BIG, 4),
Arrays.copyOfRange(binData, range.get(XORLOC), 4))){
updateNeeded++;
}
//TODO: Dont copy if arrays dont need updating
System.arraycopy(parseIntegerValue(results.get(SUMT), Settings.Endian.BIG, 4), 0, binData, range.get(SUMLOC), 4);
System.arraycopy(parseIntegerValue(results.get(XORT), Settings.Endian.BIG, 4), 0, binData, range.get(XORLOC), 4);
return updateNeeded;
return getNumberOfChecksums();
}
}