// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- // launcher.cpp : Defines the class behaviors for the application. // // The size of all of the strings was made sort of ambiguously large, since // 1) nothing is hurt by allocating an extra few bytes temporarily and // 2) if the user has a long path, and it gets copied five times over for the // classpath, the program runs the risk of crashing. Bad bad. #define JAVA_ARGS "-Xms128m -Xmx128m " #define JAVA_MAIN_CLASS "processing.app.Base" #include #include #include int STDCALL WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow) { // all these malloc statements... things may need to be larger. // what was passed to this application char *incoming_cmdline = (char *)malloc(strlen(lpCmd) * sizeof(char)); strcpy (incoming_cmdline, lpCmd); // what gets put together to pass to jre char *outgoing_cmdline = (char *)malloc(16384 * sizeof(char)); // prepend the args for -mx and -ms strcpy(outgoing_cmdline, JAVA_ARGS); // append the classpath and launcher.Application char *loaddir = (char *)malloc(MAX_PATH * sizeof(char)); *loaddir = 0; GetModuleFileName(NULL, loaddir, MAX_PATH); // remove the application name *(strrchr(loaddir, '\\')) = '\0'; char *cp = (char *)malloc(8 * strlen(loaddir) + 4096); // if this code looks shitty, that's because it is. people are // likely to have the durndest things in their CLASSPATH and QTJAVA // environment variables. mostly because installers often mangle // them without the user knowing. so who knows where and when the // quotes will show up. this is a guess at dealing with the things, // without spending a whole day to make it overly robust. [fry] // test to see if running with a java runtime nearby or not char *testpath = (char *)malloc(MAX_PATH * sizeof(char)); *testpath = 0; strcpy(testpath, loaddir); strcat(testpath, "\\java\\bin\\java.exe"); FILE *fp = fopen(testpath, "rb"); int local_jre_installed = (fp != NULL); //char *rt_jar = (fp == NULL) ? "" : "java\\lib\\rt.jar;"; if (fp != NULL) fclose(fp); // argh! this was probably causing trouble //MessageBox(NULL, local_jre_installed ? // "local jre installed" : "couldn't find jre", "p5", MB_OK); //const char *envClasspath = getenv("CLASSPATH"); char *env_classpath = (char *)malloc(16384 * sizeof(char)); // ignoring CLASSPATH for now, because it's not needed // and causes more trouble than it's worth [0060] env_classpath[0] = 0; /* // keep this code around since may be re-enabled later if (getenv("CLASSPATH") != NULL) { strcpy(env_classpath, getenv("CLASSPATH")); if (env_classpath[0] == '\"') { // starting quote in classpath.. yech env_classpath++; // shitty.. i know.. int len = strlen(env_classpath); if (env_classpath[len-1] == '\"') { env_classpath[len-1] = 0; } else { // a starting quote but no ending quote.. ugh // maybe throw an error } } int last = strlen(env_classpath); env_classpath[last++] = ';'; env_classpath[last] = 0; } else { env_classpath[0] = 0; } */ /* WE DUNNO NEED QUICKTIME JAVA FOR ARDUINO char *qtjava_path = (char *)malloc(16384 * sizeof(char)); qtjava_path[0] = 0; if (getenv("WINDIR") == NULL) { // uh-oh.. serious problem.. gonna have to report this // but hopefully WINDIR is set on win98 too } else { strcpy(qtjava_path, getenv("WINDIR")); strcat(qtjava_path, "\\SYSTEM32\\QTJava.zip"); FILE *fp = fopen(qtjava_path, "rb"); if (fp != NULL) { fclose(fp); // found it, all set strcat(qtjava_path, ";"); // add path separator } else { strcpy(qtjava_path, getenv("WINDIR")); strcat(qtjava_path, "\\SYSTEM\\QTJava.zip"); fp = fopen(qtjava_path, "rb"); if (fp != NULL) { fclose(fp); // found it, all set strcat(qtjava_path, ";"); // add path separator } else { // doesn't seem to be installed, which is a problem. // but the error will be reported by the pde qtjava_path[0] = 0; } } } END WE DUNNO NEED QUICKTIME JAVA FOR ARDUINO*/ // NO! put quotes around contents of cp, because %s might have spaces in it. // don't put quotes in it, because it's setting the environment variable // for CLASSPATH, not being included on the command line. so setting the // env var it's ok to have spaces, and the quotes prevent // javax.comm.properties from being found. sprintf(cp, //"\"" // begin quote //"'" "%s" // local jre or blank //"%s" // qtjava path "" "%s\\lib;" "%s\\lib\\build;" "%s\\lib\\pde.jar;" //"%s\\lib\\core.jar;" "%s\\lib\\mrj.jar;" "%s\\lib\\RXTXcomm.jar;" "%s\\lib\\oro.jar;" "%s\\lib\\registry.jar;" "%s\\lib\\antlr.jar;" "%s", // original CLASSPATH //"C:\\WINNT\\system32\\QTJava.zip;" // worthless //"C:\\WINDOWS\\system32\\QTJava.zip;" //"\"", // end quote //"'", //, // the first three %s args //local_jre_installed ? "java\\lib\\rt.jar;java\\lib\\jaws.jar;" : "", local_jre_installed ? "java\\lib\\rt.jar;" : "", //qtjava_path, loaddir, loaddir, loaddir, loaddir, loaddir, loaddir, loaddir, loaddir, env_classpath); //MessageBox(NULL, cp, "it's twoo! it's twoo!", MB_OK); if (!SetEnvironmentVariable("CLASSPATH", cp)) { MessageBox(NULL, "Could not set CLASSPATH environment variable", "Arduino Error", MB_OK); return 0; } // need to add the local jre to the path for 'java mode' in the env if (local_jre_installed) { char *env_path = (char *)malloc(strlen(getenv("PATH")) * sizeof(char)); strcpy(env_path, getenv("PATH")); char *paf = (char *)malloc((strlen(env_path) + strlen(loaddir) + 32) * sizeof(char)); sprintf(paf, "%s\\java\\bin;lib;%s", loaddir, env_path); if (!SetEnvironmentVariable("PATH", paf)) { MessageBox(NULL, "Could not set PATH environment variable", "Arduino Error", MB_OK); return 0; } } //MessageBox(NULL, cp, "whaadddup", MB_OK); // add the name of the class to execute and a space before the next arg strcat(outgoing_cmdline, JAVA_MAIN_CLASS " "); // append additional incoming stuff (document names), if any strcat(outgoing_cmdline, incoming_cmdline); char *executable = (char *)malloc((strlen(loaddir) + 256) * sizeof(char)); // loaddir is the name path to the current application //if (localJreInstalled) { if (local_jre_installed) { strcpy(executable, loaddir); // copy in the path for javaw, relative to launcher.exe strcat(executable, "\\java\\bin\\javaw.exe"); } else { strcpy(executable, "javaw.exe"); } SHELLEXECUTEINFO ShExecInfo; // set up the execution info ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); ShExecInfo.fMask = 0; ShExecInfo.hwnd = 0; ShExecInfo.lpVerb = "open"; ShExecInfo.lpFile = executable; ShExecInfo.lpParameters = outgoing_cmdline; ShExecInfo.lpDirectory = loaddir; ShExecInfo.nShow = SW_SHOWNORMAL; ShExecInfo.hInstApp = NULL; if (!ShellExecuteEx(&ShExecInfo)) { MessageBox(NULL, "Error calling ShellExecuteEx()", "Arduino Error", MB_OK); return 0; } if (reinterpret_cast(ShExecInfo.hInstApp) <= 32) { // some type of error occurred switch (reinterpret_cast(ShExecInfo.hInstApp)) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: MessageBox(NULL, "A required file could not be found. \n" "You may need to install a Java runtime\n" "or re-install Arduino.", "Arduino Error", MB_OK); break; case 0: case SE_ERR_OOM: MessageBox(NULL, "Not enough memory or resources to run at" " this time.", "Arduino Error", MB_OK); break; default: MessageBox(NULL, "There is a problem with your installation.\n" "If the problem persists, re-install the program.", "Arduino Error", MB_OK); break; } } return 0; }