| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #include <windows.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <math.h> |
| #include "FileUtils.h" |
| #include "StringUtils.h" |
| #include "SystemUtils.h" |
| #include "JavaUtils.h" |
| #include "RegistryUtils.h" |
| #include "ExtractUtils.h" |
| #include "Launcher.h" |
| #include "Main.h" |
| |
| const DWORD STUB_FILL_SIZE = 450000; |
| |
| void skipLauncherStub(LauncherProperties * props, DWORD stubSize) { |
| HANDLE hFileRead = props->handler; |
| |
| if(hFileRead!=INVALID_HANDLE_VALUE) { |
| // just read stub data.. no need to write it anywhere |
| DWORD read = 0; |
| char * offsetbuf = newpChar(stubSize); |
| DWORD sizeLeft = stubSize; |
| while(ReadFile(hFileRead, offsetbuf, sizeLeft, &read, 0) && sizeLeft && read) { |
| sizeLeft-=read; |
| addProgressPosition(props, read); |
| if(sizeLeft==0) break; |
| if(read==0) { // we need some more bytes to read but we can`t to read |
| props->status = ERROR_INTEGRITY; |
| break; |
| } |
| } |
| FREE(offsetbuf); |
| } |
| } |
| |
| |
| 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 modifyRestBytes(SizedString* rest, DWORD start) { |
| |
| DWORD len = rest->length - start; |
| char * restBytesNew = NULL; |
| |
| if(len>0) { |
| DWORD i; |
| restBytesNew = newpChar(len); |
| for(i=start;i<rest->length;i++) { |
| restBytesNew[i-start] = (rest->bytes) [i]; |
| } |
| } |
| FREE(rest->bytes); |
| rest->bytes = restBytesNew; |
| rest->length = len; |
| } |
| |
| DWORD readStringFromBuf(SizedString *rest, SizedString * result, DWORD isUnicode) { |
| if((rest->length)!=0) { |
| // we have smth in the restBytes that we have read but haven`t yet proceeded |
| DWORD i=0; |
| for(i=0;i<rest->length;i++) { |
| DWORD check = ((rest->bytes)[i]==0); |
| if(isUnicode) { |
| if ( (i/2)*2==i) {// i is even |
| check = check && (i < rest->length-1 && ((rest->bytes)[i+1]==0)); |
| } else { |
| check = 0; |
| } |
| } |
| if( check ) { // we have found null character in the rest bytes |
| result->bytes = appendStringN(NULL, 0, rest->bytes, i); |
| result->length = i; |
| modifyRestBytes(rest, i + 1 + isUnicode); |
| return ERROR_OK; |
| } |
| } |
| //here we have found no \0 character in the rest of bytes... |
| } |
| return ERROR_INPUTOUPUT; |
| } |
| |
| void readString(LauncherProperties * props, SizedString * result, DWORD isUnicode) { |
| DWORD * status = & props->status; |
| HANDLE hFileRead = props->handler; |
| SizedString * rest = props->restOfBytes; |
| DWORD bufferSize = props->bufsize; |
| DWORD read=0; |
| char * buf = NULL; |
| |
| if(*status != ERROR_OK ) return; |
| |
| if(readStringFromBuf(rest, result, isUnicode)==ERROR_OK) { |
| return; |
| } |
| |
| //we need to read file for more data to find \0 character... |
| |
| buf = newpChar(bufferSize); |
| |
| while (ReadFile(hFileRead, buf, bufferSize, &read, 0) && read) { |
| addProgressPosition(props, read); |
| rest->bytes = appendStringN(rest->bytes, rest->length, buf, read); |
| rest->length = rest->length + read; |
| if(readStringFromBuf(rest, result, isUnicode)==ERROR_OK) { |
| //if(result->bytes!=NULL) { |
| //we have find \0 character |
| break; |
| } |
| ZERO(buf, sizeof(char) * bufferSize); |
| if(read==0) { // we have nothing to read.. smth wrong |
| *status = ERROR_INTEGRITY; |
| break; |
| } |
| } |
| FREE(buf); |
| return; |
| } |
| |
| |
| |
| void readNumber(LauncherProperties * props, DWORD * result) { |
| if(isOK(props)) { |
| |
| SizedString * numberString = createSizedString(); |
| DWORD i =0; |
| DWORD number = 0; |
| |
| readString(props, numberString, 0); |
| if(!isOK(props)) { |
| freeSizedString(&numberString); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, |
| "Error!! Can`t read number string. Most probably integrity error.", 1); |
| return; |
| } |
| |
| if(numberString->bytes==NULL) { |
| freeSizedString(&numberString); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, |
| "Error!! Can`t read number string (it can`t be NULL). Most probably integrity error.", 1); |
| props->status = ERROR_INTEGRITY; |
| return; |
| } |
| |
| |
| for(;i<numberString->length;i++) { |
| char c = numberString->bytes[i]; |
| if(c>='0' && c<='9') { |
| number = number * 10 + (c - '0'); |
| } else if(c==0) { |
| // we have reached the end of number section |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, |
| "Can`t read number from string (it contains zero character):", 1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, numberString->bytes, 1); |
| props->status = ERROR_INTEGRITY; |
| break; |
| } else { |
| // unexpected... |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, |
| "Can`t read number from string (unexpected error):", 1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, numberString->bytes, 1); |
| props->status = ERROR_INTEGRITY; |
| break; |
| } |
| } |
| freeSizedString(&numberString); |
| *result = number; |
| } |
| } |
| |
| void readStringWithDebugW(LauncherProperties * props, WCHAR ** dest, char * paramName) { |
| SizedString *sizedStr = createSizedString(); |
| if(paramName!=NULL) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, paramName, 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " : ", 0); |
| } |
| readString(props, sizedStr, 1); |
| if(!isOK(props)) { |
| freeSizedString(&sizedStr); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, |
| "[ERROR] Can`t read string !! Seems to be integrity error", 1); |
| return; |
| } |
| *dest = createWCHAR(sizedStr); |
| freeSizedString(&sizedStr); |
| if(paramName!=NULL) { |
| if((*dest)!=NULL) { |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, *dest, 1); |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "NULL", 1); |
| } |
| } |
| return; |
| } |
| |
| void readStringWithDebugA(LauncherProperties * props, char ** dest, char * paramName) { |
| SizedString *sizedStr = createSizedString(); |
| |
| if(paramName!=NULL) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, paramName, 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " : ", 0); |
| } |
| readString( props, sizedStr, 0); |
| if(!isOK(props)) { |
| freeSizedString(&sizedStr); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, |
| "[ERROR] Can`t read string!!! Seems to be integritiy error", 1); |
| return; |
| } |
| *dest = appendString(NULL, sizedStr->bytes); |
| if(paramName!=NULL) { |
| if((*dest)==NULL) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "NULL", 1); |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, *dest, 1); |
| } |
| } |
| freeSizedString(&sizedStr); |
| return; |
| } |
| |
| |
| void readNumberWithDebug(LauncherProperties * props, DWORD * dest, char * paramName) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, paramName, 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " : ", 0); |
| readNumber(props, dest); |
| |
| if(!isOK(props)) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, |
| "[ERROR] Can`t read number !!! Seems to be integrity error", 1); |
| return; |
| } |
| writeDWORD(props, OUTPUT_LEVEL_DEBUG, 0, NULL, *dest, 1); |
| return; |
| } |
| void readBigNumberWithDebug(LauncherProperties * props, int64t * dest, char * paramName) { |
| DWORD low = 0; |
| DWORD high = 0; |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Reading ", 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, paramName, 0); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " : ", 0); |
| |
| readNumber(props, &low); |
| if(isOK(props)) { |
| readNumber(props, &high); |
| } |
| if(!isOK(props)) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, |
| "[ERROR] Can`t read number !!! Seems to be integrity error", 1); |
| return; |
| } |
| dest->High = high; |
| dest->Low = low; |
| writeint64t(props, OUTPUT_LEVEL_DEBUG, 0, "", dest, 1); |
| } |
| |
| // returns: ERROR_OK, ERROR_INPUTOUPUT, ERROR_INTEGRITY |
| void extractDataToFile(LauncherProperties * props, WCHAR *output, int64t * fileSize, DWORD expectedCRC ) { |
| if(isOK(props)) { |
| DWORD * status = & props->status; |
| HANDLE hFileRead = props->handler; |
| int64t * size = fileSize; |
| DWORD counter = 0; |
| DWORD crc32 = -1L; |
| HANDLE hFileWrite = CreateFileW(output, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, hFileRead); |
| |
| if (hFileWrite == INVALID_HANDLE_VALUE) { |
| WCHAR * err; |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "[ERROR] Can`t create file ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, output, 1); |
| |
| err = getErrorDescription(GetLastError()); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Error description : ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, err, 1); |
| |
| showErrorW(props, OUTPUT_ERROR_PROP, 2, output, err); |
| FREE(err); |
| *status = ERROR_INPUTOUPUT; |
| return; |
| } |
| if(props->restOfBytes->length!=0 && props->restOfBytes->bytes!=NULL) { |
| //check if the data stored in restBytes is more than we neen |
| // rest bytes contains much less than int64t so we operate here only bith low bits of size |
| DWORD restBytesToWrite = (compare(size, props->restOfBytes->length)> 0 ) ? props->restOfBytes->length : size->Low; |
| DWORD usedBytes = restBytesToWrite; |
| |
| char *ptr = props->restOfBytes->bytes; |
| |
| DWORD write = 0; |
| while (restBytesToWrite >0) { |
| WriteFile(hFileWrite, ptr, restBytesToWrite, &write, 0); |
| update_crc32(&crc32, ptr, write); |
| restBytesToWrite -= write; |
| ptr +=write; |
| } |
| modifyRestBytes(props->restOfBytes, usedBytes); |
| minus(size, usedBytes); |
| |
| } |
| |
| |
| if(compare(size, 0) > 0 ) { |
| DWORD bufferSize = props->bufsize; |
| char * buf = newpChar(bufferSize); |
| DWORD bufsize = (compare(size, bufferSize) > 0) ? bufferSize : size->Low; |
| DWORD read = 0 ; |
| // printf("Using buffer size: %u/%u\n", bufsize, bufferSize); |
| while (ReadFile(hFileRead, buf, bufsize, &read, 0) && read && compare(size, 0) > 0) { |
| addProgressPosition(props, read); |
| WriteFile(hFileWrite, buf, read, &read, 0); |
| update_crc32(&crc32, buf, read); |
| |
| minus(size, read); |
| |
| if((compare(size, bufsize)<0) && (compare(size, 0)>0) ) { |
| bufsize = size->Low; |
| } |
| ZERO(buf, sizeof(char) * bufferSize); |
| if(compare(size, 0)==0) { |
| break; |
| } |
| if((counter ++) % 20 == 0) { |
| if(isTerminated(props)) break; |
| } |
| |
| } |
| if((compare(size, 0)>0 || read==0) && !isTerminated(props)) { |
| // we could not read requested size |
| * status = ERROR_INTEGRITY; |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, |
| "Can`t read data from file : not enought data", 1); |
| } |
| FREE(buf); |
| } |
| CloseHandle(hFileWrite); |
| crc32=~crc32; |
| if(isOK(props) && crc32!=expectedCRC) { |
| writeDWORD(props, OUTPUT_LEVEL_DEBUG, 0, "expected CRC : ", expectedCRC, 1); |
| writeDWORD(props, OUTPUT_LEVEL_DEBUG, 0, "real CRC : ", crc32, 1); |
| * status = ERROR_INTEGRITY; |
| |
| } |
| } |
| } |
| |
| //returns : ERROR_OK, ERROR_INTEGRITY, ERROR_FREE_SPACE |
| void extractFileToDir(LauncherProperties * props, WCHAR ** resultFile) { |
| WCHAR * fileName = NULL; |
| int64t * fileLength = NULL; |
| DWORD crc = 0; |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Extracting file ...", 1); |
| readStringWithDebugW( props, & fileName, "file name"); |
| |
| fileLength = newint64_t(0, 0); |
| readBigNumberWithDebug( props, fileLength, "file length "); |
| |
| readNumberWithDebug( props, &crc, "CRC32"); |
| |
| if(!isOK(props)) return; |
| |
| if(fileName!=NULL) { |
| DWORD i=0; |
| WCHAR * dir; |
| resolveString(props, &fileName); |
| |
| for(i=0;i<getLengthW(fileName);i++) { |
| if(fileName[i]==L'/') { |
| fileName[i]=L'\\'; |
| } |
| } |
| |
| dir = getParentDirectory(fileName); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... extract to directory = ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, dir, 1); |
| |
| checkFreeSpace(props, dir, fileLength); |
| FREE(dir); |
| if(isOK(props)) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... starting data extraction", 1); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... output file is ", 0); |
| writeMessageW(props, OUTPUT_LEVEL_DEBUG, 0, fileName, 1); |
| extractDataToFile(props, fileName, fileLength, crc); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... extraction finished", 1); |
| *resultFile = fileName; |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, " ... data extraction canceled", 1); |
| } |
| } else { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "Error! File name can`t be null. Seems to be integrity error!", 1); |
| *resultFile = NULL; |
| props -> status = ERROR_INTEGRITY; |
| } |
| FREE(fileLength); |
| return; |
| } |
| |
| |
| 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); |
| } |
| } |
| |
| LauncherResource * newLauncherResource() { |
| LauncherResource * file = (LauncherResource *) LocalAlloc(LPTR, sizeof(LauncherResource)); |
| file->path=NULL; |
| file->resolved=NULL; |
| file->type=0; |
| return file; |
| } |
| WCHARList * newWCHARList(DWORD number) { |
| WCHARList * list = (WCHARList*) LocalAlloc(LPTR, sizeof(WCHARList)); |
| list->size = number; |
| if(number>0) { |
| DWORD i=0; |
| list->items = newppWCHAR(number); |
| for(i=0;i<number;i++) { |
| list->items[i] = NULL; |
| } |
| } else { |
| list->items = NULL; |
| } |
| return list; |
| } |
| |
| void freeWCHARList(WCHARList ** plist) { |
| WCHARList * list; |
| list = * plist; |
| if(list!=NULL) { |
| DWORD i=0; |
| if(list->items!=NULL) { |
| for(i=0;i<list->size;i++) { |
| FREE(list->items[i]); |
| } |
| FREE(list->items); |
| } |
| FREE(*plist); |
| } |
| } |
| |
| LauncherResourceList * newLauncherResourceList(DWORD number) { |
| LauncherResourceList * list = (LauncherResourceList*) LocalAlloc(LPTR, sizeof(LauncherResourceList)); |
| list->size = number; |
| if(number > 0) { |
| DWORD i=0; |
| |
| list->items = (LauncherResource**) LocalAlloc(LPTR, sizeof(LauncherResource*) * number); |
| for(i=0;i<number;i++) { |
| list->items[i] = NULL; |
| } |
| } else { |
| list->items = NULL; |
| } |
| return list; |
| } |
| |
| void freeLauncherResource(LauncherResource ** file) { |
| if(*file!=NULL) { |
| FREE((*file)->path); |
| FREE((*file)->resolved); |
| FREE(*file); |
| |
| } |
| } |
| |
| |
| 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 readWCHARList(LauncherProperties * props, WCHARList ** list, char * name) { |
| DWORD number = 0; |
| DWORD i =0; |
| char * numberStr = appendString(appendString(NULL, "number of "), name); |
| |
| * list = NULL; |
| readNumberWithDebug(props, &number, numberStr); |
| FREE(numberStr); |
| |
| if(!isOK(props)) return; |
| |
| * list = newWCHARList(number); |
| for(i=0;i < (*list)->size ;i++) { |
| char * nextStr = appendString(appendString(NULL, "next item in "), name); |
| readStringWithDebugW(props, &((*list)->items[i]), nextStr); |
| FREE(nextStr); |
| if(!isOK(props)) return; |
| } |
| } |
| void readLauncherResourceList(LauncherProperties * props, LauncherResourceList ** list, char * name) { |
| DWORD num = 0; |
| DWORD i=0; |
| char * numberStr = appendString(appendString(NULL, "number of "), name); |
| readNumberWithDebug(props, &num, numberStr); |
| FREE(numberStr); |
| if(!isOK(props)) return; |
| |
| * list = newLauncherResourceList(num); |
| for(i=0;i<(*list)->size;i++) { |
| extractLauncherResource(props, & ((*list)->items[i]), "launcher resource"); |
| if(!isOK(props)) { |
| char * str = appendString(appendString(NULL, "Error processing "), name); |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, str, 1); |
| FREE(str); |
| break; |
| } |
| } |
| } |
| |
| void readLauncherProperties(LauncherProperties * props) { |
| DWORD i=0; |
| char * str = NULL; |
| |
| readWCHARList(props, &(props->jvmArguments), "jvm arguments"); |
| if(!isOK(props)) return; |
| |
| readWCHARList(props, &(props->appArguments), "app arguments"); |
| if(!isOK(props)) return; |
| |
| readStringWithDebugW(props, &(props->mainClass), "Main Class"); |
| if(!isOK(props)) return; |
| |
| readStringWithDebugW(props, &(props->testJVMClass), "TestJVM Class"); |
| if(!isOK(props)) return; |
| |
| readNumberWithDebug( props, &(props->compatibleJavaNumber), |
| "compatible java"); |
| if(!isOK(props)) return; |
| |
| |
| |
| if ( props->compatibleJavaNumber > 0 ) { |
| props->compatibleJava = (JavaCompatible **) LocalAlloc(LPTR, sizeof(JavaCompatible *) * props->compatibleJavaNumber); |
| for(i=0;i<props->compatibleJavaNumber;i++) { |
| |
| props->compatibleJava [i] = newJavaCompatible() ; |
| |
| readStringWithDebugA(props, &str, "min java version"); |
| if(!isOK(props)) return; |
| props->compatibleJava[i]->minVersion = getJavaVersionFromString(str, &props->status); |
| FREE(str); |
| if(!isOK(props)) return; |
| |
| str = NULL; |
| readStringWithDebugA(props, &str, "max java version"); |
| if(!isOK(props)) return; |
| props->compatibleJava[i]->maxVersion = getJavaVersionFromString(str, &props->status); |
| FREE(str); |
| if(!isOK(props)) return; |
| |
| readStringWithDebugA(props, &(props->compatibleJava[i]->vendor) , |
| "vendor"); |
| if(!isOK(props)) return; |
| |
| readStringWithDebugA(props, &(props->compatibleJava[i]->osName) , |
| "os name"); |
| if(!isOK(props)) return; |
| |
| readStringWithDebugA(props, &(props->compatibleJava[i]->osArch) , |
| "os arch"); |
| if(!isOK(props)) return; |
| |
| } |
| } |
| readNumberWithDebug( props, &props->bundledNumber, "bundled files"); |
| readBigNumberWithDebug(props, props->bundledSize, "bundled size"); |
| } |
| |
| void extractJVMData(LauncherProperties * props) { |
| if(isOK(props)) { |
| |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Extracting JVM data... ", 1); |
| extractLauncherResource(props, &(props->testJVMFile), "testJVM file"); |
| if(!isOK(props)) { |
| writeMessageA(props, OUTPUT_LEVEL_DEBUG, 1, "Error extracting testJVM file!", 1); |
| return ; |
| } |
| |
| readLauncherResourceList(props, &(props->jvms), "JVMs"); |
| } |
| } |
| |
| void extractData(LauncherProperties *props) { |
| if(isOK(props)) { |
| writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Extracting Bundled data... ", 1); |
| readLauncherResourceList(props, &(props->jars), "bundled and external files"); |
| if(isOK(props)) { |
| readLauncherResourceList(props, &(props->other), "other data"); |
| } |
| } |
| } |