void HGTController::decompressDiff(uint64 size, UTIL::FS::FileHandle &fhSrc, UTIL::FS::FileHandle &fhDest) { uint64 done = 0; uint32 buffSize = 10*1024; char buff[10*1024] = {0}; UTIL::MISC::BZ2Worker worker(UTIL::MISC::BZ2_DECOMPRESS); fhSrc.read(done, [&worker, &fhDest](const unsigned char* buff, uint32 size) -> bool { UTIL::FS::FileHandle* pFile = &fhDest; worker.write((const char*)buff, size, [pFile](const unsigned char* tbuff, uint32 tsize) -> bool { pFile->write((const char*)tbuff, tsize); return false; }); return false; }); worker.end([&fhDest](const unsigned char* tbuff, uint32 tsize) -> bool { fhDest.write((const char*)tbuff, tsize); return false; }); }
bool SMTController::makeThreads() { for (uint32 x=0; x<m_uiNumber; x++) { gcString file("{0}", m_szFile); UTIL::FS::FileHandle* fh = new UTIL::FS::FileHandle(); if (x != 0) file += gcString(".part_{0}", x); try { fh->open(file.c_str(), UTIL::FS::FILE_WRITE); //due to the first thread being the proper MCF we have to allow for the header. if (x == 0) fh->seek(MCFCore::MCFHeader::getSizeS()); } catch (gcException &except) { safe_delete(fh); onErrorEvent(except); return false; } SMTWorkerInfo* temp = new SMTWorkerInfo(this, x, fh, file.c_str()); m_vWorkerList.push_back(temp); temp->workThread->start(); m_iRunningWorkers++; } return true; }
bool MCF::fixMD5AndCRC() { gcString empty("d41d8cd98f00b204e9800998ecf8427e"); bool fixed = false; UTIL::FS::FileHandle handle; getReadHandle(handle); for (size_t x=0; x<m_pFileList.size(); x++) { if (m_pFileList[x]->isSaved() == false) continue; if (m_pFileList[x]->isCompressed() && empty == m_pFileList[x]->getCCsum()) { fixed = true; m_pFileList[x]->generateMD5(handle); } fixed = true; m_pFileList[x]->generateCRC(handle); } handle.close(); if (fixed) { saveMCF_Header(); return true; } return false; }
void MCF::parseMCF() { gcTrace(""); if (m_bStopped) return; UTIL::FS::FileHandle hFile; getReadHandle(hFile); m_pFileList.clear(); MCFCore::MCFHeader tempHeader; tempHeader.readFromFile(hFile); setHeader(&tempHeader); hFile.seek(tempHeader.getXmlStart()); uint32 xmlBuffLen = tempHeader.getXmlSize()+1; UTIL::MISC::Buffer xmlBuff(xmlBuffLen, true); hFile.read(xmlBuff, tempHeader.getXmlSize()); if (getHeader()->getFlags() & MCFCore::MCFHeaderI::FLAG_NOTCOMPRESSED) { parseXml(xmlBuff, xmlBuffLen); } else { UTIL::MISC::BZ2Worker worker(UTIL::MISC::BZ2_DECOMPRESS); worker.write(xmlBuff, xmlBuffLen, true); worker.doWork(); if (worker.getLastStatus() != BZ_STREAM_END) throw gcException(ERR_BZ2, worker.getLastStatus(), "Failed to decompress mcf header xml"); size_t bz2BuffLen = worker.getReadSize(); if (bz2BuffLen == 0) throw gcException(ERR_BZ2, worker.getLastStatus(), "Failed to decompress mcf header xml (zero size)"); UTIL::MISC::Buffer bz2Buff(bz2BuffLen); worker.read(bz2Buff, bz2BuffLen); parseXml(bz2Buff, bz2BuffLen); } }
void MCF::makeCRC() { printf("Making crc's\n"); UTIL::FS::FileHandle hFile; getReadHandle(hFile); for (size_t x=0; x<m_pFileList.size(); x++) { if (!m_pFileList[x] || !m_pFileList[x]->isSaved()) continue; m_pFileList[x]->generateCRC(hFile); } hFile.close(); saveMCF_Header(); }
int32 FileSystemJSBinding::OpenFileForWrite(gcString file) { UTIL::FS::Path path = UTIL::FS::PathWithFile(file); UTIL::FS::recMakeFolder(path); UTIL::FS::FileHandle* handle = new UTIL::FS::FileHandle(); try { handle->open(path, UTIL::FS::FILE_WRITE); m_vFileHandles.push_back(handle); return m_vFileHandles.size() - 1; } catch (gcException &e) { safe_delete(handle); Warning("Failed to to open file in scriptcore: {0}\n", e); } return 0; }
void SMTController::postProcessing() { if (m_uiNumber == 1) return; UTIL::FS::FileHandle fhSource; UTIL::FS::FileHandle fhSink; UTIL::FS::Path path(m_szFile, "", true); uint64 sinkSize = UTIL::FS::getFileSize(path); try { fhSink.open(path, UTIL::FS::FILE_APPEND); } catch (gcException &) { return; } char buff[BLOCKSIZE]; for (size_t x=1; x<m_vWorkerList.size(); x++) { SMTWorkerInfo *worker = m_vWorkerList[x]; uint64 fileSize = UTIL::FS::getFileSize(UTIL::FS::PathWithFile(worker->file)); uint64 done = 0; uint32 readSize = BLOCKSIZE; try { fhSource.open(worker->file.c_str(), UTIL::FS::FILE_READ); while (fileSize > done) { if ((fileSize-done) < (uint64)readSize) readSize = (uint32)(fileSize-done); fhSource.read(buff, readSize); fhSink.write(buff, readSize); done += readSize; } fhSource.close(); } catch (gcException &) { } for (size_t y=0; y<worker->vFileList.size(); y++) { uint32 index = worker->vFileList[y]; MCFCore::MCFFile *temp = m_rvFileList[index]; if (!temp) continue; temp->setOffSet( temp->getOffSet() + sinkSize ); } sinkSize += fileSize; UTIL::FS::delFile(UTIL::FS::PathWithFile(worker->file)); } if (m_bCreateDiff == false) return; }
void MCF::getWriteHandle(UTIL::FS::FileHandle& handle) { assert(m_uiFileOffset == 0); handle.open(m_szFile.c_str(), UTIL::FS::FILE_WRITE, m_uiFileOffset); }
void MCF::getReadHandle(UTIL::FS::FileHandle& handle) { handle.open(m_szFile.c_str(), UTIL::FS::FILE_READ, m_uiFileOffset); }
int32 MCF::verifyAll(const char* tempPath) { if (!tempPath) { printf("Temp path is null.\n"); return 3; } if (!m_sHeader->isValid()) { printf("Mcf header is invalid.\n"); return 1; } uint32 count = 0; for (size_t x=0; x<m_pFileList.size(); x++) { if (!m_pFileList[x]->isSaved()) continue; count++; } if (count == 0) { printf("No files in the mcf are saved.\n"); return 2; } UTIL::FS::FileHandle fh(getFile(), UTIL::FS::FILE_READ); uint32 badCount = 0; bool placeholder = false; for (size_t x=0; x<m_pFileList.size(); x++) { if (!m_pFileList[x]->isSaved()) continue; try { m_pFileList[x]->verifyMcf(fh, placeholder); } catch (gcException &e) { printf("%s", gcString("{0}: Failed to verify Mcf with file: {1}\n", m_pFileList[x]->getName(), e).c_str()); badCount++; continue; } if (!m_pFileList[x]->isComplete()) { printf("%s", gcString("{0}: Failed mcf verify\n", m_pFileList[x]->getName()).c_str()); badCount++; continue; } gcString t("{0}{1}{2}", tempPath?tempPath:".", DIRS_STR, m_pFileList[x]->getFullPath()); UTIL::FS::Path path(t, "", true); UTIL::FS::recMakeFolder(path); UTIL::MISC::Buffer buff(10*1024); try { UTIL::FS::FileHandle file(path, UTIL::FS::FILE_WRITE); fh.seek(m_pFileList[x]->getOffSet()); #ifdef WIN32 size_t size = 0; #endif if (m_pFileList[x]->isCompressed()) { uint64 done = m_pFileList[x]->getCSize(); UTIL::MISC::BZ2Worker bz(UTIL::MISC::BZ2_DECOMPRESS); fh.read(done, [&bz, &file](const unsigned char* buff, uint32 size) -> bool { UTIL::FS::FileHandle* pFile = &file; bz.write((const char*)buff, size, [pFile](const unsigned char* tbuff, uint32 tsize) -> bool { pFile->write((const char*)tbuff, tsize); return false; }); return false; }); bz.end([&file](const unsigned char* tbuff, uint32 tsize) -> bool { file.write((const char*)tbuff, tsize); return false; }); } else { uint64 done = m_pFileList[x]->getSize(); fh.read(done, [&file](const unsigned char* buff, uint32 size) -> bool { file.write((const char*)buff, size); return false; }); } } catch (gcException &e) { printf("%s", gcString("{0}: Failed to save file: {1}\n", m_pFileList[x]->getName(), e).c_str()); badCount++; UTIL::FS::delFile(path); continue; } m_pFileList[x]->setDir(tempPath); m_pFileList[x]->verifyFile(); m_pFileList[x]->setDir(""); if (!m_pFileList[x]->isComplete()) { printf("%s", gcString("{0}: Failed file verify\n", m_pFileList[x]->getName()).c_str()); badCount++; } UTIL::FS::delFile(path); } UTIL::FS::delEmptyFolders(tempPath); return (int32)badCount*-1; }
bool UploadDump(const char* file, const char* user, int build, int branch, DelegateI<Prog_s&>* progress, const char* szTracer) { if (build == 0) build = 9999; if (branch == 0) branch = BUILDID_PUBLIC; g_Logger.write("---------------------------------------\r\n"); time_t ltime; /* calendar time */ ltime=time(nullptr); /* get current cal time */ #if defined(WIN32) && !defined(__MINGW32__) char buff[255] = {0}; struct tm t; localtime_s(&t, <ime); asctime_s(buff, 255, &t); #else struct tm *t = localtime(<ime); char* buff = asctime(t); #endif g_Logger.write("%s\r\n", buff); g_Logger.write("---------------------------------------\r\n"); g_Logger.write("Uploaded crash dump: [%s]\r\n", file); gcString dump(file); gcString tracer(szTracer); gcString log(dump + ".log"); if (PrepDumpForUpload(dump) == false) { g_Logger.write("Failed to prepare crash dump.\r\n"); return false; } else { g_Logger.write("Prepared crash dump to: [%s]\r\n", dump.c_str()); } if (!tracer.empty()) { try { auto valid = false; UTIL::FS::FileHandle fh; std::function<void(const char*, uint32)> write = [&fh, &valid, log](const char* szData, uint32 nSize) { if (!valid) fh.open(log.c_str(), UTIL::FS::FILE_WRITE); valid = true; fh.write(szData, nSize); }; DumpTracerToFile(tracer, write); if (!valid) log = ""; } catch (...) { log = ""; } if (!log.empty()) PrepDumpForUpload(log); #ifdef WIN32 //Let desura exit now. gcString tracerEventName("Global\\{0}Event", tracer); auto hHandle = OpenEvent(EVENT_MODIFY_STATE, FALSE, tracerEventName.c_str()); if (hHandle) { SetEvent(hHandle); CloseHandle(hHandle); } #endif } std::string os = UTIL::OS::getOSString(); HttpHandle hh(DUMP_UPLOAD_URL); if (progress) hh->getProgressEvent() += progress; hh->setUserAgent(DUMP_UPLOAD_AGENT); hh->cleanUp(); hh->addPostText("os", os.c_str()); hh->addPostText("build", build); hh->addPostText("appid", branch); if (user) hh->addPostText("user", user); hh->addPostFile("crashfile", dump.c_str()); if (!log.empty()) hh->addPostFile("crashlog", log.c_str()); try { hh->postWeb(); } catch (gcException &except) { g_Logger.write("Failed to upload crash: %s [%d.%d].\r\n", except.getErrMsg(), except.getErrId(), except.getSecErrId()); return false; } XML::gcXMLDocument doc(const_cast<char*>(hh->getData()), hh->getDataSize()); try { doc.ProcessStatus("crashupload"); g_Logger.write("Uploaded dump\r\n"); UTIL::FS::delFile(UTIL::FS::Path(dump, "", true)); } catch (gcException &) { g_Logger.write("Bad status returned from upload crash dump.\r\n"); gcString res; res.assign(hh->getData(), hh->getDataSize()); g_Logger.write("Result: \r\n\r\n%s\r\n\r\n", res.c_str()); return false; } return true; }
gcException IPCToolMain::installTool(gcRefPtr<UserCore::ToolInfo> info) { gcString exe(info->getExe()); gcString args(info->getArgs()); if (!UTIL::FS::isValidFile(exe.c_str())) return gcException(ERR_INVALIDFILE); if (exe.size() > 0 && args == "GAME_LIBRARY") { size_t pos = exe.find_last_of(".bz2"); if (pos == (exe.size()-1)) { UTIL::FS::Path pd(exe.c_str(), "", true); pd += UTIL::FS::File(info->getName()); gcString dest = pd.getFullPath(); uint64 size = UTIL::FS::getFileSize(exe.c_str()); try { UTIL::FS::FileHandle srcFh(exe.c_str(), UTIL::FS::FILE_READ); UTIL::FS::FileHandle destFh(dest.c_str(), UTIL::FS::FILE_WRITE); UTIL::MISC::BZ2Worker bz2(UTIL::MISC::BZ2_DECOMPRESS); srcFh.read(size, [&bz2, &destFh](const unsigned char* buff, uint32 size) -> bool { UTIL::FS::FileHandle *pDest = &destFh; bz2.write((const char*)buff, size, [&pDest](const unsigned char* buff, uint32 size) -> bool { pDest->write((const char*)buff, size); return false; }); return false; }); } catch (gcException &e) { return e; } info->overridePath(dest.c_str()); UTIL::FS::delFile(exe.c_str()); } else { info->overridePath(exe.c_str()); } } else if (args.find("PRECHECK_") == 0) { info->setInstalled(); } else { return gcException(ERR_TOOLINSTALL, gcString("Un-supported tool install [{0}]", info->getName())); } return gcException(ERR_COMPLETED); }