/* * Either initialize an input stream for files that exist on disk * or open a handle through the Sleuthkit for file system files that * have not been written to disk. */ void TskFileTsk::open() { if (m_isOpen) return; // Files inside of the file system if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_FS) { // Otherwise, we open a handle to the file in ImageFile m_handle = TskServices::Instance().getImageFile().openFile(m_id); if (m_handle == -1) { LOGERROR(L"TskFileTsk::open - Error opening file."); throw TskFileException("Error opening file"); } } else if (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_UNUSED) { if (TskServices::Instance().getImgDB().getUnusedSector(getId(), m_unusedSectorsRecord) == -1) { LOGERROR(L"TskFileTsk::open - Error opening file."); throw TskFileException("Error opening file"); } } // CARVED and DERIVED else if ((getTypeId() == TskImgDB::IMGDB_FILES_TYPE_CARVED) || (getTypeId() == TskImgDB::IMGDB_FILES_TYPE_DERIVED)) { if (exists()) { // Open our input stream if not already open if (m_fileInStream == NULL) { m_fileInStream = new Poco::FileInputStream(m_file.path()); } } else { std::wstringstream msg; msg << L"TskFileTsk::open - Open failed because file id (" << m_id << ") does not exist on disk and is carved or derived."; LOGERROR(msg.str()); throw TskFileException("Error opening file"); } } else { std::wstringstream msg; msg << L"TskFileTsk::open - Open failed because file id (" << m_id << ") has unknown type (" << getTypeId() << ")."; LOGERROR(msg.str()); throw TskFileException("Error opening file"); } m_offset = 0; m_isOpen = true; }
TSK_OFF_T TskFileTsk::seek(const TSK_OFF_T off, std::ios::seekdir origin) { if (!m_isOpen) { LOGERROR(L"TskFileTsk::seek : File not open."); throw TskFileException("File not open."); } if (m_fileInStream != NULL) { // Clear all error flags before seeking since an earlier // read may have set the eof flag. m_fileInStream->clear(); m_fileInStream->seekg(off, origin); return m_fileInStream->tellg(); } else { if (origin == std::ios::beg) { if (off > getSize()) { LOGERROR(L"TskFileTsk::seek - Attempt to seek beyond end of file."); throw TskFileException("Attempt to seek beyond end of file."); } m_offset = off; } else if (origin == std::ios::end) { if (off > 0) { LOGERROR(L"TskFileTsk::seek - Offset must be a negative number when seeking from end of file."); throw TskFileException("Seek from end requires negative offset."); } if (getSize() + off < 0) { LOGERROR(L"TskFileTsk::seek - Attempt to seek prior to start of file."); throw TskFileException("Attempt to seek prior to start of file"); } m_offset = getSize() + off; } else { if (m_offset + off > getSize()) { LOGERROR(L"TskFileTsk::seek - Attempt to seek beyond end of file."); throw TskFileException("Attempt to seek beyond end of file."); } if (m_offset + off < 0) { LOGERROR(L"TskFileTsk::seek - Attempt to seek prior to start of file."); throw TskFileException("Attempt to seek prior to start of file."); } m_offset += off; } return m_offset; } }
TSK_OFF_T TskFileTsk::tell() const { if (!m_isOpen) { LOGERROR(L"TskFileTsk::tell : File not open."); throw TskFileException("File not open."); } if (m_fileInStream != NULL) return m_fileInStream->tellg(); else return m_offset; }
/* Create an uncompressed version of the file on the local file system. * Note this will save zero-length files. */ int TskL01Extract::saveFile(const uint64_t fileId, const ArchivedFile &archivedFile) { try { // If a file with this id already exists we raise an error std::auto_ptr<TskFile> pFile(TskServices::Instance().getFileManager().getFile(fileId)); if (pFile.get() != NULL && pFile->exists()) { std::stringstream msg; msg << "File id " << fileId << " already exists."; throw TskFileException(msg.str()); } // Create a blank file Poco::Path destPath(TskUtilities::toUTF8(TskServices::Instance().getFileManager().getPath(fileId))); Poco::File destFile(destPath); destFile.createFile(); // Get data from archive if (archivedFile.size > 0) { Poco::FileOutputStream fos(destFile.path(), std::ios::binary); uint64_t chunkSize = ExtractChunkSize; if (archivedFile.size < ExtractChunkSize) { chunkSize = archivedFile.size; } Poco::SharedPtr<char, Poco::ReferenceCounter, ArrayReleasePolicy<char> > dataBuf(new char[chunkSize]); uint64_t accum = 0; ewf::libewf_error_t *ewfError = NULL; // Read and save data in chunks so that we only put <= ExtractChunkSize bytes on the heap at a time while (accum < archivedFile.size) { ssize_t bytesRead = ewf::libewf_file_entry_read_buffer(archivedFile.entry, dataBuf, chunkSize, &ewfError); if (bytesRead == -1) { std::stringstream logMessage; char errorString[512]; errorString[0] = '\0'; ewf::libewf_error_backtrace_sprint(ewfError, errorString, 512); logMessage << "TskL01Extract::saveFile - Error : " << errorString << std::endl; LOGERROR(logMessage.str()); return -1; } fos.write(dataBuf, bytesRead); accum += bytesRead; } fos.close(); } return 0; } catch (Poco::Exception& ex) { std::wstringstream msg; msg << L"TskL01Extract::saveFile - Error saving file from stream : " << ex.displayText().c_str(); LOGERROR(msg.str()); return -2; } }