format everything for readability and so the brackets all line up again. All whitespace changes.
This commit is contained in:
@ -5,29 +5,31 @@ import com.sun.jna.platform.win32.Kernel32;
|
|||||||
import com.sun.jna.platform.win32.Kernel32Util;
|
import com.sun.jna.platform.win32.Kernel32Util;
|
||||||
|
|
||||||
public class Elevator {
|
public class Elevator {
|
||||||
public static void main(String... args) {
|
public static void main(String... args) {
|
||||||
executeAsAdministrator("c:\\windows\\system32\\notepad.exe", "");
|
executeAsAdministrator("c:\\windows\\system32\\notepad.exe", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void executeAsAdministrator(String command, String args) {
|
public static void executeAsAdministrator(String command, String args) {
|
||||||
if (command == "" || command == null) {
|
if (command == "" || command == null) {
|
||||||
System.out.println("No command specified");
|
System.out.println("No command specified");
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
Shell32X.SHELLEXECUTEINFO execInfo = new Shell32X.SHELLEXECUTEINFO();
|
|
||||||
execInfo.lpFile = new WString(command);
|
|
||||||
if (args != null)
|
|
||||||
execInfo.lpParameters = new WString(args);
|
|
||||||
execInfo.nShow = Shell32X.SW_SHOWDEFAULT;
|
|
||||||
execInfo.fMask = Shell32X.SEE_MASK_NOCLOSEPROCESS;
|
|
||||||
execInfo.lpVerb = new WString("runas");
|
|
||||||
boolean result = Shell32X.INSTANCE.ShellExecuteEx(execInfo);
|
|
||||||
|
|
||||||
if (!result) {
|
|
||||||
int lastError = Kernel32.INSTANCE.GetLastError();
|
|
||||||
String errorMessage = Kernel32Util.formatMessageFromLastErrorCode(lastError);
|
|
||||||
throw new RuntimeException("Error performing elevation: " + lastError + ": " + errorMessage + " (apperror="
|
|
||||||
+ execInfo.hInstApp + ")");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Shell32X.SHELLEXECUTEINFO execInfo = new Shell32X.SHELLEXECUTEINFO();
|
||||||
|
execInfo.lpFile = new WString(command);
|
||||||
|
if (args != null)
|
||||||
|
execInfo.lpParameters = new WString(args);
|
||||||
|
execInfo.nShow = Shell32X.SW_SHOWDEFAULT;
|
||||||
|
execInfo.fMask = Shell32X.SEE_MASK_NOCLOSEPROCESS;
|
||||||
|
execInfo.lpVerb = new WString("runas");
|
||||||
|
boolean result = Shell32X.INSTANCE.ShellExecuteEx(execInfo);
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
int lastError = Kernel32.INSTANCE.GetLastError();
|
||||||
|
String errorMessage =
|
||||||
|
Kernel32Util.formatMessageFromLastErrorCode(lastError);
|
||||||
|
throw new RuntimeException("Error performing elevation: " + lastError +
|
||||||
|
": " + errorMessage +
|
||||||
|
" (apperror=" + execInfo.hInstApp + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package net.i2p.router;
|
package net.i2p.router;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import com.sun.jna.Native;
|
import com.sun.jna.Native;
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.Structure;
|
import com.sun.jna.Structure;
|
||||||
@ -12,100 +10,114 @@ import com.sun.jna.platform.win32.WinDef.HWND;
|
|||||||
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||||
import com.sun.jna.platform.win32.WinReg.HKEY;
|
import com.sun.jna.platform.win32.WinReg.HKEY;
|
||||||
import com.sun.jna.win32.W32APIOptions;
|
import com.sun.jna.win32.W32APIOptions;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
public interface Shell32X extends Shell32 {
|
public interface Shell32X extends Shell32 {
|
||||||
Shell32X INSTANCE = (Shell32X) Native.loadLibrary("shell32", Shell32X.class, W32APIOptions.UNICODE_OPTIONS);
|
Shell32X INSTANCE = (Shell32X)Native.loadLibrary(
|
||||||
|
"shell32", Shell32X.class, W32APIOptions.UNICODE_OPTIONS);
|
||||||
|
|
||||||
int SW_HIDE = 0;
|
int SW_HIDE = 0;
|
||||||
int SW_MAXIMIZE = 3;
|
int SW_MAXIMIZE = 3;
|
||||||
int SW_MINIMIZE = 6;
|
int SW_MINIMIZE = 6;
|
||||||
int SW_RESTORE = 9;
|
int SW_RESTORE = 9;
|
||||||
int SW_SHOW = 5;
|
int SW_SHOW = 5;
|
||||||
int SW_SHOWDEFAULT = 10;
|
int SW_SHOWDEFAULT = 10;
|
||||||
int SW_SHOWMAXIMIZED = 3;
|
int SW_SHOWMAXIMIZED = 3;
|
||||||
int SW_SHOWMINIMIZED = 2;
|
int SW_SHOWMINIMIZED = 2;
|
||||||
int SW_SHOWMINNOACTIVE = 7;
|
int SW_SHOWMINNOACTIVE = 7;
|
||||||
int SW_SHOWNA = 8;
|
int SW_SHOWNA = 8;
|
||||||
int SW_SHOWNOACTIVATE = 4;
|
int SW_SHOWNOACTIVATE = 4;
|
||||||
int SW_SHOWNORMAL = 1;
|
int SW_SHOWNORMAL = 1;
|
||||||
|
|
||||||
/** File not found. */
|
/** File not found. */
|
||||||
int SE_ERR_FNF = 2;
|
int SE_ERR_FNF = 2;
|
||||||
|
|
||||||
/** Path not found. */
|
/** Path not found. */
|
||||||
int SE_ERR_PNF = 3;
|
int SE_ERR_PNF = 3;
|
||||||
|
|
||||||
/** Access denied. */
|
/** Access denied. */
|
||||||
int SE_ERR_ACCESSDENIED = 5;
|
int SE_ERR_ACCESSDENIED = 5;
|
||||||
|
|
||||||
/** Out of memory. */
|
/** Out of memory. */
|
||||||
int SE_ERR_OOM = 8;
|
int SE_ERR_OOM = 8;
|
||||||
|
|
||||||
/** DLL not found. */
|
/** DLL not found. */
|
||||||
int SE_ERR_DLLNOTFOUND = 32;
|
int SE_ERR_DLLNOTFOUND = 32;
|
||||||
|
|
||||||
/** Cannot share an open file. */
|
/** Cannot share an open file. */
|
||||||
int SE_ERR_SHARE = 26;
|
int SE_ERR_SHARE = 26;
|
||||||
|
|
||||||
int SEE_MASK_NOCLOSEPROCESS = 0x00000040;
|
int SEE_MASK_NOCLOSEPROCESS = 0x00000040;
|
||||||
|
|
||||||
int ShellExecute(int i, String lpVerb, String lpFile, String lpParameters, String lpDirectory, int nShow);
|
int ShellExecute(int i, String lpVerb, String lpFile, String lpParameters,
|
||||||
|
String lpDirectory, int nShow);
|
||||||
|
|
||||||
boolean ShellExecuteEx(SHELLEXECUTEINFO lpExecInfo);
|
boolean ShellExecuteEx(SHELLEXECUTEINFO lpExecInfo);
|
||||||
|
|
||||||
public static class SHELLEXECUTEINFO extends Structure {
|
public static class SHELLEXECUTEINFO extends Structure {
|
||||||
/*
|
/*
|
||||||
* DWORD cbSize;
|
* DWORD cbSize;
|
||||||
* ULONG fMask;
|
* ULONG fMask;
|
||||||
* HWND hwnd;
|
* HWND hwnd;
|
||||||
* LPCTSTR lpVerb;
|
* LPCTSTR lpVerb;
|
||||||
* LPCTSTR lpFile;
|
* LPCTSTR lpFile;
|
||||||
* LPCTSTR lpParameters;
|
* LPCTSTR lpParameters;
|
||||||
* LPCTSTR lpDirectory;
|
* LPCTSTR lpDirectory;
|
||||||
* int nShow;
|
* int nShow;
|
||||||
* HINSTANCE hInstApp;
|
* HINSTANCE hInstApp;
|
||||||
* LPVOID lpIDList;
|
* LPVOID lpIDList;
|
||||||
* LPCTSTR lpClass;
|
* LPCTSTR lpClass;
|
||||||
* HKEY hkeyClass;
|
* HKEY hkeyClass;
|
||||||
* DWORD dwHotKey;
|
* DWORD dwHotKey;
|
||||||
* union {
|
* union {
|
||||||
* HANDLE hIcon;
|
* HANDLE hIcon;
|
||||||
* HANDLE hMonitor;
|
* HANDLE hMonitor;
|
||||||
* } DUMMYUNIONNAME;
|
* } DUMMYUNIONNAME;
|
||||||
* HANDLE hProcess;
|
* HANDLE hProcess;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public int cbSize = size();
|
public int cbSize = size();
|
||||||
public int fMask;
|
public int fMask;
|
||||||
public HWND hwnd;
|
public HWND hwnd;
|
||||||
public WString lpVerb;
|
public WString lpVerb;
|
||||||
public WString lpFile;
|
public WString lpFile;
|
||||||
public WString lpParameters;
|
public WString lpParameters;
|
||||||
public WString lpDirectory;
|
public WString lpDirectory;
|
||||||
public int nShow;
|
public int nShow;
|
||||||
public HINSTANCE hInstApp;
|
public HINSTANCE hInstApp;
|
||||||
public Pointer lpIDList;
|
public Pointer lpIDList;
|
||||||
public WString lpClass;
|
public WString lpClass;
|
||||||
public HKEY hKeyClass;
|
public HKEY hKeyClass;
|
||||||
public int dwHotKey;
|
public int dwHotKey;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Actually:
|
* Actually:
|
||||||
* union {
|
* union {
|
||||||
* HANDLE hIcon;
|
* HANDLE hIcon;
|
||||||
* HANDLE hMonitor;
|
* HANDLE hMonitor;
|
||||||
* } DUMMYUNIONNAME;
|
* } DUMMYUNIONNAME;
|
||||||
*/
|
*/
|
||||||
public HANDLE hMonitor;
|
public HANDLE hMonitor;
|
||||||
public HANDLE hProcess;
|
public HANDLE hProcess;
|
||||||
|
|
||||||
protected List getFieldOrder() {
|
protected List getFieldOrder() {
|
||||||
return Arrays.asList(new String[] {
|
return Arrays.asList(new String[] {
|
||||||
"cbSize", "fMask", "hwnd", "lpVerb", "lpFile", "lpParameters",
|
"cbSize",
|
||||||
"lpDirectory", "nShow", "hInstApp", "lpIDList", "lpClass",
|
"fMask",
|
||||||
"hKeyClass", "dwHotKey", "hMonitor", "hProcess",
|
"hwnd",
|
||||||
});
|
"lpVerb",
|
||||||
}
|
"lpFile",
|
||||||
|
"lpParameters",
|
||||||
|
"lpDirectory",
|
||||||
|
"nShow",
|
||||||
|
"hInstApp",
|
||||||
|
"lpIDList",
|
||||||
|
"lpClass",
|
||||||
|
"hKeyClass",
|
||||||
|
"dwHotKey",
|
||||||
|
"hMonitor",
|
||||||
|
"hProcess",
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,80 +1,88 @@
|
|||||||
package net.i2p.router;
|
package net.i2p.router;
|
||||||
|
|
||||||
import net.i2p.router.*;
|
|
||||||
import net.i2p.I2PAppContext;
|
|
||||||
|
|
||||||
import java.util.function.*;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.function.*;
|
||||||
|
import net.i2p.I2PAppContext;
|
||||||
|
import net.i2p.router.*;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
|
|
||||||
class WinUpdateProcess implements Runnable {
|
class WinUpdateProcess implements Runnable {
|
||||||
private final RouterContext ctx;
|
private final RouterContext ctx;
|
||||||
private final Supplier<String> versionSupplier;
|
private final Supplier<String> versionSupplier;
|
||||||
private final Supplier<File> fileSupplier;
|
private final Supplier<File> fileSupplier;
|
||||||
private final Log _log;
|
private final Log _log;
|
||||||
|
|
||||||
WinUpdateProcess(RouterContext ctx, Supplier<String> versionSupplier, Supplier<File> fileSupplier) {
|
WinUpdateProcess(RouterContext ctx, Supplier<String> versionSupplier,
|
||||||
this.ctx = ctx;
|
Supplier<File> fileSupplier) {
|
||||||
this.versionSupplier = versionSupplier;
|
this.ctx = ctx;
|
||||||
this.fileSupplier = fileSupplier;
|
this.versionSupplier = versionSupplier;
|
||||||
this._log = ctx.logManager().getLog(WinUpdateProcess.class);
|
this.fileSupplier = fileSupplier;
|
||||||
|
this._log = ctx.logManager().getLog(WinUpdateProcess.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private File workDir() throws IOException {
|
||||||
|
if (ctx != null) {
|
||||||
|
File workDir =
|
||||||
|
new File(ctx.getConfigDir().getAbsolutePath(), "i2p_update_win");
|
||||||
|
if (workDir.exists()) {
|
||||||
|
if (workDir.isFile())
|
||||||
|
throw new IOException(workDir +
|
||||||
|
" exists but is a file, get it out of the way");
|
||||||
|
return workDir;
|
||||||
|
} else {
|
||||||
|
workDir.mkdirs();
|
||||||
|
}
|
||||||
|
return workDir;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private File workDir() throws IOException {
|
private void runUpdateInstaller() throws IOException {
|
||||||
if (ctx != null) {
|
String version = versionSupplier.get();
|
||||||
File workDir = new File(ctx.getConfigDir().getAbsolutePath(), "i2p_update_win");
|
File file = fileSupplier.get();
|
||||||
if (workDir.exists()) {
|
if (file == null)
|
||||||
if (workDir.isFile())
|
return;
|
||||||
throw new IOException(workDir + " exists but is a file, get it out of the way");
|
|
||||||
return workDir;
|
var workingDir = workDir();
|
||||||
} else {
|
var logFile = new File(workingDir, "log-" + version + ".txt");
|
||||||
workDir.mkdirs();
|
|
||||||
}
|
if (logFile.canWrite()) {
|
||||||
return workDir;
|
// check if we can write to the log file. If we can, use the
|
||||||
}
|
// ProcessBuilder to run the installer.
|
||||||
return null;
|
ProcessBuilder pb = new ProcessBuilder(
|
||||||
|
file.getAbsolutePath(), "/S", "/D=" + workingDir.getAbsolutePath());
|
||||||
|
var env = pb.environment();
|
||||||
|
env.put("OLD_I2P_VERSION", version);
|
||||||
|
env.remove("RESTART_I2P");
|
||||||
|
|
||||||
|
int exitCode = ctx.router().scheduledGracefulExitCode();
|
||||||
|
if (exitCode == Router.EXIT_HARD_RESTART ||
|
||||||
|
exitCode == Router.EXIT_GRACEFUL_RESTART)
|
||||||
|
env.put("RESTART_I2P", "true");
|
||||||
|
|
||||||
|
try {
|
||||||
|
pb.directory(workingDir)
|
||||||
|
.redirectErrorStream(true)
|
||||||
|
.redirectOutput(logFile)
|
||||||
|
.start();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
_log.error(
|
||||||
|
"Unable to run update-program in background. Update will fail.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If we cant write to the log file and we're on Windows, use the elevator
|
||||||
|
// to execute the installer instead of the ProcessBuilder.
|
||||||
|
Elevator.executeAsAdministrator(file.getAbsolutePath(),
|
||||||
|
" /S /D=" + workingDir.getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void runUpdateInstaller() throws IOException {
|
@Override
|
||||||
String version = versionSupplier.get();
|
public void run() {
|
||||||
File file = fileSupplier.get();
|
try {
|
||||||
if (file == null)
|
runUpdateInstaller();
|
||||||
return;
|
} catch (IOException ioe) {
|
||||||
|
_log.error("Error running updater, update may fail." + ioe);
|
||||||
var workingDir = workDir();
|
|
||||||
var logFile = new File(workingDir, "log-" + version + ".txt");
|
|
||||||
|
|
||||||
if (logFile.canWrite()) {
|
|
||||||
// check if we can write to the log file. If we can, use the ProcessBuilder to
|
|
||||||
// run the installer.
|
|
||||||
ProcessBuilder pb = new ProcessBuilder(file.getAbsolutePath(), "/S", "/D=" + workingDir.getAbsolutePath());
|
|
||||||
var env = pb.environment();
|
|
||||||
env.put("OLD_I2P_VERSION", version);
|
|
||||||
env.remove("RESTART_I2P");
|
|
||||||
|
|
||||||
int exitCode = ctx.router().scheduledGracefulExitCode();
|
|
||||||
if (exitCode == Router.EXIT_HARD_RESTART || exitCode == Router.EXIT_GRACEFUL_RESTART)
|
|
||||||
env.put("RESTART_I2P", "true");
|
|
||||||
|
|
||||||
try {
|
|
||||||
pb.directory(workingDir).redirectErrorStream(true).redirectOutput(logFile).start();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
_log.error("Unable to run update-program in background. Update will fail.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// If we cant write to the log file and we're on Windows, use the elevator to
|
|
||||||
// execute the installer instead of the ProcessBuilder.
|
|
||||||
Elevator.executeAsAdministrator(file.getAbsolutePath(), " /S /D=" + workingDir.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
runUpdateInstaller();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
_log.error("Error running updater, update may fail." + ioe);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,101 +1,100 @@
|
|||||||
package net.i2p.router;
|
package net.i2p.router;
|
||||||
|
|
||||||
|
import static net.i2p.update.UpdateType.*;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.lang.InterruptedException;
|
||||||
|
import java.lang.Process;
|
||||||
|
import java.lang.ProcessBuilder;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.*;
|
import java.util.concurrent.atomic.*;
|
||||||
|
|
||||||
import net.i2p.crypto.*;
|
|
||||||
import static net.i2p.update.UpdateType.*;
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.update.UpdateType;
|
import net.i2p.crypto.*;
|
||||||
import net.i2p.update.UpdatePostProcessor;
|
import net.i2p.update.UpdatePostProcessor;
|
||||||
|
import net.i2p.update.UpdateType;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
import net.i2p.util.SystemVersion;
|
import net.i2p.util.SystemVersion;
|
||||||
|
|
||||||
import java.lang.ProcessBuilder;
|
|
||||||
import java.lang.Process;
|
|
||||||
import java.lang.InterruptedException;
|
|
||||||
|
|
||||||
public class WindowsUpdatePostProcessor implements UpdatePostProcessor {
|
public class WindowsUpdatePostProcessor implements UpdatePostProcessor {
|
||||||
private final Log _log;
|
private final Log _log;
|
||||||
private final RouterContext ctx;
|
private final RouterContext ctx;
|
||||||
private final AtomicBoolean hook = new AtomicBoolean();
|
private final AtomicBoolean hook = new AtomicBoolean();
|
||||||
private final String fileName = "i2p-jpackage-update.exe";
|
private final String fileName = "i2p-jpackage-update.exe";
|
||||||
|
|
||||||
private volatile String version;
|
private volatile String version;
|
||||||
|
|
||||||
private volatile File positionedFile = null;
|
private volatile File positionedFile = null;
|
||||||
|
|
||||||
WindowsUpdatePostProcessor(RouterContext ctx) {
|
WindowsUpdatePostProcessor(RouterContext ctx) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this._log = ctx.logManager().getLog(WindowsUpdatePostProcessor.class);
|
this._log = ctx.logManager().getLog(WindowsUpdatePostProcessor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVersion() { return version; }
|
||||||
|
|
||||||
|
public File getFile() { return positionedFile; }
|
||||||
|
|
||||||
|
public void updateDownloadedandVerified(UpdateType type, int fileType,
|
||||||
|
String version, File file)
|
||||||
|
throws IOException {
|
||||||
|
_log.info("Got an update to post-process");
|
||||||
|
if (SystemVersion.isWindows()) {
|
||||||
|
|
||||||
|
if (type != UpdateType.ROUTER_SIGNED_SU3 &&
|
||||||
|
type != UpdateType.ROUTER_DEV_SU3) {
|
||||||
|
_log.warn("Unsupported update type " + type);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileType != SU3File.TYPE_EXE) {
|
||||||
|
_log.warn("Unsupported file type " + fileType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.positionedFile = moveUpdateInstaller(file);
|
||||||
|
this.version = version;
|
||||||
|
|
||||||
|
if (!hook.compareAndSet(false, true)) {
|
||||||
|
_log.info("shutdown hook was already set");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_log.info("adding shutdown hook");
|
||||||
|
|
||||||
|
ctx.addFinalShutdownTask(
|
||||||
|
new WinUpdateProcess(ctx, this::getVersion, this::getFile));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public String getVersion() {
|
private File moveUpdateInstaller(File file) throws IOException {
|
||||||
return version;
|
if (this.ctx != null) {
|
||||||
}
|
File newFile = new File(workDir(), fileName);
|
||||||
|
boolean renamedStatus = file.renameTo(newFile);
|
||||||
public File getFile() {
|
if (renamedStatus)
|
||||||
return positionedFile;
|
return newFile;
|
||||||
}
|
else
|
||||||
|
|
||||||
public void updateDownloadedandVerified(UpdateType type, int fileType, String version, File file)
|
|
||||||
throws IOException {
|
|
||||||
_log.info("Got an update to post-process");
|
|
||||||
if (SystemVersion.isWindows()) {
|
|
||||||
|
|
||||||
if (type != UpdateType.ROUTER_SIGNED_SU3 && type != UpdateType.ROUTER_DEV_SU3) {
|
|
||||||
_log.warn("Unsupported update type " + type);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileType != SU3File.TYPE_EXE) {
|
|
||||||
_log.warn("Unsupported file type " + fileType);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.positionedFile = moveUpdateInstaller(file);
|
|
||||||
this.version = version;
|
|
||||||
|
|
||||||
if (!hook.compareAndSet(false, true)) {
|
|
||||||
_log.info("shutdown hook was already set");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_log.info("adding shutdown hook");
|
|
||||||
|
|
||||||
ctx.addFinalShutdownTask(new WinUpdateProcess(ctx, this::getVersion, this::getFile));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private File moveUpdateInstaller(File file) throws IOException {
|
|
||||||
if (this.ctx != null) {
|
|
||||||
File newFile = new File(workDir(), fileName);
|
|
||||||
boolean renamedStatus = file.renameTo(newFile);
|
|
||||||
if (renamedStatus)
|
|
||||||
return newFile;
|
|
||||||
else
|
|
||||||
throw new IOException(
|
|
||||||
"WindowsUpdatePostProcesssor unable to move file to working directory, update will fail");
|
|
||||||
}
|
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Router context not available to WindowsUpdatePostProcesssor, unable to find working directory, update will fail");
|
"WindowsUpdatePostProcesssor unable to move file to working directory, update will fail");
|
||||||
}
|
}
|
||||||
|
throw new IOException(
|
||||||
|
"Router context not available to WindowsUpdatePostProcesssor, unable to find working directory, update will fail");
|
||||||
|
}
|
||||||
|
|
||||||
private File workDir() throws IOException {
|
private File workDir() throws IOException {
|
||||||
if (this.ctx != null) {
|
if (this.ctx != null) {
|
||||||
File workDir = new File(this.ctx.getConfigDir().getAbsolutePath(), "i2p_update_win");
|
File workDir =
|
||||||
if (workDir.exists()) {
|
new File(this.ctx.getConfigDir().getAbsolutePath(), "i2p_update_win");
|
||||||
if (workDir.isFile())
|
if (workDir.exists()) {
|
||||||
throw new IOException(workDir + " exists but is a file, get it out of the way");
|
if (workDir.isFile())
|
||||||
return null;
|
throw new IOException(workDir +
|
||||||
} else {
|
" exists but is a file, get it out of the way");
|
||||||
workDir.mkdirs();
|
|
||||||
}
|
|
||||||
return workDir;
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
|
} else {
|
||||||
|
workDir.mkdirs();
|
||||||
|
}
|
||||||
|
return workDir;
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user