root/release-kits/shared/search4j/head_src/head.c @ 15093

Revision 15093, 13.4 KB (checked in by oranfry, 12 years ago)

importing the search4j tool I wrote for the release kits

Line 
1/*
2    Launch4j (http://launch4j.sourceforge.net/)
3    Cross-platform Java application wrapper for creating Windows native executables.
4
5    Copyright (C) 2004, 2006 Grzegorz Kowal
6
7    This library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
11
12    This library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with this library; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
21
22    Compiled with Mingw port of GCC,
23    Bloodshed Dev-C++ IDE (http://www.bloodshed.net/devcpp.html)
24*/
25
26#include "resource.h"
27#include "head.h"
28
29BOOL debug = FALSE;
30BOOL console = FALSE;
31int foundJava = NO_JAVA_FOUND;
32
33struct _stat statBuf;
34PROCESS_INFORMATION pi;
35
36char errTitle[STR] = "Launch4j";
37char javaMinVer[STR] = {0};
38char javaMaxVer[STR] = {0};
39char foundJavaVer[STR] = {0};
40
41char workingDir[_MAX_PATH] = {0};
42char javaHome[_MAX_PATH] = {0};
43char cmd[_MAX_PATH] = {0};
44char args[MAX_ARGS] = {0};
45
46//added by oran - whether to run the jar, print out java home, or compare java version strings
47char subcommand[8] = "run"; //can be "run", "find", "compare" - run means behave like unhacked launch4j
48
49void setConsoleFlag() {
50     console = TRUE;
51}
52
53void titledMsgBox(const char* title, const char* text) {
54    if (console) {
55        printf("%s: %s\n", title, text);
56    } else {
57        MessageBox(NULL, text, title, MB_OK);
58    }
59}
60
61void msgBox(const char* text) {
62    titledMsgBox(errTitle, text);
63}
64
65void showJavaWebPage() {
66    ShellExecute(NULL, "open", "http://java.com/download", NULL, NULL, SW_SHOWNORMAL);
67}
68
69BOOL loadString(HMODULE hLibrary, int resID, char* buffer) {
70    HRSRC hResource;
71    HGLOBAL hResourceLoaded;
72    LPBYTE lpBuffer;
73
74    hResource = FindResourceEx(hLibrary, RT_RCDATA, MAKEINTRESOURCE(resID),
75            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT));
76    if (NULL != hResource) {
77        hResourceLoaded = LoadResource(hLibrary, hResource);
78        if (NULL != hResourceLoaded) {
79            lpBuffer = (LPBYTE) LockResource(hResourceLoaded);           
80            if (NULL != lpBuffer) {     
81                int x = 0;
82                do {
83                    buffer[x] = (char) lpBuffer[x];
84                } while (buffer[x++] != 0);
85                return TRUE;
86            }
87        }   
88    }
89    return FALSE;
90}
91
92BOOL loadBoolString(HMODULE hLibrary, int resID) {
93    char boolStr[10] = {0};
94    loadString(hLibrary, resID, boolStr);
95    return strcmp(boolStr, TRUE_STR) == 0;
96}
97
98void regSearch(HKEY hKey, const char* keyName, int searchType) {
99    DWORD x = 0;
100    unsigned long size = BIG_STR;
101    FILETIME time;
102    char buffer[BIG_STR] = {0};
103    while (RegEnumKeyEx(
104                hKey,           // handle to key to enumerate
105                x++,            // index of subkey to enumerate
106                buffer,         // address of buffer for subkey name
107                &size,          // address for size of subkey buffer
108                NULL,           // reserved
109                NULL,           // address of buffer for class string
110                NULL,           // address for size of class buffer
111                &time) == ERROR_SUCCESS) {
112        if (strcmp(buffer, javaMinVer) >= 0
113                && (javaMaxVer[0] == 0 || strcmp(buffer, javaMaxVer) <= 0)
114                && strcmp(buffer, foundJavaVer) > 0) {
115            strcpy(foundJavaVer, buffer);
116            foundJava = searchType;
117        }
118        size = BIG_STR;
119    }
120}
121
122BOOL findJavaHome(char* path) {
123    HKEY hKey;
124    const char jre[] = "SOFTWARE\\JavaSoft\\Java Runtime Environment";
125    const char sdk[] = "SOFTWARE\\JavaSoft\\Java Development Kit";
126    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
127            TEXT(jre),
128            0,
129            KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
130            &hKey) == ERROR_SUCCESS) {
131        regSearch(hKey, jre, FOUND_JRE);
132        RegCloseKey(hKey);
133    }
134    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
135            TEXT(sdk),
136            0,
137            KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
138            &hKey) == ERROR_SUCCESS) {
139        regSearch(hKey, sdk, FOUND_SDK);
140        RegCloseKey(hKey);
141    }
142    if (foundJava != NO_JAVA_FOUND) {
143        char keyBuffer[BIG_STR];
144        unsigned long datatype;
145        unsigned long bufferlength = BIG_STR;
146        if (foundJava == FOUND_JRE) {
147            strcpy(keyBuffer, jre);
148        } else {
149            strcpy(keyBuffer, sdk);
150        }
151        strcat(keyBuffer, "\\");
152        strcat(keyBuffer, foundJavaVer);
153        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
154            TEXT(keyBuffer),
155            0,
156            KEY_QUERY_VALUE,
157            &hKey) == ERROR_SUCCESS) {
158            unsigned char buffer[BIG_STR] = {0};
159            if (RegQueryValueEx(hKey, "JavaHome", NULL, &datatype, buffer, &bufferlength)
160                    == ERROR_SUCCESS) {
161                int i = 0;
162                do {
163                    path[i] = buffer[i];
164                } while (path[i++] != 0);
165                if (foundJava == FOUND_SDK) {
166                    strcat(path, "\\jre");
167                }
168                RegCloseKey(hKey);
169                return TRUE;
170            }
171            RegCloseKey(hKey);
172        }
173    }
174    return FALSE;
175}
176
177/*
178 * Extract the executable name, returns path length.
179 */
180int getExePath(char* exePath) {
181    HMODULE hModule = GetModuleHandle(NULL);
182    if (hModule == 0
183            || GetModuleFileName(hModule, exePath, _MAX_PATH) == 0) {
184        return -1;
185    }
186    return strrchr(exePath, '\\') - exePath;
187}
188
189void appendJavaw(char* jrePath) {
190    if (console) {
191        strcat(jrePath, "\\bin\\java.exe");
192    } else {
193        strcat(jrePath, "\\bin\\javaw.exe");
194    }
195}
196
197void appendLauncher(BOOL setProcName, char* exePath, int pathLen, char* cmd) {
198    if (setProcName) {
199        char tmpspec[_MAX_PATH];
200        char tmpfile[_MAX_PATH];
201        strcpy(tmpspec, cmd);
202        strcat(tmpspec, LAUNCH4J_TMP_DIR);
203        tmpspec[strlen(tmpspec) - 1] = 0;
204        if (_stat(tmpspec, &statBuf) == 0) {
205            // remove temp launchers
206            struct _finddata_t c_file;
207            long hFile;
208            strcat(tmpspec, "\\*.exe");
209            strcpy(tmpfile, cmd);
210            strcat(tmpfile, LAUNCH4J_TMP_DIR);
211            char* filename = tmpfile + strlen(tmpfile);
212            if ((hFile = _findfirst(tmpspec, &c_file)) != -1L) {
213                do {
214                    strcpy(filename, c_file.name);
215                    _unlink(tmpfile);
216                } while (_findnext(hFile, &c_file) == 0);
217            }
218            _findclose(hFile);
219        } else {
220            if (_mkdir(tmpspec) != 0) {
221                appendJavaw(cmd);
222                return;
223            }
224        }
225        char javaw[_MAX_PATH];
226        strcpy(javaw, cmd);
227        appendJavaw(javaw);
228        strcpy(tmpfile, cmd);
229        strcat(tmpfile, LAUNCH4J_TMP_DIR);
230        char* exeFilePart = exePath + pathLen + 1;
231        strcat(tmpfile, exeFilePart);
232        if (CopyFile(javaw, tmpfile, FALSE)) {
233            strcpy(cmd, tmpfile);
234            return;
235        } else if (_stat(javaw, &statBuf) == 0) {
236            long fs = statBuf.st_size;
237            if (_stat(tmpfile, &statBuf) == 0 && fs == statBuf.st_size) {
238                strcpy(cmd, tmpfile);
239                return;
240            }
241        }
242    }
243    appendJavaw(cmd);
244}
245
246BOOL isJrePathOk(char* path) {
247    if (!*path) {
248        return FALSE;
249    }
250    char javaw[_MAX_PATH];
251    strcpy(javaw, path);
252    appendJavaw(javaw);
253    return _stat(javaw, &statBuf) == 0;
254}
255
256//added by oran - added the subcom argument
257BOOL prepare(HMODULE hLibrary, char *lpCmdLine, char *subcom) {
258    char tmp[MAX_ARGS] = {0};
259    GetEnvironmentVariable("launch4j", tmp, STR);
260    debug = _stricmp(tmp, "debug") == 0;
261   
262    //added by oran - set the subcommand
263    strcpy( subcommand, subcom );
264
265    // Open executable
266    char exePath[_MAX_PATH] = {0};
267    int pathLen = getExePath(exePath);
268    if (pathLen == -1) {
269        msgBox("Cannot determinate exe file name.");
270        return FALSE;
271    }
272    hLibrary = LoadLibrary(exePath);
273    if (hLibrary == NULL) {
274        char msg[BIG_STR];
275        strcpy(msg, "Cannot find file: ");
276        strcat(msg, exePath);
277        msgBox(msg);
278        return FALSE;
279    }
280
281    // Error message box title
282    loadString(hLibrary, ERR_TITLE, errTitle);
283
284    // Working dir
285    char tmp_path[_MAX_PATH] = {0};
286    if (loadString(hLibrary, CHDIR, tmp_path)) {
287        strncpy(workingDir, exePath, pathLen);
288        strcat(workingDir, "\\");
289        strcat(workingDir, tmp_path);
290        _chdir(workingDir);
291    }
292
293    // Custom process name
294    const BOOL setProcName = loadBoolString(hLibrary, SET_PROC_NAME);
295
296    // Use bundled jre or find java
297    if (loadString(hLibrary, JRE_PATH, tmp_path)) {
298        if (tmp_path[0] == '\\' || tmp_path[1] == ':') {
299            // Absolute
300            strcpy(cmd, tmp_path);
301        } else {
302            // Relative
303            strncpy(cmd, exePath, pathLen);
304            strcat(cmd, "\\");
305            strcat(cmd, tmp_path);
306        }
307    }
308    if (!isJrePathOk(cmd)) {
309        if (!loadString(hLibrary, JAVA_MIN_VER, javaMinVer)) {
310            msgBox("Cannot find bundled JRE or javaw.exe is missing.");
311            return FALSE;
312        }
313        loadString(hLibrary, JAVA_MAX_VER, javaMaxVer);
314        if (!findJavaHome(cmd)) {
315            char txt[BIG_STR];
316            strcpy(txt, "Cannot find Java ");
317            strcat(txt, javaMinVer);
318            if (*javaMaxVer) {
319                strcat(txt, " - ");
320                strcat(txt, javaMaxVer);
321            }
322            //msgBox(txt);
323            //showJavaWebPage();
324            return FALSE;
325        }
326        if (!isJrePathOk(cmd)) {
327            msgBox("Java found, but javaw.exe seems to be missing.");
328            return FALSE;
329        }
330    }
331
332    //before appending the launcher, save the cmd in javaHome
333    strcpy( javaHome, cmd );
334
335    //only affect the PATH if subcommand is run
336    if ( _stricmp( subcommand, "run" ) ) {
337        // Append a path to the Path environment variable
338        char jreBinPath[_MAX_PATH];
339        strcpy(jreBinPath, cmd);
340        strcat(jreBinPath, "\\bin");
341        if (!appendToPathVar(jreBinPath)) {
342            msgBox("Cannot set the Path environment variable.");
343            return FALSE;
344        }
345    }
346   
347    appendLauncher(setProcName, exePath, pathLen, cmd);
348
349    // JVM args
350    if (loadString(hLibrary, JVM_ARGS, tmp)) {
351        strcat(tmp, " ");
352    } else {
353        *tmp = 0;
354    }
355    // Load additional JVM arguments from ini file
356    strncpy(tmp_path, exePath, strlen(exePath) - 3);
357    strcat(tmp_path, "ini");
358    long hFile;
359    if ((hFile = _open(tmp_path, _O_RDONLY)) != -1) {
360        const int jvmArgsLen = strlen(tmp);
361        char* src = tmp + jvmArgsLen;
362        char* dst = src;
363        const int len = _read(hFile, src, MAX_ARGS - jvmArgsLen - BIG_STR);
364        int i;
365        for (i = 0; i < len; i++) {
366            if (*src == 13 || *src == 10) {
367                if (dst > tmp && *(dst - 1) != ' ') {
368                    *dst++ = ' ';
369                }
370                src++;
371            } else {
372                *dst++ = *src++;
373            }
374        }
375        *dst = 0;
376        if (len > 0 && *(dst - 1) != ' ') {
377            strcat(tmp, " ");
378        }
379        _close(hFile);
380    }
381
382    // Expand environment %variables%
383    if (*tmp) {
384        char varName[STR];
385        char varValue[MAX_VAR_SIZE];
386        char *pos = tmp;
387        while (strlen(pos) > 0) {
388            char *start = strchr(pos, '%');
389            if (start != NULL) {
390                char *end = strchr(start + 1, '%');
391                if (end == NULL) {
392                    return FALSE;
393                }
394                // Copy content up to %VAR%
395                strncat(args, pos, start - pos);
396                // Insert value of %VAR%
397                varName[0] = 0;
398                strncat(varName, start + 1, end - start - 1);
399                if (strcmp(varName, "EXEDIR") == 0) {
400                    strncat(args, exePath, pathLen);
401                } else if (strcmp(varName, "EXEFILE") == 0) {
402                    strcat(args, exePath);                   
403                } else if (GetEnvironmentVariable(varName, varValue, MAX_VAR_SIZE) > 0) {
404                    strcat(args, varValue);
405                }
406                pos = end + 1;
407            } else {
408                // Copy remaining content
409                strcat(args, pos);
410                break;
411            }
412        }
413    }
414
415    // Jar
416    strcat(args, "-jar \"");
417    if (loadString(hLibrary, JAR, tmp)) {
418        strncat(args, exePath, pathLen);
419        strcat(args, "\\");
420        strcat(args, tmp);
421    } else {
422        strcat(args, exePath);
423    }
424    strcat(args, "\"");
425
426    // Constant command line args
427    char jarArgs[BIG_STR] = {0};
428    if (loadString(hLibrary, JAR_ARGS, jarArgs)) {
429        strcat(args, " ");
430        strcat(args, jarArgs);
431    }
432
433    // Command line args
434    if (*lpCmdLine) {
435        strcat(args, " ");
436        strcat(args, lpCmdLine);
437    }
438
439    if (debug) {
440        printf("*** Launch4j debug info ***\nWorking dir:\t%s\n", workingDir);
441        printf("Launcher:\t%s\n", cmd);
442        _itoa(strlen(args), tmp, 10);     // 10 -- radix
443        printf("Args length:\t%s/32768 chars\n", tmp);
444        printf("Launcher args:\t%s\n\n", args);
445    }
446    return TRUE;
447}
448
449void closeHandles() {
450    CloseHandle(pi.hThread);
451    CloseHandle(pi.hProcess);
452}
453
454/*
455 * Append a path to the Path environment variable
456 */
457BOOL appendToPathVar(char* path) {
458    char chBuf[MAX_VAR_SIZE] = {0};
459
460    const int pathSize = GetEnvironmentVariable("Path", chBuf, MAX_VAR_SIZE);
461    if (MAX_VAR_SIZE - pathSize - 1 < strlen(path)) {
462        return FALSE;
463    }
464    strcat(chBuf, ";");
465    strcat(chBuf, path);
466    return SetEnvironmentVariable("Path", chBuf);
467}
468
469DWORD execute(BOOL wait) {
470    //added by oran - the original execute function has been wrapped in this if, and a few else ifs added after that
471    if ( _stricmp(subcommand, "run") == 0 ) {
472   
473        STARTUPINFO si;
474        memset(&pi, 0, sizeof(pi));
475        memset(&si, 0, sizeof(si));
476        si.cb = sizeof(si);
477
478        DWORD dwExitCode = -1;
479        char cmdline[MAX_ARGS];
480        strcpy(cmdline, "\"");
481        strcat(cmdline, cmd);
482        strcat(cmdline, "\" ");
483        strcat(cmdline, args);
484        if (CreateProcess(NULL, cmdline, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
485            if (wait) {
486                WaitForSingleObject(pi.hProcess, INFINITE);
487                GetExitCodeProcess(pi.hProcess, &dwExitCode);
488                closeHandles();
489            } else {
490                dwExitCode = 0;
491            }
492        }
493        return dwExitCode;
494
495    } else if ( _stricmp(subcommand, "find") == 0 ) {
496        printf("%s\n", javaHome);
497    } else if ( _stricmp(subcommand, "compare") == 0 ) {
498        printf("%s\n", foundJavaVer);
499    }
500}
Note: See TracBrowser for help on using the browser.