feat(build): add StormLib (#4)

* feat(app): add StormLib

* feat(app): add OpenArchives

* feat(util): update SFile to work with StormLib

* feat(app): update SFile

* feat(util): update SFile with logging (Windows only)

* feat(ui): implemented termination w/o notice

* chore(build): update StormLib

* chore(util): replace std::string with SStr* functions

* fix(stormlib): dwFlags argument for SFileOpenPatchArchive

* chore(ui): add Script_* stubs

* chore(util): clean up SFile::OpenEx

* chore(build): update StormLib

---------

Co-authored-by: Phaneron <superp00t@tutanota.com>
This commit is contained in:
VDm 2024-02-12 02:19:18 +04:00 committed by GitHub
parent c5e0034604
commit f86f6d6d09
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
323 changed files with 73232 additions and 75 deletions

View file

@ -1,27 +1,31 @@
#include "util/SFile.hpp"
#include <cstring>
#include <limits>
#include <StormLib.h>
#include <storm/Memory.hpp>
#include <storm/String.hpp>
#include <bc/file/File.hpp>
#include "util/Filesystem.hpp"
static char s_basepath[STORM_MAX_PATH] = {0};
static char s_datapath[STORM_MAX_PATH] = {0};
// TODO Proper implementation
int32_t SFile::Close(SFile* file) {
delete file->m_filename;
Blizzard::File::Close(file->m_stream);
SFileCloseFile(file->m_handle);
delete file;
return 1;
}
// TODO Proper implementation
size_t SFile::GetFileSize(SFile* file, size_t* filesizeHigh) {
return file->m_size;
uint32_t SFile::GetFileSize(SFile* file, uint32_t* filesizeHigh) {
DWORD high = 0;
DWORD low = SFileGetFileSize(file->m_handle, &high);
if (filesizeHigh) {
*filesizeHigh = high;
}
return low;
}
int32_t SFile::IsStreamingMode() {
@ -31,39 +35,47 @@ int32_t SFile::IsStreamingMode() {
// TODO Proper implementation
int32_t SFile::Load(SArchive* archive, const char* filename, void** buffer, size_t* bytes, size_t extraBytes, uint32_t flags, SOVERLAPPED* overlapped) {
auto pathLen = SStrLen(filename);
char path[STORM_MAX_PATH];
SStrCopy(path, filename, sizeof(path));
uint32_t openflags = BC_FILE_OPEN_MUST_EXIST | BC_FILE_OPEN_SHARE_READ | BC_FILE_OPEN_READ;
Blizzard::File::StreamRecord* stream;
bool opened = Blizzard::File::Open(path, openflags, stream);
size_t size;
char* data;
if (opened) {
size = static_cast<size_t>(Blizzard::File::GetFileInfo(stream)->size);
if (bytes) {
*bytes = size;
}
data = new char[size + extraBytes];
Blizzard::File::SetPos(stream, 0, BC_FILE_SEEK_START);
Blizzard::File::Read(stream, data, size, nullptr);
Blizzard::File::Close(stream);
if (extraBytes) {
memset(data + size, 0, extraBytes);
}
*buffer = data;
return 1;
} else {
if (!buffer || !filename) {
return 0;
}
*buffer = nullptr;
if (bytes) {
*bytes = 0;
}
SFile* file = nullptr;
if (!SFile::OpenEx(nullptr, filename, 0, &file)) {
return 0;
}
uint32_t high = 0;
uint64_t size = SFile::GetFileSize(file, &high);
size |= ((uint64_t) high << 32);
auto data = reinterpret_cast<char*>(SMemAlloc(size + extraBytes, __FILE__, __LINE__, 0));
if (!SFile::Read(file, data, size, nullptr, nullptr, nullptr)) {
SMemFree(data, __FILE__, __LINE__, 0);
SFile::Close(file);
return 0;
}
if (extraBytes) {
memset(data + size, 0, extraBytes);
}
if (bytes) {
*bytes = size;
}
if (buffer) {
*buffer = data;
}
SFile::Close(file);
return 1;
}
int32_t SFile::Open(const char* filename, SFile** file) {
@ -72,38 +84,48 @@ int32_t SFile::Open(const char* filename, SFile** file) {
// TODO Proper implementation
int32_t SFile::OpenEx(SArchive* archive, const char* filename, uint32_t flags, SFile** file) {
auto pathLen = SStrLen(filename);
char path[STORM_MAX_PATH];
SStrCopy(path, filename, sizeof(path));
SFile* fileptr = new SFile;
fileptr->m_filename = strdup(filename);
uint32_t openflags = BC_FILE_OPEN_MUST_EXIST | BC_FILE_OPEN_SHARE_READ | BC_FILE_OPEN_READ;
Blizzard::File::StreamRecord* stream;
auto opened = Blizzard::File::Open(fileptr->m_filename, openflags, stream);
if (!opened) {
*file = nullptr;
if (!file || !filename) {
return 0;
}
auto fileinfo = Blizzard::File::GetFileInfo(stream);
char path[STORM_MAX_PATH];
fileptr->m_stream = stream;
fileptr->m_size = fileinfo->size;
// Overflow protection
if (SStrLen(filename) + 1 > STORM_MAX_PATH) {
return 0;
}
*file = fileptr;
SStrCopy(path, filename, STORM_MAX_PATH);
OsFileToNativeSlashes(path);
HANDLE handle;
if (!SFileOpenFileEx(nullptr, path, SFILE_OPEN_LOCAL_FILE, &handle)) {
OsFileToBackSlashes(path);
if (!SFileOpenFileEx(g_mpqHandle, path, SFILE_OPEN_FROM_MPQ, &handle)) {
return 0;
}
}
*file = new SFile;
(*file)->m_handle = handle;
return 1;
}
// TODO Proper implementation
int32_t SFile::Read(SFile* file, void* buffer, size_t bytestoread, size_t* bytesread, SOVERLAPPED* overlapped, TASYNCPARAMBLOCK* asyncparam) {
Blizzard::File::Read(file->m_stream, buffer, bytestoread, bytesread);
return 1;
DWORD read = 0;
if (SFileReadFile(file->m_handle, buffer, static_cast<DWORD>(bytestoread), &read, nullptr)) {
if (bytesread) {
*bytesread = read;
}
return 1;
} else {
if (bytesread) {
*bytesread = 0;
}
return 0;
}
}
int32_t SFile::Unload(void* ptr) {