2013-04-03 01:39:33 +00:00
|
|
|
/**
|
2013-04-03 01:52:14 +00:00
|
|
|
* Customized I2P launcher.
|
2013-04-03 01:39:33 +00:00
|
|
|
* Launches the JRE within the process, to allow Task Manager to show
|
2013-04-03 01:52:14 +00:00
|
|
|
* "I2P.exe" as the process, and firewalls to control access of
|
|
|
|
* "I2P.exe".
|
2013-04-03 01:39:33 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "errors.h"
|
|
|
|
|
2013-04-22 20:37:42 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <stdio.h>
|
2013-04-03 01:39:33 +00:00
|
|
|
#include <malloc.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
|
|
|
//BOOL MoveFontPropertiesFile(const char *path);
|
|
|
|
void SetWorkingDirectory(char *path);
|
|
|
|
void readOptions(char***, int*);
|
|
|
|
//BOOL localJREExists(const char*);
|
2013-04-22 20:37:42 +00:00
|
|
|
BOOL exist(const char*);
|
2013-04-03 01:39:33 +00:00
|
|
|
|
|
|
|
// defined in java.c
|
|
|
|
extern void* MemAlloc(size_t);
|
|
|
|
// defined in java.c
|
|
|
|
extern int launchJVM(int, char**);
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
main(int argc, char** argv) {
|
|
|
|
|
2013-04-04 22:15:21 +00:00
|
|
|
int read_options_size;
|
|
|
|
char** read_options;
|
2013-04-03 01:39:33 +00:00
|
|
|
int ret = 0;
|
2013-04-04 22:15:21 +00:00
|
|
|
int new_argc;
|
|
|
|
char** new_argv;
|
|
|
|
int i;
|
2013-04-03 01:39:33 +00:00
|
|
|
char currentDirectory[MAX_PATH+1];
|
|
|
|
|
|
|
|
// Set/get the correct working directory.
|
|
|
|
SetWorkingDirectory(currentDirectory);
|
|
|
|
|
2013-04-04 22:15:21 +00:00
|
|
|
// If there are command-line arguments, just use them
|
|
|
|
if(argc > 1) {
|
|
|
|
ret = launchJVM(argc, argv);
|
|
|
|
} else {
|
|
|
|
// Read in options from disk (launch.properties)
|
|
|
|
// or the default ones (if no launch.properties existed)
|
|
|
|
readOptions(&read_options, &read_options_size);
|
2013-04-03 01:39:33 +00:00
|
|
|
|
2013-04-04 22:15:21 +00:00
|
|
|
// Construct a new argc & argv to pass to launchJVM
|
|
|
|
new_argc = read_options_size;
|
|
|
|
new_argv = (char**)MemAlloc(sizeof(char*) * (new_argc+1));
|
2013-04-03 01:39:33 +00:00
|
|
|
|
2013-04-04 22:15:21 +00:00
|
|
|
// copy process name
|
|
|
|
new_argv[0] = argv[0];
|
|
|
|
// copy arguments from properties file
|
|
|
|
for(i = 1; i <= read_options_size; i++)
|
|
|
|
new_argv[i] = read_options[i-1];
|
2013-04-03 01:39:33 +00:00
|
|
|
|
2013-04-04 22:15:21 +00:00
|
|
|
new_argv[i] = NULL;
|
2013-04-03 01:39:33 +00:00
|
|
|
|
2013-04-04 22:15:21 +00:00
|
|
|
// options are no longer necessary -- free them up.
|
|
|
|
if(read_options != 0)
|
|
|
|
free(read_options);
|
2013-04-03 01:39:33 +00:00
|
|
|
|
2013-04-04 22:15:21 +00:00
|
|
|
ret = launchJVM(new_argc, new_argv);
|
|
|
|
free(new_argv);
|
|
|
|
}
|
2013-04-03 01:39:33 +00:00
|
|
|
switch(ret) {
|
|
|
|
case ERROR_COULDNT_FIND_JVM:
|
|
|
|
case ERROR_COULDNT_INITIALIZE_JVM:
|
|
|
|
case ERROR_COULDNT_LOAD_JVM:
|
2013-04-03 01:52:14 +00:00
|
|
|
if (MessageBox(NULL, "I2P needs the Java Runtime Environment 5.0 or above. Click OK to go to www.java.com, where you can install Java.",
|
|
|
|
"I2P Launcher Error",
|
2013-04-03 01:39:33 +00:00
|
|
|
MB_ICONWARNING | MB_OKCANCEL) == IDOK)
|
|
|
|
ShellExecute(NULL, NULL, "http://www.java.com/", "", "", SW_SHOWNORMAL);
|
|
|
|
break;
|
|
|
|
case ERROR_COULDNT_PARSE_ARGUMENTS:
|
2013-04-03 01:52:14 +00:00
|
|
|
MessageBox(NULL, "I2P failed to parse the commandline arguments to Java.\n"
|
|
|
|
"Please download and install I2P again.",
|
|
|
|
"I2P Launcher Error", MB_OK);
|
2013-04-03 01:39:33 +00:00
|
|
|
break;
|
|
|
|
case ERROR_STARTING_PROGRAM:
|
2013-04-03 01:52:14 +00:00
|
|
|
MessageBox(NULL, "I2P was unable to load.\n"
|
|
|
|
"Please download and install I2P again.",
|
|
|
|
"I2P Launcher Error", MB_OK);
|
2013-04-03 01:39:33 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define MAX_OPTION_SIZE 100
|
|
|
|
#define MAX_OPTIONS 100
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read in the launch.properties file and generate psuedo-commandline arguments.
|
|
|
|
*/
|
|
|
|
void readOptions(char*** options, int* size) {
|
|
|
|
FILE* file;
|
|
|
|
char* buffer;
|
|
|
|
int i;
|
|
|
|
size_t currentlen;
|
|
|
|
char* command;
|
|
|
|
|
|
|
|
file = fopen("launch.properties", "r");
|
|
|
|
if(file == NULL) {
|
|
|
|
// default to certain values.
|
2013-04-04 22:25:05 +00:00
|
|
|
*size = 9;
|
2013-04-03 01:39:33 +00:00
|
|
|
|
|
|
|
*options = (char**)MemAlloc(sizeof(char*) * (*size));
|
|
|
|
i = 0;
|
|
|
|
(*options)[i++] = "-Xms64m";
|
2013-04-04 22:25:05 +00:00
|
|
|
(*options)[i++] = "-Xmx128m";
|
2013-04-03 01:39:33 +00:00
|
|
|
//(*options)[i++] = "-Djava.net.preferIPv6Addresses=false";
|
2013-04-04 22:25:05 +00:00
|
|
|
//(*options)[i++] = "-Djava.net.preferIPv4Stack=true";
|
|
|
|
(*options)[i++] = "-Djava.library.path=.;lib";
|
|
|
|
(*options)[i++] = "-DloggerFilenameOverride=logs/log-router-@.txt";
|
|
|
|
(*options)[i++] = "-Dorg.mortbay.http.Version.paranoid=true";
|
|
|
|
(*options)[i++] = "-Dorg.mortbay.util.FileResource.checkAliases=false";
|
|
|
|
(*options)[i++] = "-cp";
|
2013-04-24 03:53:12 +00:00
|
|
|
(*options)[i++] = "lib/i2p.jar;lib/router.jar;lib/jbigi.jar;lib/BOB.jar;lib/sam.jar;lib/mstreaming.jar;lib/streaming.jar;lib/routerconsole.jar;lib/i2ptunnel.jar;lib/org.mortbay.jetty.jar;lib/javax.servlet.jar;lib/jasper-compiler.jar;lib/jasper-runtime.jar;lib/commons-logging.jar;lib/commons-el.jar;lib/wrapper.jar;lib/systray.jar;lib/systray4j.jar;lib/desktopgui.jar;lib/i2psnark.jar;lib/jrobin.jar;lib/jstl.jar;lib/standard.jar;lib/jetty-continuation.jar;lib/jetty-deploy.jar;lib/jetty-http.jar;lib/jetty-i2p.jar;lib/jetty-io.jar;lib/jetty-java5-threadpool.jar;lib/jetty-rewrite-handler.jar;lib/jetty-security.jar;lib/jetty-servlet.jar;lib/jetty-servlets.jar;lib/jetty-sslengine.jar;lib/jetty-start.jar;lib/jetty-util.jar;lib/jetty-webapp.jar;lib/jetty-xml.jar";
|
2013-04-04 22:25:05 +00:00
|
|
|
(*options)[i++] = "net.i2p.router.RouterLaunch";
|
2013-04-03 01:39:33 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
*options = (char**)MemAlloc(sizeof(char*) * MAX_OPTIONS);
|
|
|
|
*size = 0;
|
|
|
|
|
|
|
|
for(i = 0; i < MAX_OPTIONS && !feof(file); i++) {
|
|
|
|
buffer = (char*)MemAlloc(sizeof(char) * MAX_OPTION_SIZE);
|
|
|
|
// get the next option.
|
|
|
|
if(fgets(buffer, MAX_OPTION_SIZE - 1, file) == NULL)
|
|
|
|
break;
|
|
|
|
// strip off the \n if it exists.
|
|
|
|
currentlen = strlen(buffer);
|
|
|
|
if(currentlen > 0 && buffer[currentlen-1] == '\n') {
|
|
|
|
buffer[currentlen-1] = 0;
|
|
|
|
currentlen--;
|
|
|
|
}
|
|
|
|
// downsize the storage for the command.
|
|
|
|
currentlen++; // (include \0)
|
|
|
|
command = (char*)MemAlloc(sizeof(char) * currentlen);
|
|
|
|
strcpy(command, buffer);
|
|
|
|
free(buffer);
|
|
|
|
|
|
|
|
// set the option & increase the size
|
|
|
|
if(currentlen > 0) {
|
|
|
|
(*options)[i] = command;
|
|
|
|
(*size)++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(file != NULL)
|
|
|
|
fclose(file);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2013-04-03 01:52:14 +00:00
|
|
|
* Sets the current working directory to wherever I2P.exe is located
|
2013-04-03 01:39:33 +00:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
SetWorkingDirectory(char *path) {
|
|
|
|
GetModuleFileName(NULL, path, MAX_PATH + 1);
|
|
|
|
*strrchr(path, '\\') = '\0'; // remove the .exe
|
|
|
|
SetCurrentDirectory(path);
|
|
|
|
GetCurrentDirectory(MAX_PATH + 1, path);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks to see if an app-installed JRE exists.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
BOOL localJREExists(const char* path) {
|
|
|
|
char localBuf[MAX_PATH + 1];
|
|
|
|
sprintf(localBuf, "%s\\jre\\bin\\hotspot\\jvm.dll\0", path);
|
|
|
|
return exist(localBuf);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copies the windows.font.properties file to the jre so that
|
|
|
|
* we use the proper fonts for international installs.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
BOOL
|
|
|
|
MoveFontPropertiesFile(const char *path) {
|
|
|
|
char curFontFile[MAX_PATH + 1];
|
|
|
|
char newFontFile[MAX_PATH + 1];
|
|
|
|
BOOL copySucceeded;
|
|
|
|
sprintf(curFontFile, "%s\\windows.font.properties\0", path);
|
|
|
|
sprintf(newFontFile, "%s\\jre\\lib\\font.properties\0", path);
|
|
|
|
if(!exist(curFontFile))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
copySucceeded = CopyFile(curFontFile, newFontFile, FALSE);
|
|
|
|
if(copySucceeded)
|
|
|
|
DeleteFile(curFontFile);
|
|
|
|
return copySucceeded;
|
|
|
|
}
|
|
|
|
*/
|
2013-04-22 20:37:42 +00:00
|
|
|
|
2013-04-03 01:39:33 +00:00
|
|
|
BOOL exist(const char *filename) {
|
|
|
|
struct stat s;
|
|
|
|
return stat(filename, &s) == 0 ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
2013-04-22 20:37:42 +00:00
|
|
|
|
2013-04-03 01:39:33 +00:00
|
|
|
__declspec(dllimport) char **__initenv;
|
|
|
|
|
|
|
|
int WINAPI
|
|
|
|
WinMain(HINSTANCE inst, HINSTANCE previnst, LPSTR cmdline, int cmdshow)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* It turns out, that Windows can set thread locale to default user locale
|
|
|
|
* instead of default system locale. We correct this by explicitely setting
|
|
|
|
* thread locale to system default.
|
|
|
|
*/
|
|
|
|
SetThreadLocale(GetSystemDefaultLCID());
|
|
|
|
|
|
|
|
__initenv = _environ;
|
|
|
|
ret = main(__argc, __argv);
|
|
|
|
|
|
|
|
return ret;
|
2013-04-03 01:52:14 +00:00
|
|
|
}
|