Example #1
0
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;
}
Example #2
0
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;
}