mirror of
https://github.com/ModOrganizer2/libbsarch.git
synced 2026-07-27 14:06:31 -07:00
Added way to add files from any source path (without using a shared/common root)
bsa_add_file_from_disk is now bsa_add_file_from_disk_root Fixed issues with using libbsarch with GCC
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
// Hint files help the Visual Studio IDE interpret Visual C++ identifiers
|
||||||
|
// such as names of functions and macros.
|
||||||
|
// For more information see https://go.microsoft.com/fwlink/?linkid=865984
|
||||||
|
#define PACKED(datastructure) datastructure __attribute__((__packed__))
|
||||||
|
#define PACKED(datastructure) __pragma(pack(push, 1)) datastructure __pragma(pack(pop))
|
||||||
|
#define BSARCH_DLL_API(ReturnType) extern "C" __declspec(dllexport) ReturnType __stdcall
|
||||||
|
#define BSARCH_DLL_API(ReturnType) extern "C" __declspec(dllimport) ReturnType __stdcall
|
||||||
@@ -65,9 +65,13 @@ int main() {
|
|||||||
{
|
{
|
||||||
bsa_entry_list_t entries = bsa_entry_list_create();
|
bsa_entry_list_t entries = bsa_entry_list_create();
|
||||||
bsa_entry_list_add(entries, L"textures\\grass\\test.dds");
|
bsa_entry_list_add(entries, L"textures\\grass\\test.dds");
|
||||||
|
bsa_entry_list_add(entries, L"textures\\grass\\test2.dds");
|
||||||
|
|
||||||
bsa_create_archive(archive, L"test_write.bsa", baSSE, entries);
|
bsa_create_archive(archive, L"test_write.bsa", baSSE, entries);
|
||||||
bsa_add_file_from_disk(archive, L"files", L"files\\textures\\grass\\test.dds");
|
bsa_add_file_from_disk_root(archive, L"", L"textures\\grass\\test.dds");
|
||||||
|
result = bsa_add_file_from_disk(archive, L"textures\\grass\\test2.dds", L"textures\\grass\\test.dds");
|
||||||
|
if (result.code < 0)
|
||||||
|
printf("%ls\n", result.text);
|
||||||
bsa_save(archive);
|
bsa_save(archive);
|
||||||
bsa_close(archive);
|
bsa_close(archive);
|
||||||
|
|
||||||
|
|||||||
+12
-8
@@ -32,11 +32,11 @@ BSARCH_DLL_API(bsa_result_message_t) bsa_free(bsa_archive_t archive) {
|
|||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *filename) {
|
BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *file_path) {
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_create_archive(bsa_archive_t archive, const wchar_t *filename, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list) {
|
BSARCH_DLL_API(bsa_result_message_t) bsa_create_archive(bsa_archive_t archive, const wchar_t *file_path, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list) {
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,15 +44,19 @@ BSARCH_DLL_API(bsa_result_message_t) bsa_save(bsa_archive_t archive) {
|
|||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *filename) {
|
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *source_path) {
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *filename, uint32_t size, bsa_buffer_t data) {
|
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk_root(bsa_archive_t archive, const wchar_t* root_dir, const wchar_t* source_path) {
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *filename) {
|
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *file_path, uint32_t size, bsa_buffer_t data) {
|
||||||
|
return { 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *file_path) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +64,7 @@ BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_record(bsa_
|
|||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *filename) {
|
BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *file_path) {
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +72,7 @@ BSARCH_DLL_API(bsa_result_message_t) bsa_file_data_free(bsa_archive_t archive, b
|
|||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *filename, const wchar_t *save_as) {
|
BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *save_as) {
|
||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +80,7 @@ BSARCH_DLL_API(bsa_result_message_t) bsa_iterate_files(bsa_archive_t archive, bs
|
|||||||
return { 0 };
|
return { 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *filename) {
|
BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *file_path) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ EXPORTS
|
|||||||
bsa_create_archive
|
bsa_create_archive
|
||||||
bsa_save
|
bsa_save
|
||||||
bsa_add_file_from_disk
|
bsa_add_file_from_disk
|
||||||
|
bsa_add_file_from_disk_root
|
||||||
bsa_add_file_from_memory
|
bsa_add_file_from_memory
|
||||||
bsa_find_file_record
|
bsa_find_file_record
|
||||||
bsa_extract_file_data_by_record
|
bsa_extract_file_data_by_record
|
||||||
|
|||||||
+29
-17
@@ -137,22 +137,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function bsa_load_from_file(obj: Pointer; const aFileName: PChar): TwbBSResultMessage; stdcall;
|
function bsa_load_from_file(obj: Pointer; const aFilePath: PChar): TwbBSResultMessage; stdcall;
|
||||||
begin
|
begin
|
||||||
Result.code := Ord(BSA_RESULT_NONE);
|
Result.code := Ord(BSA_RESULT_NONE);
|
||||||
try
|
try
|
||||||
TwbBSArchive(obj).LoadFromFile(String(aFileName));
|
TwbBSArchive(obj).LoadFromFile(String(aFilePath));
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
exception_handler(E, Result);
|
exception_handler(E, Result);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function bsa_create_archive(obj: Pointer; const aFileName: PChar; aType: TBSArchiveType; aFileList: TwbBSEntryList): TwbBSResultMessage; stdcall;
|
function bsa_create_archive(obj: Pointer; const aFilePath: PChar; aType: TBSArchiveType; aFileList: TwbBSEntryList): TwbBSResultMessage; stdcall;
|
||||||
begin
|
begin
|
||||||
Result.code := Ord(BSA_RESULT_NONE);
|
Result.code := Ord(BSA_RESULT_NONE);
|
||||||
try
|
try
|
||||||
TwbBSArchive(obj).CreateArchiveCompat(String(aFileName), aType, aFileList);
|
TwbBSArchive(obj).CreateArchiveCompat(String(aFilePath), aType, aFileList);
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
exception_handler(E, Result);
|
exception_handler(E, Result);
|
||||||
@@ -170,32 +170,43 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function bsa_add_file_from_disk(obj: Pointer; const aRootDir, aFileName: PChar): TwbBSResultMessage; stdcall;
|
function bsa_add_file_from_disk_root(obj: Pointer; const aRootDir, aSourcePath: PChar): TwbBSResultMessage; stdcall;
|
||||||
begin
|
begin
|
||||||
Result.code := Ord(BSA_RESULT_NONE);
|
Result.code := Ord(BSA_RESULT_NONE);
|
||||||
try
|
try
|
||||||
TwbBSArchive(obj).AddFile(String(aRootDir), String(aFileName));
|
TwbBSArchive(obj).AddFileDiskRoot(String(aRootDir), String(aSourcePath));
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
exception_handler(E, Result);
|
exception_handler(E, Result);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function bsa_add_file_from_memory(obj: Pointer; const aFileName: PChar; const aSize: Cardinal; const aData: PByte): TwbBSResultMessage; stdcall;
|
function bsa_add_file_from_disk(obj: Pointer; const aFilePath, aSourcePath: PChar): TwbBSResultMessage; stdcall;
|
||||||
begin
|
begin
|
||||||
Result.code := Ord(BSA_RESULT_NONE);
|
Result.code := Ord(BSA_RESULT_NONE);
|
||||||
try
|
try
|
||||||
TwbBSArchive(obj).AddFileCompat(String(aFileName), aSize, aData);
|
TwbBSArchive(obj).AddFileDisk(String(aFilePath), String(aSourcePath));
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
exception_handler(E, Result);
|
exception_handler(E, Result);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function bsa_find_file_record(obj: Pointer; const aFileName: PChar): Pointer; stdcall;
|
function bsa_add_file_from_memory(obj: Pointer; const aFilePath: PChar; const aSize: Cardinal; const aData: PByte): TwbBSResultMessage; stdcall;
|
||||||
|
begin
|
||||||
|
Result.code := Ord(BSA_RESULT_NONE);
|
||||||
|
try
|
||||||
|
TwbBSArchive(obj).AddFileDataCompat(String(aFilePath), aSize, aData);
|
||||||
|
except
|
||||||
|
on E: Exception do
|
||||||
|
exception_handler(E, Result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function bsa_find_file_record(obj: Pointer; const aFilePath: PChar): Pointer; stdcall;
|
||||||
begin
|
begin
|
||||||
try
|
try
|
||||||
Result := TwbBSArchive(obj).FindFileRecord(String(aFileName));
|
Result := TwbBSArchive(obj).FindFileRecord(String(aFilePath));
|
||||||
except
|
except
|
||||||
Result := nil
|
Result := nil
|
||||||
end;
|
end;
|
||||||
@@ -212,11 +223,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function bsa_extract_file_data_by_filename(obj: Pointer; const aFileName: PChar): TwbBSResultMessageBuffer; stdcall;
|
function bsa_extract_file_data_by_filename(obj: Pointer; const aFilePath: PChar): TwbBSResultMessageBuffer; stdcall;
|
||||||
begin
|
begin
|
||||||
Result.message.code := Ord(BSA_RESULT_NONE);
|
Result.message.code := Ord(BSA_RESULT_NONE);
|
||||||
try
|
try
|
||||||
Result.buffer := TwbBSArchive(obj).ExtractFileDataCompat(String(aFileName));
|
Result.buffer := TwbBSArchive(obj).ExtractFileDataCompat(String(aFilePath));
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
buffer_exception_handler(E, Result);
|
buffer_exception_handler(E, Result);
|
||||||
@@ -234,11 +245,11 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function bsa_extract_file(obj: Pointer; const aFileName, aSaveAs: PChar): TwbBSResultMessage; stdcall;
|
function bsa_extract_file(obj: Pointer; const aFilePath, aSaveAs: PChar): TwbBSResultMessage; stdcall;
|
||||||
begin
|
begin
|
||||||
Result.code := Ord(BSA_RESULT_NONE);
|
Result.code := Ord(BSA_RESULT_NONE);
|
||||||
try
|
try
|
||||||
TwbBSArchive(obj).ExtractFile(String(aFileName), String(aSaveAs));
|
TwbBSArchive(obj).ExtractFile(String(aFilePath), String(aSaveAs));
|
||||||
except
|
except
|
||||||
on E: Exception do
|
on E: Exception do
|
||||||
exception_handler(E, Result);
|
exception_handler(E, Result);
|
||||||
@@ -256,12 +267,12 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function bsa_file_exists(obj: Pointer; const aFileName: string): Boolean; stdcall;
|
function bsa_file_exists(obj: Pointer; const aFilePath: string): Boolean; stdcall;
|
||||||
begin
|
begin
|
||||||
try
|
try
|
||||||
Result := TwbBSArchive(obj).FileExists(aFileName);
|
Result := TwbBSArchive(obj).FileExists(aFilePath);
|
||||||
except
|
except
|
||||||
Result := False;
|
Result := False;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -401,6 +412,7 @@ exports
|
|||||||
bsa_extract_file_data_by_record,
|
bsa_extract_file_data_by_record,
|
||||||
bsa_find_file_record,
|
bsa_find_file_record,
|
||||||
bsa_add_file_from_memory,
|
bsa_add_file_from_memory,
|
||||||
|
bsa_add_file_from_disk_root,
|
||||||
bsa_add_file_from_disk,
|
bsa_add_file_from_disk,
|
||||||
bsa_save,
|
bsa_save,
|
||||||
bsa_create_archive,
|
bsa_create_archive,
|
||||||
|
|||||||
+2
-1
@@ -8,7 +8,7 @@
|
|||||||
<AppType>Library</AppType>
|
<AppType>Library</AppType>
|
||||||
<FrameworkType>None</FrameworkType>
|
<FrameworkType>None</FrameworkType>
|
||||||
<ProjectVersion>18.6</ProjectVersion>
|
<ProjectVersion>18.6</ProjectVersion>
|
||||||
<Platform Condition="'$(Platform)'==''">Win64</Platform>
|
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||||
<Base>true</Base>
|
<Base>true</Base>
|
||||||
@@ -157,6 +157,7 @@
|
|||||||
<Platform value="Win32">True</Platform>
|
<Platform value="Win32">True</Platform>
|
||||||
<Platform value="Win64">True</Platform>
|
<Platform value="Win64">True</Platform>
|
||||||
</Platforms>
|
</Platforms>
|
||||||
|
<ModelSupport>False</ModelSupport>
|
||||||
</BorlandProject>
|
</BorlandProject>
|
||||||
<ProjectFileVersion>12</ProjectFileVersion>
|
<ProjectFileVersion>12</ProjectFileVersion>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
|
|||||||
+27
-22
@@ -34,32 +34,36 @@ typedef struct bsa_dds_info_s {
|
|||||||
} bsa_dds_info_t;
|
} bsa_dds_info_t;
|
||||||
|
|
||||||
PACKED (
|
PACKED (
|
||||||
typedef struct bsa_dds_header_s {
|
struct bsa_dds_header_s {
|
||||||
uint32_t magic; // DDS_MAGIC
|
uint32_t magic; // DDS_MAGIC
|
||||||
struct DirectX::DDS_HEADER header;
|
struct DirectX::DDS_HEADER header;
|
||||||
} bsa_dds_header_t;
|
});
|
||||||
)
|
|
||||||
|
typedef struct bsa_dds_header_s bsa_dds_header_t;
|
||||||
|
|
||||||
PACKED (
|
PACKED (
|
||||||
typedef struct bsa_result_message_s {
|
struct bsa_result_message_s {
|
||||||
int8_t code; // bsa_result_code_t
|
int8_t code; // bsa_result_code_t
|
||||||
wchar_t text[1024];
|
wchar_t text[1024];
|
||||||
} bsa_result_message_t;
|
});
|
||||||
)
|
|
||||||
|
typedef struct bsa_result_message_s bsa_result_message_t;
|
||||||
|
|
||||||
PACKED (
|
PACKED (
|
||||||
typedef struct bsa_result_buffer_s {
|
struct bsa_result_buffer_s {
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
bsa_buffer_t data;
|
bsa_buffer_t data;
|
||||||
} bsa_result_buffer_t;
|
});
|
||||||
)
|
|
||||||
|
typedef struct bsa_result_buffer_s bsa_result_buffer_t;
|
||||||
|
|
||||||
PACKED (
|
PACKED (
|
||||||
typedef struct bsa_result_message_buffer_s {
|
struct bsa_result_message_buffer_s {
|
||||||
bsa_result_buffer_t buffer;
|
bsa_result_buffer_t buffer;
|
||||||
bsa_result_message_t message;
|
bsa_result_message_t message;
|
||||||
} bsa_result_message_buffer_t;
|
});
|
||||||
)
|
|
||||||
|
typedef struct bsa_result_message_buffer_s bsa_result_message_buffer_t;
|
||||||
|
|
||||||
typedef enum bsa_archive_state_e {
|
typedef enum bsa_archive_state_e {
|
||||||
stReading, stWriting
|
stReading, stWriting
|
||||||
@@ -69,8 +73,8 @@ typedef enum bsa_archive_type_e {
|
|||||||
baNone, baTES3, baTES4, baFO3, baSSE, baFO4, baFO4dds
|
baNone, baTES3, baTES4, baFO3, baSSE, baFO4, baFO4dds
|
||||||
} bsa_archive_type_t;
|
} bsa_archive_type_t;
|
||||||
|
|
||||||
typedef void (*bsa_file_dds_info_proc_t)(bsa_archive_t archive, const wchar_t *filename, bsa_dds_info_t dds_info);
|
typedef void (*bsa_file_dds_info_proc_t)(bsa_archive_t archive, const wchar_t *file_path, bsa_dds_info_t dds_info);
|
||||||
typedef bool (*bsa_file_iteration_proc_t)(bsa_archive_t archive, const wchar_t *filename, bsa_file_record_t file_record, bsa_folder_record_t folder_record, void *context);
|
typedef bool (*bsa_file_iteration_proc_t)(bsa_archive_t archive, const wchar_t *file_path, bsa_file_record_t file_record, bsa_folder_record_t folder_record, void *context);
|
||||||
|
|
||||||
BSARCH_DLL_API(bsa_entry_list_t) bsa_entry_list_create();
|
BSARCH_DLL_API(bsa_entry_list_t) bsa_entry_list_create();
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_free(bsa_entry_list_t entry_list);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_entry_list_free(bsa_entry_list_t entry_list);
|
||||||
@@ -80,18 +84,19 @@ BSARCH_DLL_API(uint32_t) bsa_entry_list_get(bsa_entry_list_t entry_list, uint32_
|
|||||||
|
|
||||||
BSARCH_DLL_API(bsa_archive_t) bsa_create();
|
BSARCH_DLL_API(bsa_archive_t) bsa_create();
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_free(bsa_archive_t archive);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_free(bsa_archive_t archive);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *filename);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_load_from_file(bsa_archive_t archive, const wchar_t *file_path);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_create_archive(bsa_archive_t archive, const wchar_t *filename, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_create_archive(bsa_archive_t archive, const wchar_t *file_path, bsa_archive_type_t archive_type, bsa_entry_list_t entry_list);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_save(bsa_archive_t archive);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_save(bsa_archive_t archive);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *filename);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *source_path);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *filename, uint32_t size, bsa_buffer_t data);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_disk_root(bsa_archive_t archive, const wchar_t *root_dir, const wchar_t *source_path);
|
||||||
BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *filename);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_add_file_from_memory(bsa_archive_t archive, const wchar_t *file_path, uint32_t size, bsa_buffer_t data);
|
||||||
|
BSARCH_DLL_API(bsa_file_record_t) bsa_find_file_record(bsa_archive_t archive, const wchar_t *file_path);
|
||||||
BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_record(bsa_archive_t archive, bsa_file_record_t file_record);
|
BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_record(bsa_archive_t archive, bsa_file_record_t file_record);
|
||||||
BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *filename);
|
BSARCH_DLL_API(bsa_result_message_buffer_t) bsa_extract_file_data_by_filename(bsa_archive_t archive, const wchar_t *file_path);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_file_data_free(bsa_archive_t archive, bsa_result_buffer_t file_data_result);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_file_data_free(bsa_archive_t archive, bsa_result_buffer_t file_data_result);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *filename, const wchar_t *save_as);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_extract_file(bsa_archive_t archive, const wchar_t *file_path, const wchar_t *save_as);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_iterate_files(bsa_archive_t archive, bsa_file_iteration_proc_t file_iteration_proc, void *context);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_iterate_files(bsa_archive_t archive, bsa_file_iteration_proc_t file_iteration_proc, void *context);
|
||||||
BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *filename);
|
BSARCH_DLL_API(bool) bsa_file_exists(bsa_archive_t archive, const wchar_t *file_path);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_get_resource_list(bsa_archive_t archive, bsa_entry_list_t entry_result_list, const wchar_t *folder);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_get_resource_list(bsa_archive_t archive, bsa_entry_list_t entry_result_list, const wchar_t *folder);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_resolve_hash(bsa_archive_t archive, uint64_t hash, bsa_entry_list_t entry_result_list);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_resolve_hash(bsa_archive_t archive, uint64_t hash, bsa_entry_list_t entry_result_list);
|
||||||
BSARCH_DLL_API(bsa_result_message_t) bsa_close(bsa_archive_t archive);
|
BSARCH_DLL_API(bsa_result_message_t) bsa_close(bsa_archive_t archive);
|
||||||
|
|||||||
@@ -149,6 +149,7 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include=".vscode\ipch\c1c5ff332820ca89\mmap_address.bin" />
|
<None Include=".vscode\ipch\c1c5ff332820ca89\mmap_address.bin" />
|
||||||
|
<None Include="cpp.hint" />
|
||||||
<None Include="libbsarch.def" />
|
<None Include="libbsarch.def" />
|
||||||
<None Include="tforge\TFL.inc" />
|
<None Include="tforge\TFL.inc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
<None Include=".vscode\ipch\c1c5ff332820ca89\mmap_address.bin">
|
<None Include=".vscode\ipch\c1c5ff332820ca89\mmap_address.bin">
|
||||||
<Filter>Resource Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="cpp.hint" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="DDS.h">
|
<ClInclude Include="DDS.h">
|
||||||
|
|||||||
+87
-76
@@ -193,11 +193,11 @@ type
|
|||||||
TBSArchiveType = (baNone, baTES3, baTES4, baFO3, baSSE, baFO4, baFO4dds);
|
TBSArchiveType = (baNone, baTES3, baTES4, baFO3, baSSE, baFO4, baFO4dds);
|
||||||
TBSArchiveState = (stReading, stWriting);
|
TBSArchiveState = (stReading, stWriting);
|
||||||
TBSArchiveStates = set of TBSArchiveState;
|
TBSArchiveStates = set of TBSArchiveState;
|
||||||
TBSFileIterationProcCompat = function(aArchive: Pointer; const aFileName: PChar;
|
TBSFileIterationProcCompat = function(aArchive: Pointer; const aFilePath: PChar;
|
||||||
aFileRecord: Pointer; aFolderRecord: Pointer; aContext: Pointer): Boolean; stdcall;
|
aFileRecord: Pointer; aFolderRecord: Pointer; aContext: Pointer): Boolean; stdcall;
|
||||||
|
|
||||||
TDDSInfo = record Width, Height, MipMaps: Integer; end;
|
TDDSInfo = record Width, Height, MipMaps: Integer; end;
|
||||||
TBSFileDDSInfoProcCompat = procedure(aArchive: Pointer; const aFileName: PChar;
|
TBSFileDDSInfoProcCompat = procedure(aArchive: Pointer; const aFilePath: PChar;
|
||||||
var aInfo: TDDSInfo); stdcall;
|
var aInfo: TDDSInfo); stdcall;
|
||||||
|
|
||||||
TwbBSHeaderTES3 = packed record
|
TwbBSHeaderTES3 = packed record
|
||||||
@@ -330,9 +330,9 @@ type
|
|||||||
function GetArchiveFormatName: string;
|
function GetArchiveFormatName: string;
|
||||||
function GetFileCount: Cardinal;
|
function GetFileCount: Cardinal;
|
||||||
procedure SetArchiveFlags(aFlags: Cardinal);
|
procedure SetArchiveFlags(aFlags: Cardinal);
|
||||||
function FindFileRecordTES3(const aFileName: string; var aFileIdx: Integer): Boolean;
|
function FindFileRecordTES3(const aFilePath: string; var aFileIdx: Integer): Boolean;
|
||||||
function FindFileRecordTES4(const aFileName: string; var aFolderIdx, aFileIdx: Integer): Boolean;
|
function FindFileRecordTES4(const aFilePath: string; var aFolderIdx, aFileIdx: Integer): Boolean;
|
||||||
function FindFileRecordFO4(const aFileName: string; var aFileIdx: Integer): Boolean;
|
function FindFileRecordFO4(const aFilePath: string; var aFileIdx: Integer): Boolean;
|
||||||
function GetDDSMipChunkNum(var aDDSInfo: TDDSInfo): Integer;
|
function GetDDSMipChunkNum(var aDDSInfo: TDDSInfo): Integer;
|
||||||
function CalcDataHash(aData: Pointer; aLen: Cardinal): TPackedDataHash;
|
function CalcDataHash(aData: Pointer; aLen: Cardinal): TPackedDataHash;
|
||||||
function FindPackedData(aSize: Cardinal; aHash: TPackedDataHash; aFileRecord: Pointer): Boolean;
|
function FindPackedData(aSize: Cardinal; aHash: TPackedDataHash; aFileRecord: Pointer): Boolean;
|
||||||
@@ -342,19 +342,20 @@ type
|
|||||||
Sync: IReadWriteSync;
|
Sync: IReadWriteSync;
|
||||||
constructor Create;
|
constructor Create;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
procedure LoadFromFile(const aFileName: string);
|
procedure LoadFromFile(const aFilePath: string);
|
||||||
procedure CreateArchiveCompat(const aFileName: string; aType: TBSArchiveType;
|
procedure CreateArchiveCompat(const aFilePath: string; aType: TBSArchiveType;
|
||||||
aFilesList: TwbBSEntryList = nil);
|
aFilesList: TwbBSEntryList = nil);
|
||||||
procedure Save;
|
procedure Save;
|
||||||
procedure AddFile(const aRootDir, aFileName: string); overload;
|
procedure AddFileDisk(const aFilePath, aSourcePath: string);
|
||||||
procedure AddFileCompat(const aFileName: string; const aSize: Cardinal; const aData: PByte);
|
procedure AddFileDiskRoot(const aRootDir, aSourcePath: string);
|
||||||
function FindFileRecord(const aFileName: string): Pointer;
|
procedure AddFileDataCompat(const aFilePath: string; const aSize: Cardinal; const aData: PByte);
|
||||||
|
function FindFileRecord(const aFilePath: string): Pointer;
|
||||||
function ExtractFileDataCompat(aFileRecord: Pointer): TwbBSResultBuffer; overload;
|
function ExtractFileDataCompat(aFileRecord: Pointer): TwbBSResultBuffer; overload;
|
||||||
function ExtractFileDataCompat(const aFileName: string): TwbBSResultBuffer; overload;
|
function ExtractFileDataCompat(const aFilePath: string): TwbBSResultBuffer; overload;
|
||||||
procedure ReleaseFileDataCompat(fileDataResult: TwbBSResultBuffer);
|
procedure ReleaseFileDataCompat(fileDataResult: TwbBSResultBuffer);
|
||||||
procedure ExtractFile(const aFileName, aSaveAs: string);
|
procedure ExtractFile(const aFilePath, aSaveAs: string);
|
||||||
procedure IterateFilesCompat(aProc: TBSFileIterationProcCompat; aContext: Pointer = nil);
|
procedure IterateFilesCompat(aProc: TBSFileIterationProcCompat; aContext: Pointer = nil);
|
||||||
function FileExists(const aFileName: string): Boolean;
|
function FileExists(const aFilePath: string): Boolean;
|
||||||
procedure ResourceListCompat(const aEntryResultList: TwbBSEntryList; aFolder: string = '');
|
procedure ResourceListCompat(const aEntryResultList: TwbBSEntryList; aFolder: string = '');
|
||||||
procedure ResolveHashCompat(const aHash: UInt64; const aEntryResultList: TwbBSEntryList);
|
procedure ResolveHashCompat(const aHash: UInt64; const aEntryResultList: TwbBSEntryList);
|
||||||
procedure Close;
|
procedure Close;
|
||||||
@@ -371,11 +372,11 @@ type
|
|||||||
property DDSInfoProc: TBSFileDDSInfoProcCompat read fDDSInfoProc write fDDSInfoProc;
|
property DDSInfoProc: TBSFileDDSInfoProcCompat read fDDSInfoProc write fDDSInfoProc;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SplitDirName(const aFileName: string; var Dir, Name: string): Integer;
|
function SplitDirName(const aFilePath: string; var Dir, Name: string): Integer;
|
||||||
function SplitNameExt(const aFileName: string; var Name, Ext: string): Integer;
|
function SplitNameExt(const aFilePath: string; var Name, Ext: string): Integer;
|
||||||
function CreateHashTES3(const aFileName: string): UInt64;
|
function CreateHashTES3(const aFilePath: string): UInt64;
|
||||||
function CreateHashTES4(const aFileName: string): UInt64; overload;
|
function CreateHashTES4(const aFilePath: string): UInt64; overload;
|
||||||
function CreateHashFO4(const aFileName: string): Cardinal;
|
function CreateHashFO4(const aFilePath: string): Cardinal;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@@ -594,35 +595,35 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SplitDirName(const aFileName: string; var Dir, Name: string): Integer;
|
function SplitDirName(const aFilePath: string; var Dir, Name: string): Integer;
|
||||||
begin
|
begin
|
||||||
Result := LastCharPos(aFileName, '\');
|
Result := LastCharPos(aFilePath, '\');
|
||||||
if Result = 0 then
|
if Result = 0 then
|
||||||
Result := LastCharPos(aFileName, '/');
|
Result := LastCharPos(aFilePath, '/');
|
||||||
Dir := Copy(aFileName, 1, Pred(Result));
|
Dir := Copy(aFilePath, 1, Pred(Result));
|
||||||
Name := Copy(aFileName, Succ(Result), Length(aFileName) - Result);
|
Name := Copy(aFilePath, Succ(Result), Length(aFilePath) - Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function SplitNameExt(const aFileName: string; var Name, Ext: string): Integer;
|
function SplitNameExt(const aFilePath: string; var Name, Ext: string): Integer;
|
||||||
begin
|
begin
|
||||||
Result := LastCharPos(aFileName, '.');
|
Result := LastCharPos(aFilePath, '.');
|
||||||
if Result <> 0 then begin
|
if Result <> 0 then begin
|
||||||
Name := Copy(aFileName, 1, Pred(Result));
|
Name := Copy(aFilePath, 1, Pred(Result));
|
||||||
Ext := Copy(aFileName, Result, Length(aFileName) - Result + 2);
|
Ext := Copy(aFilePath, Result, Length(aFilePath) - Result + 2);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
Name := aFileName;
|
Name := aFilePath;
|
||||||
Ext := '';
|
Ext := '';
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CreateHashTES3(const aFileName: string): UInt64;
|
function CreateHashTES3(const aFilePath: string): UInt64;
|
||||||
var
|
var
|
||||||
s: AnsiString;
|
s: AnsiString;
|
||||||
i, l: integer;
|
i, l: integer;
|
||||||
sum, off, temp, n: Cardinal;
|
sum, off, temp, n: Cardinal;
|
||||||
begin
|
begin
|
||||||
s := AnsiString(aFileName);
|
s := AnsiString(aFilePath);
|
||||||
l := Length(s) shr 1;
|
l := Length(s) shr 1;
|
||||||
|
|
||||||
sum := 0; off := 0;
|
sum := 0; off := 0;
|
||||||
@@ -689,22 +690,22 @@ begin
|
|||||||
Result := Result + UInt64(hash) shl 32;
|
Result := Result + UInt64(hash) shl 32;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CreateHashTES4(const aFileName: string): UInt64; overload;
|
function CreateHashTES4(const aFilePath: string): UInt64; overload;
|
||||||
var
|
var
|
||||||
fname, fext: string;
|
fname, fext: string;
|
||||||
begin
|
begin
|
||||||
SplitNameExt(aFileName, fname, fext);
|
SplitNameExt(aFilePath, fname, fext);
|
||||||
Result := CreateHashTES4(fname, fext);
|
Result := CreateHashTES4(fname, fext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CreateHashFO4(const aFileName: string): Cardinal;
|
function CreateHashFO4(const aFilePath: string): Cardinal;
|
||||||
var
|
var
|
||||||
i: Integer;
|
i: Integer;
|
||||||
s: AnsiString;
|
s: AnsiString;
|
||||||
c: AnsiChar;
|
c: AnsiChar;
|
||||||
begin
|
begin
|
||||||
Result := 0;
|
Result := 0;
|
||||||
s := AnsiString(aFileName);
|
s := AnsiString(aFilePath);
|
||||||
for i := 1 to Length(s) do begin
|
for i := 1 to Length(s) do begin
|
||||||
c := s[i];
|
c := s[i];
|
||||||
if Byte(c) > 127 then Continue;
|
if Byte(c) > 127 then Continue;
|
||||||
@@ -777,12 +778,12 @@ begin
|
|||||||
fHeaderTES4.Flags := fHeaderTES4.Flags or ARCHIVE_COMPRESS;
|
fHeaderTES4.Flags := fHeaderTES4.Flags or ARCHIVE_COMPRESS;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TwbBSArchive.FindFileRecordTES3(const aFileName: string; var aFileIdx: Integer): Boolean;
|
function TwbBSArchive.FindFileRecordTES3(const aFilePath: string; var aFileIdx: Integer): Boolean;
|
||||||
var
|
var
|
||||||
h: UInt64;
|
h: UInt64;
|
||||||
i: integer;
|
i: integer;
|
||||||
begin
|
begin
|
||||||
h := CreateHashTES3(aFileName);
|
h := CreateHashTES3(aFilePath);
|
||||||
|
|
||||||
Result := False;
|
Result := False;
|
||||||
for i := Low(fFilesTES3) to High(fFilesTES3) do
|
for i := Low(fFilesTES3) to High(fFilesTES3) do
|
||||||
@@ -793,13 +794,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TwbBSArchive.FindFileRecordTES4(const aFileName: string; var aFolderIdx, aFileIdx: Integer): Boolean;
|
function TwbBSArchive.FindFileRecordTES4(const aFilePath: string; var aFolderIdx, aFileIdx: Integer): Boolean;
|
||||||
var
|
var
|
||||||
fdir, fname, name, ext: string;
|
fdir, fname, name, ext: string;
|
||||||
h: UInt64;
|
h: UInt64;
|
||||||
i, j: integer;
|
i, j: integer;
|
||||||
begin
|
begin
|
||||||
if SplitDirName(aFileName, fdir, fname) = 0 then
|
if SplitDirName(aFilePath, fdir, fname) = 0 then
|
||||||
Exit(False);
|
Exit(False);
|
||||||
|
|
||||||
Result := False;
|
Result := False;
|
||||||
@@ -829,14 +830,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TwbBSArchive.FindFileRecordFO4(const aFileName: string; var aFileIdx: Integer): Boolean;
|
function TwbBSArchive.FindFileRecordFO4(const aFilePath: string; var aFileIdx: Integer): Boolean;
|
||||||
var
|
var
|
||||||
fdir, fname, name, ext: string;
|
fdir, fname, name, ext: string;
|
||||||
hdir, hfile: Cardinal;
|
hdir, hfile: Cardinal;
|
||||||
hext: TMagic4;
|
hext: TMagic4;
|
||||||
i: integer;
|
i: integer;
|
||||||
begin
|
begin
|
||||||
if SplitDirName(aFileName, fdir, fname) = 0 then
|
if SplitDirName(aFilePath, fdir, fname) = 0 then
|
||||||
Exit(False);
|
Exit(False);
|
||||||
|
|
||||||
SplitNameExt(fname, name, ext);
|
SplitNameExt(fname, name, ext);
|
||||||
@@ -855,7 +856,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TwbBSArchive.FindFileRecord(const aFileName: string): Pointer;
|
function TwbBSArchive.FindFileRecord(const aFilePath: string): Pointer;
|
||||||
var
|
var
|
||||||
i, j: integer;
|
i, j: integer;
|
||||||
begin
|
begin
|
||||||
@@ -863,11 +864,11 @@ begin
|
|||||||
|
|
||||||
case fType of
|
case fType of
|
||||||
baTES3:
|
baTES3:
|
||||||
if FindFileRecordTES3(aFileName, i) then Result := @fFilesTES3[i];
|
if FindFileRecordTES3(aFilePath, i) then Result := @fFilesTES3[i];
|
||||||
baTES4, baFO3, baSSE:
|
baTES4, baFO3, baSSE:
|
||||||
if FindFileRecordTES4(aFileName, i, j) then Result := @fFoldersTES4[i].Files[j];
|
if FindFileRecordTES4(aFilePath, i, j) then Result := @fFoldersTES4[i].Files[j];
|
||||||
baFO4, baFO4dds:
|
baFO4, baFO4dds:
|
||||||
if FindFileRecordFO4(aFileName, i) then Result := @fFilesFO4[i];
|
if FindFileRecordFO4(aFilePath, i) then Result := @fFilesFO4[i];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -951,14 +952,14 @@ begin
|
|||||||
Inc(fPackedDataCount);
|
Inc(fPackedDataCount);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TwbBSArchive.LoadFromFile(const aFileName: string);
|
procedure TwbBSArchive.LoadFromFile(const aFilePath: string);
|
||||||
var
|
var
|
||||||
i, j: Integer;
|
i, j: Integer;
|
||||||
begin
|
begin
|
||||||
if fStates * [stReading, stWriting] <> [] then
|
if fStates * [stReading, stWriting] <> [] then
|
||||||
Close;
|
Close;
|
||||||
|
|
||||||
fStream := TwbReadOnlyCachedFileStream.Create(aFileName, fmOpenRead or fmShareDenyWrite);
|
fStream := TwbReadOnlyCachedFileStream.Create(aFilePath, fmOpenRead or fmShareDenyWrite);
|
||||||
|
|
||||||
// magic
|
// magic
|
||||||
fMagic := Int2Magic(fStream.ReadCardinal);
|
fMagic := Int2Magic(fStream.ReadCardinal);
|
||||||
@@ -1099,7 +1100,7 @@ begin
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
fFileName := aFileName;
|
fFileName := aFilePath;
|
||||||
Include(fStates, stReading);
|
Include(fStates, stReading);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -1131,7 +1132,7 @@ begin
|
|||||||
Result := CompareStr(List[Index1], List[Index2]);
|
Result := CompareStr(List[Index1], List[Index2]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TwbBSArchive.CreateArchiveCompat(const aFileName: string; aType: TBSArchiveType;
|
procedure TwbBSArchive.CreateArchiveCompat(const aFilePath: string; aType: TBSArchiveType;
|
||||||
aFilesList: TwbBSEntryList = nil);
|
aFilesList: TwbBSEntryList = nil);
|
||||||
var
|
var
|
||||||
HashPairs: array of THashPair;
|
HashPairs: array of THashPair;
|
||||||
@@ -1371,8 +1372,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
fStream := TwbWriteCachedFileStream.Create(aFileName, fmCreate);
|
fStream := TwbWriteCachedFileStream.Create(aFilePath, fmCreate);
|
||||||
fFileName := aFileName;
|
fFileName := aFilePath;
|
||||||
Include(fStates, stWriting);
|
Include(fStates, stWriting);
|
||||||
|
|
||||||
// reserve space for the header
|
// reserve space for the header
|
||||||
@@ -1532,7 +1533,9 @@ begin
|
|||||||
Close;
|
Close;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TwbBSArchive.AddFile(const aRootDir, aFileName: string);
|
|
||||||
|
|
||||||
|
procedure TwbBSArchive.AddFileDisk(const aFilePath, aSourcePath: string);
|
||||||
var
|
var
|
||||||
fname: string;
|
fname: string;
|
||||||
i: integer;
|
i: integer;
|
||||||
@@ -1542,18 +1545,12 @@ begin
|
|||||||
if not (stWriting in fStates) then
|
if not (stWriting in fStates) then
|
||||||
raise Exception.Create('Archive is not in writing mode');
|
raise Exception.Create('Archive is not in writing mode');
|
||||||
|
|
||||||
i := Length(aRootDir);
|
stream := TFileStream.Create(aSourcePath, fmOpenRead + fmShareDenyNone);
|
||||||
if (i > 1) and (aRootDir[Length(aRootDir)] <> '\') then
|
|
||||||
Inc(i);
|
|
||||||
|
|
||||||
fname := Copy(aFileName, i + 1, Length(aFileName));
|
|
||||||
|
|
||||||
stream := TFileStream.Create(aFileName, fmOpenRead + fmShareDenyNone);
|
|
||||||
try
|
try
|
||||||
GetMem(buffer, stream.Size);
|
GetMem(buffer, stream.Size);
|
||||||
try
|
try
|
||||||
stream.Read(buffer^, stream.Size);
|
stream.Read(buffer^, stream.Size);
|
||||||
AddFileCompat(fname, stream.Size, buffer);
|
AddFileDataCompat(aFilePath, stream.Size, buffer);
|
||||||
finally
|
finally
|
||||||
if Assigned(buffer) then
|
if Assigned(buffer) then
|
||||||
FreeMem(buffer);
|
FreeMem(buffer);
|
||||||
@@ -1563,8 +1560,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TwbBSArchive.AddFileDiskRoot(const aRootDir, aSourcePath: string);
|
||||||
|
var
|
||||||
|
fname: string;
|
||||||
|
i: integer;
|
||||||
|
begin
|
||||||
|
i := Length(aRootDir);
|
||||||
|
if (i > 1) and (aRootDir[Length(aRootDir)] <> '\') then
|
||||||
|
Inc(i);
|
||||||
|
|
||||||
|
fname := Copy(aSourcePath, i + 1, Length(aSourcePath));
|
||||||
|
|
||||||
|
AddFileDisk(fname, aSourcePath);
|
||||||
|
end;
|
||||||
|
|
||||||
// Modified: Version for use in non-Borland C/C++
|
// Modified: Version for use in non-Borland C/C++
|
||||||
procedure TwbBSArchive.AddFileCompat(const aFileName: string; const aSize: Cardinal; const aData: PByte);
|
procedure TwbBSArchive.AddFileDataCompat(const aFilePath: string; const aSize: Cardinal; const aData: PByte);
|
||||||
var
|
var
|
||||||
i, j, Off, MipSize, BitsPerPixel: integer;
|
i, j, Off, MipSize, BitsPerPixel: integer;
|
||||||
fdir, fname, name, ext: string;
|
fdir, fname, name, ext: string;
|
||||||
@@ -1589,8 +1600,8 @@ begin
|
|||||||
try
|
try
|
||||||
case fType of
|
case fType of
|
||||||
baTES3: begin
|
baTES3: begin
|
||||||
if not FindFileRecordTES3(aFileName, i) then
|
if not FindFileRecordTES3(aFilePath, i) then
|
||||||
raise Exception.Create('File not found in files table: ' + aFileName);
|
raise Exception.Create('File not found in files table: ' + aFilePath);
|
||||||
|
|
||||||
if FindPackedData(aSize, DataHash, @fFilesTES3[i]) then
|
if FindPackedData(aSize, DataHash, @fFilesTES3[i]) then
|
||||||
Exit;
|
Exit;
|
||||||
@@ -1602,8 +1613,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
baTES4, baFO3, baSSE: begin
|
baTES4, baFO3, baSSE: begin
|
||||||
if not FindFileRecordTES4(aFileName, i, j) then
|
if not FindFileRecordTES4(aFilePath, i, j) then
|
||||||
raise Exception.Create('File not found in files table: ' + aFileName);
|
raise Exception.Create('File not found in files table: ' + aFilePath);
|
||||||
|
|
||||||
if FindPackedData(aSize, DataHash, @fFoldersTES4[i].Files[j]) then
|
if FindPackedData(aSize, DataHash, @fFoldersTES4[i].Files[j]) then
|
||||||
Exit;
|
Exit;
|
||||||
@@ -1669,8 +1680,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
baFO4: begin
|
baFO4: begin
|
||||||
if SplitDirName(aFileName, fdir, fname) = 0 then
|
if SplitDirName(aFilePath, fdir, fname) = 0 then
|
||||||
raise Exception.Create('File is missing the folder part: ' + aFileName);
|
raise Exception.Create('File is missing the folder part: ' + aFilePath);
|
||||||
|
|
||||||
SplitNameExt(fname, name, ext);
|
SplitNameExt(fname, name, ext);
|
||||||
if Length(ext) > 1 then Delete(ext, 1, 1); // no dot in extension
|
if Length(ext) > 1 then Delete(ext, 1, 1); // no dot in extension
|
||||||
@@ -1678,7 +1689,7 @@ begin
|
|||||||
i := fHeaderFO4.FileCount;
|
i := fHeaderFO4.FileCount;
|
||||||
Inc(fHeaderFO4.FileCount);
|
Inc(fHeaderFO4.FileCount);
|
||||||
// archive2.exe uses /
|
// archive2.exe uses /
|
||||||
fFilesFO4[i].Name := StringReplace(aFileName, '\', '/', [rfReplaceAll]);
|
fFilesFO4[i].Name := StringReplace(aFilePath, '\', '/', [rfReplaceAll]);
|
||||||
fFilesFO4[i].DirHash := CreateHashFO4(fdir);
|
fFilesFO4[i].DirHash := CreateHashFO4(fdir);
|
||||||
fFilesFO4[i].NameHash := CreateHashFO4(name);
|
fFilesFO4[i].NameHash := CreateHashFO4(name);
|
||||||
fFilesFO4[i].Ext := Int2Magic(Str2MagicInt(ext));
|
fFilesFO4[i].Ext := Int2Magic(Str2MagicInt(ext));
|
||||||
@@ -1711,8 +1722,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
baFO4dds: begin
|
baFO4dds: begin
|
||||||
if SplitDirName(aFileName, fdir, fname) = 0 then
|
if SplitDirName(aFilePath, fdir, fname) = 0 then
|
||||||
raise Exception.Create('File is missing the folder part: ' + aFileName);
|
raise Exception.Create('File is missing the folder part: ' + aFilePath);
|
||||||
|
|
||||||
SplitNameExt(fname, name, ext);
|
SplitNameExt(fname, name, ext);
|
||||||
if Length(ext) > 1 then Delete(ext, 1, 1); // no dot in extension
|
if Length(ext) > 1 then Delete(ext, 1, 1); // no dot in extension
|
||||||
@@ -1721,7 +1732,7 @@ begin
|
|||||||
i := fHeaderFO4.FileCount;
|
i := fHeaderFO4.FileCount;
|
||||||
Inc(fHeaderFO4.FileCount);
|
Inc(fHeaderFO4.FileCount);
|
||||||
// archive2.exe uses /
|
// archive2.exe uses /
|
||||||
fFilesFO4[i].Name := StringReplace(aFileName, '\', '/', [rfReplaceAll]);
|
fFilesFO4[i].Name := StringReplace(aFilePath, '\', '/', [rfReplaceAll]);
|
||||||
fFilesFO4[i].DirHash := CreateHashFO4(fdir);
|
fFilesFO4[i].DirHash := CreateHashFO4(fdir);
|
||||||
fFilesFO4[i].NameHash := CreateHashFO4(name);
|
fFilesFO4[i].NameHash := CreateHashFO4(name);
|
||||||
fFilesFO4[i].Ext := Int2Magic(Str2MagicInt(ext));
|
fFilesFO4[i].Ext := Int2Magic(Str2MagicInt(ext));
|
||||||
@@ -2197,14 +2208,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// Modified: Version for use in non-Borland C/C++
|
// Modified: Version for use in non-Borland C/C++
|
||||||
function TwbBSArchive.ExtractFileDataCompat(const aFileName: string): TwbBSResultBuffer;
|
function TwbBSArchive.ExtractFileDataCompat(const aFilePath: string): TwbBSResultBuffer;
|
||||||
var
|
var
|
||||||
FileRecord: Pointer;
|
FileRecord: Pointer;
|
||||||
begin
|
begin
|
||||||
if not (stReading in fStates) then
|
if not (stReading in fStates) then
|
||||||
raise Exception.Create('Archive is not loaded');
|
raise Exception.Create('Archive is not loaded');
|
||||||
|
|
||||||
FileRecord := FindFileRecord(aFileName);
|
FileRecord := FindFileRecord(aFilePath);
|
||||||
|
|
||||||
if not Assigned(FileRecord) then
|
if not Assigned(FileRecord) then
|
||||||
raise Exception.Create('File not found in archive');
|
raise Exception.Create('File not found in archive');
|
||||||
@@ -2219,7 +2230,7 @@ begin
|
|||||||
fileDataResult.size := 0;
|
fileDataResult.size := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TwbBSArchive.ExtractFile(const aFileName, aSaveAs: string);
|
procedure TwbBSArchive.ExtractFile(const aFilePath, aSaveAs: string);
|
||||||
var
|
var
|
||||||
fs: TFileStream;
|
fs: TFileStream;
|
||||||
fileData: TwbBSResultBuffer;
|
fileData: TwbBSResultBuffer;
|
||||||
@@ -2229,7 +2240,7 @@ begin
|
|||||||
|
|
||||||
fs := TFileStream.Create(aSaveAs, fmCreate);
|
fs := TFileStream.Create(aSaveAs, fmCreate);
|
||||||
try
|
try
|
||||||
fileData := ExtractFileDataCompat(aFileName);
|
fileData := ExtractFileDataCompat(aFilePath);
|
||||||
fs.Write(fileData.data[0], fileData.size);
|
fs.Write(fileData.data[0], fileData.size);
|
||||||
finally
|
finally
|
||||||
ReleaseFileDataCompat(fileData);
|
ReleaseFileDataCompat(fileData);
|
||||||
@@ -2285,9 +2296,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TwbBSArchive.FileExists(const aFileName: string): Boolean;
|
function TwbBSArchive.FileExists(const aFilePath: string): Boolean;
|
||||||
begin
|
begin
|
||||||
Result := Assigned(FindFileRecord(aFileName));
|
Result := Assigned(FindFileRecord(aFilePath));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TwbBSArchive.Close;
|
procedure TwbBSArchive.Close;
|
||||||
|
|||||||
Reference in New Issue
Block a user