Skip to content

cm3d2.dll API

Geoffrey Horsington edited this page Jan 1, 2019 · 25 revisions

Filesystem types

CM3D2.dll recognizes two filesystem types: Windows (0) and Archive (1).

Filesystem structures

Externally, a filesystem is a struct:

struct FileSystem {
    int* internals_ptr;    // Pointer to the internal structure
    int  fs_type;          // Type of the filesystem (0 = windows, 1 = archive)
};

Internal file system

An internal file system consists of the following interfaces: InterfaceFileShare, InterfaceFileSystemAnsi, InterfaceFileSystemWide, InterfaceFileSystemUtf8, InterfaceFileSystem.

Archive internals

Internally, the class of

The archives' internals contains the following values.

The location is in bytes and relative to structure's start address.

| Type | Location (HEX) | Notes | | -------- | -------- | -------- | -------- | | Address | 0 | Pointer to a part of vftable for FileSystemArchive | | Address | 8 | Pointer to compile-time constant; Value: 0xF8FF FFFF 7000 0000 | | Address | 10 | Pointer to a part of vftable for FileSystemArchive | | Address | 18 | Pointer to compile-time constant; Value: 0xF8FF FFFF 6000 0000 | | Address | 20 | Pointer to a part of vftable for FileSystemArchive | | Address | 28 | Pointer to compile-time constant; Value: 0xF8FF FFFF 5000 0000 | | std::wstring | 30 - 50 | Current base directory | | std::list | 58-60 | List of loaded ARCs? | | Value | 68 | 0x0 | NULL | | Value | 70 | Junk? | | Address | 78 | Pointer to vftable of FileSystemArchive |

Notes

  • Only the 4 top bytes are used fron 8, 18 and 28. Thus essentially they contain values 70, 60 and 50 respectively
  • qword at 0x7FFF26350DE8 contains a running counter (of how many filesystems are initialized?)

FileSystemArchive

Signature:

public class FileSystemArchive: public InterfaceFileSystem;

public class InterfaceFileSystem: public InterfaceFileSystemAnsi, public InterfaceFileSystemWide, public InterfaceFileSystemUtf8;

public class InterfaceFileSystemAnsi: public InterfaceFileShare;
public class InterfaceFileSystemWide: public InterfaceFileShare;
public class InterfaceFileSystemUtf8: public InterfaceFileShare;

public virtual class InterfaceFileShare;

FileSystemArchive has the following functions:

First VFTable

Index Function signature
0
1
2
3
4 Internal function for SetBaseDirectory
5 void SetBaseDirectory(*this, char* path)
6 Internal function for AddArchive
7
8 Internal for AddArchive
9 void AddArchive(*this, char* path)
10 void AddAutoPathForAllFolder(*this)
11
12
13 void AddAutoPath(*this, char* path)
14
15
16
17
18
19
20
21 Pointer to _LocaleUpdate::GetLocaleT()

Second VFTable (implements InterfaceFileSystemWide)

Index Function signature
0 GetFileW(this, wchar_t* path)
1
2 CreateFileListW(this, std::vector<std::wstring>* vec, wchar_t* path, ListType list_type)

Third VFTable

Index Function signature
0 FileMemory* GetFile(*this, char* file_str)
1
2 std::vector<std::string*>* CreateList(*this, std::vector<std::string*>* vector, char* path, ListType list_type)
3 (NOTE: Is structure; likely a lambda)
4
5
6
7
8 BOOL IsExistentFile(*this, char* path)
9
10

Fourth VFTable (InterfaceFileShare)

Index Function signature
0 bool IsValid(*this)
1

File lists

A file list is a struct

struct FileListData 
{
    std::vector<std::string*> *file_list;
    int size;
}

The pointer to the vector is a simple IntPtr in C#.

File

The API provides two main file types: Win32File (WINAPI), FileNormalWindows (C file API), FileMemory (memory).

VTable structure:

Index Function signature Notes
0 FileMemory* FileMemory::dispose(this, bool disposing) Disposes of the object and file pointer
1 bool FileMemory::close_file(this) Closes and frees raw file handler/pointer. Returns true if failed (?)
2 bool FileMemory::seek(this, uint64_t dist, bool absolute) Moves the read header by the given number of bytes absolutely or relatively. Return true on success
3 uint64_t FileMemory::read(this, void* buffer, uint64_t length) Reads at most length bytes into the given buffer. Returns the number of bytes actually read
4 uint64_t FileMemory::read_from(this, void* buffer, uint64_t pos, uint64_t length) Reads at most length bytes into the given buffer from absolute position pos. Returns the number of bytes actually read
5 bool FileMemory::is_open(this) Checks whether the file is open
6 void* FileMemory::get_data_ptr(this) Returns pointer to the data this FileMemory handles. Pretty much like c_ptr().
7 uint64_t FileMemory::tell(this) Current read position
8 uint64_t FileMemory::length(this) Total size of the current file
9 bool FileMemory::set_file(this, void* data_ptr, uint64_t data_length, uint64_t file_offset) Initializes this FileMemory to track the given data from the specified offset. file_offset allows to track only a slice of the file instead of the whole file
10 bool FileMemory::change_file_ptr2(this, void* data_ptr, uint64_t data_length, uint64_t file_offset) Does pretty much the same thing as set_file. Don't know why there is a duplicate.
11 size_t FileMemory::move_memory(this, void* dest, void* src, size_t len) Moves data from one place to another.
Clone this wiki locally