| 197 | } |
| 198 | |
| 199 | void DirectoryEntry::addFromBSA(const std::wstring& originName, |
| 200 | const std::wstring& directory, |
| 201 | const std::wstring& archivePath, int priority, |
| 202 | int order, DirectoryStats& stats) |
| 203 | { |
| 204 | FilesOrigin& origin = createOrigin(originName, directory, priority, stats); |
| 205 | const auto archiveName = std::filesystem::path(archivePath).filename().native(); |
| 206 | |
| 207 | if (containsArchive(archiveName)) { |
| 208 | return; |
| 209 | } |
| 210 | |
| 211 | BSA::Archive archive; |
| 212 | BSA::EErrorCode res = BSA::ERROR_NONE; |
| 213 | |
| 214 | try { |
| 215 | // read() can return an error, but it can also throw if the file is not a |
| 216 | // valid bsa |
| 217 | res = archive.read(ToString(archivePath, false).c_str(), false); |
| 218 | } catch (std::exception& e) { |
| 219 | log::error("invalid bsa '{}', error {}", archivePath, e.what()); |
| 220 | return; |
| 221 | } |
| 222 | |
| 223 | if ((res != BSA::ERROR_NONE) && (res != BSA::ERROR_INVALIDHASHES)) { |
| 224 | log::error("invalid bsa '{}', error {}", archivePath, res); |
| 225 | return; |
| 226 | } |
| 227 | |
| 228 | std::error_code ec; |
| 229 | const auto lwt = std::filesystem::last_write_time(archivePath, ec); |
| 230 | FILETIME ft = {}; |
| 231 | |
| 232 | if (ec) { |
| 233 | log::warn("failed to get last modified date for '{}', {}", archivePath, |
| 234 | ec.message()); |
| 235 | } else { |
| 236 | ft = ToFILETIME(lwt); |
| 237 | } |
| 238 | |
| 239 | addFiles(origin, archive.getRoot(), ft, archiveName, order, stats); |
| 240 | |
| 241 | m_Populated = true; |
| 242 | } |
| 243 | |
| 244 | void DirectoryEntry::propagateOrigin(int origin) |
| 245 | { |