aboutsummaryrefslogtreecommitdiff
path: root/libs/archive/README.md
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/archive/README.md
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/archive/README.md')
-rw-r--r--libs/archive/README.md239
1 files changed, 239 insertions, 0 deletions
diff --git a/libs/archive/README.md b/libs/archive/README.md
new file mode 100644
index 0000000..e389081
--- /dev/null
+++ b/libs/archive/README.md
@@ -0,0 +1,239 @@
+[![Build status](https://ci.appveyor.com/api/projects/status/hdthueiiuedeb38f?svg=true)](https://ci.appveyor.com/project/Modorganizer2/modorganizer-archive)
+
+# modorganizer-archive
+
+This module provides a wrapper round the 7zip `7z.dll` allowing easy(ish) access to the contents of an archive.
+
+## How to build?
+
+If you want to build this as par of ModOrganizer2, simply use ModOrganizer2 build system.
+
+If you want to build this as a standalone DLL, you can run the following (requires `cmake >= 3.16`):
+
+```batch
+mkdir build
+cd build
+cmake ..
+cmake --build . --config Release
+```
+
+This will download the two required dependencies (7z sources and [`fmtlib`](https://github.com/fmtlib/fmt)), and
+build the DLL under `build/src/Release`.
+
+In order to use the DLL, you need to have the `7z.dll` available in your path, otherwize `CreateArchive()` will
+always fail. You can get the `7z.dll` by installing `7z.exe` or by building 7z yourself (building `archive` does
+not build `7z`).
+
+## The `Archive` class
+
+The first thing to do is to create an archive wrapper:
+
+```cpp
+#include <archive.h>
+
+std::unique_ptr<Archive> CreateArchive();
+```
+
+This creates an archive handler.
+
+You can check the [src/archive.h](src/archive.h) header for more details but here are some
+of the available methods:
+
+```cpp
+/**
+ * @brief Check if this Archive wrapper is in a valid state.
+ *
+ * A non-valid Archive instance usually means that the 7z DLLs could not be loaded properly. Failures
+ * to open or extract archives do not invalidate the Archive, so this should only be used to check
+ * if the Archive object has been initialized properly.
+ *
+ * @return true if this instance is valid, false otherwise.
+ */
+bool Archive::isValid() const;
+```
+
+If this returns `false`, this probably means the system cannot find `7z.dll` or it is corrupt, very old (or possibly too new).
+**You should check this before calling `open`.**
+
+```cpp
+/**
+ * @brief Open the given archive.
+ *
+ * @param archivePath Path to the archive to open.
+ * @param passwordCallback Callback to use to ask user for password. This callback must remain
+ * valid until extraction is complete since some types of archives only requires password when
+ * extracting.
+ *
+ * @return true if the archive was open properly, false otherwise.
+ */
+bool Archive::open(std::wstring const &archiveName, ArchiveCallbacks::PasswordCallback passwordCallback)
+```
+
+This attempts to open the specified archive file. It should manage to open pretty much anything 7zip recognises. It returns `true` on success.
+If an error occurs, it returns `false` and `getLastError()` can be used to check the cause of the failure (see the `Archive.h` header for the
+list of possible errors):
+
+```cpp
+Archive::Error getLastError() const;
+```
+
+If `std::wstring passwordChangeCallback()` is not empty, it is called if when password is needed and should return the password to use.
+
+**Note:** this may be called during `extract` rather than during `open`, so should remain usable until the end of the extraction.
+If you do not supply this callback, archives with passwords will be unreadable.
+
+Once the archive is opned, you can retrieve the list of files inside using `getFileList()`:
+
+```cpp
+const std::vector<FileData*>& getFileList() const;
+```
+
+This will return a reference to a vector containing `FileData`. The vector contains non-const pointers so you can actually modify (not assign)
+the pointed `FileData` to indicate which files to extract and the path to extract them to.
+
+Once you have updated the `FileData` (see below) you want to extract, you can then perform the extraction using:
+
+```cpp
+/**
+ * @brief Extract the content of the archive.
+ *
+ * This function uses the filenames from FileData to obtain the extraction paths of file.
+ *
+ * @param outputDirectory Path to the directory where the archive should be extracted. If not empty,
+ * conflicting files will be replaced by the extracted ones.
+ * @param progressCallback Function called to notify extraction progress. This function is called
+ * when new data is written to the disk, not when the archive is read, so it may take a little
+ * time to start.
+ * @param fileChangeCallback Function called when the file currently being extracted changes.
+ * @param errorCallback Function called when an error occurs.
+ *
+ * @return true if the archive was extracted, false otherwise.
+ */
+bool extract(std::wstring const &outputDirectory, ArchiveCallbacks::ProgressCallback progressCallback,
+ ArchiveCallbacks::FileChangeCallback fileChangeCallback, ArchiveCallbacks::ErrorCallback errorCallback)
+```
+
+All callbacks are optional, you can pass an empty `std::function` instead (either `nullptr` or `{}`). The purpose of the callbacks:
+
+- `progressCallback(float)` is called during extraction to notify progress.
+- `fileChangeCallback(std::wstring const&)` is called when a file starts being extracted.
+- `errorCallback(std::wstring const&)` is called if an error occurred, with an appropriate error message. There is not much you can do
+ here beyond displaying the message. This will also result in a failure return from `extract`.
+
+Once `extract()` is done, you can call `getFileList()` again and perform a different extractions. `extract()` will clean the list of
+`FileData` (unless an error occurred).
+
+You can cancel the extraction at any time by calling:
+
+```cpp
+void Archive::cancel();
+```
+
+This will cause `extract` to return `false` and `getLastError` to return `ERROR_EXTRACT_CANCELLED`.
+
+Once you are done, do not forget to close the currently opened `Archive`:
+
+```cpp
+void Archive::close();
+```
+
+## The `FileData` class
+
+As you have seen above, the `getFileList` method returns a reference to a vector of entries about all the files in the archive.
+You can see the full declaration of `FileData` in [src/archive.h](src/archive.h). The following methods are the most important
+ones:
+
+```cpp
+void FileData::addOutputFileName(std::wstring const& filepath)
+```
+
+Adds a new output path for this file. The given `filepath` should be relative to the extraction folder specified in `Archive::extract`.
+Initially, the list of output paths is empty, so if you do not call `addOutputFileName`, the corresponding file will not be extracted.
+You can extract a file in the archive to as many files as you want.
+
+```cpp
+std::vector<std::wstring> FileData::getAndClearOutputFileNames()
+```
+
+Returns the list of output paths (relative to the extraction folder) for this file and clears it. This is normally only used inside
+`extract` but can be used to clear the output filenames after a failure.
+
+Depending on the type of archives, you may have entries corresponding to directories, in which case `FileData::isDirectory()` will
+return `true`.
+You can "extract" those like normal files, but directories will be automatically created for files if necessary anyway.
+
+## Full example
+
+Below is a full example on how to extract an archive to a given folder:
+
+```cpp
+#include <iostream>
+
+#include "archive.h"
+
+int main() {
+
+ // Path to the archive and to the output folder:
+ const std::wstring archivePath = L"archive.7z";
+ const std::wstring outputFolder = L"output";
+
+ auto archive = CreateArchive();
+
+ if (!archive->isValid()) {
+ std::wcerr << "Failed to load the archive module: " << archive->getLastError() << '\n';
+ return -1;
+ }
+
+ // You can set a log callback if you want:
+ archive->setLogCallback([](auto level, auto const& message) {
+ std::wcout << message << '\n';
+ });
+
+ // Open the archive:
+ if (!archive->open(archivePath, nullptr)) {
+ std::wcerr << "Failed to open the archive: " << archive->getLastError() << '\n';
+ return -1;
+ }
+
+ // Get the list of files:
+ auto const& files = archive->getFileList();
+
+ // Mark all files for extraction to their path in the archive:
+ for (auto *fileData: files) {
+ fileData->addOutputFileName(fileData->getFileName());
+ }
+
+ // Extract everything (without callbacks):
+ auto result = archive->extract(outputFolder, nullptr, nullptr, nullptr);
+
+ if (!result) {
+ std::wcerr << "Failed to extract the archive: " << archive->getLastError() << '\n';
+ return -1;
+ }
+
+ // Close the archive:
+ archive->close();
+
+ return 0;
+}
+```
+
+# Copyright
+
+Copyright (C) 2012 Sebastian Herbord, (C) 2020 MO2 Team. 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
+
+See [LICENSE](LICENSE) for more details.