Пример #1
0
//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;
}
Пример #2
0
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;
        }
    }
}
Пример #3
0
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;
    }
}
Пример #4
0
void printJavaProperties(LauncherProperties * props, JavaProperties * javaProps) {
    if(javaProps!=NULL) {
        char * jv = getJavaVersionFormatted(javaProps);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Current Java:", 1);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "       javaHome: ", 0);
        writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->javaHome, 1);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "        javaExe: ", 0);
        writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->javaExe, 1);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "        version: ", 0);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, jv, 1);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "         vendor: ", 0);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->vendor, 1);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "        os.name: ", 0);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->osName, 1);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "        os.arch: ", 0);
        writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, javaProps->osArch, 1);
        FREE(jv);
    }
}
Пример #5
0
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);
    }
    
}
Пример #6
0
void searchCurrentJavaRegistry(LauncherProperties * props, BOOL access64key) {
    DWORD i=0;
    WCHAR ** keys = JAVA_REGISTRY_KEYS;
    DWORD k=0;
    WCHAR * buffer = newpWCHAR(MAX_LEN_VALUE_NAME);
    HKEY rootKeys [2] = {HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER};
    DWORD rootKeysNumber = sizeof(rootKeys)/sizeof(HKEY);
    DWORD keysNumber = sizeof(JAVA_REGISTRY_KEYS)/sizeof(WCHAR*);
    DWORD status = ERROR_OK;
    
    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in CurrentVersion values...", 1);
    
    
    for ( k = 0; k < rootKeysNumber; k++) {
        for(i=0; i < keysNumber;i++) {
            if(isTerminated(props)) {
                return;
            }
            else {
                
                WCHAR * value = getStringValue(rootKeys[k], keys[i], CURRENT_VERSION, access64key);
                if(value!=NULL) {
                    WCHAR *javaHome = getStringValuePC(rootKeys[k], keys[i], value, JAVA_HOME, access64key);
                    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "... ", 0);
                    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, (rootKeys[k]==HKEY_LOCAL_MACHINE) ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER", 0);
                    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
                    writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, keys[i], 0);
                    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
                    writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, CURRENT_VERSION, 0);
                    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "->", 0);
                    writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, value, 0);
                    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[", 0);
                    writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, JAVA_HOME, 0);
                    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "] = ", 0);
                    writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaHome, 1);
                    
                    FREE(value);
                    trySetCompatibleJava(javaHome, props);
                    FREE(javaHome);
                    if(props->java!=NULL) {
                        FREE(buffer);
                        return;
                    }
                }
            }
        }
    }
    
    
    // we found no CurrentVersion java... just search for other possible keys
    writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "Search java in other values...", 1);
    
    
    for(k=0;k<rootKeysNumber;k++) {
        for(i=0;i<keysNumber;i++) {
            HKEY  hkey = 0;
            DWORD   index  = 0 ;
            if (RegOpenKeyExW(rootKeys[k], keys[i], 0, KEY_READ | ((access64key && IsWow64) ? KEY_WOW64_64KEY : 0), &hkey) == ERROR_SUCCESS) {
                DWORD number = 0;
                if (RegQueryInfoKeyW(hkey, NULL, NULL, NULL, &number, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) {
                    DWORD err = 0;
                    do {
                        
                        DWORD size = MAX_LEN_VALUE_NAME;
                        buffer[0]  = 0;
                        err = RegEnumKeyExW(hkey, index, buffer, &size, NULL, NULL, NULL, NULL);
                        if (err == ERROR_SUCCESS) {
                            WCHAR  * javaHome = getJavaHomeValue(keys[i], buffer, access64key);
                            status = ERROR_OK;
                            
                            writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, (rootKeys[k]==HKEY_LOCAL_MACHINE) ? "HKEY_LOCAL_MACHINE" : "HKEY_CURRENT_USER", 0);
                            writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
                            writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, keys[i], 0);
                            writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "\\", 0);
                            writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, buffer, 0);
                            writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "[", 0);
                            writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, JAVA_HOME, 0);
                            writeMessageA(props, OUTPUT_LEVEL_NORMAL, 0, "] = ", 0);
                            writeMessageW(props, OUTPUT_LEVEL_NORMAL, 0, javaHome, 1);
                            
                            trySetCompatibleJava(javaHome, props);
                            FREE(javaHome);
                            if(props->java!=NULL) {
                                i = keysNumber; // to the end of cycles
                                k = rootKeysNumber;
                                break;
                            }
                            
                        }
                        index++;
                    } while (err == ERROR_SUCCESS);
                }
            }
            if (hkey != 0) {
                RegCloseKey(hkey);
            }
        }
    }
    FREE(buffer);
    return;
}
Пример #7
0
DWORD getJavaPropertiesFromOutput(LauncherProperties * props, char *str, JavaProperties ** javaProps) {
    DWORD separators = getLineSeparatorNumber(str);
    DWORD result = ERROR_INPUTOUPUT;
    * javaProps = NULL;
    if(separators == TEST_JAVA_PARAMETERS) {
        char * start;
        char * end;
        char * javaVersion;
        char * javaVmVersion;
        char * javaVendor;
        char * osName;
        char * osArch;
        char * string;
        JavaVersion * vers;
        
        start = str;
        end = searchA(start, "\n");
        
        javaVersion = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "    java.version =  ", 0);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVersion, 1);
        start = end + 1;
        end = searchA(start, "\n");
        
        
        javaVmVersion = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "    java.vm.version = ", 0);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVmVersion, 1);
        start = end + 1;
        end = searchA(start, "\n");
        
        javaVendor = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "    java.vendor = ", 0);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, javaVendor, 1);
        start = end + 1;
        end = searchA(start, "\n");
        
        osName = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "    os.name = ", 0);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, osName, 1);
        start = end + 1;
        end = searchA(start, "\n");
        
        osArch = appendStringN(NULL, 0, start, getLengthA(start) - getLengthA(end)-1);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "    os.arch = ", 0);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, osArch, 2);
        
        string = javaVersion;
        
        
        if(javaVmVersion!=NULL) {
            string = searchA(javaVmVersion, javaVersion);
            if(string==NULL) {
                string = javaVersion;
            }
        }
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... getting java version from string : ", 0);
        writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, string, 1);
        
        vers = getJavaVersionFromString(string, & result);
        if(javaProps != NULL) {
            writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... some java there", 1);
            * javaProps = (JavaProperties *) LocalAlloc(LPTR, sizeof(JavaProperties));
            (*javaProps)->version = vers;
            (*javaProps)->vendor   = javaVendor;
            (*javaProps)->osName   = osName;
            (*javaProps)->osArch   = osArch;
            (*javaProps)->javaHome = NULL;
            (*javaProps)->javaExe  = NULL;
        } else {
            writeMessageA(props, OUTPUT_LEVEL_DEBUG, 0, "... no java  there", 1);
            FREE(javaVendor);
            FREE(osName);
            FREE(osArch);
        }
        FREE(javaVmVersion);
        FREE(javaVersion);
    }
    return result;
}
Пример #8
0
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);
    }
}
Пример #9
0
// 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;
            
        }
    }
}