package pw.cloudef.rpg; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.net.Uri; import android.system.Os; import android.util.Log; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.io.FileOutputStream; import java.nio.charset.Charset; import java.util.zip.ZipFile; import java.util.zip.ZipEntry; import java.util.Enumeration; public class Rtp extends Activity { protected String rtpDir() { return getApplicationContext().getFilesDir().toPath().toString() + "/rtp"; } protected String workDir() { return getApplicationContext().getCacheDir().toPath().toString() + "/temp"; } protected String zipPath() { return workDir() + "/rtp.zip"; } protected void shell(String cmd) { try { Runtime.getRuntime().exec(cmd); } catch (Exception e) {} } protected void rm(String path) { shell("rm -rf '" + path + "'"); } protected void run(String cmd, String args, String input) { shell("'" + getApplicationContext().getApplicationInfo().nativeLibraryDir + "/" + cmd + "' " + args + " '" + workDir() + "/" + input + "'"); } protected boolean matches(String name, String[] wants) { for (int i = 0; i < wants.length; ++i) if (name.equals(wants[i])) return true; return false; } protected void unzip(File file, String[] wants, String dest) { ZipFile zipFile; try { zipFile = new ZipFile(file, java.util.zip.ZipFile.OPEN_READ, Charset.forName("Windows-31J")); } catch (Exception e) { Log.d("pw.cloudef.rpg", e.toString()); return; } try { Enumeration zipEntries = zipFile.entries(); while (zipEntries.hasMoreElements()) { final ZipEntry entry = (ZipEntry)zipEntries.nextElement(); if (!matches(entry.getName(), wants)) continue; InputStream input = zipFile.getInputStream(entry); String base = entry.getName().split(".+?/(?=[^/]+$)")[1]; File out = new File(dest, base); if (!out.getCanonicalPath().startsWith(dest)) throw new Exception("Zip path traversal detected"); out.mkdirs(); OutputStream output = new FileOutputStream(out); byte[] buf = new byte[8 * 1024]; for (int read = 0; (read = input.read(buf)) != -1;) output.write(buf, 0, read); output.close(); input.close(); break; } } catch (Exception e) { Log.d("pw.cloudef.rpg", e.toString()); } try { zipFile.close(); } catch (Exception e) {} } protected String rtpId() { return getIntent().getExtras().getString("id"); } protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); try { InputStream input = getContentResolver().openInputStream(getIntent().getData()); File file = new File(zipPath()); file.mkdirs(); OutputStream output = new FileOutputStream(file); byte[] buf = new byte[8 * 1024]; for (int read = 0; (read = input.read(buf)) != -1;) output.write(buf, 0, read); output.close(); input.close(); if (rtpId().equals("2000") || rtpId().equals("2003")) { String prefix = (rtpId().equals("2003") ? "2003" : ""); // STEP 1 unzip unzip(file, new String[]{prefix + "RTPセットアップ/" + rtpId() + "RTP.exe"}, workDir()); // STEP 2 cabextract run("libcabextract.so", "-d '" + workDir() + "' -e CP932 ", rtpId() + "RTP.exe"); // STEP 3 unshield run("libunshield.so", "-d '" + workDir() + "' -e CP932 x", "data1.cab"); run("libunshield.so", "-d '" + workDir() + "' -e CP932 x", "data2.cab"); } else if (rtpId().equals("XP")) { // STEP 1 unzip unzip(file, new String[]{"RPGXP_RTP103/Setup.exe"}, workDir()); // STEP 2 innoextract run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "Setup.exe"); // STEP 3 move to RTP dir shell("mv '" + workDir() + "/app' '" + rtpDir() + "/XP'"); } else if (rtpId().equals("VX")) { // STEP 1 unzip unzip(file, new String[]{"RPGVX_RTP202/setup.exe"}, workDir()); // STEP 2 innoextract run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "setup.exe"); // STEP 3 move to RTP dir shell("mv '" + workDir() + "/app' '" + rtpDir() + "/VX'"); } else if (rtpId().equals("VXAce")) { // STEP 1 unzip unzip(file, new String[]{"RPGVXAce_RTP100/Setup.exe", "RPGVXAce_RTP100/Setup-1.bin"}, workDir()); // STEP 2 innoextract run("libinnoextract.so", "-d '" + workDir() + "' -I app ", "Setup.exe"); // STEP 3 move to RTP dir shell("mv '" + workDir() + "/app' '" + rtpDir() + "/VXAce'"); } else { throw new Exception("Unknown RTP"); } } catch (Exception e) { Log.d("pw.cloudef.rpg", e.toString()); } // rm(workDir()); finishAndRemoveTask(); } }