aboutsummaryrefslogtreecommitdiff
path: root/libs/bsatk/include
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
commit7ee008e150bc5bcf76082d726f719ee0fdfda982 (patch)
tree27fb39be241fdb5ac2734c574de678977d1856d0 /libs/bsatk/include
Fluorine Manager: full Linux port of Mod Organizer 2
Complete native Linux port with FUSE-based virtual filesystem, Proton/umu-run integration, and Flatpak packaging. Key features: - FUSE VFS replacing Windows USVFS (in-process + standalone helper for Flatpak) - Proton/GE-Proton/umu-run launcher with env var forwarding - Flatpak support (sandbox-aware VFS, NXM handler, umu-run) - Wine prefix management UI - Case-insensitive path resolution for Linux filesystems - QSettings-safe INI handling (avoids Bethesda INI corruption) - Portable instance support with auto-generated launcher scripts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'libs/bsatk/include')
-rw-r--r--libs/bsatk/include/bsatk/bsaarchive.h244
-rw-r--r--libs/bsatk/include/bsatk/bsaexception.h51
-rw-r--r--libs/bsatk/include/bsatk/bsafile.h145
-rw-r--r--libs/bsatk/include/bsatk/bsafolder.h170
-rw-r--r--libs/bsatk/include/bsatk/bsatk.h15
-rw-r--r--libs/bsatk/include/bsatk/bsatypes.h133
-rw-r--r--libs/bsatk/include/bsatk/errorcodes.h41
-rw-r--r--libs/bsatk/include/bsatk/filehash.h30
8 files changed, 829 insertions, 0 deletions
diff --git a/libs/bsatk/include/bsatk/bsaarchive.h b/libs/bsatk/include/bsatk/bsaarchive.h
new file mode 100644
index 0000000..cd15f64
--- /dev/null
+++ b/libs/bsatk/include/bsatk/bsaarchive.h
@@ -0,0 +1,244 @@
+/*
+Mod Organizer BSA handling
+
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef BSA_ARCHIVE_H
+#define BSA_ARCHIVE_H
+
+#include <functional>
+#include <memory>
+#include <queue>
+#include <vector>
+
+#include <dxgiformat.h>
+
+#include <DDS.h>
+
+#include "bsafolder.h"
+#include "bsatypes.h"
+#include "errorcodes.h"
+namespace boost
+{
+class mutex;
+namespace interprocess
+{
+ class interprocess_semaphore;
+}
+} // namespace boost
+
+namespace BSA
+{
+
+class File;
+
+/**
+ * @brief top level structure to represent a bsa file
+ */
+class Archive
+{
+public:
+ using DataBuffer = std::pair<std::shared_ptr<unsigned char[]>, BSAULong>;
+
+private:
+ static const unsigned int FLAG_HASDIRNAMES = 0x00000001;
+ static const unsigned int FLAG_HASFILENAMES = 0x00000002;
+ static const unsigned int FLAG_DEFAULTCOMPRESSED = 0x00000004;
+ static const unsigned int FLAG_NAMEPREFIXED =
+ 0x00000100; // if set, the full file name is prefixed before a data block
+
+ /* Record flags */
+#define OB_BSAFILE_FLAG_COMPRESS \
+ 0xC0000000 //!< Bit mask with OBBSAFileInfo::sizeFlags to get the compression status
+
+public:
+ /**
+ * constructor
+ */
+ Archive();
+ ~Archive();
+ /**
+ * read the archive from file
+ * @param fileName name of the file to read from
+ * @param testHashes if true, the hashes of file names will be checked to ensure the
+ * file is valid. This can be skipped for performance reasons
+ * @return ERROR_NONE on success or an error code
+ */
+ EErrorCode read(const char* fileName, bool testHashes);
+ /**
+ * write the archive to disc
+ * @param fileName name of the file to write to
+ * @return ERROR_NONE on success or an error code
+ */
+ EErrorCode write(const char* fileName);
+ /**
+ * @brief close the archive
+ */
+ void close();
+ /**
+ * change the archive type
+ * @param type new archive type
+ */
+ void setType(ArchiveType type) { m_Type = type; }
+ /**
+ * @return type of the archive (supported game)
+ */
+ ArchiveType getType() const { return m_Type; }
+ /**
+ * retrieve top-level folder
+ * @return descriptor of the root folder
+ */
+ Folder::Ptr getRoot() { return m_RootFolder; }
+ /**
+ * extract a file from the archive
+ * @param file descriptor of the file to extract
+ * @param outputDirectory name of the directory to extract to.
+ * may be absolute or relative
+ * @return ERROR_NONE on success or an error code
+ */
+ EErrorCode extract(File::Ptr file, const char* outputDirectory) const;
+ /**
+ * @return archive flags
+ */
+ BSAULong getFlags() const { return m_ArchiveFlags; }
+
+ /**
+ * extract all files. this is potentially faster than iterating over all files and
+ * extracting each
+ * @param outputDirectory name of the directory to extract to.
+ * may be absolute or relative
+ * @param progress callback function called on progress
+ * @param overwrite if true (default) files are overwritten if they exist
+ * @return ERROR_NONE on success or an error code
+ */
+ EErrorCode
+ extractAll(const char* outputDirectory,
+ const std::function<bool(int value, std::string fileName)>& progress,
+ bool overwrite = true);
+
+ /**
+ * @param file the file to check
+ * @return true if the file is compressed, false otherwise
+ */
+ bool compressed(const File::Ptr& file) const;
+ /**
+ * create a new file to be placed in this archive. The new file is NOT
+ * added to a folder, use BSA::Folder::addFile for that
+ * @param name name of the file to be used inside the archive
+ * @param sourceName filename path to the file to add
+ * @param compressed true if the file should be compressed (not supported yet!)
+ * @return pointer to the new file
+ */
+ File::Ptr createFile(const std::string& name, const std::string& sourceName,
+ bool compressed);
+
+private:
+ struct Header
+ {
+ uint32_t fileIdentifier;
+ char archType[5];
+ ArchiveType type;
+ BSAUInt offset;
+ BSAUInt archiveFlags;
+ BSAUInt folderCount;
+ BSAUInt fileCount;
+ BSAUInt folderNameLength;
+ BSAUInt fileNameLength;
+ BSAUInt fileFlags;
+ BSAHash nameTableOffset;
+ };
+
+ struct FileInfo
+ {
+ File::Ptr file;
+ DataBuffer data;
+ };
+
+private:
+ static Header readHeader(std::fstream& infile);
+
+ static ArchiveType typeFromID(BSAULong typeID);
+
+ static std::shared_ptr<unsigned char[]> decompress(unsigned char* inBuffer,
+ BSAULong inSize,
+ EErrorCode& result,
+ BSAULong& outSize);
+
+ BSAULong typeToID(ArchiveType type);
+
+ Folder readFolderRecord(std::fstream& file);
+
+ // EErrorCode extractDirect(const File &fileInfo, std::ofstream &outFile);
+ // EErrorCode extractCompressed(const File &fileInfo, std::ofstream &outFile);
+
+ bool defaultCompressed() const { return m_ArchiveFlags & FLAG_DEFAULTCOMPRESSED; }
+ // starting with FO3 the bsa may prefix the file name to the file blob if archive flag
+ // 0x100 is set
+ bool namePrefixed() const
+ {
+ return (m_Type != TYPE_OBLIVION) && ((m_ArchiveFlags & FLAG_NAMEPREFIXED) != 0);
+ }
+
+ BSAULong countFiles() const;
+
+ std::vector<std::string> collectFolderNames() const;
+ std::vector<std::string> collectFileNames() const;
+
+ BSAULong countCharacters(const std::vector<std::string>& list) const;
+ BSAULong determineFileFlags(const std::vector<std::string>& fileList) const;
+
+ void writeHeader(std::fstream& outfile, BSAULong fileFlags, BSAULong numFolders,
+ BSAULong folderNamesLength, BSAULong fileNamesLength);
+
+ DirectX::DDS_HEADER getDDSHeader(File::Ptr file,
+ DirectX::DDS_HEADER_DXT10& DX10Header,
+ bool& isDX10) const;
+ void getDX10Header(DirectX::DDS_HEADER_DXT10& DX10Header, File::Ptr file,
+ DirectX::DDS_HEADER DDSHeader) const;
+
+ EErrorCode extractDirect(File::Ptr file, std::ofstream& outFile) const;
+ EErrorCode extractCompressed(File::Ptr file, std::ofstream& outFile) const;
+
+ void createFolders(const std::string& targetDirectory, Folder::Ptr folder);
+
+ void readFiles(std::queue<FileInfo>& queue, boost::mutex& mutex,
+ boost::interprocess::interprocess_semaphore& bufferCount,
+ boost::interprocess::interprocess_semaphore& queueFree,
+ std::vector<File::Ptr>::iterator begin,
+ std::vector<File::Ptr>::iterator end);
+
+ void extractFiles(const std::string& targetDirectory, std::queue<FileInfo>& queue,
+ boost::mutex& mutex,
+ boost::interprocess::interprocess_semaphore& bufferCount,
+ boost::interprocess::interprocess_semaphore& queueFree,
+ int totalFiles, bool overwrite, int& filesDone);
+
+ void cleanFolder(Folder::Ptr folder);
+
+private:
+ mutable std::fstream m_File;
+
+ Folder::Ptr m_RootFolder;
+
+ BSAULong m_ArchiveFlags;
+ ArchiveType m_Type;
+};
+
+} // namespace BSA
+
+#endif // BSA_ARCHIVE_H
diff --git a/libs/bsatk/include/bsatk/bsaexception.h b/libs/bsatk/include/bsatk/bsaexception.h
new file mode 100644
index 0000000..1624f4a
--- /dev/null
+++ b/libs/bsatk/include/bsatk/bsaexception.h
@@ -0,0 +1,51 @@
+/*
+Mod Organizer BSA handling
+
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef BSAEXCEPTION_H
+#define BSAEXCEPTION_H
+
+#include <string>
+
+/**
+ * construct a string from a printf-style format
+ * @param format printf-style format to create the string from
+ * @param ... variable parameter list
+ * @return the constructed string
+ */
+std::string makeString(const char* format, ...);
+
+/**
+ * custom exception to be thrown when invalid data is encountered
+ */
+class data_invalid_exception : public std::exception
+{
+
+public:
+ explicit data_invalid_exception(const std::string& message);
+
+ virtual ~data_invalid_exception() noexcept {}
+
+ virtual const char* what() const noexcept { return m_Message.c_str(); }
+
+private:
+ std::string m_Message;
+};
+
+#endif // BSAEXCEPTION_H
diff --git a/libs/bsatk/include/bsatk/bsafile.h b/libs/bsatk/include/bsatk/bsafile.h
new file mode 100644
index 0000000..64fbf85
--- /dev/null
+++ b/libs/bsatk/include/bsatk/bsafile.h
@@ -0,0 +1,145 @@
+/*
+Mod Organizer BSA handling
+
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef BSAFILE_H
+#define BSAFILE_H
+
+#include <fstream>
+#include <memory>
+#include <vector>
+
+#include "errorcodes.h"
+#include "filehash.h"
+
+namespace BSA
+{
+
+class Folder;
+
+class File
+{
+
+ friend class Folder;
+ friend class Archive;
+
+public:
+ typedef std::shared_ptr<File> Ptr;
+ friend bool ByOffset(const File::Ptr& LHS, const File::Ptr& RHS);
+
+private:
+ static const unsigned int SIZEMASK = 0x3fffffff;
+ static const unsigned int COMPRESSMASK = 0xC0000000;
+
+public:
+ /**
+ * @return the name of the file
+ */
+ const std::string& getName() const { return m_Name; }
+ /**
+ * @return full path of this file within the archive
+ */
+ std::string getFilePath() const;
+ /**
+ * @return size of the file. If the source is an archive and the file is
+ * compressed, this returns the compressed size!
+ */
+ BSAULong getFileSize() const { return m_FileSize; }
+
+ BSAULong getUncompressedFileSize() const { return m_UncompressedFileSize; }
+
+private:
+ // copy constructor not implemented
+ File(const File& reference);
+
+ // assignment operator not implemented
+ File& operator=(const File& reference);
+
+ /**
+ * construct file from source archive
+ * @param file a file read from
+ * @param folder the folder to add the file to
+ * @param type the archive type we're parsing
+ */
+ File(std::fstream& file, Folder* folder);
+
+ /**
+ * construct file from morrowind BSA or BA2
+ * @param name of the base file from source archive
+ * @param folder the folder to add the file to
+ * @param fileSize the file size of the file in the archive
+ * @param dataOffset the offset of the file data in the archive
+ * @param toggleCompressed the detected compression mode of the archive
+ */
+ File(const std::string& name, Folder* folder, BSAULong fileSizee, BSAHash dataOffset,
+ BSAULong uncompressedFileSize, FO4TextureHeader header,
+ std::vector<FO4TextureChunk>& texChunks);
+
+ /**
+ * construct from loose file
+ * @param name the base name of the file inside the archive
+ * @param sourceFile the file to read from
+ * @param folder the folder to add the file to
+ * @param toggleCompressed if true, the default compression mode of the
+ * archive is overwritten
+ */
+ File(const std::string& name, const std::string& sourceFile, Folder* folder,
+ bool toggleCompressed);
+
+ /**
+ * @return true if its compression mode for this file differs from the archive default
+ */
+ bool compressToggled() const { return m_ToggleCompressed; }
+
+ /**
+ * @return offset to the file data. Only valid if the source of the file is
+ * an archive
+ */
+ BSAHash getDataOffset() const { return m_DataOffset; }
+ void writeHeader(std::fstream& file) const;
+ EErrorCode writeData(std::fstream& sourceArchive, std::fstream& targetArchive) const;
+
+ void setFileSize(BSAULong fileSize) { m_FileSize = fileSize; }
+
+ void readFileName(std::fstream& file, bool testHashes);
+
+private:
+ Folder* m_Folder;
+ bool m_New;
+
+ BSAHash m_NameHash;
+ std::string m_Name;
+ mutable BSAULong m_FileSize;
+ mutable BSAULong m_UncompressedFileSize;
+ BSAHash m_DataOffset;
+ bool m_ToggleCompressed;
+
+ FO4TextureHeader m_TextureHeader = {};
+ std::vector<FO4TextureChunk> m_TextureChunks;
+
+ std::string m_SourceFile;
+ bool m_ToggleCompressedWrite;
+ mutable BSAULong m_DataOffsetWrite;
+};
+
+extern bool ByOffset(const File::Ptr& LHS, const File::Ptr& RHS);
+
+} // namespace BSA
+
+#endif // BSAFILE_H
diff --git a/libs/bsatk/include/bsatk/bsafolder.h b/libs/bsatk/include/bsatk/bsafolder.h
new file mode 100644
index 0000000..f1afa29
--- /dev/null
+++ b/libs/bsatk/include/bsatk/bsafolder.h
@@ -0,0 +1,170 @@
+/*
+Mod Organizer BSA handling
+
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef BSAFOLDER_H
+#define BSAFOLDER_H
+
+#include "bsafile.h"
+#include "bsatypes.h"
+#include "errorcodes.h"
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+namespace BSA
+{
+
+class Folder
+{
+
+ friend class Archive;
+
+public:
+ typedef std::shared_ptr<Folder> Ptr;
+
+public:
+ /**
+ * @return name of this folder
+ */
+ const std::string& getName() const { return m_Name; }
+ /**
+ * @return full path to this folder
+ */
+ std::string getFullPath() const;
+ /**
+ * @return the number of subfolders within this folder
+ */
+ unsigned int getNumSubFolders() const
+ {
+ return static_cast<unsigned int>(m_SubFolders.size());
+ }
+ /**
+ * @param index index of a subfolder within this folder
+ * @return a descriptor for the subfolder
+ * @throw out_of_range this will throw an exception if the index is invalid
+ */
+ const Folder::Ptr getSubFolder(unsigned int index) const;
+ /**
+ * @return the number of files in this folder
+ */
+ unsigned int getNumFiles() const { return static_cast<unsigned int>(m_Files.size()); }
+ /**
+ * @return the number of files in this folder and subfolder
+ */
+ unsigned int countFiles() const;
+ /**
+ * @param index index of a file in this folder
+ * @return a descriptor for the file
+ * @throw out_of_range this will throw an exception if the index is invalid
+ */
+ const File::Ptr getFile(unsigned int index) const;
+ /**
+ * adds a new file to the folder
+ * @param file the new file to add
+ */
+ void addFile(const File::Ptr& file) { m_Files.push_back(file); }
+ /**
+ * add an empty folder as a subfolder to this one.
+ * @param folderName name of the new folder
+ * @return pointer to the new folder
+ * @note this folder will not be written to the bsa if it has no content
+ */
+ Folder::Ptr addFolder(const std::string& folderName);
+
+private:
+ /**
+ * construct a new, empty, folder
+ */
+ Folder();
+
+ // copy constructor not implemented
+ Folder(const Folder& reference);
+
+ // assignment operator - not implemented
+ Folder& operator=(const Folder& reference);
+
+ /**
+ * factory function to read a folder object from disc. This also reads part of the
+ * information about the files within
+ * @param file file stream to read from, already placed at the correct position
+ * @param fileNamesLength length of the file names list. This is required to correctly
+ * calculate offsets
+ * @param endPos position inside file where the last folder header ends. This is
+ * updated by the constructor so that it is the correct value after all
+ * folders are read
+ * @return the new Folder object
+ */
+ Folder::Ptr readFolder(std::fstream& file, BSAUInt fileNamesLength, BSAUInt& endPos);
+
+ Folder::Ptr readFolderSE(std::fstream& file, BSAUInt fileNamesLength,
+ BSAUInt& endPos);
+
+ /**
+ * recursive function to determine the correct subfolder to place the new
+ * folder in
+ */
+ void addFolderInt(Folder::Ptr folder);
+
+ /**
+ * recursive function that returns an existing folder match or generates the structure
+ * for a new folder
+ * @param folder folder to find or create
+ * @return the final determined / generated Folder
+ */
+ Folder::Ptr addOrFindFolderInt(Folder* folder);
+
+ /**
+ * Add a new folder to the structure.
+ * It will automatically be added to the correct sub-folder if applicable.
+ */
+ Folder::Ptr addFolder(std::fstream& file, BSAUInt fileNamesLength, BSAUInt& endPos,
+ ArchiveType type);
+
+ Folder::Ptr addFolderFromFile(std::string filePath, BSAUInt size, BSAHash offset,
+ BSAUInt uncompressedSize, FO4TextureHeader header,
+ std::vector<FO4TextureChunk>& texChunks);
+
+ bool resolveFileNames(std::fstream& file, bool testHashes);
+
+ void writeHeader(std::fstream& file) const;
+ void writeData(std::fstream& file, BSAULong fileNamesLength) const;
+ EErrorCode writeFileData(std::fstream& sourceFile, std::fstream& targetFile) const;
+ void collectFolders(std::vector<Folder::Ptr>& folderList) const;
+ void collectFiles(std::vector<File::Ptr>& fileList) const;
+ void collectFileNames(std::vector<std::string>& nameList) const;
+ void collectFolderNames(std::vector<std::string>& nameList) const;
+
+private:
+ Folder* m_Parent;
+ BSAHash m_NameHash;
+ std::string m_Name;
+ BSAULong m_FileCount;
+ BSAHash m_Offset;
+ std::vector<Folder::Ptr> m_SubFolders;
+ std::unordered_map<std::string, Folder::Ptr> m_SubFoldersByName;
+ std::vector<File::Ptr> m_Files;
+
+ mutable BSAULong m_OffsetWrite;
+};
+
+} // namespace BSA
+
+#endif /* BSAFOLDER_H */
diff --git a/libs/bsatk/include/bsatk/bsatk.h b/libs/bsatk/include/bsatk/bsatk.h
new file mode 100644
index 0000000..330a240
--- /dev/null
+++ b/libs/bsatk/include/bsatk/bsatk.h
@@ -0,0 +1,15 @@
+/*
+ * File: bsatk.h
+ * Author: tannin
+ *
+ * Created on March 16, 2012, 10:35 AM
+ */
+
+#ifndef BSATK_H
+#define BSATK_H
+
+#include "bsaarchive.h"
+#include "bsafile.h"
+#include "bsafolder.h"
+
+#endif /* BSATK_H */
diff --git a/libs/bsatk/include/bsatk/bsatypes.h b/libs/bsatk/include/bsatk/bsatypes.h
new file mode 100644
index 0000000..27dbdf5
--- /dev/null
+++ b/libs/bsatk/include/bsatk/bsatypes.h
@@ -0,0 +1,133 @@
+/*
+Mod Organizer BSA handling
+
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef BSATYPES_H
+#define BSATYPES_H
+
+#include <fstream>
+#include <string>
+
+#include <dxgiformat.h>
+
+#include <DDS.h>
+
+#include "bsaexception.h"
+
+#ifdef WIN32
+#include <Windows.h>
+
+typedef unsigned char BSAUChar;
+typedef unsigned short BSAUShort;
+typedef unsigned int BSAUInt;
+typedef unsigned long BSAULong;
+typedef unsigned long long BSAHash;
+
+#else // WIN32
+#include <stdint.h>
+
+typedef unsigned char BSAUChar;
+typedef unsigned short BSAUShort;
+typedef unsigned int BSAUInt;
+typedef unsigned long BSAULong;
+typedef unsigned long long BSAHash;
+
+#endif // WIN32
+
+enum ArchiveType
+{
+ TYPE_MORROWIND,
+ TYPE_OBLIVION,
+ TYPE_FALLOUT3,
+ TYPE_FALLOUTNV = TYPE_FALLOUT3,
+ TYPE_SKYRIM = TYPE_FALLOUT3,
+ TYPE_SKYRIMSE,
+ TYPE_FALLOUT4,
+ TYPE_STARFIELD,
+ TYPE_STARFIELD_LZ4_TEXTURE,
+ TYPE_FALLOUT4NG_7,
+ TYPE_FALLOUT4NG_8
+};
+
+struct MorrowindFileOffset
+{
+ BSAUInt size;
+ BSAUInt offset;
+};
+
+struct FO4TextureHeader
+{
+ BSAUInt nameHash;
+ char extension[4];
+ BSAUInt dirHash;
+ BSAUChar unknown1;
+ BSAUChar chunkNumber;
+ BSAUShort chunkHeaderSize;
+ BSAUShort height;
+ BSAUShort width;
+ BSAUChar mipCount;
+ DXGI_FORMAT format;
+ bool isCubemap;
+ BSAUChar unknown2;
+};
+
+struct FO4TextureChunk
+{
+ BSAHash offset;
+ BSAUInt packedSize;
+ BSAUInt unpackedSize;
+ BSAUShort startMip;
+ BSAUShort endMip;
+ BSAUInt unknown;
+};
+
+template <typename T>
+static T readType(std::fstream& file)
+{
+ union
+ {
+ char buffer[sizeof(T)];
+ T value;
+ };
+ if (!file.read(buffer, sizeof(T))) {
+ throw data_invalid_exception("can't read from bsa");
+ }
+ return value;
+}
+
+template <typename T>
+static void writeType(std::fstream& file, const T& value)
+{
+ union
+ {
+ char buffer[sizeof(T)];
+ T valueTemp;
+ };
+ valueTemp = value;
+
+ file.write(buffer, sizeof(T));
+}
+
+std::string readBString(std::fstream& file);
+void writeBString(std::fstream& file, const std::string& string);
+
+std::string readZString(std::fstream& file);
+void writeZString(std::fstream& file, const std::string& string);
+
+#endif // BSATYPES_H
diff --git a/libs/bsatk/include/bsatk/errorcodes.h b/libs/bsatk/include/bsatk/errorcodes.h
new file mode 100644
index 0000000..f2780db
--- /dev/null
+++ b/libs/bsatk/include/bsatk/errorcodes.h
@@ -0,0 +1,41 @@
+/*
+Mod Organizer BSA handling
+
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef ERRORCODES_H
+#define ERRORCODES_H
+
+namespace BSA
+{
+
+enum EErrorCode
+{
+ ERROR_NONE,
+ ERROR_INVALIDHASHES,
+ ERROR_FILENOTFOUND,
+ ERROR_INVALIDDATA,
+ ERROR_ACCESSFAILED,
+ ERROR_ZLIBINITFAILED,
+ ERROR_SOURCEFILEMISSING,
+ ERROR_CANCELED
+};
+
+};
+
+#endif // ERRORCODES_H
diff --git a/libs/bsatk/include/bsatk/filehash.h b/libs/bsatk/include/bsatk/filehash.h
new file mode 100644
index 0000000..f5bfd6b
--- /dev/null
+++ b/libs/bsatk/include/bsatk/filehash.h
@@ -0,0 +1,30 @@
+/*
+Mod Organizer BSA handling
+
+Copyright (C) 2012 Sebastian Herbord. All rights reserved.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+#ifndef FILEHASH_H
+#define FILEHASH_H
+
+#include <string>
+
+#include "bsatypes.h"
+
+BSAHash calculateBSAHash(const std::string& fileName);
+
+#endif // FILEHASH_H