void skipStub(LauncherProperties * props) { if(props->isOnlyStub) { WCHAR * os; props->status = EXIT_CODE_STUB; os = appendStringW(NULL, L"It`s only the launcher stub.\nOS: "); if(is9x()) os = appendStringW(os, L"Windows 9x"); if(isNT()) os = appendStringW(os, L"Windows NT"); if(is2k()) os = appendStringW(os, L"Windows 2000"); if(isXP()) os = appendStringW(os, L"Windows XP"); if(is2003()) os = appendStringW(os, L"Windows 2003"); if(isVista()) os = appendStringW(os, L"Windows Vista"); if(is2008()) os = appendStringW(os, L"Windows 2008"); if(is7()) os = appendStringW(os, L"Windows 7"); if(IsWow64) os = appendStringW(os, L" x64"); showMessageW(props, os , 0); FREE(os); } else { skipLauncherStub(props, STUB_FILL_SIZE); if(!isOK(props)) { writeMessageA(props, OUTPUT_LEVEL_NORMAL, 1, "Error! Can`t process launcher stub", 1); showErrorW(props, INTEGRITY_ERROR_PROP, 1, props->exeName); } } }
void getJavaProperties(WCHAR * location, LauncherProperties * props, JavaProperties ** javaProps) { WCHAR *testJavaClass = props->testJVMClass; WCHAR *javaExecutable = getJavaResource(location, JAVA_EXE_SUFFIX); WCHAR *libDirectory = getJavaResource(location, JAVA_LIB_SUFFIX); if(fileExists(javaExecutable) && testJavaClass!=NULL && isDirectory(libDirectory)) { WCHAR * command = NULL; HANDLE hRead; HANDLE hWrite; writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... java hierarchy there", 1); // <location>\bin\java.exe exists appendCommandLineArgument(&command, javaExecutable); appendCommandLineArgument(&command, L"-classpath"); appendCommandLineArgument(&command, props->testJVMFile->resolved); appendCommandLineArgument(&command, testJavaClass); CreatePipe(&hRead, &hWrite, NULL, 0); // Start the child process. executeCommand(props, command, NULL, JAVA_VERIFICATION_PROCESS_TIMEOUT, hWrite, INVALID_HANDLE_VALUE, JAVA_VERIFICATION_PROCESS_PRIORITY); if(props->status!= ERROR_ON_EXECUTE_PROCESS && props->status!= ERROR_PROCESS_TIMEOUT) { char * output = readHandle(hRead); writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " output :\n", 0); writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, output, 1); props->status = getJavaPropertiesFromOutput(props, output, javaProps); if(props->status == ERROR_OK) { (*javaProps)->javaHome = appendStringW(NULL, location); (*javaProps)->javaExe = appendStringW(NULL, javaExecutable); } FREE(output); } else if(props->status == ERROR_PROCESS_TIMEOUT) { // java verification process finished by time out props->status = ERROR_INPUTOUPUT; } FREE(command); CloseHandle(hWrite); CloseHandle(hRead); } else { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... not a java hierarchy", 1); props->status = ERROR_INPUTOUPUT; } FREE(libDirectory); FREE(javaExecutable); }
void extractLauncherResource(LauncherProperties * props, LauncherResource ** file, char * name) { char * typeStr = appendString(appendString(NULL, name), " type"); * file = newLauncherResource(); readNumberWithDebug( props, & ((*file)->type) , typeStr); if(isOK(props)) { FREE(typeStr); if((*file)->type==0) { //bundled writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... file is bundled", 1); extractFileToDir(props, & ((*file)->path)); if(!isOK(props)) { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error extracting file!", 1); return; } else { (*file)->resolved = appendStringW(NULL, (*file)->path); writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "file was succesfully extracted to ", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, (*file)->path, 1); } } else { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... file is external", 1); readStringWithDebugW(props, & ((*file)->path), name); if(!isOK(props)) { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error reading ", 1); writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, name, 1); } } } else { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error reading ", 0); writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, typeStr, 0); FREE(typeStr); } }
void installJVM(LauncherProperties * props, LauncherResource *jvm) { WCHAR * command = NULL; WCHAR * jvmDir = getParentDirectory(jvm->resolved); jvmDir = appendStringW(jvmDir, L"\\_jvm"); createDirectory(props, jvmDir); if(!isOK(props)) { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... cannot create dir for JVM extraction :", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 1, jvmDir, 1); FREE(jvmDir); return; } appendCommandLineArgument(&command, jvm->resolved); appendCommandLineArgument(&command, L"-d"); appendCommandLineArgument(&command, jvmDir); executeCommand(props, command, jvmDir, JVM_EXTRACTION_TIMEOUT, props->stdoutHandle, props->stderrHandle, NORMAL_PRIORITY_CLASS); FREE(command); if(!isOK(props)) { if(props->status==ERROR_PROCESS_TIMEOUT) { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... could not extract JVM : timeout", 1); } else { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... an error occured during running JVM extraction file", 1); } props->exitCode = props->status; } else { WCHAR * unpack200exe = appendStringW(appendStringW(NULL, jvmDir), UNPACK200_EXE_SUFFIX); if(fileExists(unpack200exe)) { unpackJars(props, jvmDir, jvmDir, unpack200exe); } else { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... no unpack200 command", 1); props->status = ERROR_BUNDLED_JVM_EXTRACTION; } if(!isOK(props)) { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Could not unpack200 the JVM jars", 1); } FREE(unpack200exe); } FREE(jvm->resolved); jvm->resolved = jvmDir; }
void unpackJars(LauncherProperties * props, WCHAR * jvmDir, WCHAR * startDir, WCHAR * unpack200exe) { DWORD attrs; DWORD dwError; DWORD count = 0 ; if(!isOK(props)) return; attrs = GetFileAttributesW(startDir); if(attrs==INVALID_FILE_ATTRIBUTES) { writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t get attributes of the file : ", startDir, GetLastError()); return; } if(attrs & FILE_ATTRIBUTE_DIRECTORY) { // is directory WIN32_FIND_DATAW FindFileData; HANDLE hFind = INVALID_HANDLE_VALUE; WCHAR * DirSpec = appendStringW(appendStringW(NULL, startDir), L"\\*" ); // Find the first file in the directory. hFind = FindFirstFileW(DirSpec, &FindFileData); if (hFind == INVALID_HANDLE_VALUE) { writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t file with pattern ", DirSpec, GetLastError()); } else { // List all the other files in the directory. writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... listing directory ", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, startDir, 1); while (FindNextFileW(hFind, &FindFileData) != 0 && isOK(props)) { if(lstrcmpW(FindFileData.cFileName, L".")!=0 && lstrcmpW(FindFileData.cFileName, L"..")!=0) { WCHAR * child = NULL; child = appendStringW(appendStringW(appendStringW(NULL, startDir), FILE_SEP), FindFileData.cFileName); if(isDirectory(child)) { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... directory : ", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, child, 1); unpackJars(props, jvmDir, child, unpack200exe); } else if(searchW(FindFileData.cFileName, JAR_PACK_GZ_SUFFIX)!=NULL) { WCHAR * jarName = appendStringW(appendStringW( appendStringW(NULL, startDir), FILE_SEP), appendStringNW(NULL, 0, FindFileData.cFileName, getLengthW(FindFileData.cFileName) - getLengthW(PACK_GZ_SUFFIX))); WCHAR * unpackCommand = NULL; writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... packed jar : ", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, child, 1); writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... jar name : ", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, jarName, 1); appendCommandLineArgument(&unpackCommand, unpack200exe); appendCommandLineArgument(&unpackCommand, child); appendCommandLineArgument(&unpackCommand, jarName); executeCommand(props, unpackCommand, NULL, UNPACK200_EXTRACTION_TIMEOUT, props->stdoutHandle, props->stderrHandle, NORMAL_PRIORITY_CLASS); FREE(unpackCommand); if(!isOK(props)) { if(props->status==ERROR_PROCESS_TIMEOUT) { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... could not unpack file : timeout", 1); } else { writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "... an error occured unpacking the file", 1); } props->exitCode = props->status; } FREE(jarName); } FREE(child); } } dwError = GetLastError(); FindClose(hFind); if (dwError != ERROR_NO_MORE_FILES) { writeErrorA(props, OUTPUT_LEVEL_DEBUG, 1, "Error! Can`t find file with pattern : ", DirSpec, dwError); } } FREE(DirSpec); } }
WCHAR * getJavaResource(WCHAR * location, const WCHAR * suffix) { return appendStringW(appendStringW(NULL, location), suffix); }
void loadI18NStrings(LauncherProperties * props) { DWORD i=0; DWORD j=0; //read number of locales DWORD numberOfLocales = 0; DWORD numberOfProperties = 0; readNumberWithDebug(props, &numberOfLocales, "number of locales"); if(!isOK(props)) return; if(numberOfLocales==0) { props->status = ERROR_INTEGRITY; return ; } readNumberWithDebug( props, &numberOfProperties, "i18n properties"); if(!isOK(props)) return; if(numberOfProperties==0) { props->status = ERROR_INTEGRITY; return ; } props->i18nMessages = (I18NStrings * ) LocalAlloc(LPTR, sizeof(I18NStrings) * numberOfProperties); props->I18N_PROPERTIES_NUMBER = numberOfProperties; props->i18nMessages->properties = newppChar(props->I18N_PROPERTIES_NUMBER); props->i18nMessages->strings = newppWCHAR(props->I18N_PROPERTIES_NUMBER); for(i=0; isOK(props) && i<numberOfProperties;i++) { // read property name as ASCII char * propName = NULL; char * number = DWORDtoCHARN(i,2); props->i18nMessages->properties[i] = NULL; props->i18nMessages->strings[i] = NULL; propName = appendString(NULL, "property name "); propName = appendString(propName, number); FREE(number); readStringWithDebugA(props, & (props->i18nMessages->properties[i]), propName); FREE(propName); } if(isOK(props)) { DWORD isLocaleMatches; WCHAR * localeName; WCHAR * currentLocale = getLocaleName(); writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Current System Locale : ", 0); writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, currentLocale, 1); if(props->userDefinedLocale!=NULL) { // using user-defined locale via command-line parameter writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[CMD Argument] Try to use locale ", 0); writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, props->userDefinedLocale, 1); FREE(currentLocale); currentLocale = appendStringW(NULL, props->userDefinedLocale); } for(j=0;j<numberOfLocales;j++) { // for all locales in file... // read locale name as UNICODE .. // it should be like en_US or smth like that localeName = NULL; readStringWithDebugW(props, &localeName, "locale name"); if(!isOK(props)) break; isLocaleMatches = (localeName==NULL) ? 1 : searchW(currentLocale, localeName) != NULL; //read properties names and value for(i=0;i<numberOfProperties;i++) { // read property value as UNICODE WCHAR * value = NULL; char * s1 = DWORDtoCHAR(i + 1); char * s2 = DWORDtoCHAR(numberOfProperties); char * s3 = appendString(NULL , "value "); s3 = appendString(s3 , s1); s3 = appendString(s3, "/"); s3 = appendString(s3, s2); FREE(s1); FREE(s2); readStringWithDebugW(props, &value, s3); FREE(s3); if(!isOK(props)) break; if(isLocaleMatches) { //it is a know property FREE(props->i18nMessages->strings[i]); props->i18nMessages->strings[i] = appendStringW(NULL, value); } FREE(value); } FREE(localeName); } FREE(currentLocale); } }