bool update() { writeLog(L"Update started.."); wstring updDir = L"tupdates\\ready"; deque<wstring> dirs; dirs.push_back(updDir); deque<wstring> from, to, forcedirs; do { wstring dir = dirs.front(); dirs.pop_front(); wstring toDir = exeDir; if (dir.size() > updDir.size() + 1) { toDir += (dir.substr(updDir.size() + 1) + L"\\"); forcedirs.push_back(toDir); writeLog(L"Parsing dir '" + toDir + L"' in update tree.."); } WIN32_FIND_DATA findData; HANDLE findHandle = FindFirstFileEx((dir + L"\\*").c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, 0, 0); if (findHandle == INVALID_HANDLE_VALUE) { DWORD errorCode = GetLastError(); if (errorCode == ERROR_PATH_NOT_FOUND) { // no update is ready return true; } writeLog(L"Error: failed to find update files :("); updateError(L"Failed to find update files", errorCode); delFolder(); return false; } do { if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (findData.cFileName != wstring(L".") && findData.cFileName != wstring(L"..")) { dirs.push_back(dir + L"\\" + findData.cFileName); writeLog(L"Added dir '" + dir + L"\\" + findData.cFileName + L"' in update tree.."); } } else { wstring fname = dir + L"\\" + findData.cFileName; wstring tofname = exeDir + fname.substr(updDir.size() + 1); if (equal(tofname, exeName)) { // bad update - has Updater.exe - delete all dir writeLog(L"Error: bad update, has Updater.exe! '" + tofname + L"' equal '" + exeName + L"'"); delFolder(); return false; } from.push_back(fname); to.push_back(tofname); writeLog(L"Added file '" + fname + L"' to be copied to '" + tofname + L"'"); } } while (FindNextFile(findHandle, &findData)); DWORD errorCode = GetLastError(); if (errorCode && errorCode != ERROR_NO_MORE_FILES) { // everything is found writeLog(L"Error: failed to find next update file :("); updateError(L"Failed to find next update file", errorCode); delFolder(); return false; } FindClose(findHandle); } while (!dirs.empty()); for (size_t i = 0; i < forcedirs.size(); ++i) { wstring forcedir = forcedirs[i]; writeLog(L"Forcing dir '" + forcedir + L"'.."); if (!forcedir.empty() && !CreateDirectory(forcedir.c_str(), NULL)) { DWORD errorCode = GetLastError(); if (errorCode && errorCode != ERROR_ALREADY_EXISTS) { writeLog(L"Error: failed to create dir '" + forcedir + L"'.."); updateError(L"Failed to create directory", errorCode); delFolder(); return false; } writeLog(L"Already exists!"); } } for (size_t i = 0; i < from.size(); ++i) { wstring fname = from[i], tofname = to[i]; BOOL copyResult; do { writeLog(L"Copying file '" + fname + L"' to '" + tofname + L"'.."); int copyTries = 0; do { copyResult = CopyFile(fname.c_str(), tofname.c_str(), FALSE); if (copyResult == FALSE) { ++copyTries; Sleep(100); } else { break; } } while (copyTries < 30); if (copyResult == FALSE) { writeLog(L"Error: failed to copy, asking to retry.."); WCHAR errMsg[2048]; wsprintf(errMsg, L"Failed to update Telegram :(\n%s is not accessible.", tofname); if (MessageBox(0, errMsg, L"Update error!", MB_ICONERROR | MB_RETRYCANCEL) != IDRETRY) { delFolder(); return false; } } } while (copyResult == FALSE); } writeLog(L"Update succeed! Clearing folder.."); delFolder(); return true; }
bool update() { writeLog(L"Update started.."); wstring updDir = L"tupdates\\temp", readyFilePath = L"tupdates\\temp\\ready", tdataDir = L"tupdates\\temp\\tdata"; { HANDLE readyFile = CreateFile(readyFilePath.c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (readyFile != INVALID_HANDLE_VALUE) { CloseHandle(readyFile); } else { updDir = L"tupdates\\ready"; // old tdataDir = L"tupdates\\ready\\tdata"; } } HANDLE versionFile = CreateFile((tdataDir + L"\\version").c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (versionFile != INVALID_HANDLE_VALUE) { if (!ReadFile(versionFile, &versionNum, sizeof(DWORD), &readLen, NULL) || readLen != sizeof(DWORD)) { versionNum = 0; } else { if (versionNum == 0x7FFFFFFF) { // beta version } else if (!ReadFile(versionFile, &versionLen, sizeof(DWORD), &readLen, NULL) || readLen != sizeof(DWORD) || versionLen > 63) { versionNum = 0; } else if (!ReadFile(versionFile, versionStr, versionLen, &readLen, NULL) || readLen != versionLen) { versionNum = 0; } } CloseHandle(versionFile); writeLog(L"Version file read."); } else { writeLog(L"Could not open version file to update registry :("); } deque<wstring> dirs; dirs.push_back(updDir); deque<wstring> from, to, forcedirs; do { wstring dir = dirs.front(); dirs.pop_front(); wstring toDir = updateTo; if (dir.size() > updDir.size() + 1) { toDir += (dir.substr(updDir.size() + 1) + L"\\"); forcedirs.push_back(toDir); writeLog(L"Parsing dir '" + toDir + L"' in update tree.."); } WIN32_FIND_DATA findData; HANDLE findHandle = FindFirstFileEx((dir + L"\\*").c_str(), FindExInfoStandard, &findData, FindExSearchNameMatch, 0, 0); if (findHandle == INVALID_HANDLE_VALUE) { DWORD errorCode = GetLastError(); if (errorCode == ERROR_PATH_NOT_FOUND) { // no update is ready return true; } writeLog(L"Error: failed to find update files :("); updateError(L"Failed to find update files", errorCode); delFolder(); return false; } do { wstring fname = dir + L"\\" + findData.cFileName; if (fname.substr(0, tdataDir.size()) == tdataDir && (fname.size() <= tdataDir.size() || fname.at(tdataDir.size()) == '/')) { writeLog(L"Skipped 'tdata' path '" + fname + L"'"); } else if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (findData.cFileName != wstring(L".") && findData.cFileName != wstring(L"..")) { dirs.push_back(fname); writeLog(L"Added dir '" + fname + L"' in update tree.."); } } else { wstring tofname = updateTo + fname.substr(updDir.size() + 1); if (equal(tofname, exeName)) { // bad update - has Updater.exe - delete all dir writeLog(L"Error: bad update, has Updater.exe! '" + tofname + L"' equal '" + exeName + L"'"); delFolder(); return false; } else if (equal(fname, readyFilePath)) { writeLog(L"Skipped ready file '" + fname + L"'"); } else { from.push_back(fname); to.push_back(tofname); writeLog(L"Added file '" + fname + L"' to be copied to '" + tofname + L"'"); } } } while (FindNextFile(findHandle, &findData)); DWORD errorCode = GetLastError(); if (errorCode && errorCode != ERROR_NO_MORE_FILES) { // everything is found writeLog(L"Error: failed to find next update file :("); updateError(L"Failed to find next update file", errorCode); delFolder(); return false; } FindClose(findHandle); } while (!dirs.empty()); for (size_t i = 0; i < forcedirs.size(); ++i) { wstring forcedir = forcedirs[i]; writeLog(L"Forcing dir '" + forcedir + L"'.."); if (!forcedir.empty() && !CreateDirectory(forcedir.c_str(), NULL)) { DWORD errorCode = GetLastError(); if (errorCode && errorCode != ERROR_ALREADY_EXISTS) { writeLog(L"Error: failed to create dir '" + forcedir + L"'.."); updateError(L"Failed to create directory", errorCode); delFolder(); return false; } writeLog(L"Already exists!"); } } for (size_t i = 0; i < from.size(); ++i) { wstring fname = from[i], tofname = to[i]; BOOL copyResult; do { writeLog(L"Copying file '" + fname + L"' to '" + tofname + L"'.."); int copyTries = 0; do { copyResult = CopyFile(fname.c_str(), tofname.c_str(), FALSE); if (!copyResult) { ++copyTries; Sleep(100); } else { break; } } while (copyTries < 30); if (!copyResult) { writeLog(L"Error: failed to copy, asking to retry.."); WCHAR errMsg[2048]; wsprintf(errMsg, L"Failed to update Telegram :(\n%s is not accessible.", tofname.c_str()); if (MessageBox(0, errMsg, L"Update error!", MB_ICONERROR | MB_RETRYCANCEL) != IDRETRY) { delFolder(); return false; } } } while (!copyResult); } writeLog(L"Update succeed! Clearing folder.."); delFolder(); return true; }