diff --git a/ProgramExe/xperifirm b/ProgramExe/xperifirm new file mode 100644 index 00000000..bee608b2 --- /dev/null +++ b/ProgramExe/xperifirm @@ -0,0 +1,2 @@ +#!/bin/bash +mono "$1" -o "$2" diff --git a/ant/deploy-release.xml b/ant/deploy-release.xml index ee6c6108..ac6d6332 100644 --- a/ant/deploy-release.xml +++ b/ant/deploy-release.xml @@ -1,8 +1,8 @@ - - + + @@ -36,8 +36,6 @@ - - @@ -49,10 +47,6 @@ - - - diff --git a/ant/setup-linux.xml b/ant/setup-linux.xml index 50823564..cfe025b0 100644 --- a/ant/setup-linux.xml +++ b/ant/setup-linux.xml @@ -48,6 +48,7 @@ + @@ -67,14 +68,22 @@ + + + + + + + + diff --git a/ant/setup-mac.xml b/ant/setup-mac.xml index a55acaab..03a96dbb 100644 --- a/ant/setup-mac.xml +++ b/ant/setup-mac.xml @@ -49,6 +49,7 @@ + @@ -64,12 +65,14 @@ + + diff --git a/src/flashsystem/Bundle.java b/src/flashsystem/Bundle.java index 8dc24f5f..20c97c6a 100644 --- a/src/flashsystem/Bundle.java +++ b/src/flashsystem/Bundle.java @@ -39,6 +39,8 @@ public final class Bundle { private String _version; private String _branding; private String _device; + private String _cda=""; + private String _revision=""; private String _cmd25; private String _resetCust; public final static int JARTYPE=1; @@ -79,6 +81,7 @@ private void feedFromJar(String path) { _device = _firmware.getManifest().getMainAttributes().getValue("device"); _version = _firmware.getManifest().getMainAttributes().getValue("version"); _branding = _firmware.getManifest().getMainAttributes().getValue("branding"); + _cda = _firmware.getManifest().getMainAttributes().getValue("cda"); _cmd25 = _firmware.getManifest().getMainAttributes().getValue("cmd25"); Enumeration e = _firmware.entries(); while (e.hasMoreElements()) { @@ -212,6 +215,14 @@ public void setDevice(String device) { _device=device; } + public void setCDA(String cda) { + _cda = cda; + } + + public void setRevision(String revision) { + _revision = revision; + } + public void setCmd25(String value) { _cmd25 = value; if (_cmd25==null) _cmd25="false"; @@ -241,13 +252,16 @@ public boolean hasResetStats() { } public void createFTF() throws Exception { - File ftf = new File(OS.getFolderFirmwares()+File.separator+_device+"_"+_version+"_"+_branding+".ftf"); + File ftf = new File(OS.getFolderFirmwares()+File.separator+_device+"_"+_version+"_"+(_cda.length()>0?_cda:_branding)+(_revision.length()>0?("_"+_revision):"")+".ftf"); + if (ftf.exists()) throw new Exception("Bundle already exists"); byte buffer[] = new byte[10240]; StringBuffer sbuf = new StringBuffer(); sbuf.append("Manifest-Version: 1.0\n"); sbuf.append("Created-By: FlashTool\n"); sbuf.append("version: "+_version+"\n"); sbuf.append("branding: "+_branding+"\n"); + sbuf.append("cda: "+_cda+"\n"); + sbuf.append("revision: "+_revision+"\n"); sbuf.append("device: "+_device+"\n"); sbuf.append("cmd25: "+_cmd25+"\n"); Manifest manifest = new Manifest(new ByteArrayInputStream(sbuf.toString().getBytes("UTF-8"))); diff --git a/src/flashsystem/BundleMetaData.java b/src/flashsystem/BundleMetaData.java index bd32e6a6..164d99b0 100644 --- a/src/flashsystem/BundleMetaData.java +++ b/src/flashsystem/BundleMetaData.java @@ -160,7 +160,7 @@ else if (intname.toUpperCase().contains("RPM")) add(intname,"kernel".toUpperCase()); else if (intname.toUpperCase().contains("ELABEL")) add(intname,"elabel".toUpperCase()); - else if (intname.toUpperCase().contains("VENDOR")) + else if (intname.toUpperCase().contains("VENDOR") || intname.toUpperCase().contains("OEM")) add(intname,"vendor".toUpperCase()); else if (intname.toUpperCase().contains("BOOT_DELIVERY")) add(intname,"bootbundle".toUpperCase()); diff --git a/src/flashsystem/Command.java b/src/flashsystem/Command.java index 01b84d6d..078ca436 100644 --- a/src/flashsystem/Command.java +++ b/src/flashsystem/Command.java @@ -6,11 +6,14 @@ import org.logger.MyLogger; import org.util.HexDump; +import com.sonymobile.cs.generic.array.ArrayUtils; + import flashsystem.io.USBFlash; public class Command { private boolean _simulate; + private byte[] reply; public static final byte[] TA_FLASH_STARTUP_SHUTDOWN_RESULT_ONGOING = { 0x00, 0x00, 0x27, 0x74, 0x00, 0x00, 0x00, 0x01, 0x01}; @@ -49,6 +52,7 @@ public class Command { static final int CMD10 = 10; static final int CMD12 = 12; static final int CMD13 = 13; + static final int CMD18 = 18; static final int CMD25 = 25; @@ -62,7 +66,7 @@ public Command(boolean simulate) { public String getLastReplyString() { try { - return new String(USBFlash.getLastReply()); + return new String(reply); } catch (Exception e) { return ""; @@ -71,7 +75,7 @@ public String getLastReplyString() { public String getLastReplyHex() { try { - return HexDump.toHex(USBFlash.getLastReply()); + return HexDump.toHex(reply); } catch (Exception e) { return ""; @@ -80,12 +84,20 @@ public String getLastReplyHex() { public short getLastReplyLength() { try { - return (short)USBFlash.getLastReply().length; + return (short)reply.length; } catch (Exception e) { return 0; } } + + public byte[] getLastReply() { + return reply; + } + + public boolean isMultiPacketMessage() { + return (USBFlash.getLastFlags() & 4) > 0; + } private void writeCommand(int command, byte data[], boolean ongoing) throws X10FlashException, IOException { if (!_simulate) { @@ -112,12 +124,19 @@ private void writeCommand(int command, byte data[], boolean ongoing) throws X10F public void send(int cmd, byte data[], boolean ongoing) throws X10FlashException, IOException { writeCommand(cmd, data, ongoing); - LogProgress.updateProgress(); + reply = USBFlash.getLastReply(); if (USBFlash.getLastFlags()==0) { writeCommand(Command.CMD07, Command.VALNULL, false); throw new X10FlashException(getLastReplyString()); } - + while(isMultiPacketMessage()) { + writeCommand(cmd, data, ongoing); + reply = ArrayUtils.concatenateByteArrays(reply, USBFlash.getLastReply()); + if (USBFlash.getLastFlags()==0) { + writeCommand(Command.CMD07, Command.VALNULL, false); + throw new X10FlashException(getLastReplyString()); + } + } + LogProgress.updateProgress(); } - } \ No newline at end of file diff --git a/src/flashsystem/TaFile.java b/src/flashsystem/TaFile.java index 409e172c..5d4afab8 100644 --- a/src/flashsystem/TaFile.java +++ b/src/flashsystem/TaFile.java @@ -12,6 +12,7 @@ public class TaFile { FileInputStream _in; Scanner _scanner; Vector entries = new Vector(); + int _partition = 0; public TaFile(File f) throws TaParseException, FileNotFoundException { _taf = f; @@ -22,7 +23,8 @@ public TaFile(File f) throws TaParseException, FileNotFoundException { boolean beginentry=false; while (_scanner.hasNextLine()) { String line = _scanner.nextLine().trim(); - if (!line.startsWith("/") && !(line.length()<=4)) { + if (line.startsWith("/")) continue; + if (!(line.length()<=4)) { Scanner scanline = new Scanner(line); scanline.useDelimiter(" "); while (scanline.hasNext()) { @@ -50,7 +52,21 @@ public TaFile(File f) throws TaParseException, FileNotFoundException { } } } + if(_partition == 0 && line.length() == 2){ + try { + _partition = Integer.parseInt(line); + if (_partition !=1 && _partition != 2) { + throw new TaParseException("TA partition should be 1 or 2"); + } + } catch (NumberFormatException e) { + + } + } } + + if(_partition == 0){ + _partition = 2; + } entry.close(); entries.add(entry); try { @@ -66,6 +82,10 @@ public Vector entries() { public String getName() { return _taf.getName(); } + + public int getPartition() { + return _partition; + } public String toString() { String result = ""; diff --git a/src/flashsystem/X10flash.java b/src/flashsystem/X10flash.java index 2f2edc63..567ab6fb 100644 --- a/src/flashsystem/X10flash.java +++ b/src/flashsystem/X10flash.java @@ -5,6 +5,7 @@ import gui.tools.XMLBootConfig; import gui.tools.XMLBootDelivery; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -23,8 +24,14 @@ import org.util.BytesUtil; import org.util.HexDump; +import com.sonymobile.cs.generic.array.ArrayUtils; +import com.sonymobile.cs.generic.bytes.ByteUtils; +import com.sonymobile.cs.generic.stream.StreamUtils; + import java.util.Enumeration; import java.util.Iterator; +import java.util.Map; +import java.util.TreeMap; import java.util.Vector; public class X10flash { @@ -87,13 +94,26 @@ private void sendTA(File f) throws FileNotFoundException, IOException,X10FlashEx } private void sendTA(TaFile ta) throws FileNotFoundException, IOException,X10FlashException { - logger.info("Flashing "+ta.getName()); + logger.info("Flashing "+ta.getName()+" to partition "+ta.getPartition()); Vector entries = ta.entries(); for (int i=0;i entries = ta.entries(); + for (int i=0;i dumpProperties() - { - Vector v = new Vector(); - try { - logger.info("Start Dumping TA"); - LogProgress.initProgress(9789); - for(int i = 0; i < 4920; i++) { - try { - cmd.send(Command.CMD12, BytesUtil.getBytesWord(i, 4),false); - String reply = cmd.getLastReplyHex(); - reply = reply.replace("[", ""); - reply = reply.replace("]", ""); - reply = reply.replace(",", ""); - if (cmd.getLastReplyLength()>0) { - TaEntry ta = new TaEntry(); - ta.setPartition(HexDump.toHex(i)); - ta.addData(reply.trim()); - v.add(ta); - } - - } - catch (X10FlashException e) { - } - } - LogProgress.initProgress(0); - logger.info("Dumping TA finished."); - } - catch (Exception ioe) { - LogProgress.initProgress(0); - logger.error(ioe.getMessage()); - logger.error("Error dumping TA. Aborted"); - closeDevice(); - } - return v; + public void BackupTA() throws IOException, X10FlashException { + String timeStamp = OS.getTimeStamp(); + BackupTA(1, timeStamp); + BackupTA(2, timeStamp); } - public void BackupTA() throws IOException, X10FlashException { - int partition = 2; + public void BackupTA(int partition, String timeStamp) throws IOException, X10FlashException { openTA(partition); - String folder = OS.getFolderMyDevices()+File.separator+getPhoneProperty("MSN")+File.separator+"s1ta"+File.separator+OS.getTimeStamp(); + String folder = OS.getFolderMyDevices()+File.separator+getPhoneProperty("MSN")+File.separator+"s1ta"+File.separator+timeStamp; new File(folder).mkdirs(); TextFile tazone = new TextFile(folder+File.separator+partition+".ta","ISO8859-1"); - logger.info("TA partition "+partition+" saved to "+folder+File.separator+partition+".ta"); tazone.open(false); try { - logger.info("Start Dumping TA"); - LogProgress.initProgress(4920); - for(int i = 0; i < 4920; i++) { - try { - logger.debug((new StringBuilder("%%% read TA property id=")).append(i).toString()); - cmd.send(Command.CMD12, BytesUtil.getBytesWord(i, 4),false); - String reply = cmd.getLastReplyHex(); - reply = reply.replace("[", ""); - reply = reply.replace("]", ""); - reply = reply.replace(",", ""); - if (cmd.getLastReplyLength()>0) { - tazone.writeln(HexDump.toHex(i) + " " + HexDump.toHex(cmd.getLastReplyLength()) + " " + reply.trim()); - } - } - catch (X10FlashException e) { - } - } - LogProgress.initProgress(0); + tazone.writeln(String.format("%02d", partition)); + try { + logger.info("Start Dumping TA partition "+partition); + cmd.send(Command.CMD18, Command.VALNULL, false); + logger.info("Finished Dumping TA partition "+partition); + ByteArrayInputStream inputStream = new ByteArrayInputStream(cmd.getLastReply()); + TreeMap treeMap = new TreeMap(); + int i = 0; + while(i == 0) { + int j = inputStream.read(); + if (j == -1) { + i = 1; + } + else { + byte[] buff = new byte[3]; + if(StreamUtils.fillArray(inputStream, buff)!=3){ + throw new X10FlashException("Not enough data to read Uint32 when decoding command"); + } + byte[] unitbuff = ArrayUtils.concatenateByteArrays(new byte[] { (byte)j }, buff); + long unit = ByteUtils.bytesToInt(ByteUtils.getSubByteArray(unitbuff, 0, unitbuff.length), false) & 0xFFFFFFFF; + long unitdatalen = decodeUint32(inputStream); + if (unitdatalen > 1000000L) { + throw new X10FlashException("Maximum unit size exceeded, application will handle units of a maximum size of 0x" + + Long.toHexString(1000000L) + ". Got a unit of size 0x" + Long.toHexString(unitdatalen) + "."); + } + byte[] databuff = new byte[(int)unitdatalen]; + if (StreamUtils.fillArray(inputStream, databuff) != unitdatalen) { + throw new X10FlashException("Not enough data to read unit data decoding command"); + } + treeMap.put((int)unit, databuff); + } + } + for (Map.Entry entry : treeMap.entrySet()) + { + int unit = entry.getKey(); + byte[] unitdate = entry.getValue(); + String dataStr = HexDump.toHex(unitdate); + dataStr = dataStr.replace("[", ""); + dataStr = dataStr.replace("]", ""); + dataStr = dataStr.replace(",", ""); + tazone.writeln(HexDump.toHex((int)unit) + " " + HexDump.toHex((short)unitdate.length) + " " + dataStr); + } + + }catch (X10FlashException e) { + throw e; + } tazone.close(); + logger.info("TA partition "+partition+" saved to "+folder+File.separator+partition+".ta"); closeTA(); } catch (Exception ioe) { tazone.close(); closeTA(); - LogProgress.initProgress(0); logger.error(ioe.getMessage()); logger.error("Error dumping TA. Aborted"); } } + private long decodeUint32(InputStream inputStream) throws IOException, X10FlashException { + byte[] buff = new byte[4]; + if (StreamUtils.fillArray(inputStream, buff) != 4) + { + throw new X10FlashException("Not enough data to read Uint32 when decoding command"); + } + return ByteUtils.bytesToInt(ByteUtils.getSubByteArray(buff, 0, buff.length), false) & 0xFFFFFFFF; + } + public void RestoreTA(String tafile) throws FileNotFoundException, IOException, X10FlashException { - openTA(2); + File f = new File(tafile); + boolean taopened = false; + try { + TaFile ta = new TaFile(f); + openTA(ta.getPartition()); + taopened = true; + sendTA(ta); + }catch (TaParseException tae) { + logger.error("Error parsing TA file. Skipping"); + } sendTA(new File(tafile)); - closeTA(); + if (taopened) { + closeTA(); + } LogProgress.initProgress(0); } @@ -443,17 +479,28 @@ public void sendBootDelivery() throws FileNotFoundException, IOException,X10Flas public void sendTAFiles() throws FileNotFoundException, IOException,X10FlashException { Enumeration entries = _bundle.getMeta().getEntriesOf("TA",true); if (entries.hasMoreElements()) { - openTA(2); while (entries.hasMoreElements()) { String entry = (String)entries.nextElement(); BundleEntry bent = _bundle.getEntry(entry); - if (!bent.getName().toUpperCase().contains("SIM")) - sendTA(new File(bent.getAbsolutePath())); + if (!bent.getName().toUpperCase().contains("SIM")) { + boolean taopened = false; + try { + TaFile ta = new TaFile(new File(bent.getAbsolutePath())); + openTA(ta.getPartition()); + taopened = true; + sendTA2(ta); + } + catch (TaParseException tae) { + logger.error("Error parsing TA file. Skipping"); + } + if(taopened){ + closeTA(); + } + } else { logger.warn("This file is ignored : "+bent.getName()); } } - closeTA(); } } diff --git a/src/gui/BundleCreator.java b/src/gui/BundleCreator.java index 32386c3f..c63a504c 100644 --- a/src/gui/BundleCreator.java +++ b/src/gui/BundleCreator.java @@ -129,7 +129,7 @@ public Object open(String folder) { File srcdir = new File(sourceFolder.getText()); File[] chld = srcdir.listFiles(); for(int i = 0; i < chld.length; i++) { - if (chld[i].getName().toUpperCase().endsWith("SIN") || (chld[i].getName().toUpperCase().endsWith("TA") && !chld[i].getName().toUpperCase().contains("SIMLOCK")) || (chld[i].getName().toUpperCase().endsWith("XML") && !chld[i].getName().toUpperCase().contains("UPDATE"))) { + if (chld[i].getName().toUpperCase().endsWith("SIN") || (chld[i].getName().toUpperCase().endsWith("TA") && !chld[i].getName().toUpperCase().contains("SIMLOCK")) || (chld[i].getName().toUpperCase().endsWith("XML") && (!chld[i].getName().toUpperCase().contains("UPDATE") && !chld[i].getName().toUpperCase().contains("FWINFO")))) { files.add(chld[i]); } } @@ -439,7 +439,7 @@ public void widgetSelected(SelectionEvent e) { File srcdir = new File(sourceFolder.getText()); File[] chld = srcdir.listFiles(); for(int i = 0; i < chld.length; i++) { - if (chld[i].getName().toUpperCase().endsWith("SIN") || (chld[i].getName().toUpperCase().endsWith("TA") && !chld[i].getName().toUpperCase().contains("SIMLOCK")) || (chld[i].getName().toUpperCase().endsWith("XML") && !chld[i].getName().toUpperCase().contains("UPDATE"))) { + if (chld[i].getName().toUpperCase().endsWith("SIN") || (chld[i].getName().toUpperCase().endsWith("TA") && !chld[i].getName().toUpperCase().contains("SIMLOCK")) || (chld[i].getName().toUpperCase().endsWith("XML") && (!chld[i].getName().toUpperCase().contains("UPDATE") && !chld[i].getName().toUpperCase().contains("FWINFO")))) { files.add(chld[i]); } } diff --git a/src/gui/HomeSelector.java b/src/gui/HomeSelector.java new file mode 100644 index 00000000..27808a9b --- /dev/null +++ b/src/gui/HomeSelector.java @@ -0,0 +1,183 @@ +package gui; + +import gui.tools.WidgetTask; +import gui.tools.WidgetsTool; + +import java.io.File; + +import org.apache.log4j.Logger; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.layout.FormLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.Button; +import org.eclipse.wb.swt.SWTResourceManager; +import org.eclipse.swt.layout.FormAttachment; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.system.Elf; +import org.system.GlobalConfig; +import org.system.OS; + +public class HomeSelector extends Dialog { + + protected Object result; + protected Shell shlHomeSelector; + private Text sourceFolder; + private static Logger logger = Logger.getLogger(HomeSelector.class); + private Button btnAccept; + private boolean cancelable = true; + + /** + * Create the dialog. + * @param parent + * @param style + */ + public HomeSelector(Shell parent, int style) { + super(parent, style); + setText("SWT Dialog"); + } + + /** + * Open the dialog. + * @return the result + */ + public Object open(boolean pcancelable) { + cancelable = pcancelable; + createContents(); + WidgetsTool.setSize(shlHomeSelector); + + Button btnCancel = new Button(shlHomeSelector, SWT.NONE); + btnCancel.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (cancelable) { + result = ""; + shlHomeSelector.dispose(); + } + else { + WidgetTask.openOKBox(shlHomeSelector, "You must choose a user home folder"); + } + } + }); + FormData fd_btnCancel = new FormData(); + fd_btnCancel.bottom = new FormAttachment(btnAccept, 0, SWT.BOTTOM); + fd_btnCancel.right = new FormAttachment(btnAccept, -6); + btnCancel.setLayoutData(fd_btnCancel); + btnCancel.setText("Cancel"); + shlHomeSelector.open(); + shlHomeSelector.layout(); + Display display = getParent().getDisplay(); + while (!shlHomeSelector.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return result; + } + + /** + * Create contents of the dialog. + */ + private void createContents() { + shlHomeSelector = new Shell(getParent(), getStyle()); + shlHomeSelector.setSize(538, 128); + shlHomeSelector.setText("User Home Selector"); + shlHomeSelector.setLayout(new FormLayout()); + shlHomeSelector.addListener(SWT.Close, new Listener() { + public void handleEvent(Event event) { + if (cancelable) { + result = ""; + event.doit = true; + } + else { + WidgetTask.openOKBox(shlHomeSelector, "You must choose a user home folder"); + event.doit = false; + } + } + }); + Composite composite = new Composite(shlHomeSelector, SWT.NONE); + composite.setLayout(new GridLayout(3, false)); + FormData fd_composite = new FormData(); + fd_composite.top = new FormAttachment(0, 10); + fd_composite.right = new FormAttachment(100, -9); + composite.setLayoutData(fd_composite); + + Label lblHomeFolder = new Label(composite, SWT.NONE); + GridData gd_lblHomeFolder = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1); + gd_lblHomeFolder.widthHint = 62; + lblHomeFolder.setLayoutData(gd_lblHomeFolder); + lblHomeFolder.setText("Folder :"); + + sourceFolder = new Text(composite, SWT.BORDER); + sourceFolder.setEditable(false); + sourceFolder.setText(GlobalConfig.getProperty("user.flashtool")); + GridData gd_sourceFolder = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1); + gd_sourceFolder.widthHint = 385; + sourceFolder.setLayoutData(gd_sourceFolder); + + Button btnFolderChoose = new Button(composite, SWT.NONE); + btnFolderChoose.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + DirectoryDialog dlg = new DirectoryDialog(shlHomeSelector); + + // Set the initial filter path according + // to anything they've selected or typed in + dlg.setFilterPath(sourceFolder.getText()); + + // Change the title bar text + dlg.setText("Home User Folder Chooser"); + // Calling open() will open and run the dialog. + // It will return the selected directory, or + // null if user cancels + String dir = dlg.open(); + if (dir != null) { + // Set the text box to the new selection + if (!sourceFolder.getText().equals(dir)) { + try { + sourceFolder.setText(dir); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + } + } + }); + GridData gd_btnFolderChoose = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1); + gd_btnFolderChoose.widthHint = 34; + btnFolderChoose.setLayoutData(gd_btnFolderChoose); + btnFolderChoose.setText("..."); + btnFolderChoose.setFont(SWTResourceManager.getFont("Arial", 11, SWT.NORMAL)); + + btnAccept = new Button(shlHomeSelector, SWT.NONE); + btnAccept.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + result=sourceFolder.getText(); + if (!((String)result).startsWith(OS.getWorkDir()+File.separator)) + shlHomeSelector.dispose(); + else + WidgetTask.openOKBox(shlHomeSelector, "User home folder must be out of Flashtool application folder"); + } + }); + FormData fd_btnAccept = new FormData(); + fd_btnAccept.bottom = new FormAttachment(100, -10); + fd_btnAccept.right = new FormAttachment(100, -10); + btnAccept.setLayoutData(fd_btnAccept); + btnAccept.setText("Accept"); + + } +} \ No newline at end of file diff --git a/src/gui/MainSWT.java b/src/gui/MainSWT.java index 1fee9e4b..0b27e1df 100644 --- a/src/gui/MainSWT.java +++ b/src/gui/MainSWT.java @@ -12,7 +12,9 @@ import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.zip.Deflater; + import linuxlib.JUsb; + import org.adb.AdbUtility; import org.apache.log4j.Logger; import org.eclipse.core.runtime.IProgressMonitor; @@ -57,6 +59,8 @@ import org.system.Proxy; import org.system.StatusEvent; import org.system.StatusListener; +import org.util.XperiFirm; + import flashsystem.Bundle; import flashsystem.X10flash; import gui.tools.APKInstallJob; @@ -76,7 +80,9 @@ import gui.tools.VersionCheckerJob; import gui.tools.WidgetTask; import gui.tools.WidgetsTool; +import gui.tools.XperiFirmJob; import gui.tools.Yaffs2Job; + import org.eclipse.swt.custom.ScrolledComposite; public class MainSWT { @@ -112,14 +118,16 @@ public void open() { guimode=true; shlSonyericsson.open(); shlSonyericsson.layout(); - try { - while (new File(OS.getWorkDir()+File.separator+"firmwares").list().length>0) - WidgetTask.openOKBox(shlSonyericsson, "Please move "+OS.getWorkDir()+File.separator+"firmwares content to "+OS.getFolderFirmwares()); - } catch (NullPointerException npe) {} - try { - while (new File(OS.getWorkDir()+File.separator+"custom"+File.separator+"mydevices").list().length>0) - WidgetTask.openOKBox(shlSonyericsson, "Please move "+OS.getWorkDir()+File.separator+"custom"+File.separator+"mydevices content to "+OS.getFolderMyDevices()); - } catch (NullPointerException npe) {} + boolean folderexists = (new File(OS.getWorkDir()+File.separator+"firmwares").exists() || new File(OS.getWorkDir()+File.separator+"custom"+File.separator+"mydevices").exists()); + if (folderexists) { + HomeSelector hs = new HomeSelector(shlSonyericsson,SWT.PRIMARY_MODAL | SWT.SHEET); + String result = (String)hs.open(false); + GlobalConfig.setProperty("user.flashtool", result); + forceMove(OS.getWorkDir()+File.separator+"firmwares",OS.getFolderFirmwares()); + forceMove(OS.getWorkDir()+File.separator+"custom"+File.separator+"mydevices",OS.getFolderMyDevices()); + new File(OS.getWorkDir()+File.separator+"firmwares").delete(); + new File(OS.getWorkDir()+File.separator+"custom"+File.separator+"mydevices").delete(); + } if (GlobalConfig.getProperty("gitauto").equals("true")) { WaitForDevicesSync sync = new WaitForDevicesSync(shlSonyericsson,SWT.PRIMARY_MODAL | SWT.SHEET); sync.open(); @@ -196,8 +204,8 @@ public void handleEvent(Event event) { shlSonyericsson.setSize(794, 451); shlSonyericsson.setText("Sony Mobile Flasher by Androxyde"); - shlSonyericsson.setImage(SWTResourceManager.getImage(MainSWT.class, "/gui/ressources/icons/flash_32.png")); - shlSonyericsson.setLayout(new FormLayout()); + shlSonyericsson.setImage(SWTResourceManager.getImage(MainSWT.class, "/gui/ressources/icons/flash_512.png")); + shlSonyericsson.setLayout(new FormLayout() ); Menu menu = new Menu(shlSonyericsson, SWT.BAR); shlSonyericsson.setMenuBar(menu); @@ -235,6 +243,21 @@ public void widgetSelected(SelectionEvent e) { }); mntmSwitchPro.setText(GlobalConfig.getProperty("devfeatures").equals("yes")?"Switch Simple":"Switch Pro"); + MenuItem mntmChangeUserHome = new MenuItem(menu_1, SWT.NONE); + mntmChangeUserHome.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + HomeSelector hs = new HomeSelector(shlSonyericsson,SWT.PRIMARY_MODAL | SWT.SHEET); + String result = (String)hs.open(true); + if (!result.equals(GlobalConfig.getProperty("user.flashtool")) && result.length()>0) { + forceMove(GlobalConfig.getProperty("user.flashtool"),result); + GlobalConfig.setProperty("user.flashtool", result); + new File(result+File.separator+"config.properties").delete(); + } + } + }); + mntmChangeUserHome.setText("Change User Home"); + MenuItem mntmExit = new MenuItem(menu_1, SWT.NONE); mntmExit.addSelectionListener(new SelectionAdapter() { @Override @@ -590,7 +613,7 @@ public void widgetSelected(SelectionEvent e) { }); mntmCheckDrivers.setText("Check Drivers"); - MenuItem mntmCheck = new MenuItem(menu_6, SWT.NONE); + /*MenuItem mntmCheck = new MenuItem(menu_6, SWT.NONE); mntmCheck.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { @@ -609,7 +632,7 @@ public void widgetSelected(SelectionEvent e) { } } }); - mntmCheck.setText("Check Updates"); + mntmCheck.setText("Check Updates");*/ MenuItem mntmEditor = new MenuItem(menu_6, SWT.CASCADE); mntmEditor.setText("Manage"); @@ -821,7 +844,7 @@ public void widgetSelected(SelectionEvent e) { ToolBar toolBar = new ToolBar(shlSonyericsson, SWT.FLAT | SWT.RIGHT); FormData fd_toolBar = new FormData(); - fd_toolBar.right = new FormAttachment(0, 316); + fd_toolBar.right = new FormAttachment(0, 392); fd_toolBar.top = new FormAttachment(0, 10); fd_toolBar.left = new FormAttachment(0, 10); toolBar.setLayoutData(fd_toolBar); @@ -933,6 +956,16 @@ public void widgetSelected(SelectionEvent e) { tltmRecovery.setImage(SWTResourceManager.getImage(MainSWT.class, "/gui/ressources/icons/recovery_32.png")); tltmRecovery.setEnabled(false); + ToolItem tltmNewItem_1 = new ToolItem(toolBar, SWT.NONE); + tltmNewItem_1.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + WaitForXperiFirm wx = new WaitForXperiFirm(shlSonyericsson,SWT.PRIMARY_MODAL | SWT.SHEET); + wx.open(); + } + }); + tltmNewItem_1.setImage(SWTResourceManager.getImage(MainSWT.class, "/gui/ressources/icons/download_32.png")); + ProgressBar progressBar = new ProgressBar(shlSonyericsson, SWT.NONE); fd_btnSaveLog.bottom = new FormAttachment(100, -43); progressBar.setState(SWT.NORMAL); @@ -1429,4 +1462,11 @@ public void doYaffs2Unpack() { else logger.info("Canceled"); } + + public void forceMove(String source, String dest) { + try { + while (new File(source).list().length>0) + WidgetTask.openOKBox(shlSonyericsson, "Please move "+source+" content to "+dest+"\n("+source+" folder MUST be empty once done)"); + } catch (NullPointerException npe) {} + } } \ No newline at end of file diff --git a/src/gui/WaitForXperiFirm.java b/src/gui/WaitForXperiFirm.java new file mode 100644 index 00000000..83a49a87 --- /dev/null +++ b/src/gui/WaitForXperiFirm.java @@ -0,0 +1,107 @@ +package gui; + +import gui.tools.WidgetTask; +import gui.tools.WidgetsTool; +import gui.tools.XperiFirmJob; + +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.IJobChangeListener; +import org.eclipse.swt.widgets.Dialog; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Label; + +public class WaitForXperiFirm extends Dialog { + + protected Object result; + protected Shell shlWaiForXperiFirm; + protected boolean canClose = false; + protected Dialog mydial; + + /** + * Create the dialog. + * @param parent + * @param style + */ + public WaitForXperiFirm(Shell parent, int style) { + super(parent, style); + setText("XperiFirm running"); + mydial = this; + } + + /** + * Open the dialog. + * @return the result + */ + public Object open() { + createContents(); + WidgetsTool.setSize(shlWaiForXperiFirm); + + Label lblNewLabel = new Label(shlWaiForXperiFirm, SWT.NONE); + lblNewLabel.setBounds(10, 32, 323, 15); + lblNewLabel.setText("Please wait until the end of process"); + shlWaiForXperiFirm.open(); + shlWaiForXperiFirm.layout(); + Display display = getParent().getDisplay(); + while (!shlWaiForXperiFirm.isDisposed()) { + if (!display.readAndDispatch()) { + display.sleep(); + } + } + return result; + } + + /** + * Create contents of the dialog. + */ + private void createContents() { + shlWaiForXperiFirm = new Shell(getParent(), getStyle()); + shlWaiForXperiFirm.addListener(SWT.Close, new Listener() { + public void handleEvent(Event event) { + if (canClose) { + result = ""; + event.doit = true; + } + else { + WidgetTask.openOKBox(shlWaiForXperiFirm, "Wait for end of process"); + event.doit = false; + } + } + }); + shlWaiForXperiFirm.setSize(365, 128); + shlWaiForXperiFirm.setText("Running XperiFirm"); + XperiFirmJob xj = new XperiFirmJob("XperiFirm"); + xj.addJobChangeListener(new IJobChangeListener() { + public void aboutToRun(IJobChangeEvent event) { + } + + public void awake(IJobChangeEvent event) { + } + + public void done(IJobChangeEvent event) { + canClose=true; + Display.getDefault().asyncExec( + new Runnable() { + public void run() { + shlWaiForXperiFirm.dispose(); + } + } + ); + } + + public void running(IJobChangeEvent event) { + } + + public void scheduled(IJobChangeEvent event) { + } + + public void sleeping(IJobChangeEvent event) { + } + }); + xj.schedule(); + + } +} diff --git a/src/gui/ressources/icons/download_32.png b/src/gui/ressources/icons/download_32.png new file mode 100644 index 00000000..7c1ba4c3 Binary files /dev/null and b/src/gui/ressources/icons/download_32.png differ diff --git a/src/gui/tools/BackupTAJob.java b/src/gui/tools/BackupTAJob.java index 96ef3f46..e2fc98e0 100644 --- a/src/gui/tools/BackupTAJob.java +++ b/src/gui/tools/BackupTAJob.java @@ -5,6 +5,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; +import org.logger.LogProgress; import flashsystem.X10flash; @@ -29,11 +30,13 @@ protected IStatus run(IProgressMonitor monitor) { flash.BackupTA(); flash.closeDevice(); logger.info("Dumping TA finished."); + LogProgress.initProgress(0); return Status.OK_STATUS; } catch (Exception e) { e.printStackTrace(); + LogProgress.initProgress(0); return Status.CANCEL_STATUS; } } -} +} \ No newline at end of file diff --git a/src/gui/tools/XperiFirmJob.java b/src/gui/tools/XperiFirmJob.java new file mode 100644 index 00000000..46825211 --- /dev/null +++ b/src/gui/tools/XperiFirmJob.java @@ -0,0 +1,29 @@ +package gui.tools; + +import org.apache.log4j.Logger; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; +import org.util.XperiFirm; + +public class XperiFirmJob extends Job { + + private static Logger logger = Logger.getLogger(DecryptJob.class); + + public XperiFirmJob(String name) { + super(name); + } + + + protected IStatus run(IProgressMonitor monitor) { + try { + XperiFirm.run(); + return Status.OK_STATUS; + } + catch (Exception e) { + e.printStackTrace(); + return Status.CANCEL_STATUS; + } + } +} diff --git a/src/org/system/GlobalConfig.java b/src/org/system/GlobalConfig.java index b45f7f79..3910902b 100644 --- a/src/org/system/GlobalConfig.java +++ b/src/org/system/GlobalConfig.java @@ -1,5 +1,10 @@ package org.system; +import java.io.File; +import java.io.FileReader; +import java.util.Enumeration; +import java.util.Properties; + public class GlobalConfig { private static PropertiesFile config; @@ -16,12 +21,36 @@ public static void setProperty(String property, String value) { } public static void reloadProperties() { - config = new PropertiesFile("gui/ressources/config.properties","./config.properties"); + Properties p = null; + try { + File pfile = new File("./config.properties"); + if (pfile.exists()) { + p = new Properties(); + FileReader pread = new FileReader(pfile); + p.load(pread); + pread.close(); + pfile.delete(); + } + } catch (Exception e) { + p = null; + } + String folder = OS.getUserHome()+File.separator+".flashTool"; + new File(folder).mkdirs(); + config = new PropertiesFile("gui/ressources/config.properties",folder+File.separator+"config.properties"); if (config.getProperty("devfeatures")==null) config.setProperty("devfeatures", "no"); if (config.getProperty("bundle")!=null) config.remove("bundle"); - config.write("UTF-8"); + config.write("UTF-8"); + if (p!=null) { + Enumeration keys = p.keys(); + while (keys.hasMoreElements()) { + String key = (String)keys.nextElement(); + GlobalConfig.setProperty(key, p.getProperty(key)); + } + } + String userfolder = GlobalConfig.getProperty("user.flashtool"); + if (userfolder ==null) GlobalConfig.setProperty("user.flashtool", folder); } - -} + +} \ No newline at end of file diff --git a/src/org/system/OS.java b/src/org/system/OS.java index b25a4793..c3ca293f 100644 --- a/src/org/system/OS.java +++ b/src/org/system/OS.java @@ -1,5 +1,8 @@ package org.system; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -25,6 +28,7 @@ import java.util.zip.ZipInputStream; import org.apache.log4j.Logger; +import org.apache.log4j.lf5.util.StreamUtils; import org.logger.LogProgress; import org.util.HexDump; @@ -94,6 +98,11 @@ public static String getPathBin2Elf() { return new File(System.getProperty("user.dir")+fsep+"x10flasher_lib"+fsep+"bin2elf").getAbsolutePath(); } + public static String getPathXperiFirmWrapper() { + String fsep = OS.getFileSeparator(); + return new File(System.getProperty("user.dir")+fsep+"x10flasher_lib"+fsep+"xperifirm").getAbsolutePath(); + } + public static String getPathFastBoot() { String fsep = OS.getFileSeparator(); if (OS.getName().equals("windows")) @@ -102,6 +111,11 @@ public static String getPathFastBoot() { return new File(System.getProperty("user.dir")+fsep+"x10flasher_lib"+fsep+"fastboot."+OS.getName()).getAbsolutePath(); } + public static String getPathXperiFirm() { + String fsep = OS.getFileSeparator(); + return new File(OS.getFolderUserFlashtool()+fsep+"XperiFirm.exe").getAbsolutePath(); + } + public static String getWorkDir() { return System.getProperty("user.dir"); } @@ -345,7 +359,7 @@ public static void ZipExplodeToFolder(String zippath) throws FileNotFoundExcepti public static void ZipExplodeToHere(String zippath) throws FileNotFoundException, IOException { byte buffer[] = new byte[10240]; File zipfile = new File(zippath); - File outfolder = new File(zipfile.getParentFile().getAbsolutePath()+File.separator+zipfile.getName().replace(".zip", "").replace(".ZIP", "")); + File outfolder = new File(zipfile.getParentFile().getAbsolutePath()); outfolder.mkdirs(); ZipInputStream zis = new ZipInputStream(new FileInputStream(zippath)); ZipEntry ze = zis.getNextEntry(); @@ -361,7 +375,25 @@ public static void ZipExplodeToHere(String zippath) throws FileNotFoundException zis.closeEntry(); zis.close(); } - + + public static void ZipExplodeTo(InputStream stream, File outfolder) throws FileNotFoundException, IOException { + byte buffer[] = new byte[10240]; + outfolder.mkdirs(); + ZipInputStream zis = new ZipInputStream(stream); + ZipEntry ze = zis.getNextEntry(); + while (ze != null) { + FileOutputStream fout = new FileOutputStream(outfolder.getAbsolutePath()+File.separator+ze.getName()); + int len; + while ((len=zis.read(buffer))>0) { + fout.write(buffer,0,len); + } + fout.close(); + ze=zis.getNextEntry(); + } + zis.closeEntry(); + zis.close(); + } + public static void viewAllThreads() { @@ -486,12 +518,15 @@ public static String getFolderCustom() { } public static String getFolderDevices() { - return OS.getWorkDir()+File.separator+"devices"; + return OS.getFolderUserFlashtool()+File.separator+"devices"; } public static String getFolderUserFlashtool() { - new File(getUserHome()+File.separator+".flashTool").mkdirs(); - return getUserHome()+File.separator+".flashTool"; + String folder = GlobalConfig.getProperty("user.flashtool"); + if (folder==null) folder = getUserHome()+File.separator+".flashTool"; + new File(folder).mkdirs(); + GlobalConfig.setProperty("user.flashtool", folder); + return folder; } public static String getFolderFirmwares() { @@ -515,8 +550,8 @@ public static String getFolderFirmwaresSinExtracted() { } public static String getFolderCustomDevices() { - new File(OS.getFolderUserFlashtool()+File.separator+"devices").mkdirs(); - return OS.getFolderUserFlashtool()+File.separator+"devices"; + new File(OS.getFolderUserFlashtool()+File.separator+"mydevices").mkdirs(); + return OS.getFolderUserFlashtool()+File.separator+"mydevices"; } public static String getFolderMyDevices() { @@ -524,4 +559,23 @@ public static String getFolderMyDevices() { return OS.getFolderUserFlashtool()+File.separator+"registeredDevices"; } + public static void unpackArchive(URL url, File targetDir) throws IOException { + if (!targetDir.exists()) { + targetDir.mkdirs(); + } + byte[] zipfile = StreamUtils.getBytes(url.openStream()); + OS.ZipExplodeTo(new ByteArrayInputStream(zipfile),new File(OS.getFolderUserFlashtool())); + } + + public static void copyInputStream(InputStream in, OutputStream out) throws IOException { + byte[] buffer = new byte[1024]; + int len = in.read(buffer); + while (len >= 0) { + out.write(buffer, 0, len); + len = in.read(buffer); + } + in.close(); + out.close(); + } + } \ No newline at end of file diff --git a/src/org/system/XMLFwInfo.java b/src/org/system/XMLFwInfo.java new file mode 100644 index 00000000..8c4be8b9 --- /dev/null +++ b/src/org/system/XMLFwInfo.java @@ -0,0 +1,81 @@ +package org.system; + +import org.apache.log4j.Logger; +import org.jdom.input.SAXBuilder; +import org.jdom.Document; +import org.jdom.JDOMException; +import org.jdom.Element; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Properties; +import java.util.Vector; + +public class XMLFwInfo { + + private String project=""; + private String product=""; + private String model=""; + private String cda=""; + private String market=""; + private String operator=""; + private String network=""; + private String swVer=""; + private String cdfVer=""; + + public XMLFwInfo(File xmlsource) throws IOException, JDOMException { + SAXBuilder builder = new SAXBuilder(); + FileInputStream fin = new FileInputStream(xmlsource); + Document document = builder.build(fin); + fin.close(); + Iterator i = document.getRootElement().getChildren().iterator(); + while (i.hasNext()) { + Element element = (Element)i.next(); + if (element.getName().equals("project")) + project = element.getValue(); + if (element.getName().equals("product")) + product = element.getValue(); + if (element.getName().equals("model")) + model = element.getValue(); + if (element.getName().equals("cda")) + cda = element.getValue(); + if (element.getName().equals("market")) + market = element.getValue(); + if (element.getName().equals("operator")) + operator = element.getValue(); + if (element.getName().equals("network")) + network = element.getValue(); + if (element.getName().equals("swVer")) + swVer = element.getValue(); + if (element.getName().equals("cdfVer")) + cdfVer = element.getValue(); + } + } + + public String getVersion() { + return swVer; + } + + public String getCDA() { + return cda; + } + + public String getOperator() { + return operator; + } + + public String getModel() { + return model; + } + + public String getProduct() { + return product; + } + + public String getRevision() { + return cdfVer; + } + +} \ No newline at end of file diff --git a/src/org/util/XperiFirm.java b/src/org/util/XperiFirm.java new file mode 100644 index 00000000..58c08c94 --- /dev/null +++ b/src/org/util/XperiFirm.java @@ -0,0 +1,133 @@ +package org.util; + +import flashsystem.Bundle; +import flashsystem.BundleMetaData; +import gui.DeviceUpdates; +import gui.models.CategoriesModel; +import gui.tools.WidgetTask; +import gui.tools.createFTFJob; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Vector; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.swt.layout.FormData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Label; +import org.system.DeviceEntry; +import org.system.Devices; +import org.system.OS; +import org.system.ProcessBuilderWrapper; +import org.system.TextFile; +import org.system.XMLFwInfo; + +public class XperiFirm { + + private static Logger logger = Logger.getLogger(XperiFirm.class); + + public static void run() throws Exception { + try { + String version = IOUtils.toString(new URL("http://www.iagucool.com/xperifirm/version")); + String downloadurl = IOUtils.toString(new URL("http://www.iagucool.com/xperifirm/download")); + TextFile tf = new TextFile(OS.getFolderUserFlashtool()+File.separator+"XperiFirm.version","ISO8859-15"); + try { + tf.readLines(); + if (!version.equals(tf.getLines().iterator().next())) { + tf.open(false); + logger.info("Downloading latest XperiFirm"); + OS.unpackArchive(new URL(downloadurl), new File(OS.getFolderUserFlashtool())); + tf.write(version); + tf.close(); + } + } catch (FileNotFoundException fne) { + tf.open(false); + logger.info("Downloading latest XperiFirm"); + OS.unpackArchive(new URL(downloadurl), new File(OS.getFolderUserFlashtool())); tf.write(version); + tf.write(version); + tf.close(); + } + ProcessBuilderWrapper command=null; + try { + List cmdargs = new ArrayList(); + if (OS.getName().equals("windows")) { + cmdargs.add(OS.getPathXperiFirm()); + cmdargs.add("-o"); + cmdargs.add("\""+OS.getFolderFirmwaresDownloaded()+"\""); + } + else { + cmdargs.add(OS.getPathXperiFirmWrapper()); + cmdargs.add(OS.getPathXperiFirm()); + cmdargs.add(OS.getFolderFirmwaresDownloaded()); + } + command = new ProcessBuilderWrapper(cmdargs); + } + catch (Exception e) { + throw new Exception(command.getStdOut()+" / "+command.getStdErr()); + } + String[] downloaded = new File(OS.getFolderFirmwaresDownloaded()).list(); + for (int i = 0; i