const std::string& osqueryHomeDirectory() { static std::string homedir; if (homedir.size() == 0) { // Try to get the caller's home directory boost::system::error_code ec; auto userdir = getHomeDirectory(); if (userdir.is_initialized() && isWritable(*userdir).ok()) { auto osquery_dir = (fs::path(*userdir) / ".osquery"); if (isWritable(osquery_dir) || boost::filesystem::create_directories(osquery_dir, ec)) { homedir = osquery_dir.make_preferred().string(); return homedir; } } // Fail over to a temporary directory (used for the shell). auto temp = fs::temp_directory_path(ec) / fs::unique_path("osquery%%%%%%%%", ec); boost::filesystem::create_directories(temp, ec); homedir = temp.make_preferred().string(); } return homedir; }
void CPatchFile::ExecuteDELD(Framework::CStream& stream) { uint32 pathSize = stream.Read32_MSBF(); std::vector<char> pathData(pathSize); stream.Read(pathData.data(), pathSize); std::string path(std::begin(pathData), std::end(pathData)); uint32 otherData[4]; stream.Read(otherData, sizeof(otherData)); auto fullDirPath = m_gameLocationPath / path; fullDirPath.make_preferred(); if(!boost::filesystem::exists(fullDirPath)) { m_result.messages.push_back(string_format("Warning: Directory '%s' deletion requested but directory doesn't exist.", fullDirPath.string().c_str() )); } else { boost::filesystem::remove_all(fullDirPath); } }
void CPatchFile::ExecuteETRY(Framework::CStream& inputStream) { uint32 pathSize = inputStream.Read32_MSBF(); std::vector<char> pathData(pathSize); inputStream.Read(pathData.data(), pathSize); std::string path(std::begin(pathData), std::end(pathData)); auto fullFilePath = m_gameLocationPath / path; auto fullFileDirectory = fullFilePath; fullFileDirectory.remove_leaf(); fullFileDirectory.make_preferred(); fullFilePath.make_preferred(); if(!boost::filesystem::exists(fullFileDirectory)) { m_result.messages.push_back(string_format("Warning: Directory '%s' doesn't exist. Creating.", fullFileDirectory.string().c_str() )); boost::filesystem::create_directories(fullFileDirectory); } if(!boost::filesystem::exists(fullFilePath)) { m_result.messages.push_back(string_format("Warning: File '%s' doesn't exist. Creating.", fullFilePath.string().c_str())); } uint32 itemCount = inputStream.Read32_MSBF(); for(unsigned int i = 0; i < itemCount; i++) { //0x41 = last hash, 0x44 = first hash, 0x4D = both hashes? uint32 hashMode = inputStream.Read32(); assert(hashMode == 0x41 || hashMode == 0x44 || hashMode == 0x4D); uint8 srcFileHash[0x14]; uint8 dstFileHash[0x14]; inputStream.Read(srcFileHash, sizeof(srcFileHash)); inputStream.Read(dstFileHash, sizeof(dstFileHash)); //4E is no compression //5A is zlib compression uint32 compressionMode = inputStream.Read32(); assert((compressionMode == 0x4E) || (compressionMode == 0x5A)); uint32 compressedFileSize = inputStream.Read32_MSBF(); uint32 previousFileSize = inputStream.Read32_MSBF(); uint32 newFileSize = inputStream.Read32_MSBF(); if(i != (itemCount - 1)) { assert(compressedFileSize == 0); } if(compressedFileSize == 0) continue; //Data starts here { //Retrying here because explorer.exe can sometimes open the ffxiv*.exe files to load //the icons making the open operation fail if we need to patch it again. auto outputStream = CreateOutputStdStreamWithRetry(fullFilePath.native()); if(compressionMode == 0x4E) { ExtractUncompressed(outputStream, inputStream, compressedFileSize); } else if(compressionMode == 0x5A) { ExtractCompressed(outputStream, inputStream, compressedFileSize); } else { throw std::runtime_error("Unknown compression type."); } } } inputStream.Seek(0x08, Framework::STREAM_SEEK_CUR); }