diff --git a/apisupport.harness/release/README b/apisupport.harness/release/README --- a/apisupport.harness/release/README +++ b/apisupport.harness/release/README @@ -707,7 +707,7 @@ copy unmodified to the output cluster. Since 6.0 beta2 also applies to module suite projects. -run.app.exe - "bin\nb.exe"; name of Windows launcher to start (inside +run.app.exe - "bin\netbeans.exe"; name of Windows launcher to start (inside ${netbeans.dest.dir}) if trying to run the application for interactive testing. Only relevant if ${app.name} is unset. diff --git a/apisupport.harness/release/launchers/app.exe b/apisupport.harness/release/launchers/app.exe index c078faae1df1557a2c01de8b3aea166544a0dd0e..6317a0e1dddbd0171e2e7dbebe4680e330a38cad GIT binary patch literal 123904 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 - + diff --git a/apisupport.harness/release/suite.xml b/apisupport.harness/release/suite.xml --- a/apisupport.harness/release/suite.xml +++ b/apisupport.harness/release/suite.xml @@ -199,7 +199,6 @@ - diff --git a/apisupport.harness/windows-launcher-src/.dep.inc b/apisupport.harness/windows-launcher-src/.dep.inc new file mode 100644 --- /dev/null +++ b/apisupport.harness/windows-launcher-src/.dep.inc @@ -0,0 +1,5 @@ +# This code depends on make tool being used +DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES})) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/apisupport.harness/windows-launcher-src/Makefile b/apisupport.harness/windows-launcher-src/Makefile --- a/apisupport.harness/windows-launcher-src/Makefile +++ b/apisupport.harness/windows-launcher-src/Makefile @@ -1,74 +1,94 @@ -# -*- Makefile -*- # -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: # -# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target # -# The contents of this file are subject to the terms of either the GNU -# General Public License Version 2 only ("GPL") or the Common -# Development and Distribution License("CDDL") (collectively, the -# "License"). You may not use this file except in compliance with the -# License. You can obtain a copy of the License at -# http://www.netbeans.org/cddl-gplv2.html -# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the -# specific language governing permissions and limitations under the -# License. When distributing the software, include this License Header -# Notice in each file and include the License file at -# nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun in the GPL Version 2 section of the License file that -# accompanied this code. If applicable, add the following below the -# License Header, with the fields enclosed by brackets [] replaced by -# your own identifying information: -# "Portions Copyrighted [year] [name of copyright owner]" +# Targets beginning with '.' are not intended to be called on their own. # -# Contributor(s): +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. # -# The Original Software is Forte for Java, Community Edition. The Initial -# Developer of the Original Software is Sun Microsystems, Inc. Portions -# Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. -# -# If you wish your version of this file to be governed by only the CDDL -# or only the GPL Version 2, indicate your decision by adding -# "[Contributor] elects to include this software in this distribution -# under the [CDDL or GPL Version 2] license." If you do not indicate a -# single choice of license, a recipient has the option to distribute -# your version of this file under either the CDDL, the GPL Version 2 or -# to extend the choice of license to its licensees as provided above. -# However, if you add GPL Version 2 code and therefore, elected the GPL -# Version 2 license, then the option applies only if the new code is -# made subject to such option by the copyright holder. -# +# NOCDDL -LIBS = -#LIBS = advapi32.lib user32.lib -CFLAGS = -s -mno-cygwin -#!ifdef DEBUG -# CFLAGS = $(CFLAGS) -Zi -#!endif +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib -all : app.exe app_w.exe -app.exe : app.cpp app.res - gcc $(CFLAGS) $(LIBS) -mwindows -DWINMAIN app.cpp -o app.exe app.res - mv app.exe ../release/launchers/ +# build +build: .build-post -app_w.exe : app.cpp - gcc $(CFLAGS) $(LIBS) app.cpp -o app_w.exe - mv app_w.exe ../release/launchers/ +.build-pre: app.res +# Add your pre 'build' code here... + +.build-post: .build-impl +# Add your post 'build' code here... app.res : app.rc windres -o$@ -Ocoff app.rc -clean : - -rm *.res *.obj *.pdb *.ilk *~ 2>NUL +# clean +clean: .clean-post -distclean : clean - -rm *.exe 2>NUL +.clean-pre: +# Add your pre 'clean' code here... -test : - ../release/launchers/app.exe +.clean-post: .clean-impl +# Add your post 'clean' code here... -test_w : - ../release/launchers/app_w.exe + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk diff --git a/apisupport.harness/windows-launcher-src/Makefile_windows-launcher-src.mk b/apisupport.harness/windows-launcher-src/Makefile_windows-launcher-src.mk deleted file mode 100644 --- a/apisupport.harness/windows-launcher-src/Makefile_windows-launcher-src.mk +++ /dev/null @@ -1,92 +0,0 @@ -# -# There exist several targets which are by default empty and which can be -# used for execution of your targets. These targets are usually executed -# before and after some main targets. They are: -# -# .build-pre: called before 'build' target -# .build-post: called after 'build' target -# .clean-pre: called before 'clean' target -# .clean-post: called after 'clean' target -# .clobber-pre: called before 'clobber' target -# .clobber-post: called after 'clobber' target -# .all-pre: called before 'all' target -# .all-post: called after 'all' target -# .help-pre: called before 'help' target -# .help-post: called after 'help' target -# -# Targets beginning with '.' are not intended to be called on their own. -# -# Main targets can be executed directly, and they are: -# -# build build a specific configuration -# clean remove built files from a configuration -# clobber remove all built files -# all build all configurations -# help print help mesage -# -# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and -# .help-impl are implemented in nbproject/makefile-impl.mk. -# -# NOCDDL - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin -RANLIB=ranlib - - -# build -build: .build-pre .build-impl .build-post - -.build-pre: -# Add your pre 'build' code here... - -.build-post: -# Add your post 'build' code here... - - -# clean -clean: .clean-pre .clean-impl .clean-post - -.clean-pre: -# Add your pre 'clean' code here... - -.clean-post: -# Add your post 'clean' code here... - - -# clobber -clobber: .clobber-pre .clobber-impl .clobber-post - -.clobber-pre: -# Add your pre 'clobber' code here... - -.clobber-post: -# Add your post 'clobber' code here... - - -# all -all: .all-pre .all-impl .all-post - -.all-pre: -# Add your pre 'all' code here... - -.all-post: -# Add your post 'all' code here... - - -# help -help: .help-pre .help-impl .help-post - -.help-pre: -# Add your pre 'help' code here... - -.help-post: -# Add your post 'help' code here... - - - -# include project implementation makefile -include nbproject/Makefile-impl.mk diff --git a/apisupport.harness/windows-launcher-src/app.cpp b/apisupport.harness/windows-launcher-src/app.cpp --- a/apisupport.harness/windows-launcher-src/app.cpp +++ b/apisupport.harness/windows-launcher-src/app.cpp @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common @@ -24,7 +24,7 @@ * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun * Microsystems, Inc. All Rights Reserved. * * If you wish your version of this file to be governed by only the CDDL @@ -37,559 +37,14 @@ * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. + * + * Author: Tomas Holy */ -#include -#include -#include -#include -#include -#include -#include -#include -// #define DEBUG 1 +#include "applauncher.h" -static char* getUserHomeFromRegistry(char* userhome); -static char* GetStringValue(HKEY key, const char *name); -static DWORD GetDWordValue(HKEY key, const char *name); -static void parseConfigFile(const char* path); -static void parseArgs(int argc, char *argv[]); -static int readClusterFile(const char* path); -static int dirExists(const char* path); -static void ErrorExit(LPTSTR lpszMessage, LPTSTR lpszFunction); - -static char userdir[MAX_PATH] = "c:\\nbuser"; -static char options[4098] = ""; -static char dirs[4098] = "", extradirs[4098]; -static char jdkswitch[MAX_PATH] = ""; -static char appname[MAX_PATH] = ""; - -static char* defaultDirs[512]; - -#ifdef WINMAIN - -static void parseCommandLine(char *argstr); - -int WINAPI - WinMain (HINSTANCE /* hSelf */, HINSTANCE /* hPrev */, LPSTR cmdline, int /* nShow */) { -#else - int main(int argc, char* argv[]) { - char cmdline[10240] = ""; - - for (int i = 1; i < argc; i++) { - char buf[10240]; - sprintf(buf, "\"%s\" ", argv[i]); - strcat(cmdline, buf); - } -#endif - - char topdir[MAX_PATH]; - char buf[MAX_PATH * 10], *pc; - - GetModuleFileName(0, buf, sizeof buf); - - pc = strrchr(buf, '\\'); - if (pc != NULL) { // always holds - strlwr(pc + 1); - strcpy(appname, pc + 1); // store the app name - *pc = '\0'; // remove .exe filename - } - - pc = strrchr(appname, '.'); - if (pc != NULL) { - *pc = '\0'; - } - - // printf("appname = %s\n", appname); - - pc = strrchr(appname, '_'); - if (pc != NULL) { - if (!strcmp(pc, "_w")) { - *pc = '\0'; - } - } - - - - pc = strrchr(buf, '\\'); - if (pc != NULL && ((0 == stricmp("\\bin", pc)) || (0 == stricmp("\\launchers", pc)))) - *pc = '\0'; - strcpy(topdir, buf); - - sprintf(buf, "%s\\etc\\%s.conf", topdir, appname); - parseConfigFile(buf); - -#ifdef WINMAIN - parseCommandLine(cmdline); -#else - parseArgs(argc - 1, argv + 1); // skip progname -#endif - - char olduserdir[MAX_PATH]; - strcpy(olduserdir, userdir); - sprintf(buf, "%s\\etc\\%s.conf", userdir, appname); - parseConfigFile(buf); - strcpy(userdir, olduserdir); - - char clusterFileName[MAX_PATH]; - sprintf(clusterFileName, "%s\\etc\\%s.clusters", topdir, appname); - - if (!readClusterFile(clusterFileName)) { - ErrorExit("Cannot read cluster file!", NULL); - } - - char nbexec[MAX_PATH]; - char cmdline2[10240]; - - for (char **pdir = defaultDirs; *pdir != NULL; pdir++) { - sprintf(buf, "%s\\%s", topdir, *pdir); - if (dirExists(buf)) { - if (dirs[0] != '\0') { - sprintf(buf, "%s;%s\\%s", dirs, topdir, *pdir); - } - strcpy(dirs, buf); - } - } - - char *p = NULL; - char *q = NULL; - - // printf("extradirs = %s\n", extradirs); - - p = extradirs; - while (*p != '\0') { - if ((q = strchr(p, ';')) != NULL) { - *q = '\0'; - } - if (*(p + 1) == ':') { - sprintf(buf, "%s;%s", dirs, p); - } else { - sprintf(buf, "%s;%s\\%s", dirs, topdir, p); - } - strcpy(dirs, buf); - if (q == NULL) { - break; - } else { - p = q + 1; - } - } - // printf("%s\n", dirs); - // printf("%s\n", userdir); - - char pattern [MAX_PATH]; - WIN32_FIND_DATA ffd; - HANDLE hFind; - BOOL bNext = TRUE; - - sprintf(pattern, "%s\\platform*", topdir); - - hFind = FindFirstFile(pattern, &ffd); - do { - if (hFind == INVALID_HANDLE_VALUE || bNext == FALSE) { - ErrorExit("Cannot find 'platform*' folder!", NULL); - } - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - sprintf(nbexec, "%s\\%s\\lib\\nbexec.exe", topdir, ffd.cFileName); - break; - } - bNext = FindNextFile(hFind, &ffd); - } while (1); - - sprintf(cmdline2, "\"%s\" %s --clusters \"%s\" --userdir \"%s\" %s %s", - nbexec, - jdkswitch, - dirs, - userdir, - options, - cmdline); - - STARTUPINFO start; - PROCESS_INFORMATION pi; - - memset (&start, 0, sizeof (start)); - start.cb = sizeof (start); - -#ifdef WINMAIN - start.dwFlags = STARTF_USESHOWWINDOW; - start.wShowWindow = SW_HIDE; -#endif - -#ifdef DEBUG - printf("Cmdline: >%s<\ncwd >%s<\n", cmdline2, topdir); -#endif - if (!CreateProcess (NULL, cmdline2, - NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, - NULL, - _T(topdir), // lpCurrentDirectory - &start, - &pi)) { - sprintf(buf, "Cannot start %s", appname); - ErrorExit(buf, "CreateProcess"); - } else { - // Wait until child process exits. - WaitForSingleObject( pi.hProcess, INFINITE ); - - // Close process and thread handles. - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - exit(0); - } - return 0; +int main(int argc, char *argv[]) { + AppLauncher launcher; + return launcher.start(argc - 1, argv + 1); } - -char* getUserHomeFromRegistry(char* userhome) -{ - HKEY key; - - if (RegOpenKeyEx( - HKEY_CURRENT_USER, - "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", - 0, - KEY_READ, - &key) != 0) - return NULL; - - char *path = GetStringValue(key, "AppData"); - RegCloseKey(key); - - strcpy(userhome, path); - return userhome; -} - - -char * GetStringValue(HKEY key, const char *name) -{ - DWORD type, size; - char *value = 0; - - if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0 && type == REG_SZ) { - value = (char*) malloc(size); - if (RegQueryValueEx(key, name, 0, 0, (unsigned char*)value, &size) != 0) { - free(value); - value = 0; - } - } - return value; -} - - -DWORD GetDWordValue(HKEY key, const char *name) -{ - DWORD type, size; - DWORD value = 0; - - if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0 && type == REG_DWORD) { - if (RegQueryValueEx(key, name, 0, 0, (LPBYTE)&value, &size) != 0) { - return 0; - } - } - return value; -} - - -void parseConfigFile(const char* path) { - FILE* fin = fopen(path, "r"); - if (fin == NULL) - return; - - char line[2048], *pc; - - while (NULL != fgets(line, sizeof line, fin)) { - for (pc = line; *pc != '\0' && (*pc == ' ' || *pc == '\t' || *pc == '\n' || *pc == '\r'); pc++) - ; - if (*pc == '#') - continue; - if (strstr(pc, "default_userdir=") == pc) { - char *q = strstr(pc, "=") + 1; - pc = line + strlen(line) - 1; - while (*pc == '\n' || *pc == '\r' || *pc == '\t' || *pc == ' ') - pc--; - - if (*q == '"' && *pc == '"') { - q++; - pc--; - } - - *(pc+1) = '\0'; - *userdir = '\0'; - - if (strstr(q, "${HOME}") == q) { - char userhome[MAX_PATH]; - strcpy(userdir, getUserHomeFromRegistry(userhome)); - q = q + strlen("${HOME}"); - } - char *r = NULL; - if ((r = strstr(q, "${APPNAME}")) != NULL) { - strncat(userdir, q, r - q); - strcat(userdir, appname); - q = r + strlen("${APPNAME}"); - } - strcat(userdir, q); - } else if (strstr(pc, "default_options=") == pc) { - char *q = strstr(pc, "=") + 1; - pc = line + strlen(line) - 1; - while (*pc == '\n' || *pc == '\r' || *pc == '\t' || *pc == ' ') - pc--; - - if (*q == '"' && *pc == '"') { - q++; - pc--; - } - - *(pc+1) = '\0'; - strcpy(options, q); - } else if (strstr(pc, "extra_clusters=") == pc) { - char *q = strstr(pc, "=") + 1; - pc = line + strlen(line) - 1; - while (*pc == '\n' || *pc == '\r' || *pc == '\t' || *pc == ' ') - pc--; - - if (*q == '"' && *pc == '"') { - q++; - pc--; - } - - *(pc+1) = '\0'; - strcpy(extradirs, q); - } else if (strstr(pc, "jdkhome=") == pc) { - char *q = strstr(pc, "=") + 1; - pc = line + strlen(line) - 1; - while (*pc == '\n' || *pc == '\r' || *pc == '\t' || *pc == ' ') - pc--; - - if (*q == '"' && *pc == '"') { - q++; - pc--; - } - - *(pc+1) = '\0'; - sprintf(jdkswitch, "--jdkhome \"%s\"", q); - } - } - fclose(fin); -} - -#ifdef WINMAIN - -void parseCommandLine(char *argstr) { - char **argv = (char**) malloc(2048 * sizeof (char*)); - int argc = 0; - -#define START 0 -#define NORMAL 1 -#define IN_QUOTES 2 -#define IN_APOS 3 - - char *p, *q; - int state = NORMAL; - char token[1024 * 64]; - int eof; - - q = argstr; - p = token; - state = START; - eof = 0; - - while (!eof) { - if (*q == '\0') - eof = 1; - - switch (state) { - case START: - if (*q == ' ' || *q == '\r' || *q == '\n' || *q == '\t') { - q++; - continue; - } - - p = token; - *p = '\0'; - - if (*q == '"') { - state = IN_QUOTES; - q++; - continue; - } - if (*q == '\'') { - state = IN_APOS; - q++; - continue; - } - - state = NORMAL; - continue; - - case NORMAL: - if (*q == ' ' || *q == '\r' || *q == '\n' || *q == '\t' || *q == '\0') { - *p = '\0'; - argv[argc] = strdup(token); - argc++; - state = START; - } else { - *p++ = *q++; - } - break; - - case IN_QUOTES: - if (*q == '"') { - if (*(q+1) == '"') { - *p++ = '"'; - q += 2; - } else { - *p = '\0'; - - argv[argc] = strdup(token); - argc++; - - q++; - state = START; - } - } else if (*q == '\0') { - *p = '\0'; - argv[argc] = strdup(token); - argc++; - state = START; - } else { - *p++ = *q++; - } - break; - - case IN_APOS: - if (*q == '\'') { - if (*(q+1) == '\'') { - *p++ = '\''; - q += 2; - } else { - *p = '\0'; - - argv[argc] = strdup(token); - argc++; - - q++; - state = START; - } - } else if (*q == '\0') { - *p = '\0'; - argv[argc] = strdup(token); - argc++; - state = START; - } else { - *p++ = *q++; - } - break; - } - } - - parseArgs(argc, argv); - -} -#endif // WINMAIN - -void parseArgs(int argc, char *argv[]) { - char *arg; - - while (argc > 0 && (arg = *argv) != 0) { - argv++; - argc--; - - if (0 == strcmp("--userdir", arg)) { - if (argc > 0) { - arg = *argv; - argv++; - argc--; - if (arg != 0) { - strcpy(userdir, arg); - } - } - } - } -} - -int readClusterFile(const char* path) { - - char **dirs = defaultDirs; - - FILE* fin = fopen(path, "r"); - if (fin == NULL) - return 0; - - char line[2048], *pc; - - while (NULL != fgets(line, sizeof line, fin)) { - for (pc = line; *pc != '\0' && (*pc == ' ' || *pc == '\t' || *pc == '\n' || *pc == '\r'); pc++) - ; - if (*pc == '#') - continue; - - char *s = pc; - - while (*pc != '\0' && *pc != '\t' && *pc != '\n' && *pc != '\r') - pc++; - - *pc = '\0'; - - *dirs = strdup(s); - dirs++; - } - *dirs = NULL; - fclose(fin); - - return 1; -} - -int dirExists(const char* path) { - WIN32_FIND_DATA ffd; - HANDLE ffh; - - memset(&ffd, 0, sizeof ffd); - ffd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; - ffh = FindFirstFile(path, &ffd); - if (ffh != INVALID_HANDLE_VALUE) { - FindClose(ffh); - return 1; - } else { - return 0; - } -} - -// Show error dialog and exits the program -// lpszMessage - error message to be printed -// lpszFunction - name of last called method that return fail status -// can be NULL -void ErrorExit(LPTSTR lpszMessage, LPTSTR lpszFunction) -{ - LPVOID lpMsgBuf; - LPVOID lpDisplayBuf; - DWORD dw = GetLastError(); - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL ); - - if (lpszFunction != NULL ) { - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); - wsprintf((LPTSTR)lpDisplayBuf, - TEXT("%s\n%s failed with error %d: %s"), - lpszMessage, lpszFunction, dw, lpMsgBuf); - } - else { - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - lstrlen((LPCTSTR)lpMsgBuf)); - wsprintf((LPTSTR)lpDisplayBuf, - TEXT("%s"), - lpszMessage); - } - - MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_ICONSTOP | MB_OK); - - LocalFree(lpMsgBuf); - LocalFree(lpDisplayBuf); - ExitProcess( (dw != 0)? dw: 1); -} - diff --git a/apisupport.harness/windows-launcher-src/app.res b/apisupport.harness/windows-launcher-src/app.res new file mode 100644 index 0000000000000000000000000000000000000000..423f0bd785026158d394c4e728ca6be8ecc3eea1 GIT binary patch literal 21658 zc%1EgcU)A-(suRa!MuthCQO(RFel78XHgUb1`q@kl#CJ-6%iFMpeQJ2%!&#I5ET{U z8UYh##f(UX`l`}_V?Ix=G5tasybD5&tVW_z|+D}0OBVZGj?)z znhM`jS-NLNdB0KOwSv$MOcVKMm-N2<#cw4brT+~8e9BXPgYqBm%Z2jC()SX|XH(AQ zmryRFJc@ET<;VZ<90RosO3D4<`-;E#-ryJCoBrbaZh!LqH2VMbFZc{2`N@Qx<-glW zRgvtd`hFdx2Vf)rew|&5Ca+}Mr?PUox zG8qkQ{ACz0#0F%x!N3-N0M^P5MoeE0Wl|6pEnNmop#sU6qafLf5E^>|nAII<*t8kQ zt5k>3y9L0OWrORYqrhqo2Ud1Eu$CKu4LJ!4|LZ`V3ht#n0QKQQ@YwwVq;1VX(s~ZC zk!Qi>LJ_c9o>YEyP@f{s<$8j0$1AFH9a!7i0c#oppdLZxO$F8=8Wsn|fVZzds3JZC zJ4JfxSb{40E4<4shS2b%ppGjBY5#EWTz?B#b6b#&bBAWb1Ar+z!92G`uyogbVBPn^ z@c1IIO)iEet=z!a_B=ET{RpaPz z;;8Ngnc(i_4b$Bs;K}23BJnNM@#iylg|5GtUK5UKK*Ws|b1d`4F_~7|8li`?)+J&hNlI z1giZx;Cb*JY~H#Z6!8d-PR_up%!T3-grXwSEi4Zd zM~i`txd_nA9F$8RLQYODB%DnFraKfQ$En<=(|}F74td4&xmExT$R5B|l9lrdQlxiubKpCVN5 zz7UFwi=nc9570>_j;*(Yj@cGiyEz%0UEM&rEnOJ@_-{?}e@^;z$nn1~oZHlPvs2|` zf4Atv5~o#u1NOV3@=H!W(BZ&D?PMnxFxO{kcQs4eRsK8kdprWU8#_hTAU_tt~v$boRByst^^R-ow zSEiyH9(Ccu5u$J-6G41WRE4VR*Dveaw~16+ewfIEga>O%{_X79vwQZWUb_~xuj8_1 z%c>f`>G56u*f1)ZXb7?9o%Qa<5-q_f<$#)g56cT4qKPr|>j{lxWo*vk@&;Gj#zLz*Hb$VYeS(w+WoDo0Y~G)Z_u zcNdp0Tb4IL6MK6Pjr`5--A4+kyUwOKF$oU{^7~1?EN|i_O`2+&tKz{A%_zmwzYil7 zIy})6T;6M;r6?aB?wpdM>8A3!y?XU(#Z#|Vy?Vt52v2Z%U0sLqmNibEEL)z^#fukv ziUyLe9Mn3&a442l^JV90TYV~2$22%FAP3;=tTs$#Rxiq5)jzL!;(IZD3 zsbx!j{SbMnyzsz;070HixnxNh694r48LQB^O26jg1ZjQ!+k(8~YA)YZkmtphqlUU} zW6sz!>gN?MPj{Wuuem=L*MB6)-(0;~kpC|3U}?iGGp)wu3KgFA?pxKhO20)0Bwt5p zfQq8Lz@9n|l}_R(Or{NvSTSqXir&+WjhEf;SH+H=FxbYM>ov&>#S7%Wl|I<8{j8(i z4kV8oH~RDE&pZ0f$y{W>8$kY*iZ2!CWUfa&y)}IJq)G24Pu`xLJ!aseItKouM>pRw zXHI5Qp}X7!Cjo@{2;R*nzAa}f3vF^&ip+kqdySpFC$RO$6yC>J5F(WjT zOHx|5u6PT{-;Q0U78*cK>Daj*j?s7O%8Y`t)~@Mw`^J0xq8Uq1qn?( zMs3SIcI^0%D-(b2xbLf(v!&b3vP*?{Y53PkF8>=s|IsA)LB*QoTeBl{g=n%F3K|mC+nwtfhO;&$?N=-SNO+yqIRzQALi13 zocsJ$&izuw+L%wCFSs)KwsUvF*uB{>n&N3y zbT-9nXO=J5vDnmm|pGZQ2{ZkzK2Bvl&=G1;aq@ni>Q zkQm#7XDG!mOS3>~HlE_mN5Cwug51IfWW8*GQEbIrUQp~32yA&a^gmnxdK4cqueYSb zW?+Ztb7&4!J68hl-hTp}GbJGH)ED{<8boo+Juo~*_SjD{VL8wtwg6=7b3vlt6(qHM zC`K9yimjhuuGd~6K4Wzk0_(94*o;(A$J2915f(1qA;wcveh1c>V%f15seOjP+2nL! zWH-e@k~5@Of9_K#DWNu*c$MO@5s+0-LUFene9fWdRBb`ASun_Vl~CO72Y!La;J0ek zDVC?0-|ZzmN9EU^$x{;#S{Zkxm5=O>vt5`!cV~LQ$e-j z4U|xSlEl!nmHUDd#h%PK6eN>=hi-#bf!_-R=PenaZ!ig@rf$&2G7Kb!y})I|9q?Iv z7)CBn2WvYgsM*{b94OWt;S>kV?mnmv=0QObO$?33fPQ2?oI0HVQcFjQ!=0f{Z%+t+ zfY515nFn?J*$b;TO;<@W!68RM>_w)ssGxg!g@c?C~LT%FkXm=SQH3wmY z)nc%S&V*Ir2S94j5=O>m!LU)I!HoKmNAOOt+qe}RedEB&HwoI?oPY|GF2i)M<3fyF zL^g_khj4~)|M?d1zb*;`)th|n7^I^m8-^Kk1y z?1lDymqTaECE(<;09-viA#zJJNLGCTMd(NHobLnYQf|S;tGD6mwR9LaDGXHWKf==B zL*TPK0W1S9myZ8GowR?M+)V5@KK$i;ADmxz{z=`s%m4hYcX67ouFh1OC5eBm0)m~_ zPaQgH)a!Mx)x8!c{UiWmXKd54S@3#xLw)^~GwZnY&imofCLj4tb^Dns^=l0XA5cfH z_kpqBAN4y$H#3BrbLNCEov^cUmEOHS1!(R&>kM5tYIZ|@)7^3Dguy%e_rF$!{Dcb{ z3Qg4Q8w&S=_^ocP-CSK8(Ea-LbH(BfR?^L&!Tq~+8?wlZr$s|fNJwB|oInApEnRBc z-*t$YwI(F6Hd|C%Ql*Nj{=!I30nU9rTF!das=iNode(Op2^dQxReG!H*V#??!zQ<0 zwygD(Nn?aG>}lUs)@C79Boe*ey*7FC`<9h>n&(sfH}X3s4Ws*uLaM|_^z>Yo@OBC? z@7Qr1#X=o#&m#%CU(U=mL>1GfO`FAwxu194+)zm4#&xutSAER0Rn|lLPpEHXG;NxP z2X6(3j)u*7G8}ieqn+KGNh9gDdwrv6PAh8ENTvIpqi1!!YbXeGw5zmh*YqQ{18Vhh za#~YEp-AWV+qP}nm5WdncDtUmp591ayWx@*bh~WX`)-Jpd-NcI(Gyp%ene_KX=lb%|4n=n9sW`_F3%f`JQ4D_<-#7q%3(0$=H zJ#9<3)kAgX*LY`TBpEbtpT!4&@;#_@vK-wuzVhnwj!S+;N%e9n_;>0aHR$a{fO~Y? z=lP!FHP2LwFfho>tlG0@J@PfzwyNM?@$4ah(<4S$P9EN}WwmPWH}~liyT!g;yAB;X z`1<;0bs7KoF+k6|&&F$ymtF@+UrB?)h#3IIBE%Lr#0nMZf$bINaK1dxx1rG8r zlmzLYfc*;a?F8V*l)+uJPZf~+AQd%!$Y1#&$;rv&GqeY0bqk zJ_RmaxlYgA68sscVg_u$QBs!Hbf5R2-jOTpCo3#ZfNIkhQ0{#Wl6EUVz5ETRX$??C zeg>ugQ(HATwPLQO7eN?nb7tm(2GbmD|%n+Icw0=B9(hz)aYel^Avg zrNdRK=M8{Pb5L!kHEJzcNM<1JS1-r}kQ)-;S0L$s81CM?2a;v9?swh+3X79){4`y+ z>kq8U4*Glrl-}ncF8Lm<7v$$u?F{NQ@5yiI2J(PwaQw^zka#@?#pEPVZTJKV^08Fj zq}!$|5OtFDT9+fNr*cJ7G?`pIQCx2r0W27tx^5fy+i%stC|Pfb?gRU7_HJ>TWd4ueHmdHxR{gdCgh$luF~?zyPe7lE zdl$|Fa2aR3-)Tg}Euoc6hRtt71pOzwHeFr4YS{rEgOp0H!R*R?rw5hY>DzOoUWlNg zw#Gh6XC07^noUl8Eda-*06S>_RG|rz`ake_y@?t?xEBP_pYC;Y^`ZNTP(L?=ru84s zBn|$TTJ8UjM2ly0!U{s)|2CJun}};U0(U=;k5qvGroI>7(@f50fpY%t=v{Gszb@w0!_EAywIFc$3loip)OjU-G! zP)|lEHv^&kID`s)P`AGMm;8dF3@W3+{~~Ww!Vw-+`(c#yJArIqJhGk#5W4L_=(L*er9&+)Y0>*3$KgynLqu;JkIHkCd?_&eTsTa?W#+)$u@9-yc~c z;%u~>Y`z*<8?t-HXk=Ytkm5dM{o_zFC;=rS&!c3_Wn`nzBO4Tl&|?>IwnS(|wr@NI zp~*CaW;WPjxKCzrNy%+)!+(iH*u~&oNH)vUPhcl zi1Rw?C!46BY$47&k@eV%tj{52gO4G_B1mxrvN0EtjlYT#%bO^fat9?-@6dON$eK+P z`8Tl=J~QGE&FyjKf=Iqov-O|kf4&cjK3EI9s6?)(t{PK$O<6f9DkmZvf*JCm&!5bs6Ad$|_pZK90@&aonAfo~G^ z4dOc?MZ`qnH|Ykl$-g6;epiHb8cJq9K#A=`%I{HGPRLr)7-~WDs|mrFU`lnjoQ>+X zt_2^n3x6kGo&E;@vef6F8JNs}!K#z3>k(%|&Y9-G))AteIpji|3~iG(tMz0W$lC$Q&OboBbHsoD7uAq3e#+wx-lKTg{+)$o4G>rnZ6(VB(C8 z1}}VHT!N2?UzLBrzglr|NoLjdE8YwJqgBNBzR{cPJdo@>^yH5==6ok|zQomvxY}^8 z_eD4mH;2a}oC$NE5i*EB!G+-Tl<)*uXLn>K6T~)XZB6}&Y~R*_^4WAfN6^8-C4!HI zg9OQ6@Nbx3Q2bcOY)cL^qyEud(>MOWxzxU;w!N>#^Qj2em%oPFD+1}_@|^GjS=ag0 z*Da|3Oc8ZxMfPt^I<%vH)zOu%Y27oKi`x&K<$m7Wzu?~@JFobjd_rQ0WCU>@p&5S@ zE`7IgseQR^wYj=;WQtgzjdxnmeCI~+c%{*Ubm+B+#_c%bKUw78lKN3A@c0 zr31}%?L4vf)UYSS@$6sl@A39)(KY4#hp6zrk22>}8e{iFJKIwKwSV-ZZQZpv`hWP2 zML$9NUa1~}uDl%5p>Gh)`D4h&v=*Au9NJ>KI0o9#THc!4pbfP_J8x_{dPOGrM|?h# z|APO>haZbBs8+r~RY)ePR%N0hC==xYZ%{J-HQ9{noKNu6=J^R(U=|_!7swL9i&ZN^edT#Nvic9 zQMK_is-nK2YE!n5D=C++$wF!97i7zc*Rn4nR((Yl@)ro=(9)$;2i^_>e`bI1_9q|C zh_Yv2F1*kq$i0W95 zB2*ut{AiK*`Dih!4i}?he-X-d6`^EHA+imGa8150U&J>(wA$bse@*}A<7re3aULsj zZ>rIu39Sc>X*@Tk@lc=ok|E7U4QAo7Q&;#LG~*Zi*9SfbR*Y=pPkQ{oKkNH=F10=9KlTuDrZ}vL1%dcCB45;S zJn^M9p+5PFb!lAJq4uaV6<3BI;y&HtU+|A{N-w#fbE*V&623!yhHzGcBz}#kPSk+k zCwUd=q9onqhq)d_B7femLjQ!nw(a>mJnlI0pCIx#Bs8SCv_7HkSc-iJHR-b+#TV5r zaMs*)_lW1VU+_O=eyik~4)N5vfC9>JP-I=^k_H#)`-|c|owI}_6!l5av<*Q;?In-p z{i;CZzw+ykeMhkUQ*piH>!0}v;!oqY5w$@>>PPj6s{#4DH3>B+#;8g@yDp*PQ0zC% zllu{8{)9UtT1}Vflz)cz;Ib^IlxLc)t<2-xt^MF%$b`Ps)&|Avw-}$4k0!ewVa#xvHfH*Wn!9Ptvpj*CC$93LirU z`Ix6UD=r`9G1(|tMstn}ai2}Lx4SR;OWc1NMlo5FsT4zw7P;3V?$w5n?@MvVZ+$5C z=!r~ahD_N3E9>{j&dJI7KzytJ#J>{xc&}=o#@Fm9@#l!ufIds&5M^AK^BP^W+k~#w zT!%z)EC}PC^FK`dX}(qSxp+U#$;W67+43GGUSxZUUzo*JF|HYWl;#)m|Lag+sWD8$ zy)VT|y@-1k;@y$Zl3;{Vb)%BkuQQ)=U*{+OHH%8{Wrali!cG!r;wt2&IH9G>F=`jO zRwil22#pUN4jS7!rS|9Z>_NU>Aa@*d@D$#=H7D#m8qPi$Z% za@XVBd4K6nd^;0bBU7}X+>lV8ppSR%-n&bD2mQpqNp3Mdl%2&QM!W=^)0x zcpuwG0T1;vIbHKPl=ppM&WbNWVGb_k&)36f;vfEj{F1kXSJWnNP`URx`6ky;GMeIv z+GPJK#Je)}mkK>JHg84TjVNzOs6(HtQC<#@9gn*~d~JW?-|=H1-elAdzCl|LZT?5Z z@xl4C?T8Rf`Nm?DL>8hfst^^s^HH^r)<3=u?xOWOI$QKd1pee(EqQ@TpGT-%`jFb@ z2`aaxqjabz=`d92FCc4AT&ce(nh@#{Y7nXt_p$^PhOJq9mG7JV#DBo^d`w}~4+Q*5 zhoc(q9D4~n2%9zQ7R~ptlIF{$Ur@5-Bg&S2M8z87yx|k7!wGBNqk1{neerYR{{WS) zcTwqZ6%{@=Q0}q;r55v0Vn%CKHPS(Dh#;*&IoVuMo}d=EGldH692|H&x$`Ifl0sF`TQ=-GnWvCQv5dHC`$StM(K!Hl#fqD#f*!n zn0Xl$Ru@p-Hx#ADHYjathq57Fq{m{Ej&-H$fi$LTBa^GX>Cwoj`72rjxF4t1;=dr~ zJtq8;zjnXp{bn0}=N_ivUg{f^a_8~d=oB&b?l^|kn~3VDr* zKk(PK{mZ|6Qvls~qai45VNPRX7Rsi2kRHyY$0SUB z{P;R?9;U_rsO1B^{0H0r+~+mi%Z2A+<*=`45b_DzgnhsP8#2*+!*jIX`V4(zp5daH z#~8f#0j}AbjvMyh!|+|dpmJVJ~4T1_nnE?=`q2C>R$n3&KT91JT>Z7w5XU zqob2ETFy_^yrD9u_tKd$K_i5?~F^sj2<@;dr`{_B)?`d zt#Wn*nxfI^atXR#Dn_^Sh3HP)-A?78+tDoaIP?KM54=IInCIxd;|b1>PR9is@1oE8 z>*%}o68eQEq2G!V=)d$R`Y+jo3zu%Ed?We=gb{)WO9+e6XW=4T;O8&E+t&|0=FcZR z+|a?v32p7|ahkOajxryE9nCsnW!<2*0HbXc=$8U-un)ncD_dEZBKFD=11td;SRd4y@76_ zDd@5CEP5av^zz+~UOpQMVT2&ULV_=P&i5fKKzA>1bo2B=7Y|RI=kAWq zuCD0h;)0IObJ5np0j=%q@@d`5c9=8gy_<)}^YNAwc>lkk#eWFFhOf(fEEC8R!!+_q z-{lqImSgufN|;%e|g9*^0fyDfain zu?bf$T)do;nwFmO>hu!AhoPB%Il5I))29w@Ad-jU&$9Mh@*2~YLH_|-&;_9{ZvmLs+r-IISgtAi+ zD%xR_c5_}96&3SX;NSKeC@QOpW*$w+{+gfavpnIfLCeK2d3{jX0in7pLTw*}dW$Hx z#SvDEACoNq)%`Eew*E$)5^hI6ZxeT(SNDKkpCt7j@<9!j1PIzWhGVGv<8F=H9QFz6Y{;3z0R^{Dz{_ zPL%XGf|7x!kqthD&^H#L$9{xX{s@hxqRePk@x`mR`QGC2zgcg0!UodyRouy2iS7F? zPh&M)kr_~(O?jPbk+s=~%xtT8=Gs42JZ~M9jFR!!Q8MW!N-VC>{pG^%2AGj8*6Ho} z`NPLg@2T8+e^GBsLPF--&)3N(OsZ`f@S4^2qdHfRZTZ+QGtxvm^0RHex9j;vJX`X8 zPoTJTA?5z>#Tb?E%lOgf`ENxo{QPzLS!#c(-*mEgZrRF?Y~f7($P3$8hVj0@_lk71 z>Q5XQn{`7O@*d?uZ&B(`W%=;)(~ndaVaaET=f8+Cy*2{ryCvG^U-XvxmqzQ4;G_rXAw#^YtEq76(C!ik8DjIapN3*s-K@D*ry@1w5B;= z3_=sKLF0+Y_|kh*4<0?^zX|N3slO`4GjH`0i$4qd)?--cJ^mME#BQ zuQ`P3)|^|E=lkbo!v1-O&gRc}oTph|JA5p}TkMqPJc5IwBStH?l%h$+Y4IFIXqWRP zsFNt3W2p}nh-cYbzM^Vd7Aj--`2)>;Hnbk}I)tn~`32PmhHeqPcRnW8!64N$M9 z@h9?`GBy5FkIVwR#>l>m^kxZ!QyLD3#Qk{59^w*1cG)MMF{_V~?uQG6eR$QDFQ{7g z0aYtrqiXF7RBp~ddB9~F>!g4AZV3F$pmg6|X&~&m>r||qN3k-ufdOG`Y7U+k_U1T; zGn)F3YwABB?r}k6u{icZ@=&ts3(7-3qjLRcR7ZS5HLpMT4Jv&eqtfFpDwo|snR5h6 zI!~fLM^T2P9s<)vCKvb2r7E4`?Cfk|4j?$3$-+cokLs*O|I+otj?X!K zzVp)TgVWj|vAvCQhg+y{p?cj?QR#dK71L5sK4cBb20NqF+!dvr#!&yOC+-zXq{Kss z?>~It=OtYTi=y9Q!VmQy|89F0O?5|T_EeW;iE}LfjT7(ZW3M0#A^)TMK7-IT52M{9sUSN_?f1*bB z(zB%Pd_S7zo3K3boZ3rM_l$eU#?u%ZN`6QW@=0256n`K3+iYrYns3VVN2b>cCAGSu zwBaa}HJ^yG9u6p<=z~&AN0fBxiP3xZCUD*Pp2xI@cuCNm*Bz@>_a>@)b)LrNZ&5-v zSK8dc3X?8lU8}R$-sS|3aEe1m-#GLMJcdhy4`Jxq{kVSPZuIc-#SWc1Va2L?D6LQf zCDodv#IP62`bZ7z>S+@as8%UxGo|R*KLTvl_8<% zJZ~P3wXneU9Xn#>YSodI(M732OYAhqo9|U~4r%Q!V@4Gk_cf{A4UZtUKT?dn4;J8v zeYrR><}+IFc#E^PK11iIhv>554!WC`if*WCL*6`o<7oqrW zz(9f{VU=dT>K6GZ?+S`ao@VD2r+xTR`1}3mUoOU;dvY!$D&>lk*Z#C|lfvE%9X+(lhdH8k+|Fa~*`?7feT{8gc_=xYyYQHb5{Vwd!_@`2yuzSEj4yLB!8?*c` zSu!xFBVO^pV<~}(6~!z5S1hF(Ndw_;Sjse#2Et#klz(HO{Pq_)mEZmbr}Eoh-Bf=2 WJDW=3FKCLNwEx~H|56G(O! +#include + +#include "../../ide/launcher/windows/nblauncher.h" + +class AppLauncher : public NbLauncher { + + static const char *OPT_DEFAULT_USER_DIR; + static const char *OPT_DEFAULT_OPTIONS; + static const char *OPT_EXTRA_CLUSTERS; + static const char *OPT_JDK_HOME; + static const char *APPNAME_TOKEN; + static const char *REG_APPDATA_NAME; + +public: + AppLauncher(); + virtual ~AppLauncher(); + +protected: + virtual bool initBaseNames(); + virtual const char * getAppName(); + virtual void addSpecificOptions(CmdArgs &args); + virtual void adjustHeapSize(); + virtual bool findUserDir(const char *str); + virtual const char * getDefUserDirOptName(); + virtual const char * getDefOptionsOptName(); + virtual const char * getExtraClustersOptName(); + virtual const char * getJdkHomeOptName(); + +private: + AppLauncher(const AppLauncher& orig); +}; + +#endif /* _NBLAUNCHER_H */ + diff --git a/apisupport.harness/windows-launcher-src/nbproject/Makefile-Default.mk b/apisupport.harness/windows-launcher-src/nbproject/Makefile-Default.mk deleted file mode 100644 --- a/apisupport.harness/windows-launcher-src/nbproject/Makefile-Default.mk +++ /dev/null @@ -1,53 +0,0 @@ -# -# Gererated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add custumized code. -# -# This makefile implements configuration specific macros and targets. - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin -RANLIB=ranlib -CC=gcc -CCC=g++ -CXX=g++ -FC=g77 - -# Include project Makefile -include Makefile_windows-launcher-src.mk - -# Object Files -OBJECTFILES= - -# C Compiler Flags -CFLAGS= - -# CC Compiler Flags -CCFLAGS= -CXXFLAGS= - -# Fortran Compiler Flags -FFLAGS= - -# Link Libraries and Options -LDLIBSOPTIONS= - -# Build Targets -.build-conf: - cd .;\ - make -f Makefile - -# Subprojects -.build-subprojects: - -# Clean Targets -.clean-conf: - cd .;\ - make -f Makefile clean - -# Subprojects -.clean-subprojects: diff --git a/apisupport.harness/windows-launcher-src/nbproject/Makefile-Release.mk b/apisupport.harness/windows-launcher-src/nbproject/Makefile-Release.mk new file mode 100644 --- /dev/null +++ b/apisupport.harness/windows-launcher-src/nbproject/Makefile-Release.mk @@ -0,0 +1,95 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc.exe +CCC=g++.exe +CXX=g++.exe +FC= +AS= + +# Macros +PLATFORM=Cygwin-Windows + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=build/Release/${PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/apisupport.harness/windows-launcher-src/../../ide/launcher/windows/nblauncher.o \ + ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/apisupport.harness/windows-launcher-src/../../o.n.bootstrap/launcher/windows/utilsfuncs.o \ + ${OBJECTDIR}/app.o \ + ${OBJECTDIR}/applauncher.o + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-m32 -s -mno-cygwin +CXXFLAGS=-m32 -s -mno-cygwin + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=app.res + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + ${MAKE} -f nbproject/Makefile-Release.mk ../release/launchers/app.exe.exe + +../release/launchers/app.exe.exe: ${OBJECTFILES} + ${MKDIR} -p ../release/launchers + ${LINK.cc} -mwindows -o ../release/launchers/app.exe ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/apisupport.harness/windows-launcher-src/../../ide/launcher/windows/nblauncher.o: ../../ide/launcher/windows/nblauncher.cpp + ${MKDIR} -p ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/apisupport.harness/windows-launcher-src/../../ide/launcher/windows + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -I/cygdrive/c/cygwin/usr/include/mingw -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/apisupport.harness/windows-launcher-src/../../ide/launcher/windows/nblauncher.o ../../ide/launcher/windows/nblauncher.cpp + +${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/apisupport.harness/windows-launcher-src/../../o.n.bootstrap/launcher/windows/utilsfuncs.o: ../../o.n.bootstrap/launcher/windows/utilsfuncs.cpp + ${MKDIR} -p ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/apisupport.harness/windows-launcher-src/../../o.n.bootstrap/launcher/windows + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -I/cygdrive/c/cygwin/usr/include/mingw -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/apisupport.harness/windows-launcher-src/../../o.n.bootstrap/launcher/windows/utilsfuncs.o ../../o.n.bootstrap/launcher/windows/utilsfuncs.cpp + +${OBJECTDIR}/app.o: app.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -I/cygdrive/c/cygwin/usr/include/mingw -MMD -MP -MF $@.d -o ${OBJECTDIR}/app.o app.cpp + +${OBJECTDIR}/applauncher.o: applauncher.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -I/cygdrive/c/cygwin/usr/include/mingw -MMD -MP -MF $@.d -o ${OBJECTDIR}/applauncher.o applauncher.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: + ${RM} -r build/Release + ${RM} ../release/launchers/app.exe.exe + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/apisupport.harness/windows-launcher-src/nbproject/Makefile-impl.mk b/apisupport.harness/windows-launcher-src/nbproject/Makefile-impl.mk --- a/apisupport.harness/windows-launcher-src/nbproject/Makefile-impl.mk +++ b/apisupport.harness/windows-launcher-src/nbproject/Makefile-impl.mk @@ -27,27 +27,27 @@ PROJECTNAME=windows-launcher-src # Active Configuration -ACTIVECONF=Default -CONF=${ACTIVECONF} +DEFAULTCONF=Release +CONF=${DEFAULTCONF} # All Configurations -ALLCONFS=Default +ALLCONFS=Release # build -.build-impl: .validate-impl +.build-impl: .build-pre .validate-impl .depcheck-impl @#echo "=> Running $@... Configuration=$(CONF)" ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf # clean -.clean-impl: .validate-impl +.clean-impl: .clean-pre .validate-impl .depcheck-impl @#echo "=> Running $@... Configuration=$(CONF)" ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf # clobber -.clobber-impl: +.clobber-impl: .clobber-pre .depcheck-impl @#echo "=> Running $@..." for CONF in ${ALLCONFS}; \ do \ @@ -55,13 +55,25 @@ done # all -.all-impl: +.all-impl: .all-pre .depcheck-impl @#echo "=> Running $@..." for CONF in ${ALLCONFS}; \ do \ ${MAKE} -f nbproject/Makefile-$${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf; \ done +# dependency checking support +.depcheck-impl: + @echo "# This code depends on make tool being used" >.dep.inc + @if [ -n "${MAKE_VERSION}" ]; then \ + echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ + echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ + echo "include \$${DEPFILES}" >>.dep.inc; \ + echo "endif" >>.dep.inc; \ + else \ + echo ".KEEP_STATE:" >>.dep.inc; \ + echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ + fi # configuration validation .validate-impl: @@ -80,7 +92,7 @@ # help -.help-impl: +.help-impl: .help-pre @echo "This makefile supports the following configurations:" @echo " ${ALLCONFS}" @echo "" @@ -108,10 +120,4 @@ @echo " also build subprojects." @echo "Target 'help' prints this message." @echo "" - @echo "The active configuration (${ACTIVECONF}) is being used if the configuration is not specified." - @echo "" - -# Enable dependency checking -.KEEP_STATE: -.KEEP_STATE_FILE:.make.state.${CONF} diff --git a/apisupport.harness/windows-launcher-src/nbproject/Package-Release.bash b/apisupport.harness/windows-launcher-src/nbproject/Package-Release.bash new file mode 100644 --- /dev/null +++ b/apisupport.harness/windows-launcher-src/nbproject/Package-Release.bash @@ -0,0 +1,72 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +PLATFORM=Cygwin-Windows +TMPDIR=build/Release/${PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=../release/launchers/app.exe +OUTPUT_BASENAME=app.exe +PACKAGE_TOP_DIR=windows-launcher-src/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p dist/Release/${PLATFORM}/package +rm -rf ${TMPDIR} +mkdir -p ${TMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory ${TMPDIR}/windows-launcher-src/bin +copyFileToTmpDir "${OUTPUT_PATH}.exe" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}.exe" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f dist/Release/${PLATFORM}/package/windows-launcher-src.tar +cd ${TMPDIR} +tar -vcf ../../../../dist/Release/${PLATFORM}/package/windows-launcher-src.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${TMPDIR} diff --git a/apisupport.harness/windows-launcher-src/nbproject/configurations.xml b/apisupport.harness/windows-launcher-src/nbproject/configurations.xml --- a/apisupport.harness/windows-launcher-src/nbproject/configurations.xml +++ b/apisupport.harness/windows-launcher-src/nbproject/configurations.xml @@ -1,50 +1,82 @@ - + + + applauncher.h + ../../ide/launcher/windows/nblauncher.h + ../../o.n.bootstrap/launcher/windows/utilsfuncs.h + + + + + app.cpp + applauncher.cpp + ../../ide/launcher/windows/nblauncher.cpp + ../../o.n.bootstrap/launcher/windows/utilsfuncs.cpp + - Makefile_windows-launcher-src.mk + Makefile - app.rc - app.ico - app.cpp - Makefile - Makefile_windows-launcher-src.mk - 0 + Makefile - + - 1 + localhost + Cygwin|Cygwin 3 - - - . - make -f Makefile - make -f Makefile clean - ../release/launcher/app.exe - - - - - - - - + + + 5 + + + 5 + 1 + + c:/cygwin/usr/include/mingw + + -s -mno-cygwin + 2 + + + 5 + + + ../release/launchers/app.exe + + app.res + + -mwindows + + + + 1 + + + 3 + + + 1 + + + 3 + 1 - - - - 3 + + 1 - - 3 - - + 3 diff --git a/apisupport.harness/windows-launcher-src/nbproject/project.xml b/apisupport.harness/windows-launcher-src/nbproject/project.xml --- a/apisupport.harness/windows-launcher-src/nbproject/project.xml +++ b/apisupport.harness/windows-launcher-src/nbproject/project.xml @@ -3,8 +3,13 @@ org.netbeans.modules.cnd.makeproject - windows-launcher-src + Platform App Launcher Win 0 + + cpp + h + UTF-8 + diff --git a/ide/launcher/windows/.dep.inc b/ide/launcher/windows/.dep.inc new file mode 100644 --- /dev/null +++ b/ide/launcher/windows/.dep.inc @@ -0,0 +1,5 @@ +# This code depends on make tool being used +DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES})) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/ide/launcher/windows/Makefile b/ide/launcher/windows/Makefile --- a/ide/launcher/windows/Makefile +++ b/ide/launcher/windows/Makefile @@ -1,75 +1,95 @@ -# -*- Makefile -*- # -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: # -# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target # -# The contents of this file are subject to the terms of either the GNU -# General Public License Version 2 only ("GPL") or the Common -# Development and Distribution License("CDDL") (collectively, the -# "License"). You may not use this file except in compliance with the -# License. You can obtain a copy of the License at -# http://www.netbeans.org/cddl-gplv2.html -# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the -# specific language governing permissions and limitations under the -# License. When distributing the software, include this License Header -# Notice in each file and include the License file at -# nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun in the GPL Version 2 section of the License file that -# accompanied this code. If applicable, add the following below the -# License Header, with the fields enclosed by brackets [] replaced by -# your own identifying information: -# "Portions Copyrighted [year] [name of copyright owner]" +# Targets beginning with '.' are not intended to be called on their own. # -# Contributor(s): +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. # -# The Original Software is Forte for Java, Community Edition. The Initial -# Developer of the Original Software is Sun Microsystems, Inc. Portions -# Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. -# -# If you wish your version of this file to be governed by only the CDDL -# or only the GPL Version 2, indicate your decision by adding -# "[Contributor] elects to include this software in this distribution -# under the [CDDL or GPL Version 2] license." If you do not indicate a -# single choice of license, a recipient has the option to distribute -# your version of this file under either the CDDL, the GPL Version 2 or -# to extend the choice of license to its licensees as provided above. -# However, if you add GPL Version 2 code and therefore, elected the GPL -# Version 2 license, then the option applies only if the new code is -# made subject to such option by the copyright holder. -# +# NOCDDL -LIBS = -#LIBS = advapi32.lib user32.lib -CFLAGS = -s -mno-cygwin -#!ifdef DEBUG -# CFLAGS = $(CFLAGS) -Zi -#!endif +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib -all : netbeans.exe nb.exe +# build +build: .build-post -netbeans.exe : netbeans.cpp netbeans.res - gcc $(CFLAGS) $(LIBS) -mwindows -DWINMAIN netbeans.cpp -o netbeans.exe netbeans.res -nb.exe : netbeans.cpp - gcc $(CFLAGS) $(LIBS) netbeans.cpp -o nb.exe +.build-pre: netbeans.res +# Add your pre 'build' code here... -netbeans.res : netbeans.rc +.build-post: .build-impl +# Add your post 'build' code here... + cp *.exe ../../../nbbuild/netbeans/bin/ + +netbeans.res: netbeans.rc windres -o$@ -Ocoff netbeans.rc -clean : - -rm *.res *.obj *.pdb *.ilk *~ 2>NUL +# clean +clean: .clean-post -distclean : clean - -rm *.exe 2>NUL +.clean-pre: +# Add your pre 'clean' code here... -testinst : all - cp *.exe ../../../nbbuild/netbeans/bin/ +.clean-post: .clean-impl +# Add your post 'clean' code here... -test : testinst - ../../../nbbuild/netbeans/bin/netbeans.exe -test2 : testinst - ../../../nbbuild/netbeans/bin/nb.exe +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk diff --git a/ide/launcher/windows/Makefile_windows.mk b/ide/launcher/windows/Makefile_windows.mk deleted file mode 100644 --- a/ide/launcher/windows/Makefile_windows.mk +++ /dev/null @@ -1,92 +0,0 @@ -# -# There exist several targets which are by default empty and which can be -# used for execution of your targets. These targets are usually executed -# before and after some main targets. They are: -# -# .build-pre: called before 'build' target -# .build-post: called after 'build' target -# .clean-pre: called before 'clean' target -# .clean-post: called after 'clean' target -# .clobber-pre: called before 'clobber' target -# .clobber-post: called after 'clobber' target -# .all-pre: called before 'all' target -# .all-post: called after 'all' target -# .help-pre: called before 'help' target -# .help-post: called after 'help' target -# -# Targets beginning with '.' are not intended to be called on their own. -# -# Main targets can be executed directly, and they are: -# -# build build a specific configuration -# clean remove built files from a configuration -# clobber remove all built files -# all build all configurations -# help print help mesage -# -# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and -# .help-impl are implemented in nbproject/makefile-impl.mk. -# -# NOCDDL - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin -RANLIB=ranlib - - -# build -build: .build-pre .build-impl .build-post - -.build-pre: -# Add your pre 'build' code here... - -.build-post: -# Add your post 'build' code here... - - -# clean -clean: .clean-pre .clean-impl .clean-post - -.clean-pre: -# Add your pre 'clean' code here... - -.clean-post: -# Add your post 'clean' code here... - - -# clobber -clobber: .clobber-pre .clobber-impl .clobber-post - -.clobber-pre: -# Add your pre 'clobber' code here... - -.clobber-post: -# Add your post 'clobber' code here... - - -# all -all: .all-pre .all-impl .all-post - -.all-pre: -# Add your pre 'all' code here... - -.all-post: -# Add your post 'all' code here... - - -# help -help: .help-pre .help-impl .help-post - -.help-pre: -# Add your pre 'help' code here... - -.help-post: -# Add your post 'help' code here... - - - -# include project implementation makefile -include nbproject/Makefile-impl.mk diff --git a/ide/launcher/windows/cmdargs.h b/ide/launcher/windows/cmdargs.h new file mode 100644 --- /dev/null +++ b/ide/launcher/windows/cmdargs.h @@ -0,0 +1,140 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#ifndef _CMDARGS_H +#define _CMDARGS_H + +class CmdArgs { +public: + + CmdArgs(int _count) { + used = 0; + size = _count; + args = new char*[size]; + memset(args, 0, size * sizeof (char*)); + } + + ~CmdArgs() { + if (args) { + for (int i = 0; i < size; i++) { + delete[] args[i]; + } + delete[] args; + } + } + + void add(const char *arg) { + if (used + 1 > size) { + int newSize = size + size / 2 + 1; + char **newArgs = new char*[newSize]; + memcpy(newArgs, args, size * sizeof (char*)); + memset(newArgs + size, 0, (newSize - size) * sizeof (char*)); + delete[] args; + args = newArgs; + size = newSize; + } + args[used] = new char[strlen(arg) + 1]; + strcpy(args[used++], arg); + } + + void addCmdLine(const char *cmdLine) { + char arg[1024] = ""; + bool inQuotes = false; + bool inText = false; + int i = 0; + int j = 0; + char c; + while (c = cmdLine[i]) { + if (inQuotes) { + if (c == '\"') { + inQuotes = false; + } else { + arg[j++] = c; + } + } else { + switch (c) { + case '\"': + inQuotes = true; + inText = true; + break; + case ' ': + case '\t': + case '\n': + case '\r': + if (inText) { + arg[j] = '\0'; + add(arg); + j = 0; + } + inText = false; + break; + default: + inText = true; + arg[j++] = c; + break; + } + } + i++; + } + if (j > 0) { + arg[j] = '\0'; + add(arg); + } + } + + int getCount() { + return used; + } + + char **getArgs() { + return args; + } + +private: + int used; + int size; + char **args; +}; + +#endif /* _CMDARGS_H */ + diff --git a/ide/launcher/windows/nb.exe b/ide/launcher/windows/nb.exe deleted file mode 100644 Binary file ide/launcher/windows/nb.exe has changed diff --git a/ide/launcher/windows/nblauncher.cpp b/ide/launcher/windows/nblauncher.cpp new file mode 100644 --- /dev/null +++ b/ide/launcher/windows/nblauncher.cpp @@ -0,0 +1,387 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#include "nblauncher.h" +#include "../../../o.n.bootstrap/launcher/windows/utilsfuncs.h" +#include "../../../o.n.bootstrap/launcher/windows/argnames.h" +#include "../../../o.n.bootstrap/launcher/windows/nbexecloader.h" + +using namespace std; + +const char *NbLauncher::NBEXEC_FILE_PATH = "\\lib\\nbexec.dll"; +const char *NbLauncher::OPT_NB_DEFAULT_USER_DIR = "netbeans_default_userdir="; +const char *NbLauncher::OPT_NB_DEFAULT_OPTIONS = "netbeans_default_options="; +const char *NbLauncher::OPT_NB_EXTRA_CLUSTERS = "netbeans_extraclusters="; +const char *NbLauncher::OPT_NB_JDK_HOME = "netbeans_jdkhome="; +const char *NbLauncher::ENV_USER_PROFILE = "USERPROFILE"; +const char *NbLauncher::HOME_TOKEN = "${HOME}"; +const char *NbLauncher::REG_SHELL_FOLDERS_KEY = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; +const char *NbLauncher::REG_DESKTOP_NAME = "Desktop"; + +const char *NbLauncher::staticOptions[] = { + "-J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade", + "-J-Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense", + "--branding", + "nb" +}; + +NbLauncher::NbLauncher() { +} + +NbLauncher::NbLauncher(const NbLauncher& orig) { +} + +NbLauncher::~NbLauncher() { +} + +int NbLauncher::start(char *cmdLine) { + CmdArgs args(50); + args.addCmdLine(cmdLine); + return start(args.getCount(), args.getArgs()); +} + +int NbLauncher::start(int argc, char *argv[]) { + SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); + + if (!checkLoggingArg(argc, argv, true) || !setUpProcess(argc, argv) || !initBaseNames() || !readClusterFile()) { + return -1; + } + + parseConfigFile((baseDir + "\\etc\\" + getAppName() + ".conf").c_str()); + + if (!parseArgs(argc, argv)) { + return -1; + } + string oldUserDir = userDir; + parseConfigFile((userDir + "\\etc\\" + getAppName() + ".conf").c_str()); + userDir = oldUserDir; + + adjustHeapSize(); + addExtraClusters(); + string nbexecPath; + if (dirExists(platformDir.c_str())) { + nbexecPath = platformDir; + } else { + nbexecPath = baseDir + '\\' + platformDir; + } + if (!dirExists(nbexecPath.c_str())) { + logErr(false, true, "Could not find platform cluster:\n%s", nbexecPath.c_str()); + return false; + } + + CmdArgs newArgs(argc + 20); + addSpecificOptions(newArgs); + + if (!jdkHome.empty()) { + newArgs.add(ARG_NAME_JDKHOME); + newArgs.add(jdkHome.c_str()); + } + if (!clusters.empty()) { + newArgs.add(ARG_NAME_CLUSTERS); + newArgs.add(clusters.c_str()); + } + if (!userDir.empty()) { + newArgs.add(ARG_NAME_USER_DIR); + newArgs.add(userDir.c_str()); + } + if (!nbOptions.empty()) { + newArgs.addCmdLine(nbOptions.c_str()); + } + for (int i = 0; i < argc; i++) { + newArgs.add(argv[i]); + } + nbexecPath += NBEXEC_FILE_PATH; + + NBExecLoader loader; + return loader.start(nbexecPath.c_str(), newArgs.getCount(), newArgs.getArgs()); +} + +bool NbLauncher::initBaseNames() { + char path[MAX_PATH] = ""; + getCurrentModulePath(path, MAX_PATH); + logMsg("Executable: %s", path); + char *bslash = strrchr(path, '\\'); + if (!bslash) { + return false; + } + appName = bslash + 1; + appName.erase(appName.find('.')); + logMsg("Application name: %s", appName.c_str()); + + *bslash = '\0'; + bslash = strrchr(path, '\\'); + if (!bslash) { + return false; + } + *bslash = '\0'; + + baseDir = path; + logMsg("Base dir: %s", baseDir.c_str()); + return true; +} + +void NbLauncher::addCluster(const char *cl) { + string cluster = dirExists(cl) ? cl : (baseDir + '\\' + cl); + if (!clusters.empty()) { + clusters += ';'; + } + logMsg("Adding cluster %s", cluster.c_str()); + clusters += cluster; +} + +void NbLauncher::addExtraClusters() { + logMsg("addExtraClusters()"); + const char delim = ';'; + string::size_type start = extraClusters.find_first_not_of(delim, 0); + string::size_type end = extraClusters.find_first_of(delim, start); + while (string::npos != end || string::npos != start) { + string cluster = extraClusters.substr(start, end - start); + addCluster(cluster.c_str()); + start = extraClusters.find_first_not_of(delim, end); + end = extraClusters.find_first_of(delim, start); + } +} + +bool NbLauncher::readClusterFile() { + clusters = ""; + string clusterFile = baseDir + "\\etc\\" + getAppName() + ".clusters"; + logMsg("readClusterFile() file: %s", clusterFile.c_str()); + + FILE* file = fopen(clusterFile.c_str(), "r"); + if (!file) { + logErr(true, true, "Cannot open file \"%s\" for reading.", clusterFile.c_str()); + return false; + } + + char line[4096] = ""; + while (fgets(line, sizeof(line), file)) { + char *str = skipWhitespaces(line); + if (*str == '#' || *str == '\0') { + continue; + } + char *pc = str; + while (*pc != '\0' && *pc != '\t' && *pc != '\n' && *pc != '\r') { + pc++; + } + *pc = '\0'; + + if (platformDir.empty()) { + char *slash = strrchr(str, '\\'); + if (!slash) { + slash = strrchr(str, '/'); + } + char *dir = slash ? slash + 1 : str; + if (strncmp(dir, "platform", strlen("platform")) == 0) { + platformDir = str; + } else { + addCluster(str); + } + } else { + addCluster(str); + } + } + bool ok = ferror(file) == 0; + if (!ok) { + logErr(true, true, "Error while reading file \"%s\".", clusterFile.c_str()); + } + fclose(file); + return ok; +} + +bool NbLauncher::parseArgs(int argc, char *argv[]) { +#define CHECK_ARG \ + if (i+1 == argc) {\ + logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);\ + return false;\ + } + + logMsg("parseArgs():"); + for (int i = 0; i < argc; i++) { + logMsg("\t%s", argv[i]); + } + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_USER_DIR, argv[i]) == 0) { + CHECK_ARG; + char tmp[MAX_PATH + 1] = {0}; + strncpy(tmp, argv[++i], MAX_PATH); + if (!normalizePath(tmp)) { + logErr(false, true, "User directory path \"%s\" is not valid.", argv[i]); + return false; + } + userDir = tmp; + logMsg("User dir: %s", userDir.c_str()); + } + } + logMsg("parseArgs() finished"); + return true; +} + +bool NbLauncher::findUserDir(const char *str) { + logMsg("NbLauncher::findUserDir()"); + if (strncmp(str, HOME_TOKEN, strlen(HOME_TOKEN)) == 0) { + if (userHome.empty()) { + char *userProfile = getenv(ENV_USER_PROFILE); + if (userProfile) { + userHome = userProfile; + } else { + + if (!getStringFromRegistry(HKEY_CURRENT_USER, REG_SHELL_FOLDERS_KEY, REG_DESKTOP_NAME, userHome)) { + return false; + } + userHome.erase(userHome.rfind('\\')); + } + logMsg("User home: %s", userHome.c_str()); + } + userDir = userHome + (str + strlen(HOME_TOKEN)); + } else { + userDir = str; + } + return true; +} + +bool NbLauncher::getOption(char *&str, const char *opt) { + if (strncmp(str, opt, strlen(opt)) == 0) { + str += strlen(opt); + char *end = trimWhitespaces(str); + if (*str == '"') { + str++; + } + if (end >= str && *end == '"') { + *end = '\0'; + } + logMsg("Option found: %s%s", opt, str); + return true; + } + return false; +} + +bool NbLauncher::parseConfigFile(const char* path) { + logMsg("parseConfigFile(%s)", path); + FILE *file = fopen(path, "r"); + if (!file) { + logErr(true, false, "Cannot open file \"%s\" for reading.", path); + return false; + } + + char line[4096] = ""; + while (fgets(line, sizeof(line), file)) { + char *str = skipWhitespaces(line); + if (*str == '#') { + continue; + } + if (getOption(str, getDefUserDirOptName())) { + findUserDir(str); + logMsg("User dir: %s", userDir.c_str()); + } else if (getOption(str, getDefOptionsOptName())) { + // replace \" by " + int len = strlen(str); + int k = 0; + for (int i = 0; i < len; i++) { + if (str[i] == '\\' && str[i+1] == '\"') { + continue; + } + str[k++] = str[i]; + } + str[k] = '\0'; + nbOptions = str; + logMsg("After replacement: %s", nbOptions.c_str()); + + } else if (getOption(str, getExtraClustersOptName())) { + extraClusters = str; + } else if (getOption(str, getJdkHomeOptName())) { + jdkHome = str; + } + } + bool ok = ferror(file) == 0; + if (!ok) { + logErr(true, false, "Error while reading file \"%s\".", path); + } + fclose(file); + return true; +} + +// Search if -Xmx is specified in existing arguments +// If it isn't it adds it - 20% of available RAM but min is 96M and max 512M +void NbLauncher::adjustHeapSize() { + if (nbOptions.find("-J-Xmx") == string::npos) { + // find how much memory we have and add -Xmx + MEMORYSTATUS ms = {0}; + GlobalMemoryStatus(&ms); + int memory = (int)((ms.dwTotalPhys / 1024 / 1024) / 5); + if (memory < 96) { + memory = 96; + } + else if (memory > 512) { + memory = 512; + } + char tmp[32]; + snprintf(tmp, 32, " -J-Xmx%dm", memory); + nbOptions += tmp; + } +} + +const char * NbLauncher::getAppName() { + return "netbeans"; +} + +void NbLauncher::addSpecificOptions(CmdArgs &args) { + for (unsigned i = 0; i < sizeof (staticOptions) / sizeof (char*); i++) { + args.add(staticOptions[i]); + } +} + +const char * NbLauncher::getDefUserDirOptName() { + return OPT_NB_DEFAULT_USER_DIR; +} + +const char * NbLauncher::getDefOptionsOptName() { + return OPT_NB_DEFAULT_OPTIONS; +} + +const char * NbLauncher::getExtraClustersOptName() { + return OPT_NB_EXTRA_CLUSTERS; +} + +const char * NbLauncher::getJdkHomeOptName() { + return OPT_NB_JDK_HOME; +} diff --git a/ide/launcher/windows/nblauncher.h b/ide/launcher/windows/nblauncher.h new file mode 100644 --- /dev/null +++ b/ide/launcher/windows/nblauncher.h @@ -0,0 +1,108 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#ifndef _NBLAUNCHER_H +#define _NBLAUNCHER_H + +#include +#include +#include "cmdargs.h" + +class NbLauncher { +protected: + static const char *NBEXEC_FILE_PATH; + static const char *OPT_NB_DEFAULT_USER_DIR; + static const char *OPT_NB_DEFAULT_OPTIONS; + static const char *OPT_NB_EXTRA_CLUSTERS; + static const char *OPT_NB_JDK_HOME; + static const char *REG_SHELL_FOLDERS_KEY; + static const char *HOME_TOKEN; + +private: + static const char *ENV_USER_PROFILE; + static const char *REG_DESKTOP_NAME; + static const char* staticOptions[]; + + typedef int (*StartPlatform)(int argc, char *argv[]); + +public: + NbLauncher(); + virtual ~NbLauncher(); + + int start(int argc, char *argv[]); + int start(char *cmdLine); + +protected: + virtual bool initBaseNames(); + virtual void addSpecificOptions(CmdArgs &args); + virtual void adjustHeapSize(); + virtual bool findUserDir(const char *str); + virtual const char * getAppName(); + virtual const char * getDefUserDirOptName(); + virtual const char * getDefOptionsOptName(); + virtual const char * getExtraClustersOptName(); + virtual const char * getJdkHomeOptName(); + +private: + NbLauncher(const NbLauncher& orig); + bool readClusterFile(); + bool parseArgs(int argc, char *argv[]); + bool parseConfigFile(const char* path); + bool getOption(char *&str, const char *opt); + void addCluster(const char *cl); + void addExtraClusters(); + +protected: + std::string baseDir; + std::string appName; + std::string platformDir; + std::string userHome; + std::string userDir; + std::string clusters; + std::string extraClusters; + std::string nbOptions; + std::string jdkHome; +}; + +#endif /* _NBLAUNCHER_H */ + diff --git a/ide/launcher/windows/nbproject/Makefile-Default.mk b/ide/launcher/windows/nbproject/Makefile-Default.mk deleted file mode 100644 --- a/ide/launcher/windows/nbproject/Makefile-Default.mk +++ /dev/null @@ -1,54 +0,0 @@ -# -# Gererated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add customized code. -# -# This makefile implements configuration specific macros and targets. - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin -RANLIB=ranlib -CC=gcc.exe -CCC=g++.exe -CXX=g++.exe -FC= - -# Include project Makefile -include Makefile_windows.mk - -# Object Directory -OBJECTDIR=build/Default/Cygwin-Windows - -# Object Files -OBJECTFILES= - -# C Compiler Flags -CFLAGS= - -# CC Compiler Flags -CCFLAGS= -CXXFLAGS= - -# Fortran Compiler Flags -FFLAGS= - -# Link Libraries and Options -LDLIBSOPTIONS= - -# Build Targets -.build-conf: ${BUILD_SUBPROJECTS} - cd . && make -f Makefile testinst - -# Subprojects -.build-subprojects: - -# Clean Targets -.clean-conf: - cd . && make -f Makefile clean - -# Subprojects -.clean-subprojects: diff --git a/ide/launcher/windows/nbproject/Makefile-impl.mk b/ide/launcher/windows/nbproject/Makefile-impl.mk --- a/ide/launcher/windows/nbproject/Makefile-impl.mk +++ b/ide/launcher/windows/nbproject/Makefile-impl.mk @@ -27,27 +27,27 @@ PROJECTNAME=windows # Active Configuration -DEFAULTCONF=Default +DEFAULTCONF=netbeans.exe CONF=${DEFAULTCONF} # All Configurations -ALLCONFS=Default +ALLCONFS=netbeans.exe # build -.build-impl: .validate-impl +.build-impl: .build-pre .validate-impl .depcheck-impl @#echo "=> Running $@... Configuration=$(CONF)" ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf # clean -.clean-impl: .validate-impl +.clean-impl: .clean-pre .validate-impl .depcheck-impl @#echo "=> Running $@... Configuration=$(CONF)" ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf # clobber -.clobber-impl: +.clobber-impl: .clobber-pre .depcheck-impl @#echo "=> Running $@..." for CONF in ${ALLCONFS}; \ do \ @@ -55,13 +55,25 @@ done # all -.all-impl: +.all-impl: .all-pre .depcheck-impl @#echo "=> Running $@..." for CONF in ${ALLCONFS}; \ do \ ${MAKE} -f nbproject/Makefile-$${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf; \ done +# dependency checking support +.depcheck-impl: + @echo "# This code depends on make tool being used" >.dep.inc + @if [ -n "${MAKE_VERSION}" ]; then \ + echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ + echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ + echo "include \$${DEPFILES}" >>.dep.inc; \ + echo "endif" >>.dep.inc; \ + else \ + echo ".KEEP_STATE:" >>.dep.inc; \ + echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ + fi # configuration validation .validate-impl: @@ -80,7 +92,7 @@ # help -.help-impl: +.help-impl: .help-pre @echo "This makefile supports the following configurations:" @echo " ${ALLCONFS}" @echo "" @@ -108,6 +120,4 @@ @echo " also build subprojects." @echo "Target 'help' prints this message." @echo "" - @echo "The active configuration (${ACTIVECONF}) is being used if the configuration is not specified." - @echo "" diff --git a/ide/launcher/windows/nbproject/Makefile-netbeans.exe.mk b/ide/launcher/windows/nbproject/Makefile-netbeans.exe.mk new file mode 100644 --- /dev/null +++ b/ide/launcher/windows/nbproject/Makefile-netbeans.exe.mk @@ -0,0 +1,88 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc.exe +CCC=g++.exe +CXX=g++.exe +FC= +AS= + +# Macros +PLATFORM=Cygwin-Windows + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=build/netbeans.exe/${PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/netbeans.o \ + ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/ide/launcher/windows/../../../o.n.bootstrap/launcher/windows/utilsfuncs.o \ + ${OBJECTDIR}/nblauncher.o + +# C Compiler Flags +CFLAGS= + +# CC Compiler Flags +CCFLAGS=-m32 -s -mno-cygwin +CXXFLAGS=-m32 -s -mno-cygwin + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS=netbeans.res + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + ${MAKE} -f nbproject/Makefile-netbeans.exe.mk netbeans.exe.exe + +netbeans.exe.exe: ${OBJECTFILES} + ${LINK.cc} -mwindows -o netbeans.exe ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/netbeans.o: netbeans.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -I/cygdrive/c/cygwin/usr/include/mingw -MMD -MP -MF $@.d -o ${OBJECTDIR}/netbeans.o netbeans.cpp + +${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/ide/launcher/windows/../../../o.n.bootstrap/launcher/windows/utilsfuncs.o: ../../../o.n.bootstrap/launcher/windows/utilsfuncs.cpp + ${MKDIR} -p ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/ide/launcher/windows/../../../o.n.bootstrap/launcher/windows + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -I/cygdrive/c/cygwin/usr/include/mingw -MMD -MP -MF $@.d -o ${OBJECTDIR}/_ext/E_/work/netbeans/hg/main_work/ide/launcher/windows/../../../o.n.bootstrap/launcher/windows/utilsfuncs.o ../../../o.n.bootstrap/launcher/windows/utilsfuncs.cpp + +${OBJECTDIR}/nblauncher.o: nblauncher.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -I/cygdrive/c/cygwin/usr/include/mingw -MMD -MP -MF $@.d -o ${OBJECTDIR}/nblauncher.o nblauncher.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: + ${RM} -r build/netbeans.exe + ${RM} netbeans.exe.exe + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/ide/launcher/windows/nbproject/Package-netbeans.exe.bash b/ide/launcher/windows/nbproject/Package-netbeans.exe.bash new file mode 100644 --- /dev/null +++ b/ide/launcher/windows/nbproject/Package-netbeans.exe.bash @@ -0,0 +1,72 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +PLATFORM=Cygwin-Windows +TMPDIR=build/netbeans.exe/${PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=netbeans.exe +OUTPUT_BASENAME=netbeans.exe +PACKAGE_TOP_DIR=windows/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p dist/netbeans.exe/${PLATFORM}/package +rm -rf ${TMPDIR} +mkdir -p ${TMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory ${TMPDIR}/windows/bin +copyFileToTmpDir "${OUTPUT_PATH}.exe" "${TMPDIR}/${PACKAGE_TOP_DIR}bin/${OUTPUT_BASENAME}.exe" 0755 + + +# Generate tar file +cd "${TOP}" +rm -f dist/netbeans.exe/${PLATFORM}/package/windows.tar +cd ${TMPDIR} +tar -vcf ../../../../dist/netbeans.exe/${PLATFORM}/package/windows.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${TMPDIR} diff --git a/ide/launcher/windows/nbproject/configurations.xml b/ide/launcher/windows/nbproject/configurations.xml --- a/ide/launcher/windows/nbproject/configurations.xml +++ b/ide/launcher/windows/nbproject/configurations.xml @@ -1,35 +1,69 @@ - + + + cmdargs.h + nblauncher.h + ../../../o.n.bootstrap/launcher/windows/utilsfuncs.h + + + + + nblauncher.cpp + netbeans.cpp + ../../../o.n.bootstrap/launcher/windows/utilsfuncs.cpp + - Makefile_windows.mk + Makefile - Makefile - netbeans.cpp - Makefile_windows.mk + Makefile - + - Cygwin - true - true - false + localhost + Cygwin|Cygwin 3 - - - . - make -f Makefile testinst - make -f Makefile clean - netbeans.exe - - - - - + + + 5 + 1 + + c:/cygwin/usr/include/mingw + + -s -mno-cygwin + 2 + + + netbeans.exe + + netbeans.res + + -mwindows + + + + 1 + + + 3 + + + 3 + + + 1 + + 3 diff --git a/ide/launcher/windows/nbproject/project.xml b/ide/launcher/windows/nbproject/project.xml --- a/ide/launcher/windows/nbproject/project.xml +++ b/ide/launcher/windows/nbproject/project.xml @@ -3,8 +3,12 @@ org.netbeans.modules.cnd.makeproject - windows + NB Launcher Win 0 + + cpp + h + UTF-8 diff --git a/ide/launcher/windows/netbeans.cpp b/ide/launcher/windows/netbeans.cpp --- a/ide/launcher/windows/netbeans.cpp +++ b/ide/launcher/windows/netbeans.cpp @@ -24,7 +24,7 @@ * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original - * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun * Microsystems, Inc. All Rights Reserved. * * If you wish your version of this file to be governed by only the CDDL @@ -37,577 +37,14 @@ * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. + * + * Author: Tomas Holy */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -// #define DEBUG 1 +#include "nblauncher.h" -static char* getUserHomeFromRegistry(char* userhome); -static char* GetStringValue(HKEY key, const char *name); -static DWORD GetDWordValue(HKEY key, const char *name); -static void parseConfigFile(const char* path); -static void parseArgs(int argc, char *argv[]); -static int readClusterFile(const char* path); -static int dirExists(const char* path); -static void ErrorExit(LPTSTR lpszMessage, LPTSTR lpszFunction); -static void adjustHeapSize(); - -static char userdir[MAX_PATH] = "c:\\nbuser"; -static char options[4098] = ""; -static char dirs[4098] = "", extradirs[4098]; -static char jdkswitch[MAX_PATH] = ""; -static char platformDir[MAX_PATH] = ""; -static char* defaultDirs[512]; -static char msg[MAX_PATH + 128]; - -#ifdef WINMAIN - -static void parseCommandLine(char *argstr); - -int WINAPI - WinMain (HINSTANCE /* hSelf */, HINSTANCE /* hPrev */, LPSTR cmdline, int /* nShow */) { -#else - int main(int argc, char* argv[]) { - char cmdline[10240] = ""; - - for (int i = 1; i < argc; i++) { - char buf[10240]; - char *arg = argv[i]; - int len = strlen(arg); - if (arg[len-1] == '\"') - arg[len-1] = '\0'; - sprintf(buf, "\"%s\" ", arg); - strcat(cmdline, buf); - } -#endif - - char topdir[MAX_PATH]; - char *appname = NULL; - char buf[MAX_PATH * 10], *pc; - - GetModuleFileName(0, buf, sizeof buf); - - pc = strrchr(buf, '\\'); - if (pc != NULL) { // always holds - strlwr(pc + 1); - appname = strdup(pc + 1); - *pc = '\0'; // remove .exe filename - } - - pc = strrchr(buf, '\\'); - if (pc != NULL && 0 == stricmp("\\bin", pc)) - *pc = '\0'; - strcpy(topdir, buf); - - char clusterFileName[MAX_PATH]; - sprintf(clusterFileName, "%s\\etc\\netbeans.clusters", topdir); - - if (!readClusterFile(clusterFileName)) { - sprintf(msg, "Cannot read cluster file: %s", clusterFileName); - ErrorExit(msg, NULL); - } - - sprintf(buf, "%s\\etc\\netbeans.conf", topdir); - parseConfigFile(buf); - -#ifdef WINMAIN - parseCommandLine(cmdline); -#else - parseArgs(argc - 1, argv + 1); // skip progname -#endif - - char olduserdir[MAX_PATH]; - strcpy(olduserdir, userdir); - sprintf(buf, "%s\\etc\\netbeans.conf", userdir); - parseConfigFile(buf); - strcpy(userdir, olduserdir); - - adjustHeapSize(); - - char nbexec[MAX_PATH]; - char cmdline2[10240]; - - dirs[0] = '\0'; - for (char **pdir = defaultDirs; *pdir != NULL; pdir++) { - sprintf(buf, "%s\\%s", topdir, *pdir); - if (dirExists(buf)) { - if (dirs[0] != '\0') { - sprintf(buf, "%s;%s\\%s", dirs, topdir, *pdir); - } - strcpy(dirs, buf); - } - } - - if (extradirs[0] != '\0') { - strcat(strcat(dirs, ";"), extradirs); - } - - if (*platformDir == '\0') { - ErrorExit("Undefined platform cluster!", NULL); - } - - if (!dirExists(platformDir)) { - sprintf(nbexec, "%s\\%s", topdir, platformDir); - } else { - strcpy(nbexec,platformDir); - } - - if (!dirExists(nbexec)) { - sprintf(msg, "Could not find platform cluster:\n\n%s", nbexec); - ErrorExit(msg, NULL); - exit(1); - } - - strcat(nbexec, "\\lib\\nbexec.exe"); - - sprintf(cmdline2, "\"%s\" %s -J-Dnetbeans.importclass=org.netbeans.upgrade.AutoUpgrade -J-Dnetbeans.accept_license_class=org.netbeans.license.AcceptLicense --branding nb --clusters \"%s\" --userdir \"%s\" %s %s", - nbexec, - jdkswitch, - dirs, - userdir, - options, - cmdline); - - STARTUPINFO start; - PROCESS_INFORMATION pi; - - memset (&start, 0, sizeof (start)); - start.cb = sizeof (start); - -#ifdef WINMAIN - start.dwFlags = STARTF_USESHOWWINDOW; - start.wShowWindow = SW_HIDE; -#endif - -#ifdef DEBUG - printf("Cmdline: >%s<\ncwd >%s<\n", cmdline2, topdir); -#endif - if (!CreateProcess (NULL, cmdline2, - NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, - NULL, - NULL, // lpCurrentDirectory - &start, - &pi)) { - sprintf (buf, "Cannot start %s", appname); - ErrorExit(buf, "CreateProcess"); - return 255; - } else { - // Wait until child process exits. - WaitForSingleObject( pi.hProcess, INFINITE ); - - DWORD retCode = 0; - GetExitCodeProcess(pi.hProcess, &retCode); - // Close process and thread handles. - CloseHandle( pi.hProcess ); - CloseHandle( pi.hThread ); - return retCode; - } +int main(int argc, char *argv[]) { + NbLauncher launcher; + return launcher.start(argc - 1, argv + 1); } - -char* getUserHomeFromRegistry(char* userhome) -{ - HKEY key; - - if (RegOpenKeyEx( - HKEY_CURRENT_USER, - "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", - 0, - KEY_READ, - &key) != 0) - return NULL; - - char *path = GetStringValue(key, "Desktop"); - RegCloseKey(key); - - char *pc = strrchr(path, '\\'); - if (pc == NULL) { - return NULL; - } - *pc = '\0'; - strcpy(userhome, path); - return userhome; -} - - -char * GetStringValue(HKEY key, const char *name) -{ - DWORD type, size; - char *value = 0; - - if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0 && type == REG_SZ) { - value = (char*) malloc(size); - if (RegQueryValueEx(key, name, 0, 0, (unsigned char*)value, &size) != 0) { - free(value); - value = 0; - } - } - return value; -} - - -DWORD GetDWordValue(HKEY key, const char *name) -{ - DWORD type, size; - DWORD value = 0; - - if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0 && type == REG_DWORD) { - if (RegQueryValueEx(key, name, 0, 0, (LPBYTE)&value, &size) != 0) { - return 0; - } - } - return value; -} - - -void parseConfigFile(const char* path) { - FILE* fin = fopen(path, "r"); - if (fin == NULL) - return; - - char line[2048], *pc; - - while (NULL != fgets(line, sizeof line, fin)) { - for (pc = line; *pc != '\0' && (*pc == ' ' || *pc == '\t' || *pc == '\n' || *pc == '\r'); pc++) - ; - if (*pc == '#') - continue; - if (strstr(pc, "netbeans_default_userdir=") == pc) { - char *q = strstr(pc, "=") + 1; - pc = line + strlen(line) - 1; - while (*pc == '\n' || *pc == '\r' || *pc == '\t' || *pc == ' ') - pc--; - - if (*q == '"' && *pc == '"') { - q++; - pc--; - } - - *(pc+1) = '\0'; - if (strstr(q, "${HOME}") == q) { - char userhome[MAX_PATH]; - char *userprofile = getenv("USERPROFILE"); - - if (userprofile == NULL) { - userprofile = getUserHomeFromRegistry(userhome); - } - if (userprofile != NULL) { - strcpy(userdir, userprofile); - } - // else { - // ... keep the default userdir value 'c:\nbuser' - // } - strcat(userdir, q + strlen("${HOME}")); - } else { - strcpy(userdir, q); - } - } else if (strstr(pc, "netbeans_default_options=") == pc) { - char *q = strstr(pc, "=") + 1; - pc = line + strlen(line) - 1; - while (*pc == '\n' || *pc == '\r' || *pc == '\t' || *pc == ' ') - pc--; - - if (*q == '"' && *pc == '"') { - q++; - pc--; - } - - *(pc+1) = '\0'; - strcpy(options, q); - } else if (strstr(pc, "netbeans_extraclusters=") == pc) { - char *q = strstr(pc, "=") + 1; - pc = line + strlen(line) - 1; - while (*pc == '\n' || *pc == '\r' || *pc == '\t' || *pc == ' ') - pc--; - - if (*q == '"' && *pc == '"') { - q++; - pc--; - } - - *(pc+1) = '\0'; - strcpy(extradirs, q); - } else if (strstr(pc, "netbeans_jdkhome=") == pc) { - char *q = strstr(pc, "=") + 1; - pc = line + strlen(line) - 1; - while (*pc == '\n' || *pc == '\r' || *pc == '\t' || *pc == ' ') - pc--; - - if (*q == '"' && *pc == '"') { - q++; - pc--; - } - - *(pc+1) = '\0'; - sprintf(jdkswitch, "--jdkhome \"%s\"", q); - } - } - fclose(fin); -} - -#ifdef WINMAIN - -void parseCommandLine(char *argstr) { - char **argv = (char**) malloc(2048 * sizeof (char*)); - int argc = 0; - -#define START 0 -#define NORMAL 1 -#define IN_QUOTES 2 -#define IN_APOS 3 - - char *p, *q; - int state = NORMAL; - char token[1024 * 64]; - int eof; - - q = argstr; - p = token; - state = START; - eof = 0; - - while (!eof) { - if (*q == '\0') - eof = 1; - - switch (state) { - case START: - if (*q == ' ' || *q == '\r' || *q == '\n' || *q == '\t') { - q++; - continue; - } - - p = token; - *p = '\0'; - - if (*q == '"') { - state = IN_QUOTES; - q++; - continue; - } - if (*q == '\'') { - state = IN_APOS; - q++; - continue; - } - - state = NORMAL; - continue; - - case NORMAL: - if (*q == ' ' || *q == '\r' || *q == '\n' || *q == '\t' || *q == '\0') { - *p = '\0'; - argv[argc] = strdup(token); - argc++; - state = START; - } else { - *p++ = *q++; - } - break; - - case IN_QUOTES: - if (*q == '"') { - if (*(q+1) == '"') { - *p++ = '"'; - q += 2; - } else { - *p = '\0'; - - argv[argc] = strdup(token); - argc++; - - q++; - state = START; - } - } else if (*q == '\0') { - *p = '\0'; - argv[argc] = strdup(token); - argc++; - state = START; - } else { - *p++ = *q++; - } - break; - - case IN_APOS: - if (*q == '\'') { - if (*(q+1) == '\'') { - *p++ = '\''; - q += 2; - } else { - *p = '\0'; - - argv[argc] = strdup(token); - argc++; - - q++; - state = START; - } - } else if (*q == '\0') { - *p = '\0'; - argv[argc] = strdup(token); - argc++; - state = START; - } else { - *p++ = *q++; - } - break; - } - } - - parseArgs(argc, argv); - -} -#endif // WINMAIN - -void parseArgs(int argc, char *argv[]) { - char *arg; - - while (argc > 0 && (arg = *argv) != 0) { - argv++; - argc--; - - if (0 == strcmp("--userdir", arg)) { - if (argc > 0) { - arg = *argv; - argv++; - argc--; - if (arg != 0) { - strcpy(userdir, arg); - } - } - } - } -} - -int readClusterFile(const char* path) { - - char **dirs = defaultDirs; - - FILE* fin = fopen(path, "r"); - if (fin == NULL) - return 0; - - char line[2048], *pc; - - while (NULL != fgets(line, sizeof line, fin)) { - for (pc = line; *pc != '\0' && (*pc == ' ' || *pc == '\t' || *pc == '\n' || *pc == '\r'); pc++) - ; - if (*pc == '#') - continue; - - char *s = pc; - - while (*pc != '\0' && *pc != '\t' && *pc != '\n' && *pc != '\r') - pc++; - - *pc = '\0'; - - if (*platformDir == '\0') { // no platform found yet - char *platformStr = strrchr(s,'\\'); - if (platformStr == NULL) { - platformStr = s; - } else { // move over backslash - platformStr++; - } - - if (!strncmp("platform", platformStr, 8)) { // strlen("platform") == 8 - strcpy(platformDir, s); - } - } - else { - *dirs = strdup(s); - dirs++; - } - } - *dirs = NULL; - fclose(fin); - - return 1; -} - -int dirExists(const char* path) { - WIN32_FIND_DATA ffd; - HANDLE ffh; - - memset(&ffd, 0, sizeof ffd); - ffd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; - ffh = FindFirstFile(path, &ffd); - if (ffh != INVALID_HANDLE_VALUE) { - FindClose(ffh); - return 1; - } else { - return 0; - } -} - -// Show error dialog and exits the program -// lpszMessage - error message to be printed -// lpszFunction - name of last called method that return fail status -// can be NULL -void ErrorExit(LPTSTR lpszMessage, LPTSTR lpszFunction) -{ - LPVOID lpMsgBuf; - LPVOID lpDisplayBuf; - DWORD dw = GetLastError(); - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - dw, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL ); - - if (lpszFunction != NULL ) { - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - (lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR)); - wsprintf((LPTSTR)lpDisplayBuf, - TEXT("%s\n%s failed with error %d: %s"), - lpszMessage, lpszFunction, dw, lpMsgBuf); - } - else { - lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, - lstrlen((LPCTSTR)lpMsgBuf)); - wsprintf((LPTSTR)lpDisplayBuf, - TEXT("%s"), - lpszMessage); - } - - MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_ICONSTOP | MB_OK); - - LocalFree(lpMsgBuf); - LocalFree(lpDisplayBuf); - ExitProcess( (dw != 0)? dw: 1); -} - -// Seaches if -Xmx is specified in existing arguments -// If it isn't it adds it - 20% of available RAM but min is 96M and max 512M -void adjustHeapSize() { - - MEMORYSTATUS ms; - char buf[20]; - - if (strstr(options, "-J-Xmx") == NULL) { - // find how much memory we have and add -Xmx - GlobalMemoryStatus(&ms); - DWORDLONG memory = (ms.dwTotalPhys / 1024 / 1024) / 5; - if (memory < 96) { - memory = 96; - } - else if (memory > 512) { - memory = 512; - } - sprintf(buf, " -J-Xmx%ldm", memory); - strcat(options, buf); - } -} diff --git a/ide/launcher/windows/netbeans.exe b/ide/launcher/windows/netbeans.exe index 80f912945d62b7775f86199ad94f75e7c9a81ecb..76199626bcffbf8c09fc414ad81d508c63038207 GIT binary patch literal 396800 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 k4BO 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 W!Jj-l{wm+4qsP}o_w_BxvHuT0MO2^w diff --git a/nbbuild/build.xml b/nbbuild/build.xml --- a/nbbuild/build.xml +++ b/nbbuild/build.xml @@ -589,7 +589,6 @@ - @@ -1217,7 +1216,7 @@ - + @@ -1300,7 +1299,7 @@ - + diff --git a/o.n.bootstrap/launcher/windows/.dep.inc b/o.n.bootstrap/launcher/windows/.dep.inc new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/.dep.inc @@ -0,0 +1,5 @@ +# This code depends on make tool being used +DEPFILES=$(wildcard $(addsuffix .d, ${OBJECTFILES})) +ifneq (${DEPFILES},) +include ${DEPFILES} +endif diff --git a/o.n.bootstrap/launcher/windows/Makefile b/o.n.bootstrap/launcher/windows/Makefile --- a/o.n.bootstrap/launcher/windows/Makefile +++ b/o.n.bootstrap/launcher/windows/Makefile @@ -1,69 +1,97 @@ -# -*- Makefile -*- # -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# There exist several targets which are by default empty and which can be +# used for execution of your targets. These targets are usually executed +# before and after some main targets. They are: # -# Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved. +# .build-pre: called before 'build' target +# .build-post: called after 'build' target +# .clean-pre: called before 'clean' target +# .clean-post: called after 'clean' target +# .clobber-pre: called before 'clobber' target +# .clobber-post: called after 'clobber' target +# .all-pre: called before 'all' target +# .all-post: called after 'all' target +# .help-pre: called before 'help' target +# .help-post: called after 'help' target # -# The contents of this file are subject to the terms of either the GNU -# General Public License Version 2 only ("GPL") or the Common -# Development and Distribution License("CDDL") (collectively, the -# "License"). You may not use this file except in compliance with the -# License. You can obtain a copy of the License at -# http://www.netbeans.org/cddl-gplv2.html -# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the -# specific language governing permissions and limitations under the -# License. When distributing the software, include this License Header -# Notice in each file and include the License file at -# nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this -# particular file as subject to the "Classpath" exception as provided -# by Sun in the GPL Version 2 section of the License file that -# accompanied this code. If applicable, add the following below the -# License Header, with the fields enclosed by brackets [] replaced by -# your own identifying information: -# "Portions Copyrighted [year] [name of copyright owner]" +# Targets beginning with '.' are not intended to be called on their own. # -# Contributor(s): +# Main targets can be executed directly, and they are: +# +# build build a specific configuration +# clean remove built files from a configuration +# clobber remove all built files +# all build all configurations +# help print help mesage +# +# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and +# .help-impl are implemented in nbproject/makefile-impl.mk. # -# The Original Software is Forte for Java, Community Edition. The Initial -# Developer of the Original Software is Sun Microsystems, Inc. Portions -# Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. -# -# If you wish your version of this file to be governed by only the CDDL -# or only the GPL Version 2, indicate your decision by adding -# "[Contributor] elects to include this software in this distribution -# under the [CDDL or GPL Version 2] license." If you do not indicate a -# single choice of license, a recipient has the option to distribute -# your version of this file under either the CDDL, the GPL Version 2 or -# to extend the choice of license to its licensees as provided above. -# However, if you add GPL Version 2 code and therefore, elected the GPL -# Version 2 license, then the option applies only if the new code is -# made subject to such option by the copyright holder. -# +# NOCDDL -LIBS = -#LIBS = advapi32.lib user32.lib -CFLAGS = -s -mno-cygwin -#!ifdef DEBUG -# CFLAGS = $(CFLAGS) -Zi -#!endif +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib -all : nbexec.exe +# build +build: .build-post -nbexec.exe : nbexec.cpp - g++ $(CFLAGS) $(LIBS) nbexec.cpp -o nbexec.exe +.build-pre: +# Add your pre 'build' code here... -clean : - -rm *.res *.obj *.pdb *.ilk *~ 2>NUL +.build-post: .build-impl nbexec.exe +# Add your post 'build' code here... + cp nbexec.exe ../../../nbbuild/netbeans/platform9/lib/ + cp nbexec.dll ../../../nbbuild/netbeans/platform9/lib/ -distclean : clean - -rm *.exe 2>NUL +nbexec.exe: nbexecexe.cpp nbexecloader.h utilsfuncs.cpp + g++ -s -mno-cygwin nbexecexe.cpp utilsfuncs.cpp -o nbexec.exe -testinst : all - cp *.exe ../../../nbbuild/netbeans/platform9/lib/ +# clean +clean: .clean-post -test : testinst - ../../../nbbuild/netbeans/platform9/lib/nbexec.exe +.clean-pre: +# Add your pre 'clean' code here... +# -rm -r build/* -test2 : testinst - ../../../nbbuild/netbeans/platform9/lib/nbexec.exe +.clean-post: .clean-impl +# Add your post 'clean' code here... + rm -f nbexec.exe + + +# clobber +clobber: .clobber-post + +.clobber-pre: +# Add your pre 'clobber' code here... + +.clobber-post: .clobber-impl +# Add your post 'clobber' code here... + + +# all +all: .all-post + +.all-pre: +# Add your pre 'all' code here... + +.all-post: .all-impl +# Add your post 'all' code here... + + +# help +help: .help-post + +.help-pre: +# Add your pre 'help' code here... + +.help-post: .help-impl +# Add your post 'help' code here... + + + +# include project implementation makefile +include nbproject/Makefile-impl.mk diff --git a/o.n.bootstrap/launcher/windows/Makefile_windows.mk b/o.n.bootstrap/launcher/windows/Makefile_windows.mk deleted file mode 100644 --- a/o.n.bootstrap/launcher/windows/Makefile_windows.mk +++ /dev/null @@ -1,92 +0,0 @@ -# -# There exist several targets which are by default empty and which can be -# used for execution of your targets. These targets are usually executed -# before and after some main targets. They are: -# -# .build-pre: called before 'build' target -# .build-post: called after 'build' target -# .clean-pre: called before 'clean' target -# .clean-post: called after 'clean' target -# .clobber-pre: called before 'clobber' target -# .clobber-post: called after 'clobber' target -# .all-pre: called before 'all' target -# .all-post: called after 'all' target -# .help-pre: called before 'help' target -# .help-post: called after 'help' target -# -# Targets beginning with '.' are not intended to be called on their own. -# -# Main targets can be executed directly, and they are: -# -# build build a specific configuration -# clean remove built files from a configuration -# clobber remove all built files -# all build all configurations -# help print help mesage -# -# Targets .build-impl, .clean-impl, .clobber-impl, .all-impl, and -# .help-impl are implemented in nbproject/makefile-impl.mk. -# -# NOCDDL - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin -RANLIB=ranlib - - -# build -build: .build-pre .build-impl .build-post - -.build-pre: -# Add your pre 'build' code here... - -.build-post: -# Add your post 'build' code here... - - -# clean -clean: .clean-pre .clean-impl .clean-post - -.clean-pre: -# Add your pre 'clean' code here... - -.clean-post: -# Add your post 'clean' code here... - - -# clobber -clobber: .clobber-pre .clobber-impl .clobber-post - -.clobber-pre: -# Add your pre 'clobber' code here... - -.clobber-post: -# Add your post 'clobber' code here... - - -# all -all: .all-pre .all-impl .all-post - -.all-pre: -# Add your pre 'all' code here... - -.all-post: -# Add your post 'all' code here... - - -# help -help: .help-pre .help-impl .help-post - -.help-pre: -# Add your pre 'help' code here... - -.help-post: -# Add your post 'help' code here... - - - -# include project implementation makefile -include nbproject/Makefile-impl.mk diff --git a/o.n.bootstrap/launcher/windows/argnames.h b/o.n.bootstrap/launcher/windows/argnames.h new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/argnames.h @@ -0,0 +1,25 @@ +/* + * File: argnames.h + * Author: Holy + * + * Created on 4. prosinec 2008, 14:13 + */ + +#ifndef _ARGNAMES_H +#define _ARGNAMES_H + +#define ARG_NAME_SEPAR_PROC "--javaprocess" +#define ARG_NAME_CONSOLE "--console" +#define ARG_NAME_LAUNCHER_LOG "--trace" +#define ARG_NAME_LA_START_APP "--la_start_app" +#define ARG_NAME_LA_START_AU "--la_start_au" +#define ARG_NAME_USER_DIR "--userdir" +#define ARG_NAME_CLUSTERS "--clusters" +#define ARG_NAME_BOOTCLASS "--bootclass" +#define ARG_NAME_JDKHOME "--jdkhome" +#define ARG_NAME_CP_PREPEND "--cp:p" +#define ARG_NAME_CP_APPEND "--cp:a" + + +#endif /* _ARGNAMES_H */ + diff --git a/o.n.bootstrap/launcher/windows/jvmlauncher.cpp b/o.n.bootstrap/launcher/windows/jvmlauncher.cpp new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/jvmlauncher.cpp @@ -0,0 +1,394 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#include "jvmlauncher.h" +#include + +using namespace std; + +const char *JvmLauncher::JDK_KEY = "Software\\JavaSoft\\Java Development Kit"; +const char *JvmLauncher::JRE_KEY = "Software\\JavaSoft\\Java Runtime Environment"; +const char *JvmLauncher::CUR_VERSION_NAME = "CurrentVersion"; +const char *JvmLauncher::JAVA_HOME_NAME = "JavaHome"; +const char *JvmLauncher::JAVA_BIN_DIR = "\\bin"; +const char *JvmLauncher::JAVA_EXE_FILE = "\\bin\\java.exe"; +const char *JvmLauncher::JAVA_CLIENT_DLL_FILE = "\\bin\\client\\jvm.dll"; +const char *JvmLauncher::JAVA_SERVER_DLL_FILE = "\\bin\\server\\jvm.dll"; +const char *JvmLauncher::JAVA_JRE_PREFIX = "\\jre"; +const char *JvmLauncher::JNI_CREATEVM_FUNC = "JNI_CreateJavaVM"; + + +JvmLauncher::JvmLauncher() { +} + +JvmLauncher::JvmLauncher(const JvmLauncher& orig) { +} + +JvmLauncher::~JvmLauncher() { +} + +bool JvmLauncher::checkJava(const char *path, const char *prefix) { + assert(path); + assert(prefix); + logMsg("checkJava(%s)", path); + javaPath = path; + if (*javaPath.rbegin() == '\\') { + javaPath.erase(javaPath.length() - 1, 1); + } + javaExePath = javaPath + prefix + JAVA_EXE_FILE; + javaClientDllPath = javaPath + prefix + JAVA_CLIENT_DLL_FILE; + javaServerDllPath = javaPath + prefix + JAVA_SERVER_DLL_FILE; + if (!fileExists(javaClientDllPath.c_str())) { + javaClientDllPath = ""; + } + if (!fileExists(javaServerDllPath.c_str())) { + javaServerDllPath = ""; + } + javaBinPath = javaPath + prefix + JAVA_BIN_DIR; + if (fileExists(javaExePath.c_str()) && (!javaClientDllPath.empty() || !javaServerDllPath.empty())) { + return true; + } + + javaPath.clear(); + javaBinPath.clear(); + javaExePath.clear(); + javaClientDllPath.clear(); + javaServerDllPath.clear(); + return false; +} + +bool JvmLauncher::initialize(const char *javaPathOrMinVersion) { + logMsg("JvmLauncher::initialize()\n\tjavaPathOrMinVersion: %s", javaPathOrMinVersion); + assert(javaPathOrMinVersion); + if (isVersionString(javaPathOrMinVersion)) { + return findJava(javaPathOrMinVersion); + } else { + return (checkJava(javaPathOrMinVersion, JAVA_JRE_PREFIX) || checkJava(javaPathOrMinVersion, "")); + } +} + +bool JvmLauncher::getJavaPath(string &path) { + logMsg("JvmLauncher::getJavaPath()"); + path = javaPath; + return !javaPath.empty(); +} + +bool JvmLauncher::start(const char *mainClassName, list args, list options, bool &separateProcess, DWORD *retCode) { + assert(mainClassName); + logMsg("JvmLauncher::start()\n\tmainClassName: %s\n\tseparateProcess: %s", + mainClassName, separateProcess ? "true" : "false"); + logMsg(" args:"); + for (list::iterator it = args.begin(); it != args.end(); ++it) { + logMsg("\t%s", it->c_str()); + } + logMsg(" options:"); + for (list::iterator it = options.begin(); it != options.end(); ++it) { + logMsg("\t%s", it->c_str()); + } + + if (javaExePath.empty() || (javaClientDllPath.empty() && javaServerDllPath.empty())) { + if (!initialize("")) { + return false; + } + } + + if (!separateProcess) { + // both client/server found, check option which should be used + if (!javaClientDllPath.empty() && !javaServerDllPath.empty()) { + javaDllPath = findClientOption(options) ? javaClientDllPath : javaServerDllPath; + } else { + javaDllPath = javaClientDllPath.empty() ? javaServerDllPath : javaClientDllPath; + } + logMsg("Java DLL path: %s", javaDllPath.c_str()); + if (!canLoadJavaDll()) { + logMsg("Fallbacking to running java in separate process, dll cannot be loaded (64bit dll?)."); + separateProcess = true; + } + } + + return separateProcess ? startOutProcJvm(mainClassName, args, options, retCode) + : startInProcJvm(mainClassName, args, options); +} + +bool JvmLauncher::findClientOption(list &options) { + for (list::iterator it = options.begin(); it != options.end(); ++it) { + if (*it == "-client") { + return false; + } + } + return true; +} + +bool JvmLauncher::canLoadJavaDll() { + // be prepared for stupid placement of msvcr71.dll in java installation + // (in java 1.6/1.7 jvm.dll is dynamically linked to msvcr71.dll which si placed + // in bin directory) + PrepareDllPath prepare(javaBinPath.c_str()); + HMODULE hDll = LoadLibrary(javaDllPath.c_str()); + if (hDll) { + FreeLibrary(hDll); + return true; + } + logErr(true, false, "Cannot load %s.", javaDllPath.c_str()); + return false; +} + +bool JvmLauncher::isVersionString(const char *str) { + char *end = 0; + strtod(str, &end); + return *end == '\0'; +} + +bool JvmLauncher::startInProcJvm(const char *mainClassName, std::list args, std::list options) { + + class Jvm { + public: + + Jvm(JvmLauncher *jvmLauncher) + : hDll(0) + , jvm(0) + , env(0) + , jvmOptions(0) + , jvmLauncher(jvmLauncher) + { + } + + ~Jvm() { + if (env && env->ExceptionOccurred()) { + env->ExceptionDescribe(); + } + + if (jvm) { + logMsg("Destroying JVM"); + jvm->DestroyJavaVM(); + } + + if (jvmOptions) { + delete[] jvmOptions; + } + + if (hDll) { + FreeLibrary(hDll); + } + } + + bool init(list options) { + logMsg("JvmLauncher::Jvm::init()"); + logMsg("LoadLibrary(\"%s\")", jvmLauncher->javaDllPath.c_str()); + PrepareDllPath prepare(jvmLauncher->javaBinPath.c_str()); + hDll = LoadLibrary(jvmLauncher->javaDllPath.c_str()); + if (!hDll) { + logErr(true, true, "Cannot load %s.", jvmLauncher->javaDllPath.c_str()); + return false; + } + + CreateJavaVM createJavaVM = (CreateJavaVM) GetProcAddress(hDll, JNI_CREATEVM_FUNC); + if (!createJavaVM) { + logErr(true, true, "GetProcAddress for %s failed.", JNI_CREATEVM_FUNC); + return false; + } + + logMsg("JVM options:"); + jvmOptions = new JavaVMOption[options.size()]; + int i = 0; + for (list::iterator it = options.begin(); it != options.end(); ++it, ++i) { + string &option = *it; + logMsg("\t%s", option.c_str()); + jvmOptions[i].optionString = (char *) option.c_str(); + jvmOptions[i].extraInfo = 0; + } + + JavaVMInitArgs jvmArgs; + jvmArgs.options = jvmOptions; + jvmArgs.nOptions = options.size(); + jvmArgs.version = JNI_VERSION_1_4; + jvmArgs.ignoreUnrecognized = JNI_TRUE; + + logMsg("Creating JVM..."); + if (createJavaVM(&jvm, &env, &jvmArgs) < 0) { + logErr(false, true, "JVM creation failed"); + return false; + } + logMsg("JVM created."); + return true; + } + typedef jint (CALLBACK *CreateJavaVM)(JavaVM **jvm, JNIEnv **env, void *args); + + HMODULE hDll; + JavaVM *jvm; + JNIEnv *env; + JavaVMOption *jvmOptions; + JvmLauncher *jvmLauncher; + }; + + Jvm jvm(this); + if (!jvm.init(options)) { + return false; + } + + jclass mainClass = jvm.env->FindClass(mainClassName); + if (!mainClass) { + logErr(false, true, "Cannot find class %s.", mainClassName); + return false; + } + + jmethodID mainMethod = jvm.env->GetStaticMethodID(mainClass, "main", "([Ljava/lang/String;)V"); + if (!mainMethod) { + logErr(false, true, "Cannot get main method."); + return false; + } + + jclass jclassString = jvm.env->FindClass("java/lang/String"); + if (!jclassString) { + logErr(false, true, "Cannot find java/lang/String class"); + return false; + } + + jstring jstringArg = jvm.env->NewStringUTF(""); + if (!jstringArg) { + logErr(false, true, "NewStringUTF() failed"); + return false; + } + + jobjectArray mainArgs = jvm.env->NewObjectArray(args.size(), jclassString, jstringArg); + if (!mainArgs) { + logErr(false, true, "NewObjectArray() failed"); + return false; + } + int i = 0; + for (list::iterator it = args.begin(); it != args.end(); ++it, ++i) { + string &arg = *it; + jstring jstringArg = jvm.env->NewStringUTF(arg.c_str()); + if (!jstringArg) { + logErr(false, true, "NewStringUTF() failed"); + return false; + } + jvm.env->SetObjectArrayElement(mainArgs, i, jstringArg); + } + + jvm.env->CallStaticVoidMethod(mainClass, mainMethod, mainArgs); + return true; +} + + +bool JvmLauncher::startOutProcJvm(const char *mainClassName, std::list args, std::list options, DWORD *retCode) { + STARTUPINFO si = {0}; + si.cb = sizeof(STARTUPINFO); + PROCESS_INFORMATION pi = {0}; + string cmdLine = '\"' + javaExePath + '\"'; + cmdLine.reserve(32*1024); + for (list::iterator it = options.begin(); it != options.end(); ++it) { + cmdLine += " \""; + cmdLine += *it; + cmdLine += "\""; + } + + // mainClass and args + cmdLine += ' '; + cmdLine += mainClassName; + for (list::iterator it = args.begin(); it != args.end(); ++it) { + if (javaClientDllPath.empty() && *it == "-client") { + logMsg("Removing -client option, client java dll not found."); + // remove client parameter, no client java found + continue; + } + cmdLine += " \""; + cmdLine += *it; + cmdLine += "\""; + } + + logMsg("Command line:\n%s", cmdLine.c_str()); + if (cmdLine.size() >= 32*1024) { + logErr(false, true, "Command line is too long. Length: %u. Maximum length: %u.", cmdLine.c_str(), 32*1024); + return false; + } + + char cmdLineStr[32*1024] = ""; + strcpy(cmdLineStr, cmdLine.c_str()); + if (!CreateProcess(NULL, cmdLineStr, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { + logErr(true, true, "Failed to create process"); + return false; + } + + disableFolderVirtualization(pi.hProcess); + ResumeThread(pi.hThread); + WaitForSingleObject(pi.hProcess, INFINITE); + if (retCode) { + GetExitCodeProcess(pi.hProcess, retCode); + } + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return true; +} + +bool JvmLauncher::findJava(const char *minJavaVersion) { + if (findJava(JDK_KEY, JAVA_JRE_PREFIX, minJavaVersion)) { + return true; + } + if (findJava(JRE_KEY, "", minJavaVersion)) { + return true; + } + javaPath = ""; + javaExePath = ""; + javaClientDllPath = ""; + javaServerDllPath = ""; + javaBinPath = ""; + return false; +} + +bool JvmLauncher::findJava(const char *javaKey, const char *prefix, const char *minJavaVersion) { + logMsg("JvmLauncher::findJava()\n\tjavaKey: %s\n\tprefix: %s\n\tminJavaVersion: %s", javaKey, prefix, minJavaVersion); + string value; + if (getStringFromRegistry(HKEY_LOCAL_MACHINE, javaKey, CUR_VERSION_NAME, value)) { + if (value > minJavaVersion) { + string path; + if (getStringFromRegistry(HKEY_LOCAL_MACHINE, (string(javaKey) + "\\" + value).c_str(), JAVA_HOME_NAME, path)) { + if (*path.rbegin() == '\\') { + path.erase(path.length() - 1, 1); + } + return checkJava(path.c_str(), prefix); + } + } + } + return false; +} diff --git a/o.n.bootstrap/launcher/windows/jvmlauncher.h b/o.n.bootstrap/launcher/windows/jvmlauncher.h new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/jvmlauncher.h @@ -0,0 +1,134 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#ifndef _JVMLAUNCHER_H +#define _JVMLAUNCHER_H + +#include +#include +#include +#include "jni.h" +#include "utilsfuncs.h" + +class JvmLauncher { + static const int MAX_ARGS_LEN = 32*1024; + + static const char *JDK_KEY; + static const char *JRE_KEY; + static const char *CUR_VERSION_NAME; + static const char *JAVA_HOME_NAME; + static const char *JAVA_BIN_DIR; + static const char *JAVA_EXE_FILE; + static const char *JAVA_CLIENT_DLL_FILE; + static const char *JAVA_SERVER_DLL_FILE; + static const char *JAVA_JRE_PREFIX; + static const char *JNI_CREATEVM_FUNC; + +public: + JvmLauncher(); + virtual ~JvmLauncher(); + + bool initialize(const char *javaPathOrMinVersion); + bool getJavaPath(std::string &path); + bool start(const char *mainClassName, std::list args, std::list options, bool &separateProcess, DWORD *retCode); + +private: + JvmLauncher(const JvmLauncher& orig); + + bool checkJava(const char *javaPath, const char *prefix); + bool findJava(const char *minJavaVersion); + bool findJava(const char *javaKey, const char *prefix, const char *minJavaVersion); + bool startOutProcJvm(const char *mainClassName, std::list args, std::list options, DWORD *retCode); + bool startInProcJvm(const char *mainClassName, std::list args, std::list options); + bool isVersionString(const char *str); + bool canLoadJavaDll(); + bool findClientOption(std::list &options); + +private: + std::string javaExePath; + std::string javaDllPath; + std::string javaClientDllPath; + std::string javaServerDllPath; + std::string javaPath; + std::string javaBinPath; + + class PrepareDllPath { + public: + PrepareDllPath(const char *dllDirectory) + : setDllDirectory(0) { + logMsg("PrepareDllPath: %s", dllDirectory); + oldCurDir[0] = '\0'; + + // SetDllDirectory is present since XP SP1, so we have to load it dynamically + HINSTANCE hKernel32 = GetModuleHandle("kernel32"); + if (!hKernel32) { + logErr(true, false, "Cannot load kernel32."); + return; + } + + LPFNSDD setDllDirectory = (LPFNSDD)GetProcAddress(hKernel32, "SetDllDirectoryA"); + if (setDllDirectory) { + setDllDirectory(dllDirectory); + } else { + logErr(true, false, "Cannot find SetDllDirectoryA"); + } + GetCurrentDirectory(MAX_PATH, oldCurDir); + SetCurrentDirectory(dllDirectory); + } + ~PrepareDllPath() { + if (setDllDirectory) { + setDllDirectory(NULL); + } + if (oldCurDir[0]) { + SetCurrentDirectory(oldCurDir); + } + } + private: + typedef BOOL (WINAPI *LPFNSDD)(LPCTSTR lpPathname); + LPFNSDD setDllDirectory; + char oldCurDir[MAX_PATH]; + }; +}; + +#endif /* _JVMLAUNCHER_H */ + diff --git a/o.n.bootstrap/launcher/windows/nbexec.cpp b/o.n.bootstrap/launcher/windows/nbexec.cpp --- a/o.n.bootstrap/launcher/windows/nbexec.cpp +++ b/o.n.bootstrap/launcher/windows/nbexec.cpp @@ -37,1109 +37,39 @@ * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. + * + * Author: Tomas Holy */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "platformlauncher.h" +#include "utilsfuncs.h" -using namespace std; +PlatformLauncher launcher; -#define PROG_FULLNAME "Error" -#define IDE_MAIN_CLASS "org/netbeans/Main" -#define UPDATER_MAIN_CLASS "org/netbeans/updater/UpdaterFrame" +extern "C" BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH: + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + launcher.onExit(); + break; + } + return TRUE; +} -#define JDK_KEY "Software\\JavaSoft\\Java Development Kit" -#define JRE_KEY "Software\\JavaSoft\\Java Runtime Environment" +#define NBEXEC_EXPORT extern "C" __declspec(dllexport) -#define RUN_NORMAL "-run_normal" -#define RUN_UPDATER "-run_updater" - -#define BAD_OPTION_MSG "Wrong option." - -// #define DEBUG 1 - -static char jdkhome[MAX_PATH]; -static char plathome[MAX_PATH]; -static char userdir[MAX_PATH]; - -static char clusters[MAX_PATH * 20]; - -static char *bootclass = NULL; - -static int runnormal = 0; -static int runupdater = 0; - -static char classpath[1024 * 16]; -static char classpathBefore[1024 * 16]; -static char classpathAfter[1024 * 16]; - -static char **options; -static int numOptions, maxOptions; - -static char *progArgv[1024]; -static int progArgc = 0; - -static void runClass(char *mainclass, bool deleteAUClustersFile, DWORD *retCode); - -static void fatal(const char *str); -static char *findJavaExeInDirectory(char *dir); -static int findJdkFromRegistry(const char* keyname, char jdkhome[]); - -static void addJdkJarsToClassPath(const char *jdkhome); -static void addLauncherJarsToClassPath(); - -static void addToClassPath(const char *pathprefix, const char *path); -static void addToClassPathIfExists(const char *pathprefix, const char *path); -static void addAllFilesToClassPath(const char *dir, const char *subdir, const char *pattern); - -static void parseArgs(int argc, char *argv[]); -static void addOption(char *str); - -static int fileExists(const char* path); - -static void normalizePath(char *userdir); -static bool runAutoUpdater(bool firstStart, const char * root); -static bool runAutoUpdaterOnClusters(bool firstStart); - -static int findProxiesFromRegistry(char **proxy, char **nonProxy, char **socksProxy); -static int findHttpProxyFromEnv(char **proxy, char **nonProxy); - -static char* processAUClustersList(char *userdir); -static int removeAUClustersListFile(char *userdir); - -int checkForNewUpdater(const char *basePath); -int createProcessNoVirt(const char *exePath, char *argv[], DWORD *retCode = 0); -double getPreciseTime(); -int createPath(const char *path); - -#define HELP_STRING \ -"Usage: launcher {options} arguments\n\ -\n\ -General options:\n\ - --help show this help\n\ - --nosplash do not show the splash screen\n\ - --jdkhome path to JDK\n\ - -J pass to JVM\n\ -\n\ - --cp:p prepend to classpath\n\ - --cp:a append to classpath\n\ -\n" - -int main(int argc, char *argv[]) { - for (int i = 0; i < argc; i++) - { - if (strcmp(argv[i], "-h") == 0 - || strcmp(argv[i], "-help") == 0 - || strcmp(argv[i], "--help") == 0 - || strcmp(argv[i], "/?") == 0) - { - printf(HELP_STRING); - return 0; - } - } - - char exepath[1024 * 4]; - char buf[1024 * 8], *pc; - - GetModuleFileName(0, buf, sizeof buf); - strcpy(exepath, buf); - -#ifdef DEBUG - printf("argc = %d\n", argc); - printf("exepath = %s\n", exepath); -#endif - - pc = strrchr(buf, '\\'); - if (pc != NULL) { // always holds - strlwr(pc + 1); - *pc = '\0'; // remove .exe filename - } - - pc = strrchr(buf, '\\'); - if (pc != NULL && 0 == stricmp("\\lib", pc)) - *pc = '\0'; - strcpy(plathome, buf); - strcpy(clusters, buf); - -#ifdef DEBUG - printf("plathome = %s\n", plathome); -#endif - - if (0 != findJdkFromRegistry(JDK_KEY, jdkhome)) - findJdkFromRegistry(JRE_KEY, jdkhome); - -#ifdef DEBUG - printf("jdkhome = %s\n", jdkhome); -#endif - - parseArgs(argc - 1, argv + 1); // skip progname - +NBEXEC_EXPORT int startPlatform(int argc, char *argv[]) { DWORD retCode = 0; - if (!runnormal && !runupdater) { - char **newargv = (char**) malloc((argc+8) * sizeof (char*)); - int i; - - if (userdir[0] == '\0') { - fatal("Need to specify userdir using command line option --userdir"); - exit(1); - } - - sprintf(buf, "\"%s\"", argv[0]); - newargv[0] = strdup(buf); - -#ifdef DEBUG - printf("newargv[0] = %s\n", newargv[0]); -#endif - - for (i = 1; i < argc; i++) { - sprintf(buf, "\"%s\"", argv[i]); - newargv[i+1] = strdup(buf); -#ifdef DEBUG - printf("newargv[%d] = %s\n", i+1, newargv[i+1]); -#endif - } - i++; - - newargv[i] = NULL; - - bool runUpdater = runAutoUpdaterOnClusters(true); - - if (runUpdater) { - newargv[1] = RUN_UPDATER; - _spawnv(_P_WAIT, exepath, newargv); - } - - AGAIN: - - // run IDE - - newargv[1] = RUN_NORMAL; - retCode = _spawnv(_P_WAIT, exepath, newargv); - - runUpdater = runAutoUpdaterOnClusters(false); - if (runUpdater) { - newargv[1] = RUN_UPDATER; - _spawnv(_P_WAIT, exepath, newargv); - - goto AGAIN; - } - } else if (runnormal) { - argc -= 2; - argv += 2; - if (bootclass != NULL) { - runClass(bootclass, TRUE, &retCode); - } - else { - runClass(IDE_MAIN_CLASS, TRUE, &retCode); - } - } else if (runupdater) { - argc -= 2; - argv += 2; - runClass(UPDATER_MAIN_CLASS, FALSE, &retCode); + if (!launcher.start(argv, argc, &retCode)) { + return -1; } return retCode; } - -bool runAutoUpdaterOnClusters(bool firstStart) { - bool runUpdater = false; - char *sClusters = processAUClustersList(userdir); - if (sClusters == NULL) { - sClusters = strdup(clusters); - } - char *pc; - - checkForNewUpdater(plathome); - runUpdater = runAutoUpdater(firstStart, plathome); - - pc = strtok(sClusters, ";"); - while (pc != NULL) { - checkForNewUpdater(pc); - runUpdater |= runAutoUpdater(firstStart, pc); - pc = strtok(NULL, ";"); - } - - checkForNewUpdater(userdir); - runUpdater |= runAutoUpdater(firstStart, userdir); - -#ifdef DEBUG - printf("runAutoUpdaterOnClusters returning %d (platform %s, clusters %s, userdir %s)\n", - runUpdater, plathome, sClusters, userdir); -#endif - free(sClusters); - return runUpdater; -} - -bool runAutoUpdater(bool firstStart, const char * root) { - WIN32_FIND_DATA ffd; - char tmp [MAX_PATH]; - - // The logic is following: - // if there is an NBM for installation then run updater - // unless it is not a first start and we asked to install later (on next start) - - // then also check if last run left list of modules to disable/uninstall and - // did not mark them to be deactivated later (on next start) - strcpy(tmp, root); - strcat(tmp, "\\update\\download\\*.nbm"); - HANDLE nbmFiles = FindFirstFile(tmp, &ffd); - - strcpy(tmp, root); - strcat(tmp, "\\update\\download\\install_later.xml"); - HANDLE laterFile = FindFirstFile(tmp, &ffd); - - FindClose(nbmFiles); - FindClose(laterFile); - - if (INVALID_HANDLE_VALUE != nbmFiles && (firstStart || INVALID_HANDLE_VALUE == laterFile)) - return true; - - strcpy(tmp, root); - strcat(tmp, "\\update\\deactivate\\deactivate_later.txt"); - laterFile = FindFirstFile(tmp, &ffd); - FindClose(laterFile); - if (firstStart || (INVALID_HANDLE_VALUE == laterFile)) { - strcpy(tmp, root); - strcat(tmp, "\\update\\deactivate\\to_disable.txt"); - laterFile = FindFirstFile(tmp, &ffd); - if (INVALID_HANDLE_VALUE != laterFile) { - FindClose(laterFile); - return true; - } - strcpy(tmp, root); - strcat(tmp, "\\update\\deactivate\\to_uninstall.txt"); - laterFile = FindFirstFile(tmp, &ffd); - if (INVALID_HANDLE_VALUE != laterFile) { - FindClose(laterFile); - return true; - } - } - - return false; -} - -void runClass(char *mainclass, bool deleteAUClustersFile, DWORD *retCode) { - char buf[10240]; - -#ifdef DEBUG - printf("Running class %s\n", mainclass); -#endif - if (jdkhome[0] == '\0') - fatal("JDK 5.0 or newer cannot be found on your machine."); - - strcat(strcpy(buf, "-Djdk.home="), jdkhome); - addOption(buf); - - strcat(strcpy(buf, "-Dnetbeans.home="), plathome); - addOption(buf); - - char *sAUclusters = processAUClustersList(userdir); - if (sAUclusters != NULL) { - strcat(strcpy(buf, "-Dnetbeans.dirs="), sAUclusters); - } - else { - strcat(strcpy(buf, "-Dnetbeans.dirs="), clusters); - } - addOption(buf); - if (deleteAUClustersFile) { - removeAUClustersListFile(userdir); - } - - if (userdir[0] != '\0') { - strcat(strcpy(buf, "-Dnetbeans.user="), userdir); - addOption(buf); - } - - if (classpathBefore[0] != '\0') - strcpy(classpath, classpathBefore); - else - classpath[0] = '\0'; - - addLauncherJarsToClassPath(); - addJdkJarsToClassPath(jdkhome); - - char *proxy = 0, *nonProxyHosts = 0; - char *socksProxy = 0; - if (0 == findHttpProxyFromEnv(&proxy, &nonProxyHosts)) { - sprintf(buf, "-Dnetbeans.system_http_proxy=%s", proxy); - addOption(buf); - sprintf(buf, "-Dnetbeans.system_http_non_proxy_hosts=%s", nonProxyHosts); - addOption(buf); - free(proxy); - free(nonProxyHosts); - } - else if (0 == findProxiesFromRegistry(&proxy, &nonProxyHosts, &socksProxy)) { - if (proxy) - { - sprintf(buf, "-Dnetbeans.system_http_proxy=%s", proxy); - addOption(buf); - free(proxy); - } - if (nonProxyHosts) - { - sprintf(buf, "-Dnetbeans.system_http_non_proxy_hosts=%s", nonProxyHosts); - addOption(buf); - free(nonProxyHosts); - } - if (socksProxy) - { - snprintf(buf, 10240, "-Dnetbeans.system_socks_proxy=%s", socksProxy); - addOption(buf); - free(socksProxy); - } - } - - // see BugTraq #5043070 - addOption("-Dsun.awt.keepWorkingSetOnMinimize=true"); - - // enabling heap dump on OOME - addOption("-XX:+HeapDumpOnOutOfMemoryError"); - snprintf(buf, 10240, "-XX:HeapDumpPath=%s\\var\\log\\heapdump.hprof", userdir); - addOption(buf); - - char *javapath = findJavaExeInDirectory(jdkhome); - if (javapath == NULL) { - sprintf(buf, "Cannot find java.exe.\nNeither %s%s nor %s%s exists.", - jdkhome, "\\jre\\bin\\java.exe", - jdkhome, "\\bin\\java.exe" - ); - fatal(buf); - } - - int argc = numOptions + 3 + progArgc + 1; - char **args = (char**) malloc(argc * sizeof(char*)); - char **p = args; - - sprintf(buf, "\"%s\"", javapath); - *p++ = strdup(buf); - - int i; - for (i = 0; i < numOptions; i++) { -#ifdef DEBUG - printf("runClass[%d] = %s\n", i, options[i]); -#endif - sprintf(buf, "\"%s\"", options[i]); - *p++ = strdup(buf); - } - - *p++ = "-cp"; - - if (classpathAfter[0] != '\0') { - if (classpath[strlen(classpath)] != ';') - strcat(classpath, ";"); - strcat(classpath, classpathAfter); - } - sprintf(buf, "\"%s\"", classpath); - *p++ = strdup(buf); - - *p++ = mainclass; - - for (i = 0; i < progArgc; i++) { - sprintf(buf, "\"%s\"", progArgv[i]); - *p++ = strdup(buf); - } - *p++ = NULL; - - // Prevents Windows from bringing up a "No floppy in drive A:" dialog. - // The error mode should be inherited by the java process - SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); - -#ifdef DEBUG - fflush(stdout); -#endif - //_spawnv(_P_WAIT, javapath, args); - double start = getPreciseTime(); - if (!createProcessNoVirt(javapath, args, retCode) && *retCode == 1 && (getPreciseTime() - start < 2)) - { - // workaround for 64-bit java - int i = 0; - bool optionClient = false; - while (args[i]) - { - if (strcmp(args[i], "-client") == 0 || strcmp(args[i], "\"-client\"") == 0) - { - optionClient = true; - int k = i; - while (args[k]) - { - args[k] = args[k+1]; - k++; - } - } - else - i++; - } - if (optionClient) - { - printf("Rerunnig without \"-client\" option...\n"); - createProcessNoVirt(javapath, args, retCode); - } - } -} - -////////// - -/* - * Returns string data for the specified registry value name, or - * NULL if not found. - */ -static char * GetStringValue(HKEY key, const char *name) -{ - DWORD type, size; - char *value = 0; - - if (RegQueryValueEx(key, name, 0, &type, 0, &size) == 0 && type == REG_SZ) { - value = (char*) malloc(size); - if (RegQueryValueEx(key, name, 0, 0, (unsigned char*)value, &size) != 0) { - free(value); - value = 0; - } - } - return value; -} - -// returns non zero if version is acceptable to run the application -// currently it means at least JDK 1.5 -static int isAcceptable( const char *version) { - if (version == NULL) - return 0; - - // should work for 1.4, 1.5, 1.5.0, 1.5.0_xy, 1.6, 1.6.0, 1.7 - return (strcmp(version, "1.5") >= 0)? 1: 0; -} - -/* Looks for jre\bin\java.exe or bin\java.exe in given directory - and return newly allocated char array pointing to this .exe file - or NULL -*/ -static char *findJavaExeInDirectory(char *dir) { - char *javapath = (char *)malloc(strlen(dir)+20); - WIN32_FIND_DATA ffd; - - strcat(strcpy(javapath, dir), "\\jre\\bin\\java.exe"); - HANDLE hFind = FindFirstFile(javapath, &ffd); - if (INVALID_HANDLE_VALUE == hFind) { - strcat(strcpy(javapath, dir), "\\bin\\java.exe"); - hFind = FindFirstFile(javapath, &ffd); - if (INVALID_HANDLE_VALUE == hFind) { - free(javapath); - return NULL; - } - FindClose(hFind); - } - FindClose(hFind); - return javapath; -} - -static int findJdkFromRegistry(const char* keyname, char jdkhome[]) -{ - HKEY hkey = NULL, subkey = NULL; - char *ver = NULL; - int rc = 1; - - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &hkey) == 0) { - ver = GetStringValue(hkey, "CurrentVersion"); - // try default Java - if (isAcceptable(ver)) { - if (RegOpenKeyEx(hkey, ver, 0, KEY_READ, &subkey) == 0) { - char *home = GetStringValue(subkey, "JavaHome"); - if (home != NULL) { - strcpy(jdkhome, home); - if (fileExists(home)) { -#ifdef DEBUG - printf("Found Java in registry (default, version=%s, path=%s)\n", ver, home); -#endif - rc = 0; - } - free(home); - } - if (subkey != NULL) - RegCloseKey(subkey); - } -#ifdef DEBUG - else { - printf("Failed to open key %s under %s, error %ld\n", ver, keyname, GetLastError()); - } -#endif - } - if (rc != 0) { - // try Java SE 6 - if (RegOpenKeyEx(hkey, "1.6", 0, KEY_READ, &subkey) == 0) { - char *home = GetStringValue(subkey, "JavaHome"); - if (home != NULL) { - strcpy(jdkhome, home); - if (fileExists(home)) { -#ifdef DEBUG - printf("Found Java in registry (1.6, path=%s)\n", home); -#endif - rc = 0; - } - free(home); - } - if (subkey != NULL) - RegCloseKey(subkey); - } - } - if (rc != 0) { - // try JDK 1.5 - if (RegOpenKeyEx(hkey, "1.5", 0, KEY_READ, &subkey) == 0) { - char *home = GetStringValue(subkey, "JavaHome"); - if (home != NULL) { - strcpy(jdkhome, home); - if (fileExists(home)) { -#ifdef DEBUG - printf("Found Java in registry (1.6, path=%s)\n", home); -#endif - rc = 0; - } - free(home); - } - if (subkey != NULL) - RegCloseKey(subkey); - } - } - } - - if (ver != NULL) - free(ver); - if (hkey != NULL) - RegCloseKey(hkey); - return rc; -} - -int findProxiesFromRegistry(char **proxy, char **nonProxy, char **socksProxy) -{ - HKEY hkey = NULL; - char *proxyServer = NULL; - char *proxyOverrides = NULL; - int rc = 1; - *proxy = NULL; *nonProxy = NULL; *socksProxy = NULL; - - if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet settings", 0, KEY_READ, &hkey) == 0) { - DWORD proxyEnable, size = sizeof proxyEnable; - - if (RegQueryValueEx(hkey, "ProxyEnable", 0, 0, (unsigned char*) &proxyEnable, &size) == 0) { - if (proxyEnable) { - proxyServer = GetStringValue(hkey, "ProxyServer"); - if (proxyServer == NULL) - goto quit; - - if (strstr(proxyServer, "=") == NULL) { - *proxy = strdup(proxyServer); - rc = 0; - } else { - char *pc = strstr(proxyServer, "socks="); - if (pc) - { - pc += strlen("socks="); - if (*pc != '\0' && *pc != ';') - { - char *end = strchr(pc, ';'); - if (end) - { - *socksProxy = (char *) malloc(end - pc + 1); - strncpy(*socksProxy, pc, end - pc); - } - else - *socksProxy = strdup(pc); - rc = 0; - } - } - pc = strstr(proxyServer, "http="); - if (pc != NULL) { - pc += strlen("http="); - char *qc = strstr(pc, ";"); - if (qc != NULL) - *qc = '\0'; - *proxy = strdup(pc); - rc = 0; - } - } - // ProxyOverride contains semicolon delimited list of host name prefixes - // to connect them directly w/o proxy - // optionally last entry is to bypass local addresses - // *acme.com also works there - proxyOverrides = GetStringValue(hkey, "ProxyOverride"); - if (proxyOverrides != NULL) - *nonProxy = strdup(proxyOverrides); - else - *nonProxy = strdup(""); - } - else { - *proxy = strdup("DIRECT"); - *nonProxy = strdup(""); - rc = 0; - } - } - } - - quit: - if (proxyServer != NULL) - free(proxyServer); - if (proxyOverrides != NULL) - free(proxyOverrides); - if (hkey != NULL) - RegCloseKey(hkey); - return rc; -} - -/* Reads value of http_proxy environment variable to use it as proxy setting - * Returns 0 if it exists and is successfully parsed, other value if there - * is some problem. - */ -int findHttpProxyFromEnv(char **proxy, char **nonProxy) -{ - char *proxyServer = NULL; - char *proxyOverrides = NULL; - int rc = 1; - *proxy = NULL; *nonProxy = NULL; - - char *envvar = getenv("http_proxy"); - if (envvar != NULL) { - // is it URL? - if (strncmp(envvar, "http://", strlen("http://")) == 0 - && envvar[strlen(envvar)-1] == '/' - && strlen(envvar) > strlen("http://")) { - // trim URL part to keep only 'host[:port]' - *proxy = strdup(envvar + strlen("http://")); - (*proxy)[strlen(*proxy)-1] = '\0'; - *nonProxy = strdup(""); - rc = 0; - } - } - return rc; -} - -void addToClassPath(const char *pathprefix, const char *path) { - char buf[1024]; - - strcpy(buf, pathprefix); - if (path != NULL) - strcat(strcat(buf, "\\"), path); - - if (classpath[0] != '\0') - strcat(classpath, ";"); - strcat(classpath, buf); -} - -void addToClassPathIfExists(const char *pathprefix, const char *path) { - char buf[1024]; - - strcpy(buf, pathprefix); - if (path != NULL) - strcat(strcat(buf, "\\"), path); - - if (fileExists(buf) != 0) - addToClassPath(pathprefix, path); -} - - -void addJdkJarsToClassPath(const char *jdkhome) -{ - addToClassPathIfExists(jdkhome, "lib\\dt.jar"); - addToClassPathIfExists(jdkhome, "lib\\tools.jar"); -} - -void addJarsToClassPathFrom(const char *dir) -{ - addAllFilesToClassPath(dir, "lib\\patches", "*.jar"); - addAllFilesToClassPath(dir, "lib\\patches", "*.zip"); - - addAllFilesToClassPath(dir, "lib", "*.jar"); - addAllFilesToClassPath(dir, "lib", "*.zip"); - - addAllFilesToClassPath(dir, "lib\\locale", "*.jar"); - addAllFilesToClassPath(dir, "lib\\locale", "*.zip"); -} - -void addLauncherJarsToClassPath() -{ - addJarsToClassPathFrom(userdir); - addJarsToClassPathFrom(plathome); - - if (runupdater) { - char userUpdater[MAX_PATH] = ""; - _snprintf(userUpdater, MAX_PATH, "%s\\modules\\ext\\updater.jar", userdir); - const char *baseUpdaterPath = plathome; - if (fileExists(userUpdater)) - baseUpdaterPath = userdir; - addToClassPath(baseUpdaterPath, "\\modules\\ext\\updater.jar"); - addAllFilesToClassPath(baseUpdaterPath, "\\modules\\ext\\locale", "updater_*.jar"); - } -} - -set addedToCP; - -void addAllFilesToClassPath(const char *dir, const char *subdir, const char *pattern) { - char path[1024]; - char pathPattern[1024]; - struct _finddata_t fileinfo; - long hFile; - snprintf(path, 1024, "%s\\%s", dir, subdir); - snprintf(pathPattern, 1024, "%s\\%s", path, pattern); - - if ((hFile = _findfirst(pathPattern, &fileinfo)) != -1L) { - do { - string name = subdir; - name += fileinfo.name; - if (addedToCP.insert(name).second) { - addToClassPath(path, fileinfo.name); - } - } while (0 == _findnext(hFile, &fileinfo)); - _findclose(hFile); - } -} - -void fatal(const char *str) -{ -//#ifdef WINMAIN - ::MessageBox(NULL, str, PROG_FULLNAME, MB_ICONSTOP | MB_OK); -//#else -// fprintf(stderr, "%s\n", str); -//#endif - exit(255); -} - -/* - * Adds a new VM option with the given given name and value. - * - * Doesn't modify the input string, creates its copy. - * - */ -void addOption(char *str) -{ - /* - * Expand options array if needed to accomodate at least one more - * VM option. - */ - if (numOptions >= maxOptions) { - if (options == 0) { - maxOptions = 4; - options = (char**) malloc(maxOptions * sizeof(char*)); - } else { - char** tmp; - maxOptions *= 2; - tmp = (char**)malloc(maxOptions * sizeof(char*)); - memcpy(tmp, options, numOptions * sizeof(char*)); - free(options); - options = tmp; - } - } - int len = strlen(str); - char *strOpt = (char *) malloc(len+1); - int k = 0; - for (int i = 0; i < len; i++) { - if (str[i] != '\"') - strOpt[k++] = str[i]; - } - strOpt[k] = '\0'; - options[numOptions++] = strOpt; -} - -void parseArgs(int argc, char *argv[]) { - char *arg; - - while (argc > 0 && (arg = *argv) != 0) { - argv++; - argc--; - -#ifdef DEBUG - printf("parseArgs - processing %s\n", arg); -#endif - - if (0 == strcmp("--userdir", arg)) { - if (argc > 0) { - arg = *argv; - argv++; - argc--; - if (arg != 0) { - strcpy(userdir, arg); - normalizePath(userdir); - } - } - else { - fatal(BAD_OPTION_MSG); - } - } else if (0 == strcmp("--clusters", arg)) { - if (argc > 0) { - arg = *argv; - argv++; - argc--; - if (arg != 0) { - strcpy(clusters, arg); - } - } - else { - fatal(BAD_OPTION_MSG); - } - } else if (0 == strcmp("--bootclass", arg)) { - if (argc > 0) { - arg = *argv; - argv++; - argc--; - if (arg != 0) { - bootclass = strdup(arg); - } - } - else { - fatal(BAD_OPTION_MSG); - } - } else if (0 == strcmp(RUN_NORMAL, arg)) { - runnormal = 1; - runupdater = 0; - } else if (0 == strcmp(RUN_UPDATER, arg)) { - runnormal = 0; - runupdater = 1; - } else if (0 == strcmp("--jdkhome", arg)) { - if (argc > 0) { - arg = *argv; - argv++; - argc--; - if (arg != 0) { - if (findJavaExeInDirectory(arg)) - strcpy(jdkhome, arg); - else { - argv[-1] = argv[-2] = ""; - char errMsg[1024] = ""; - sprintf(errMsg, "Cannot find java.exe in specified jdkhome.\nNeither %s%s nor %s%s exists.\nDo you want to try to use default version?", - arg, "\\jre\\bin\\java.exe", - arg, "\\bin\\java.exe" - ); - if (::MessageBox(NULL, errMsg, "Invalid jdkhome specified", MB_ICONQUESTION | MB_YESNO) == IDNO) - exit(255); - } - } - } - else { - fatal(BAD_OPTION_MSG); - } - } else if (0 == strcmp("-cp:p", arg) || 0 == strcmp("--cp:p", arg)) { - if (argc > 0) { - arg = *argv; - argv++; - argc--; - if (arg != 0) { - if (classpathBefore[0] != '\0' - && classpathBefore[strlen(classpathBefore)] != ';') - strcat(classpathBefore, ";"); - strcat(classpathBefore, arg); - } - } - else { - fatal(BAD_OPTION_MSG); - } - } else if (0 == strcmp("-cp", arg) || 0 == strcmp("-cp:a", arg) || 0 == strcmp("--cp", arg) || 0 == strcmp("--cp:a", arg)) { - if (argc > 0) { - arg = *argv; - argv++; - argc--; - if (arg != 0) { - if (classpathAfter[0] != '\0' - && classpathAfter[strlen(classpathAfter)] != ';') - strcat(classpathAfter, ";"); - strcat(classpathAfter, arg); - } - } - else { - fatal(BAD_OPTION_MSG); - } - } else if (0 == strncmp("-J", arg, 2)) { - addOption(arg + 2); - } else { - progArgv[progArgc++] = arg; - } - } -} - -void normalizePath(char *userdir) -{ - char tmp[MAX_PATH] = ""; - int i = 0; - while (userdir[i] && i < MAX_PATH - 1) - { - tmp[i] = userdir[i] == '/' ? '\\' : userdir[i]; - i++; - } - tmp[i] = '\0'; - _fullpath(userdir, tmp, MAX_PATH); -} - -int fileExists(const char* path) { - WIN32_FIND_DATA ffd; - HANDLE ffh; - - memset(&ffd, 0, sizeof ffd); - ffh = FindFirstFile(path, &ffd); - if (ffh != INVALID_HANDLE_VALUE) { - FindClose(ffh); - return 1; - } else { - return 0; - } -} - -/** Looks for ${userdir}\update\download\netbeans.dirs and reads - * list of clusters. - * @return newly allocated string with file content if file exists - * or NULL if it is not found - */ -char* processAUClustersList(char *userdir) { - if (userdir == NULL || userdir[0] == '\0') - return NULL; - char *pPath = (char*)malloc(strlen(userdir)+32); - if (pPath == NULL) fatal("Cannot allocate memory (processAUClustersList)."); - - strcpy(pPath, userdir); - strcat(pPath, "\\update\\download\\netbeans.dirs"); - -#ifdef DEBUG - if (fileExists(pPath)) printf("Found file with new clusters %s\n", pPath); -#endif - FILE* fin = fopen(pPath, "r"); - if (fin == NULL) - return 0; - - long len = _filelength(_fileno(fin)); - char *pClusters = (char*)malloc(len+1); - if (fgets(pClusters, len+1, fin)) { - while(strlen(pClusters) > 1 && - (pClusters[strlen(pClusters) - 1] == '\r' || pClusters[strlen(pClusters) - 1] == '\n')) { - pClusters[strlen(pClusters) - 1] = '\0'; - } - fclose(fin); -#ifdef DEBUG - printf("Overriden clusters %s\n", pClusters); -#endif - return pClusters; - } - fclose(fin); - return NULL; -} - -/** Deletes ${userdir}\update\download\netbeans.dirs if it exists. - */ -int removeAUClustersListFile(char* userdir) { - if (userdir == NULL || userdir[0] == '\0') - return 0; - char *pPath = (char*)malloc(strlen(userdir)+32); - if (pPath == NULL) fatal("Cannot allocate memory (removeAUClustersListFile)."); - - strcpy(pPath, userdir); - strcat(pPath, "\\update\\download\\netbeans.dirs"); - if (remove(pPath) != 0) { - if (errno != ENOENT) return -1; // an error while deleting - } - return 0; -} - -// check if new updater exists, if exists install it (replace old one) and remove ...\new_updater directory -int checkForNewUpdater(const char *basePath) -{ - char srcPath[MAX_PATH] = ""; - _snprintf(srcPath, MAX_PATH, "%s\\update\\new_updater\\updater.jar", basePath); - WIN32_FIND_DATA fd = {0}; - HANDLE hFind = FindFirstFile(srcPath, &fd); - if (hFind != INVALID_HANDLE_VALUE) - { - FindClose(hFind); - char destPath[MAX_PATH] = ""; - _snprintf(destPath, MAX_PATH, "%s\\modules\\ext\\updater.jar", basePath); - createPath(destPath); - if (!MoveFileEx(srcPath, destPath, MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) - return -1; - _snprintf(srcPath, MAX_PATH, "%s\\update\\new_updater", basePath); - RemoveDirectory(srcPath); - } - return 0; -} - -int createPath(const char *path) { - char dir[MAX_PATH] = ""; - const char *sep = strchr(path, '\\'); - while (sep) { - strncpy(dir, path, sep - path); - CreateDirectory(dir, 0); - sep = strchr(sep + 1, '\\'); - } - return 0; -} - -// creates process and disable virtualization (Win VISTA fix) -int createProcessNoVirt(const char *exePath, char *argv[], DWORD *retCode) -{ - const int maxCmdLineLen = 32*1024; - int filled = 0; - char cmdLine[maxCmdLineLen] = ""; - int i = 0; - while (argv[i]) - { - int len = (int) strlen(argv[i]); - if (len + filled + 2 > maxCmdLineLen) - { - char err[1024] = ""; - _snprintf(err, 1024, "Command line arguments for \"%s\" exceeds 32K characters!", exePath); - MessageBox(NULL, err, "Error", MB_OK | MB_ICONSTOP); - return -1; - } - memcpy(cmdLine + filled, argv[i], len); - filled += len; - cmdLine[filled++] = ' '; - i++; - } - cmdLine[filled++] = '\0'; - - STARTUPINFO si = {0}; - si.cb = sizeof(STARTUPINFO); - PROCESS_INFORMATION pi = {0}; - - if (!CreateProcess(NULL, cmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) - { - MessageBox(NULL, "Failed to create process.", "Error", MB_OK | MB_ICONSTOP); - return -1; - } - OSVERSIONINFO osvi = {0}; - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - if (GetVersionEx(&osvi) && osvi.dwMajorVersion == 6) // check it is Win VISTA - { - HANDLE hToken; - if (OpenProcessToken(pi.hProcess, TOKEN_ALL_ACCESS, &hToken)) - { - DWORD tokenInfoVal = 0; - if (!SetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) 24, &tokenInfoVal, sizeof(DWORD))) - { - // invalid token information class (24) is OK, it means there is no folder virtualization on current system - if (GetLastError() != ERROR_INVALID_PARAMETER) - MessageBox(NULL, "Failed to set token information.", "Warning", MB_OK | MB_ICONWARNING); - } - CloseHandle(hToken); - } - else - MessageBox(NULL, "Failed to open process token.", "Warning", MB_OK | MB_ICONWARNING); - } - ResumeThread(pi.hThread); - WaitForSingleObject(pi.hProcess, INFINITE); - if (retCode) - GetExitCodeProcess(pi.hProcess, retCode); - CloseHandle(pi.hProcess); - CloseHandle(pi.hThread); - return 0; -} - - -double getPreciseTime() -{ - static LARGE_INTEGER perfFrequency = {0}; - LARGE_INTEGER currentCount; - if (perfFrequency.QuadPart == 0) - QueryPerformanceFrequency(&perfFrequency); - QueryPerformanceCounter(¤tCount); - return currentCount.QuadPart / (double) perfFrequency.QuadPart; -} diff --git a/o.n.bootstrap/launcher/windows/nbexec.dll b/o.n.bootstrap/launcher/windows/nbexec.dll new file mode 100644 index 0000000000000000000000000000000000000000..2742ebd7f56e8d28841954622bc12b0939486f27 GIT binary patch literal 191488 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

-KNt$DrvvwJt< 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 diff --git a/o.n.bootstrap/launcher/windows/nbexec.exe b/o.n.bootstrap/launcher/windows/nbexec.exe index fd7e1979f9eacc75ad50aca31b1a0ea999c3a6da..3164d48d094bed972e223283f30ff40b210a10ce GIT binary patch literal 79360 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

h^Zj7s1j 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 diff --git a/o.n.bootstrap/launcher/windows/nbexecexe.cpp b/o.n.bootstrap/launcher/windows/nbexecexe.cpp new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/nbexecexe.cpp @@ -0,0 +1,51 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#include +#include "nbexecloader.h" + +int main(int argc, char *argv[]) { + checkLoggingArg(argc, argv, true); + NBExecLoader loader; + return loader.start("nbexec.dll", argc - 1, argv + 1); +} diff --git a/o.n.bootstrap/launcher/windows/nbexecloader.h b/o.n.bootstrap/launcher/windows/nbexecloader.h new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/nbexecloader.h @@ -0,0 +1,48 @@ +/* + * File: nbexecloader.h + * Author: Holy + * + * Created on 19. prosinec 2008, 15:14 + */ + +#ifndef _NBEXECLOADER_H +#define _NBEXECLOADER_H + +#include "utilsfuncs.h" + +class NBExecLoader { + typedef int (*StartPlatform)(int argc, char *argv[]); + +public: + NBExecLoader() + : hLib(0) { + } + ~NBExecLoader() { + if (hLib) { + FreeLibrary(hLib); + } + } + int start(const char *path, int argc, char *argv[]) { + if (!hLib) { + hLib = LoadLibrary(path); + if (!hLib) { + logErr(true, true, "Cannot load \"%s\".", path); + return -1; + } + } + + StartPlatform startPlatform = (StartPlatform) GetProcAddress(hLib, "startPlatform"); + if (!startPlatform) { + logErr(true, true, "Cannot start platform, failed to find startPlatform() in %s", path); + return -1; + } + logMsg("Starting platform...\n"); + return startPlatform(argc, argv); + } + +private: + HMODULE hLib; +}; + +#endif /* _NBEXECLOADER_H */ + diff --git a/o.n.bootstrap/launcher/windows/nbproject/Makefile-Default.mk b/o.n.bootstrap/launcher/windows/nbproject/Makefile-Default.mk deleted file mode 100644 --- a/o.n.bootstrap/launcher/windows/nbproject/Makefile-Default.mk +++ /dev/null @@ -1,54 +0,0 @@ -# -# Gererated Makefile - do not edit! -# -# Edit the Makefile in the project folder instead (../Makefile). Each target -# has a -pre and a -post target defined where you can add customized code. -# -# This makefile implements configuration specific macros and targets. - - -# Environment -MKDIR=mkdir -CP=cp -CCADMIN=CCadmin -RANLIB=ranlib -CC=gcc.exe -CCC=g++.exe -CXX=g++.exe -FC= - -# Include project Makefile -include Makefile_windows.mk - -# Object Directory -OBJECTDIR=build/Default/Cygwin-Windows - -# Object Files -OBJECTFILES= - -# C Compiler Flags -CFLAGS= - -# CC Compiler Flags -CCFLAGS= -CXXFLAGS= - -# Fortran Compiler Flags -FFLAGS= - -# Link Libraries and Options -LDLIBSOPTIONS= - -# Build Targets -.build-conf: ${BUILD_SUBPROJECTS} - cd . && make -f Makefile testinst - -# Subprojects -.build-subprojects: - -# Clean Targets -.clean-conf: - cd . && make -f Makefile distclean - -# Subprojects -.clean-subprojects: diff --git a/o.n.bootstrap/launcher/windows/nbproject/Makefile-impl.mk b/o.n.bootstrap/launcher/windows/nbproject/Makefile-impl.mk --- a/o.n.bootstrap/launcher/windows/nbproject/Makefile-impl.mk +++ b/o.n.bootstrap/launcher/windows/nbproject/Makefile-impl.mk @@ -27,27 +27,27 @@ PROJECTNAME=windows # Active Configuration -DEFAULTCONF=Default +DEFAULTCONF=nbexec CONF=${DEFAULTCONF} # All Configurations -ALLCONFS=Default +ALLCONFS=nbexec # build -.build-impl: .validate-impl +.build-impl: .build-pre .validate-impl .depcheck-impl @#echo "=> Running $@... Configuration=$(CONF)" ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf # clean -.clean-impl: .validate-impl +.clean-impl: .clean-pre .validate-impl .depcheck-impl @#echo "=> Running $@... Configuration=$(CONF)" ${MAKE} -f nbproject/Makefile-${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .clean-conf # clobber -.clobber-impl: +.clobber-impl: .clobber-pre .depcheck-impl @#echo "=> Running $@..." for CONF in ${ALLCONFS}; \ do \ @@ -55,13 +55,25 @@ done # all -.all-impl: +.all-impl: .all-pre .depcheck-impl @#echo "=> Running $@..." for CONF in ${ALLCONFS}; \ do \ ${MAKE} -f nbproject/Makefile-$${CONF}.mk SUBPROJECTS=${SUBPROJECTS} .build-conf; \ done +# dependency checking support +.depcheck-impl: + @echo "# This code depends on make tool being used" >.dep.inc + @if [ -n "${MAKE_VERSION}" ]; then \ + echo "DEPFILES=\$$(wildcard \$$(addsuffix .d, \$${OBJECTFILES}))" >>.dep.inc; \ + echo "ifneq (\$${DEPFILES},)" >>.dep.inc; \ + echo "include \$${DEPFILES}" >>.dep.inc; \ + echo "endif" >>.dep.inc; \ + else \ + echo ".KEEP_STATE:" >>.dep.inc; \ + echo ".KEEP_STATE_FILE:.make.state.\$${CONF}" >>.dep.inc; \ + fi # configuration validation .validate-impl: @@ -80,7 +92,7 @@ # help -.help-impl: +.help-impl: .help-pre @echo "This makefile supports the following configurations:" @echo " ${ALLCONFS}" @echo "" @@ -108,6 +120,4 @@ @echo " also build subprojects." @echo "Target 'help' prints this message." @echo "" - @echo "The active configuration (${ACTIVECONF}) is being used if the configuration is not specified." - @echo "" diff --git a/o.n.bootstrap/launcher/windows/nbproject/Makefile-nbexec.mk b/o.n.bootstrap/launcher/windows/nbproject/Makefile-nbexec.mk new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/nbproject/Makefile-nbexec.mk @@ -0,0 +1,100 @@ +# +# Generated Makefile - do not edit! +# +# Edit the Makefile in the project folder instead (../Makefile). Each target +# has a -pre and a -post target defined where you can add customized code. +# +# This makefile implements configuration specific macros and targets. + + +# Environment +MKDIR=mkdir +CP=cp +CCADMIN=CCadmin +RANLIB=ranlib +CC=gcc.exe +CCC=g++.exe +CXX=g++.exe +FC= +AS= + +# Macros +PLATFORM=Cygwin-Windows + +# Include project Makefile +include Makefile + +# Object Directory +OBJECTDIR=build/nbexec/${PLATFORM} + +# Object Files +OBJECTFILES= \ + ${OBJECTDIR}/jvmlauncher.o \ + ${OBJECTDIR}/platformlauncher.o \ + ${OBJECTDIR}/utilsfuncs.o \ + ${OBJECTDIR}/nbexec.o \ + ${OBJECTDIR}/nbexecexe.o + +# C Compiler Flags +CFLAGS=-m32 + +# CC Compiler Flags +CCFLAGS=-m32 -s -mno-cygwin +CXXFLAGS=-m32 -s -mno-cygwin + +# Fortran Compiler Flags +FFLAGS= + +# Assembler Flags +ASFLAGS= + +# Link Libraries and Options +LDLIBSOPTIONS= + +# Build Targets +.build-conf: ${BUILD_SUBPROJECTS} + ${MAKE} -f nbproject/Makefile-nbexec.mk nbexec.dll + +nbexec.dll: ${OBJECTFILES} + ${LINK.cc} -mno-cygwin -shared -o nbexec.dll -fPIC ${OBJECTFILES} ${LDLIBSOPTIONS} + +${OBJECTDIR}/jvmlauncher.o: jvmlauncher.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -s -I/cygdrive/c/cygwin/usr/include/mingw -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include/win32 -fPIC -MMD -MP -MF $@.d -o ${OBJECTDIR}/jvmlauncher.o jvmlauncher.cpp + +${OBJECTDIR}/platformlauncher.o: platformlauncher.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -s -I/cygdrive/c/cygwin/usr/include/mingw -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include/win32 -fPIC -MMD -MP -MF $@.d -o ${OBJECTDIR}/platformlauncher.o platformlauncher.cpp + +${OBJECTDIR}/utilsfuncs.o: utilsfuncs.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -s -I/cygdrive/c/cygwin/usr/include/mingw -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include/win32 -fPIC -MMD -MP -MF $@.d -o ${OBJECTDIR}/utilsfuncs.o utilsfuncs.cpp + +${OBJECTDIR}/nbexec.o: nbexec.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -s -I/cygdrive/c/cygwin/usr/include/mingw -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include/win32 -fPIC -MMD -MP -MF $@.d -o ${OBJECTDIR}/nbexec.o nbexec.cpp + +${OBJECTDIR}/nbexecexe.o: nbexecexe.cpp + ${MKDIR} -p ${OBJECTDIR} + ${RM} $@.d + $(COMPILE.cc) -O2 -Wall -s -I/cygdrive/c/cygwin/usr/include/mingw -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include -I/cygdrive/C/Program\ Files/Java/jdk1.6.0_10/include/win32 -fPIC -MMD -MP -MF $@.d -o ${OBJECTDIR}/nbexecexe.o nbexecexe.cpp + +# Subprojects +.build-subprojects: + +# Clean Targets +.clean-conf: + ${RM} -r build/nbexec + ${RM} nbexec.dll + +# Subprojects +.clean-subprojects: + +# Enable dependency checking +.dep.inc: .depcheck-impl + +include .dep.inc diff --git a/o.n.bootstrap/launcher/windows/nbproject/Package-nbexec.bash b/o.n.bootstrap/launcher/windows/nbproject/Package-nbexec.bash new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/nbproject/Package-nbexec.bash @@ -0,0 +1,72 @@ +#!/bin/bash -x + +# +# Generated - do not edit! +# + +# Macros +TOP=`pwd` +PLATFORM=Cygwin-Windows +TMPDIR=build/nbexec/${PLATFORM}/tmp-packaging +TMPDIRNAME=tmp-packaging +OUTPUT_PATH=nbexec.dll +OUTPUT_BASENAME=nbexec.dll +PACKAGE_TOP_DIR=libwindows.dll/ + +# Functions +function checkReturnCode +{ + rc=$? + if [ $rc != 0 ] + then + exit $rc + fi +} +function makeDirectory +# $1 directory path +# $2 permission (optional) +{ + mkdir -p "$1" + checkReturnCode + if [ "$2" != "" ] + then + chmod $2 "$1" + checkReturnCode + fi +} +function copyFileToTmpDir +# $1 from-file path +# $2 to-file path +# $3 permission +{ + cp "$1" "$2" + checkReturnCode + if [ "$3" != "" ] + then + chmod $3 "$2" + checkReturnCode + fi +} + +# Setup +cd "${TOP}" +mkdir -p dist/nbexec/${PLATFORM}/package +rm -rf ${TMPDIR} +mkdir -p ${TMPDIR} + +# Copy files and create directories and links +cd "${TOP}" +makeDirectory ${TMPDIR}/libwindows.dll/lib +copyFileToTmpDir "${OUTPUT_PATH}" "${TMPDIR}/${PACKAGE_TOP_DIR}lib/${OUTPUT_BASENAME}" 0644 + + +# Generate tar file +cd "${TOP}" +rm -f dist/nbexec/${PLATFORM}/package/libwindows.dll.tar +cd ${TMPDIR} +tar -vcf ../../../../dist/nbexec/${PLATFORM}/package/libwindows.dll.tar * +checkReturnCode + +# Cleanup +cd "${TOP}" +rm -rf ${TMPDIR} diff --git a/o.n.bootstrap/launcher/windows/nbproject/configurations.xml b/o.n.bootstrap/launcher/windows/nbproject/configurations.xml --- a/o.n.bootstrap/launcher/windows/nbproject/configurations.xml +++ b/o.n.bootstrap/launcher/windows/nbproject/configurations.xml @@ -1,40 +1,96 @@ - + + + argnames.h + jvmlauncher.h + platformlauncher.h + utilsfuncs.h + + + + + jvmlauncher.cpp + nbexec.cpp + nbexecexe.cpp + nbexecloader.h + platformlauncher.cpp + utilsfuncs.cpp + - Makefile_windows.mk + Makefile - Makefile - nbexec.cpp - Makefile_windows.mk + Makefile - + - Cygwin - true - true - false + localhost + Cygwin|Cygwin 3 - - - . - make -f Makefile testinst - make -f Makefile distclean - nbexec.exe - - - - - + + + 5 + 1 + 2 + + + 5 + true + 1 + + c:/cygwin/usr/include/mingw + C:/Program Files/Java/jdk1.6.0_10/include + C:/Program Files/Java/jdk1.6.0_10/include/win32 + + -s -mno-cygwin + 2 + + + nbexec.dll + + + + + + 3 + + + 1 + + 3 1 + + 1 + + + 3 + + + 1 + + + 3 + + + 1 + + + 3 + diff --git a/o.n.bootstrap/launcher/windows/nbproject/project.xml b/o.n.bootstrap/launcher/windows/nbproject/project.xml --- a/o.n.bootstrap/launcher/windows/nbproject/project.xml +++ b/o.n.bootstrap/launcher/windows/nbproject/project.xml @@ -3,8 +3,12 @@ org.netbeans.modules.cnd.makeproject - windows + Platform Launcher Win 0 + + cpp + h + UTF-8 diff --git a/o.n.bootstrap/launcher/windows/platformlauncher.cpp b/o.n.bootstrap/launcher/windows/platformlauncher.cpp new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/platformlauncher.cpp @@ -0,0 +1,659 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#include "utilsfuncs.h" +#include "platformlauncher.h" +#include "argnames.h" + +using namespace std; + +const char *PlatformLauncher::HELP_MSG = +"\nUsage: launcher {options} arguments\n\ +\n\ +General options:\n\ + --help show this help\n\ + --nosplash do not show the splash screen\n\ + --jdkhome path to JDK\n\ + -J pass to JVM\n\ +\n\ + --cp:p prepend to classpath\n\ + --cp:a append to classpath\n\ +\n\ + --javaprocess run java in separate process\n\ + --trace path for launcher log (for trouble shooting)\n\ +\n"; + +const char *PlatformLauncher::REQ_JAVA_VERSION = "1.5"; + +const char *PlatformLauncher::OPT_JDK_HOME = "-Djdk.home="; +const char *PlatformLauncher::OPT_NB_PLATFORM_HOME = "-Dnetbeans.home="; +const char *PlatformLauncher::OPT_NB_CLUSTERS = "-Dnetbeans.dirs="; +const char *PlatformLauncher::OPT_NB_USERDIR = "-Dnetbeans.user="; +const char *PlatformLauncher::OPT_HTTP_PROXY = "-Dnetbeans.system_http_proxy="; +const char *PlatformLauncher::OPT_HTTP_NONPROXY = "-Dnetbeans.system_http_non_proxy_hosts="; +const char *PlatformLauncher::OPT_SOCKS_PROXY = "-Dnetbeans.system_socks_proxy="; +const char *PlatformLauncher::OPT_HEAP_DUMP = "-XX:+HeapDumpOnOutOfMemoryError"; +const char *PlatformLauncher::OPT_HEAP_DUMP_PATH = "-XX:HeapDumpPath="; +const char *PlatformLauncher::OPT_KEEP_WORKING_SET_ON_MINIMIZE = "-Dsun.awt.keepWorkingSetOnMinimize=true"; +const char *PlatformLauncher::OPT_CLASS_PATH = "-Djava.class.path="; + +const char *PlatformLauncher::REG_PROXY_KEY = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet settings"; +const char *PlatformLauncher::REG_PROXY_ENABLED_NAME = "ProxyEnable"; +const char *PlatformLauncher::REG_PROXY_SERVER_NAME = "ProxyServer"; +const char *PlatformLauncher::REG_PROXY_OVERRIDE_NAME = "ProxyOverride"; +const char *PlatformLauncher::PROXY_DIRECT = "DIRECT"; +const char *PlatformLauncher::HEAP_DUMP_PATH = "\\var\\log\\heapdump.hprof"; + +const char *PlatformLauncher::UPDATER_MAIN_CLASS = "org/netbeans/updater/UpdaterFrame"; +const char *PlatformLauncher::IDE_MAIN_CLASS = "org/netbeans/Main"; + +PlatformLauncher::PlatformLauncher() + : separateProcess(false) { +} + +PlatformLauncher::PlatformLauncher(const PlatformLauncher& orig) { +} + +PlatformLauncher::~PlatformLauncher() { +} + +bool PlatformLauncher::start(char* argv[], int argc, DWORD *retCode) { + if (!checkLoggingArg(argc, argv, false) || !initPlatformDir() || !parseArgs(argc, argv)) { + return false; + } + + if (jdkhome.empty()) { + if (!jvmLauncher.initialize(REQ_JAVA_VERSION)) { + logErr(false, true, "Cannot find Java %s or higher.", REQ_JAVA_VERSION); + return false; + } + } + jvmLauncher.getJavaPath(jdkhome); + + prepareOptions(); + + if (nextAction.empty()) { + if (shouldAutoUpdateClusters(true)) { + // run updater + if (!run(true, retCode)) { + return false; + } + } + + while (true) { + // run app + if (!run(false, retCode)) { + return false; + } + + if (shouldAutoUpdateClusters(false)) { + // run updater + if (!run(true, retCode)) { + return false; + } + } else { + break; + } + } + } else { + if (nextAction == ARG_NAME_LA_START_APP) { + return run(false, retCode); + } else if (nextAction == ARG_NAME_LA_START_AU) { + return run(true, retCode); + } else { + logErr(false, true, "We should not get here."); + return false; + } + } + + return true; +} + +bool PlatformLauncher::run(bool updater, DWORD *retCode) { + constructClassPath(updater); + const char *mainClass; + if (updater) { + mainClass = UPDATER_MAIN_CLASS; + nextAction = ARG_NAME_LA_START_APP; + } else { + mainClass = bootclass.empty() ? IDE_MAIN_CLASS : bootclass.c_str(); + nextAction = ARG_NAME_LA_START_AU; + } + + string option = OPT_CLASS_PATH; + option += classPath; + javaOptions.push_back(option); + bool rc = jvmLauncher.start(mainClass, progArgs, javaOptions, separateProcess, retCode); + javaOptions.pop_back(); + return rc; +} + + + +bool PlatformLauncher::initPlatformDir() { + char path[MAX_PATH] = ""; + getCurrentModulePath(path, MAX_PATH); + logMsg("Module: %s", path); + char *bslash = strrchr(path, '\\'); + if (!bslash) { + return false; + } + *bslash = '\0'; + bslash = strrchr(path, '\\'); + if (!bslash) { + return false; + } + *bslash = '\0'; + clusters = platformDir = path; + logMsg("Platform dir: %s", platformDir.c_str()); + return true; +} + +bool PlatformLauncher::parseArgs(int argc, char *argv[]) { +#define CHECK_ARG \ + if (i+1 == argc) {\ + logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]);\ + return false;\ + } + + logMsg("Parsing arguments:"); + for (int i = 0; i < argc; i++) { + logMsg("\t%s", argv[i]); + } + + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_SEPAR_PROC, argv[i]) == 0) { + separateProcess = true; + logMsg("Run Java in separater process"); + } else if (strcmp(ARG_NAME_LAUNCHER_LOG, argv[i]) == 0) { + CHECK_ARG; + i++; + } else if (strcmp(ARG_NAME_LA_START_APP, argv[i]) == 0 + || strcmp(ARG_NAME_LA_START_AU, argv[i]) == 0) { + nextAction = argv[i++]; + logMsg("Next launcher action: %s", nextAction.c_str()); + } else if (strcmp(ARG_NAME_USER_DIR, argv[i]) == 0) { + CHECK_ARG; + char tmp[MAX_PATH + 1] = {0}; + strncpy(tmp, argv[++i], MAX_PATH); + if (!normalizePath(tmp)) { + logErr(false, true, "User directory path \"%s\" is not valid.", argv[i]); + return false; + } + userDir = tmp; + logMsg("User dir: %s", userDir.c_str()); + } else if (strcmp(ARG_NAME_CLUSTERS, argv[i]) == 0) { + CHECK_ARG; + clusters = argv[++i]; + } else if (strcmp(ARG_NAME_BOOTCLASS, argv[i]) == 0) { + CHECK_ARG; + bootclass = argv[++i]; + } else if (strcmp(ARG_NAME_JDKHOME, argv[i]) == 0) { + CHECK_ARG; + jdkhome = argv[++i]; + if (!jvmLauncher.initialize(jdkhome.c_str())) { + logMsg("Cannot locate java installation in specified jdkhome: %s", jdkhome.c_str()); + string errMsg = "Cannot locate java installation in specified jdkhome:\n"; + errMsg += jdkhome; + errMsg += "\nDo you want to try to use default version?"; + jdkhome = ""; + if (::MessageBox(NULL, errMsg.c_str(), "Invalid jdkhome specified", MB_ICONQUESTION | MB_YESNO) == IDNO) { + return false; + } + } + } else if (strcmp(ARG_NAME_CP_PREPEND, argv[i]) == 0 + || strcmp(ARG_NAME_CP_PREPEND + 1, argv[i]) == 0) { + CHECK_ARG; + cpBefore += argv[++i]; + } else if (strcmp(ARG_NAME_CP_APPEND, argv[i]) == 0 + || strcmp(ARG_NAME_CP_APPEND + 1, argv[i]) == 0 + || strncmp(ARG_NAME_CP_APPEND + 1, argv[i], 3) == 0 + || strncmp(ARG_NAME_CP_APPEND, argv[i], 4) == 0) { + CHECK_ARG; + cpAfter += argv[++i]; + } else if (strncmp("-J", argv[i], 2) == 0) { + javaOptions.push_back(argv[i] + 2); + } else { + if (strcmp(argv[i], "-h") == 0 + || strcmp(argv[i], "-help") == 0 + || strcmp(argv[i], "--help") == 0 + || strcmp(argv[i], "/?") == 0) { + FILE *console = fopen("CON", "a"); + if (console) { + fprintf(console, "%s", HELP_MSG); + fclose(console); + } + } + progArgs.push_back(argv[i]); + } + } + return true; +} + +bool PlatformLauncher::processAutoUpdateCL() { + auClusters = ""; + logMsg("processAutoUpdateCL()..."); + if (userDir.empty()) { + logMsg("\tuserdir empty, quiting"); + return false; + } + string listPath = userDir; + listPath += "\\update\\download\\netbeans.dirs"; + + WIN32_FIND_DATA fd = {0}; + HANDLE hFind = 0; + hFind = FindFirstFile(listPath.c_str(), &fd); + if (hFind == INVALID_HANDLE_VALUE) { + logMsg("File \"%s\" does not exist", listPath.c_str()); + return false; + } + FindClose(hFind); + + FILE *file = fopen(listPath.c_str(), "r"); + if (!file) { + logErr(true, false, "Cannot open file %s", listPath.c_str()); + return false; + } + + int len = fd.nFileSizeLow + 1; + char *str = new char[len]; + if (!fgets(str, len, file)) { + fclose(file); + delete[] str; + logErr(true, false, "Cannot read from file %s", listPath.c_str()); + return false; + } + len = strlen(str) - 1; + if (str[len] == '\n') { + str[len] = '\0'; + } + + auClusters = str; + fclose(file); + delete[] str; + return true; +} + +// check if new updater exists, if exists install it (replace old one) and remove ...\new_updater directory +bool PlatformLauncher::checkForNewUpdater(const char *basePath) { + logMsg("checkForNewUpdater() at %s", basePath); + string srcPath = basePath; + srcPath += "\\update\\new_updater\\updater.jar"; + WIN32_FIND_DATA fd = {0}; + HANDLE hFind = FindFirstFile(srcPath.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("New updater found: %s", srcPath.c_str()); + FindClose(hFind); + string destPath = basePath; + destPath += "\\modules\\ext\\updater.jar"; + createPath(destPath.c_str()); + + if (!MoveFileEx(srcPath.c_str(), destPath.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH)) { + logErr(true, false, "Failed to move \"%s\" to \"%s\"", srcPath.c_str(), destPath.c_str()); + return false; + } + + srcPath.erase(srcPath.rfind('\\')); + logMsg("Removing directory \"%s\"", srcPath.c_str()); + if (!RemoveDirectory(srcPath.c_str())) { + logErr(true, false, "Failed to remove directory \"%s\"", srcPath.c_str()); + } + } else { + logMsg("No new updater at %s", srcPath.c_str()); + } + return true; +} + +bool PlatformLauncher::shouldAutoUpdate(bool firstStart, const char *basePath) { + // The logic is following: + // if there is an NBM for installation then run updater + // unless it is not a first start and we asked to install later (on next start) + + // then also check if last run left list of modules to disable/uninstall and + // did not mark them to be deactivated later (on next start) + string path = basePath; + path += "\\update\\download\\*.nbm"; + logMsg("Checking for updates: %s", path.c_str()); + WIN32_FIND_DATA fd; + HANDLE hFindNbms = FindFirstFile(path.c_str(), &fd); + if (hFindNbms != INVALID_HANDLE_VALUE) { + logMsg("Some updates found."); + FindClose(hFindNbms); + } + + path = basePath; + path += "\\update\\download\\install_later.xml"; + HANDLE hFind = FindFirstFile(path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("install_later.xml found: %s", path.c_str()); + FindClose(hFind); + } + + if (hFindNbms != INVALID_HANDLE_VALUE && (firstStart || hFind == INVALID_HANDLE_VALUE)) { + return true; + } + + path = basePath; + path += "\\update\\deactivate\\deactivate_later.txt"; + hFind = FindFirstFile(path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("deactivate_later.txt found: %s", path.c_str()); + FindClose(hFind); + } + + if (firstStart || hFind == INVALID_HANDLE_VALUE) { + path = basePath; + path += "\\update\\deactivate\\to_disable.txt"; + hFind = FindFirstFile(path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("to_disable.txt found: %s", path.c_str()); + FindClose(hFind); + return true; + } + + path = basePath; + path += "\\update\\deactivate\\to_uninstall.txt"; + hFind = FindFirstFile(path.c_str(), &fd); + if (hFind != INVALID_HANDLE_VALUE) { + logMsg("to_uninstall.txt found: %s", path.c_str()); + FindClose(hFind); + return true; + } + } + + return false; +} + +bool PlatformLauncher::shouldAutoUpdateClusters(bool firstStart) { + bool runUpdater = false; + string cl = processAutoUpdateCL() ? auClusters : clusters; + checkForNewUpdater(platformDir.c_str()); + runUpdater = shouldAutoUpdate(firstStart, platformDir.c_str()); + + const char delim = ';'; + string::size_type start = cl.find_first_not_of(delim, 0); + string::size_type end = cl.find_first_of(delim, start); + while (string::npos != end || string::npos != start) { + string cluster = cl.substr(start, end - start); + checkForNewUpdater(cluster.c_str()); + if (!runUpdater) { + runUpdater = shouldAutoUpdate(firstStart, cluster.c_str()); + } + start = cl.find_first_not_of(delim, end); + end = cl.find_first_of(delim, start); + } + + checkForNewUpdater(userDir.c_str()); + if (!runUpdater) { + runUpdater = shouldAutoUpdate(firstStart, userDir.c_str()); + } + return runUpdater; +} + +void PlatformLauncher::prepareOptions() { + string option = OPT_JDK_HOME; + option += jdkhome; + javaOptions.push_back(option); + + option = OPT_NB_PLATFORM_HOME; + option += platformDir; + javaOptions.push_back(option); + + option = OPT_NB_CLUSTERS; + option += auClusters.empty() ? clusters : auClusters; + javaOptions.push_back(option); + + option = OPT_NB_USERDIR; + option += userDir; + javaOptions.push_back(option); + + option = OPT_HEAP_DUMP; + javaOptions.push_back(option); + + option = OPT_HEAP_DUMP_PATH; + option += userDir; + option += HEAP_DUMP_PATH; + javaOptions.push_back(option); + + string proxy, nonProxy, socksProxy; + if (!findHttpProxyFromEnv(proxy)) { + findProxiesFromRegistry(proxy, nonProxy, socksProxy); + } + if (!proxy.empty()) { + option = OPT_HTTP_PROXY; + option += proxy; + javaOptions.push_back(option); + } + if (!nonProxy.empty()) { + option = OPT_HTTP_NONPROXY; + option += nonProxy; + javaOptions.push_back(option); + } + if (!socksProxy.empty()) { + option = OPT_SOCKS_PROXY; + option += socksProxy; + javaOptions.push_back(option); + } + + option = OPT_KEEP_WORKING_SET_ON_MINIMIZE; + javaOptions.push_back(option); +} + +// Reads value of http_proxy environment variable to use it as proxy setting +bool PlatformLauncher::findHttpProxyFromEnv(string &proxy) { + logMsg("findHttpProxyFromEnv()"); + char *envVar = getenv("http_proxy"); + if (envVar) { + // is it URL? + int prefixLen = strlen("http://"); + if (strncmp(envVar, "http://", prefixLen) == 0 && envVar[strlen(envVar) - 1] == '/' + && strlen(envVar) > strlen("http://")) { + // trim URL part to keep only 'host[:port]' + proxy = envVar + prefixLen; + proxy.erase(proxy.size() - 1); + logMsg("Found proxy in environment variable: %s", proxy.c_str()); + return true; + } + } + return false; +} + +bool PlatformLauncher::findProxiesFromRegistry(string &proxy, string &nonProxy, string &socksProxy) { + logMsg("findProxiesFromRegistry()"); + socksProxy = nonProxy = proxy = ""; + DWORD proxyEnable = 0; + if (!getDwordFromRegistry(HKEY_CURRENT_USER, REG_PROXY_KEY, REG_PROXY_ENABLED_NAME, proxyEnable)) { + return false; + } + + if (!proxyEnable) { + logMsg("Proxy disabled"); + proxy = PROXY_DIRECT; + return true; + } + + string proxyServer; + if (!getStringFromRegistry(HKEY_CURRENT_USER, REG_PROXY_KEY, REG_PROXY_SERVER_NAME, proxyServer)) { + return false; + } + + if (proxyServer.find('=') == string::npos) { + proxy = proxyServer; + } else { + string::size_type pos = proxyServer.find("socks="); + if (pos != string::npos) { + if (proxyServer.size() > pos + 1 && proxyServer.at(pos) != ';') { + string::size_type endPos = proxyServer.find(';', pos); + socksProxy = proxyServer.substr(pos, endPos == string::npos ? string::npos : endPos - pos); + } + } + pos = proxyServer.find("http="); + if (pos != string::npos) { + string::size_type endPos = proxyServer.find(';', pos); + proxy = proxyServer.substr(pos, endPos == string::npos ? string::npos : endPos - pos); + } + } + logMsg("Proxy servers:\n\tproxy: %s\n\tsocks proxy: %s\n\tnonProxy: %s", proxy.c_str(), socksProxy.c_str(), nonProxy.c_str()); + getStringFromRegistry(HKEY_CURRENT_USER, REG_PROXY_KEY, REG_PROXY_OVERRIDE_NAME, nonProxy); + return true; +} + +string & PlatformLauncher::constructClassPath(bool runUpdater) { + logMsg("constructClassPath()"); + addedToCP.clear(); + classPath = cpBefore; + + addJarsToClassPathFrom(userDir.c_str()); + addJarsToClassPathFrom(platformDir.c_str()); + + if (runUpdater) { + const char *baseUpdaterPath = userDir.c_str(); + string updaterPath = userDir + "\\modules\\ext\\updater.jar"; + + // if user updater does not exist, use updater from platform + if (!fileExists(updaterPath.c_str())) { + baseUpdaterPath = platformDir.c_str(); + updaterPath = platformDir + "\\modules\\ext\\updater.jar"; + } + + addToClassPath(updaterPath.c_str(), false); + addFilesToClassPath(baseUpdaterPath, "\\modules\\ext\\locale", "updater_*.jar"); + } + + addToClassPath((jdkhome + "\\lib\\dt.jar").c_str(), true); + addToClassPath((jdkhome + "\\lib\\tools.jar").c_str(), true); + + classPath += cpAfter; + logMsg("ClassPath: %s", classPath.c_str()); + return classPath; +} + +void PlatformLauncher::addJarsToClassPathFrom(const char *dir) { + addFilesToClassPath(dir, "lib\\patches", "*.jar"); + addFilesToClassPath(dir, "lib\\patches", "*.zip"); + + addFilesToClassPath(dir, "lib", "*.jar"); + addFilesToClassPath(dir, "lib", "*.zip"); + + addFilesToClassPath(dir, "lib\\locale", "*.jar"); + addFilesToClassPath(dir, "lib\\locale", "*.zip"); +} + +void PlatformLauncher::addFilesToClassPath(const char *dir, const char *subdir, const char *pattern) { + logMsg("addFilesToClassPath()\n\tdir: %s\n\tsubdir: %s\n\tpattern: %s", dir, subdir, pattern); + string path = dir; + path += '\\'; + path += subdir; + path += '\\'; + + WIN32_FIND_DATA fd = {0}; + string patternPath = path + pattern; + HANDLE hFind = FindFirstFile(patternPath.c_str(), &fd); + if (hFind == INVALID_HANDLE_VALUE) { + logMsg("Nothing found (%s)", patternPath.c_str()); + return; + } + do { + string name = subdir; + name += fd.cFileName; + string fullName = path + fd.cFileName; + if (addedToCP.insert(name).second) { + addToClassPath(fullName.c_str()); + } else { + logMsg("\"%s\" already added, skipping \"%s\"", name.c_str(), fullName.c_str()); + } + } while (FindNextFile(hFind, &fd)); + FindClose(hFind); +} + +void PlatformLauncher::addToClassPath(const char *path, bool onlyIfExists) { + logMsg("addToClassPath()\n\tpath: %s\n\tonlyIfExists: %s", path, onlyIfExists ? "true" : "false"); + if (onlyIfExists && !fileExists(path)) { + return; + } + + if (!classPath.empty()) { + classPath += ';'; + } + classPath += path; +} + +void PlatformLauncher::onExit() { + logMsg("onExit()"); + if (separateProcess) { + logMsg("JVM in separate process, no need to restart"); + return; + } + if (nextAction == ARG_NAME_LA_START_APP || (nextAction == ARG_NAME_LA_START_AU && shouldAutoUpdateClusters(false))) { + string cmdLine = GetCommandLine(); + logMsg("Old command line: %s", cmdLine.c_str()); + string::size_type bslashPos = cmdLine.find_last_of('\\'); + string::size_type pos = cmdLine.find(ARG_NAME_LA_START_APP); + if (bslashPos < pos && pos != string::npos) { + cmdLine.erase(pos, strlen(ARG_NAME_LA_START_APP)); + } + pos = cmdLine.find(ARG_NAME_LA_START_AU); + if (bslashPos < pos && pos != string::npos) { + cmdLine.erase(pos, strlen(ARG_NAME_LA_START_AU)); + } + if (*cmdLine.rbegin() != ' ') { + cmdLine += ' '; + } + cmdLine += nextAction; + logMsg("New command line: %s", cmdLine.c_str()); + + char cmdLineStr[32 * 1024] = ""; + strcpy(cmdLineStr, cmdLine.c_str()); + STARTUPINFO si = {0}; + PROCESS_INFORMATION pi = {0}; + si.cb = sizeof(STARTUPINFO); + if (!CreateProcess(NULL, cmdLineStr, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { + logErr(true, true, "Failed to create process."); + return; + } + // wait for a while so our child process can attach our console + Sleep(1000); + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } +} diff --git a/o.n.bootstrap/launcher/windows/platformlauncher.h b/o.n.bootstrap/launcher/windows/platformlauncher.h new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/platformlauncher.h @@ -0,0 +1,123 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#ifndef _PLATFORMLAUNCHER_H +#define _PLATFORMLAUNCHER_H + +#include "jvmlauncher.h" +#include +#include +#include + +class PlatformLauncher { + static const char *REQ_JAVA_VERSION; + static const char *HELP_MSG; + static const char *REG_PROXY_KEY; + static const char *REG_PROXY_ENABLED_NAME; + static const char *REG_PROXY_SERVER_NAME; + static const char *REG_PROXY_OVERRIDE_NAME; + + static const char *PROXY_DIRECT; + static const char *HEAP_DUMP_PATH; + + static const char *OPT_JDK_HOME; + static const char *OPT_NB_PLATFORM_HOME; + static const char *OPT_NB_CLUSTERS; + static const char *OPT_NB_USERDIR; + static const char *OPT_HTTP_PROXY; + static const char *OPT_HTTP_NONPROXY; + static const char *OPT_SOCKS_PROXY; + static const char *OPT_HEAP_DUMP; + static const char *OPT_HEAP_DUMP_PATH; + static const char *OPT_KEEP_WORKING_SET_ON_MINIMIZE; + static const char *OPT_CLASS_PATH; + + static const char *UPDATER_MAIN_CLASS; + static const char *IDE_MAIN_CLASS; + + +public: + PlatformLauncher(); + virtual ~PlatformLauncher(); + + bool start(char* argv[], int argc, DWORD *retCode); + void onExit(); + +private: + PlatformLauncher(const PlatformLauncher& orig); + bool parseArgs(int argc, char *argv[]); + bool initPlatformDir(); + bool processAutoUpdateCL(); + bool checkForNewUpdater(const char *basePath); + bool shouldAutoUpdate(bool firstStart, const char *basePath); + bool shouldAutoUpdateClusters(bool firstStart); + void prepareOptions(); + bool findHttpProxyFromEnv(std::string &proxy); + bool findProxiesFromRegistry(std::string &proxy, std::string &nonProxy, std::string &socksProxy); + std::string & constructClassPath(bool runUpdater); + void addFilesToClassPath(const char *dir, const char *subdir, const char *pattern); + void addToClassPath(const char *path, bool onlyIfExists = false); + void addJarsToClassPathFrom(const char *dir); + bool run(bool updater, DWORD *retCode); + +private: + bool separateProcess; + std::string platformDir; + std::string userDir; + std::string clusters; + std::string bootclass; + std::string jdkhome; + std::string cpBefore; + std::string cpAfter; + std::string auClusters; + std::string nextAction; + + std::list javaOptions; + std::list progArgs; + JvmLauncher jvmLauncher; + std::set addedToCP; + std::string classPath; +}; + +#endif /* _PLATFORMLAUNCHER_H */ + diff --git a/o.n.bootstrap/launcher/windows/utilsfuncs.cpp b/o.n.bootstrap/launcher/windows/utilsfuncs.cpp new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/utilsfuncs.cpp @@ -0,0 +1,321 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#include "utilsfuncs.h" +#include "argnames.h" + +using namespace std; + +bool disableFolderVirtualization(HANDLE hProcess) { + OSVERSIONINFO osvi = {0}; + osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + if (GetVersionEx(&osvi) && osvi.dwMajorVersion == 6) // check it is Win VISTA + { + HANDLE hToken; + if (OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken)) { + DWORD tokenInfoVal = 0; + if (!SetTokenInformation(hToken, (TOKEN_INFORMATION_CLASS) 24, &tokenInfoVal, sizeof (DWORD))) { + // invalid token information class (24) is OK, it means there is no folder virtualization on current system + if (GetLastError() != ERROR_INVALID_PARAMETER) { + logErr(true, true, "Failed to set token information."); + return false; + } + } + CloseHandle(hToken); + } else { + logErr(true, true, "Failed to open process token."); + return false; + } + } + return true; +} + +bool getStringFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, string &value) { + logMsg("getStringFromRegistry()\n\tkeyName: %s\n\tvalueName: %s", keyName, valueName); + HKEY hKey = 0; + if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + DWORD valSize = 4096; + DWORD type = 0; + char val[4096] = ""; + if (RegQueryValueEx(hKey, valueName, 0, &type, (BYTE *) val, &valSize) == ERROR_SUCCESS + && type == REG_SZ) { + logMsg("%s: %s", valueName, val); + RegCloseKey(hKey); + value = val; + return true; + } else { + logErr(true, false, "RegQueryValueEx() failed."); + } + RegCloseKey(hKey); + } else { + logErr(true, false, "RegOpenKeyEx() failed."); + } + return false; +} + +bool getDwordFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, DWORD &value) { + logMsg("getDwordFromRegistry()\n\tkeyName: %s\n\tvalueName: %s", keyName, valueName); + HKEY hKey = 0; + if (RegOpenKeyEx(rootKey, keyName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { + DWORD valSize = sizeof(DWORD); + DWORD type = 0; + if (RegQueryValueEx(hKey, valueName, 0, &type, (BYTE *) &value, &valSize) == ERROR_SUCCESS + && type == REG_DWORD) { + logMsg("%s: %u", valueName, value); + RegCloseKey(hKey); + return true; + } else { + logErr(true, false, "RegQueryValueEx() failed."); + } + RegCloseKey(hKey); + } else { + logErr(true, false, "RegOpenKeyEx() failed."); + } + return false; +} + +bool dirExists(const char *path) { + WIN32_FIND_DATA fd = {0}; + HANDLE hFind = 0; + hFind = FindFirstFile(path, &fd); + if (hFind == INVALID_HANDLE_VALUE) { + return false; + } + FindClose(hFind); + return (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; +} + +bool fileExists(const char *path) { + WIN32_FIND_DATA fd = {0}; + HANDLE hFind = 0; + hFind = FindFirstFile(path, &fd); + if (hFind == INVALID_HANDLE_VALUE) { + logMsg("File \"%s\" does not exist", path); + return false; + } + + logMsg("File \"%s\" exists", path); + FindClose(hFind); + return true; +} + +bool normalizePath(char *path) { + char tmp[MAX_PATH] = ""; + int i = 0; + while (path[i] && i < MAX_PATH - 1) { + tmp[i] = path[i] == '/' ? '\\' : path[i]; + i++; + } + tmp[i] = '\0'; + return _fullpath(path, tmp, MAX_PATH) != NULL; +} + +bool createPath(const char *path) { + logMsg("Creating directory \"%s\"", path); + char dir[MAX_PATH] = ""; + const char *sep = strchr(path, '\\'); + while (sep) { + strncpy(dir, path, sep - path); + if (!CreateDirectory(dir, 0) && GetLastError() != ERROR_ALREADY_EXISTS) { + logErr(true, false, "Failed to create directory %s", dir); + return false; + } + sep = strchr(sep + 1, '\\'); + } + return true; +} + + +char * getCurrentModulePath(char *path, int pathLen) { + MEMORY_BASIC_INFORMATION mbi; + static int dummy; + VirtualQuery(&dummy, &mbi, sizeof (mbi)); + HMODULE hModule = (HMODULE) mbi.AllocationBase; + GetModuleFileName(hModule, path, pathLen); + return path; +} + +char * skipWhitespaces(char *str) { + while (*str != '\0' && (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r')) { + str++; + } + return str; +} + +char * trimWhitespaces(char *str) { + char *end = str + strlen(str) - 1; + while (end >= str && (*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r')) { + *end = '\0'; + end--; + } + return end; +} + +char* getSysError(char *str, int strSize) { + int err = GetLastError(); + LPTSTR lpMsgBuf; + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) & lpMsgBuf, + 0, + NULL + ); + LPTSTR tmp = strchr(lpMsgBuf, '\r'); + if (tmp != NULL) { + *tmp = '\0'; + } + + _snprintf(str, strSize, " %s (%u)", lpMsgBuf, err); + LocalFree(lpMsgBuf); + return str; +} + +string gLogFileName; + +void logV(bool appendSysError, bool showMsgBox, const char *format, va_list args) { + char msg[4096] = ""; + vsnprintf(msg, 4096, format, args); + + if (appendSysError) { + char sysErr[512] = ""; + getSysError(sysErr, 512); + strncat(msg, sysErr, 4096 - strlen(msg)); + } + + if (!gLogFileName.empty()) { + FILE *file = fopen(gLogFileName.c_str(), "a"); + if (file) { + fprintf(file, "%s\n", msg); + fclose(file); + } + } + + if (showMsgBox) { + ::MessageBox(NULL, msg, "Error", MB_OK | MB_ICONSTOP); + } +} + +void logErr(bool appendSysError, bool showMsgBox, const char *format, ...) { + va_list args; + va_start(args, format); + logV(appendSysError, showMsgBox, format, args); +} + +void logMsg(const char *format, ...) { + va_list args; + va_start(args, format); + logV(false, false, format, args); +} + +bool restarting(int argc, char *argv[]) { + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_LA_START_APP, argv[i]) == 0 || strcmp(ARG_NAME_LA_START_AU, argv[i]) == 0) { + return true; + } + } + return false; +} + +bool checkLoggingArg(int argc, char *argv[], bool delFile) { + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_LAUNCHER_LOG, argv[i]) == 0) { + if (i + 1 == argc) { + logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]); + return false; + } + gLogFileName = argv[++i]; + // if we are restarting, keep log file + if (delFile && !restarting(argc, argv)) { + DeleteFile(gLogFileName.c_str()); + } + break; + } + } + return true; +} + +bool setUpProcess(int &argc, char *argv[]) { + for (int i = 0; i < argc; i++) { + if (strcmp(ARG_NAME_CONSOLE, argv[i]) == 0) { + if (i + 1 == argc) { + logErr(false, true, "Argument is missing for \"%s\" option.", argv[i]); + return false; + } + if (strcmp("new", argv[i + 1]) == 0){ + AllocConsole(); + } else if (strcmp("suppress", argv[i + 1]) == 0) { + // nothing, no console should be attached + } else { + logErr(false, true, "Invalid argument for \"%s\" option.", argv[i]); + return false; + } + // remove options + for (int k = i + 2; k < argc; k++) { + argv[k-2] = argv[k]; + } + argc -= 2; + return true; + } + } + + // default, attach to parent process console if exists + // AttachConsole exists since WinXP, so be nice and do it dynamically + typedef BOOL (WINAPI *LPFAC)(DWORD dwProcessId); + HINSTANCE hKernel32 = GetModuleHandle("kernel32"); + if (hKernel32) { + LPFAC attachConsole = (LPFAC) GetProcAddress(hKernel32, "AttachConsole"); + if (attachConsole) { + if (!attachConsole((DWORD)-1)) { + logErr(true, false, "AttachConsole failed."); + } + } else { + logErr(true, false, "GetProcAddress() for AttachConsole failed."); + } + } + return true; +} diff --git a/o.n.bootstrap/launcher/windows/utilsfuncs.h b/o.n.bootstrap/launcher/windows/utilsfuncs.h new file mode 100644 --- /dev/null +++ b/o.n.bootstrap/launcher/windows/utilsfuncs.h @@ -0,0 +1,66 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * Contributor(s): + * + * The Original Software is NetBeans. The Initial Developer of the Original + * Software is Sun Microsystems, Inc. Portions Copyright 1997-2008 Sun + * Microsystems, Inc. All Rights Reserved. + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Author: Tomas Holy + */ + +#ifndef _UTILSFUNCS_H +#define _UTILSFUNCS_H + +#include +#include + +bool disableFolderVirtualization(HANDLE hProcess); +bool getStringFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, std::string &value); +bool getDwordFromRegistry(HKEY rootKey, const char *keyName, const char *valueName, DWORD &value); +bool dirExists(const char *path); +bool fileExists(const char *path); +bool normalizePath(char *path); +bool createPath(const char *path); +char * getCurrentModulePath(char *path, int pathLen); +char * skipWhitespaces(char *str); +char * trimWhitespaces(char *str); +void logMsg(const char *format, ...); +void logErr(bool appendSysError, bool showMsgBox, const char *format, ...); +bool checkLoggingArg(int argc, char *argv[], bool delFile); +bool setUpProcess(int &argc, char *argv[]); + +#endif /* _UTILSFUNCS_H */ +