Files
i2p.i2p/installer/c/i2pExe/java_md.c

389 lines
9.2 KiB
C
Raw Normal View History

2013-04-03 01:39:33 +00:00
/**
* Derived from the shared source for the 'java' commandline tool.
*/
/* Backported from Tiger (1.5) java_md.c 1.40 04/01/12 */
/* AMD64 support removed */
#include <windows.h>
#include <process.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "jni.h"
#include "java.h"
#define JVM_DLL "jvm.dll"
#define JAVA_DLL "java.dll"
/*
* Prototypes.
*/
static jboolean GetPublicJREHome(char *path, jint pathsize);
static jboolean GetJVMPath(const char *jrepath, const char *jvmtype,
char *jvmpath, jint jvmpathsize);
static jboolean GetJREPath(char *path, jint pathsize);
const char *
GetArch()
{
#ifdef _WIN64
return "ia64";
#else
return "i386";
#endif
}
/*
*
*/
int
CreateExecutionEnvironment(int *_argc,
char ***_argv,
char jrepath[],
jint so_jrepath,
char jvmpath[],
jint so_jvmpath,
char **original_argv) {
char * jvmtype;
/* Find out where the JRE is that we will be using. */
if (!GetJREPath(jrepath, so_jrepath)) {
ReportErrorMessage("Could not find a suitable Java 2 Runtime Environment.",
JNI_TRUE);
return 1;
}
/* Find the specified JVM type */
if (ReadKnownVMs(jrepath, (char*)GetArch(), JNI_FALSE) < 1) {
ReportErrorMessage("Error: no known VMs. (check for corrupt jvm.cfg file)",
JNI_TRUE);
return 1;
}
jvmtype = CheckJvmType(_argc, _argv, JNI_FALSE);
jvmpath[0] = '\0';
if (!GetJVMPath(jrepath, jvmtype, jvmpath, so_jvmpath)) {
char * message=NULL;
const char * format = "Error: no `%s' JVM at `%s'.";
message = (char *)MemAlloc((strlen(format)+strlen(jvmtype)+
strlen(jvmpath)) * sizeof(char));
sprintf(message,format, jvmtype, jvmpath);
ReportErrorMessage(message, JNI_TRUE);
return 1;
}
/* If we got here, jvmpath has been correctly initialized. */
return 0;
}
/*
* Find path to JRE based on .exe's location or registry settings.
*/
jboolean
GetJREPath(char *path, jint pathsize)
{
char javadll[MAXPATHLEN];
struct stat s;
//
// if (GetApplicationHome(path, pathsize)) {
// /* Is JRE co-located with the application? */
// sprintf(javadll, "%s\\bin\\" JAVA_DLL, path);
// if (stat(javadll, &s) == 0) {
// goto found;
// }
// /* Does this app ship a private JRE in <apphome>\jre directory? */
// sprintf(javadll, "%s\\jre\\bin\\" JAVA_DLL, path);
// if (stat(javadll, &s) == 0) {
// strcat(path, "\\jre");
// goto found;
// }
// }
/* Look for a public JRE on this machine. */
if (GetPublicJREHome(path, pathsize))
goto found;
fprintf(stderr, "Error: could not find " JAVA_DLL "\n");
return JNI_FALSE;
found:
{
// trick into thinking that the jre/bin path is in the PATH
char *oldPath = getenv("PATH");
char *newPath;
if(oldPath != NULL) {
newPath = MemAlloc(strlen(oldPath) + strlen(path) + 6 + 6 + 1); // PATH=<new>\bin;<old>
sprintf(newPath, "PATH=%s\\bin;%s", path, oldPath);
} else {
newPath = MemAlloc(strlen(path) + 6 + 1);
sprintf(newPath, "PATH=%s\\bin", path);
}
_putenv(newPath);
free(newPath);
}
return JNI_TRUE;
}
/*
* Given a JRE location and a JVM type, construct what the name the
* JVM shared library will be. Return true, if such a library
* exists, false otherwise.
*/
static jboolean
GetJVMPath(const char *jrepath, const char *jvmtype,
char *jvmpath, jint jvmpathsize)
{
struct stat s;
if (strchr(jvmtype, '/') || strchr(jvmtype, '\\')) {
sprintf(jvmpath, "%s\\" JVM_DLL, jvmtype);
} else {
sprintf(jvmpath, "%s\\bin\\%s\\" JVM_DLL, jrepath, jvmtype);
}
if (stat(jvmpath, &s) == 0) {
return JNI_TRUE;
} else {
return JNI_FALSE;
}
}
/*
* Load a jvm from "jvmpath" and initialize the invocation functions.
*/
jboolean
LoadJavaVM(const char *jvmpath, InvocationFunctions *ifn)
{
HINSTANCE handle;
/* Load the Java VM DLL */
if ((handle = LoadLibrary(jvmpath)) == 0) {
ReportErrorMessage2("Error loading: %s", (char *)jvmpath, JNI_TRUE);
return JNI_FALSE;
}
/* Now get the function addresses */
ifn->CreateJavaVM =
(void *)GetProcAddress(handle, "JNI_CreateJavaVM");
ifn->GetDefaultJavaVMInitArgs =
(void *)GetProcAddress(handle, "JNI_GetDefaultJavaVMInitArgs");
if (ifn->CreateJavaVM == 0 || ifn->GetDefaultJavaVMInitArgs == 0) {
ReportErrorMessage2("Error: can't find JNI interfaces in: %s",
(char *)jvmpath, JNI_TRUE);
return JNI_FALSE;
}
return JNI_TRUE;
}
/*
* If app is "c:\foo\bin\javac", then put "c:\foo" into buf.
*/
jboolean
GetApplicationHome(char *buf, jint bufsize)
{
char *cp;
GetModuleFileName(0, buf, bufsize);
*strrchr(buf, '\\') = '\0'; /* remove .exe file name */
if ((cp = strrchr(buf, '\\')) == 0) {
/* This happens if the application is in a drive root, and
* there is no bin directory. */
buf[0] = '\0';
return JNI_FALSE;
}
if(strcmp(cp, "\\bin") == 0)
*cp = '\0'; /* remove the bin\ part */
// else c:\foo\something\javac
return JNI_TRUE;
}
/*
* Helpers to look in the registry for a public JRE.
*/
/* Same for 1.5.0, 1.5.1, 1.5.2 etc. */
#define DOTRELEASE JDK_MAJOR_VERSION "." JDK_MINOR_VERSION
#define JRE_KEY "Software\\JavaSoft\\Java Runtime Environment"
static jboolean
GetStringFromRegistry(HKEY key, const char *name, char *buf, jint bufsize)
{
DWORD type, size;
if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0
&& type == REG_SZ
&& (size < (unsigned int)bufsize)) {
if (RegQueryValueEx(key, name, 0, 0, buf, &size) == 0) {
return JNI_TRUE;
}
}
return JNI_FALSE;
}
static BOOL versionOk(char *version)
{
char *major;
int major_version;
int minor_version;
char *minor_start;
// 1. find the .
minor_start = strstr(version,".");
if (minor_start == NULL) // no . found.
return FALSE;
major = (char *)malloc(minor_start - version + 1);
strncpy(major,version,minor_start - version);
major[minor_start - version]='\0';
major_version = atoi(major);
free(major);
if (minor_start[1] == '\0') // "x." ?
return FALSE;
// anything less than 1.6 is not supported
minor_version = atoi(++minor_start);
if (major_version <1 || (major_version < 2 && minor_version < 6))
return FALSE;
return TRUE;
}
static jboolean
GetPublicJREHome(char *buf, jint bufsize)
{
HKEY key, subkey;
char version[MAXPATHLEN];
/* Find the current version of the JRE */
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, JRE_KEY, 0, KEY_READ, &key) != 0) {
fprintf(stderr, "Error opening registry key '" JRE_KEY "'\n");
return JNI_FALSE;
}
if (!GetStringFromRegistry(key, "CurrentVersion",
version, sizeof(version))) {
fprintf(stderr, "Failed reading value of registry key:\n\t"
JRE_KEY "\\CurrentVersion\n");
RegCloseKey(key);
return JNI_FALSE;
}
/* Check if the version is good */
if (!versionOk(version))
{
RegCloseKey(key);
return JNI_FALSE;
}
/* Find directory where the current version is installed. */
if (RegOpenKeyEx(key, version, 0, KEY_READ, &subkey) != 0) {
fprintf(stderr, "Error opening registry key '"
JRE_KEY "\\%s'\n", version);
RegCloseKey(key);
return JNI_FALSE;
}
if (!GetStringFromRegistry(subkey, "JavaHome", buf, bufsize)) {
fprintf(stderr, "Failed reading value of registry key:\n\t"
JRE_KEY "\\%s\\JavaHome\n", version);
RegCloseKey(key);
RegCloseKey(subkey);
return JNI_FALSE;
}
RegCloseKey(key);
RegCloseKey(subkey);
return JNI_TRUE;
}
void ReportErrorMessage(char * message, jboolean always) {
if (message != NULL) {
// MessageBox(NULL, message, "Java Virtual Machine Launcher",
// (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
}
}
void ReportErrorMessage2(char * format, char * string, jboolean always) {
/*
* The format argument must be a printf format string with one %s
* argument, which is passed the string argument.
*/
size_t size;
char * message;
size = strlen(format) + strlen(string);
message = (char*)MemAlloc(size*sizeof(char));
sprintf(message, (const char *)format, string);
if (message != NULL) {
// MessageBox(NULL, message, "Java Virtual Machine Launcher",
// (MB_OK|MB_ICONSTOP|MB_APPLMODAL));
}
}
void ReportExceptionDescription(JNIEnv * env) {
/*
* This code should be replaced by code which opens a window with
* the exception detail message.
*/
(*env)->ExceptionDescribe(env);
}
/*
* Return JNI_TRUE for an option string that has no effect but should
* _not_ be passed on to the vm; return JNI_FALSE otherwise. On
* windows, there are no options that should be screened in this
* manner.
*/
jboolean RemovableMachineDependentOption(char * option) {
return JNI_FALSE;
}
void PrintMachineDependentOptions() {
return;
}
jboolean
ServerClassMachine() {
jboolean result = JNI_FALSE;
return result;
}
/*
* Wrapper for platform dependent unsetenv function.
*/
int
UnsetEnv(char *name)
{
int ret;
char *buf = MemAlloc(strlen(name) + 2);
buf = strcat(strcpy(buf, name), "=");
ret = _putenv(buf);
free(buf);
return (ret);
}
/*
* The following just map the common UNIX name to the Windows API name,
* so that the common UNIX name can be used in shared code.
*/
int
strcasecmp(const char *s1, const char *s2)
{
return (stricmp(s1, s2));
}
int
strncasecmp(const char *s1, const char *s2, size_t n)
{
return (strnicmp(s1, s2, n));
}