diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/FileDescriptor.cs b/FFXIVClientStructs/FFXIV/Client/System/File/FileDescriptor.cs index ec5df4ed22..b2a44310b7 100644 --- a/FFXIVClientStructs/FFXIV/Client/System/File/FileDescriptor.cs +++ b/FFXIVClientStructs/FFXIV/Client/System/File/FileDescriptor.cs @@ -8,7 +8,7 @@ public unsafe partial struct FileDescriptor { [FieldOffset(0x8)] public byte* FileBuffer; [FieldOffset(0x10)] public ulong FileLength; [FieldOffset(0x18)] public ulong CurrentFileOffset; - [FieldOffset(0x30)] public void* FileInterface; // Client::System::File::FileInterface + [FieldOffset(0x30)] public FileInterface* FileInterface; // Client::System::File::FileInterface [FieldOffset(0x60)] public FileDescriptor* Previous; // believe its a queue [FieldOffset(0x68)] public FileDescriptor* Next; [FieldOffset(0x70), FixedSizeArray(isString: true)] internal FixedSizeArray260 _filePath; diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/FileInterface.cs b/FFXIVClientStructs/FFXIV/Client/System/File/FileInterface.cs new file mode 100644 index 0000000000..40d41e882b --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/File/FileInterface.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FFXIVClientStructs.FFXIV.Client.System.File; + +[GenerateInterop] +[StructLayout(LayoutKind.Explicit, Size = 0x230)] +public unsafe partial struct FileInterface { + [FieldOffset(0x10)] public nint FileHandle; + [FieldOffset(0x20)] public bool IsOpen; + + [MemberFunction("E8 ?? ?? ?? ?? 33 F6 45 32 F6")] + public partial void Ctor(); + + [MemberFunction("E8 ?? ?? ?? ?? 0F B6 C8 3C 01"), GenerateStringOverloads] + public partial sbyte Open(CStringPointer filePath,int openMode); + + [MemberFunction("E8 ?? ?? ?? ?? 8B 05 ?? ?? ?? ?? EB 18")] + public partial sbyte Close(); + + [MemberFunction("E8 ?? ?? ?? ?? 89 1F 33 C0")] + public partial sbyte Read(void* buffer,ulong size); + + [MemberFunction("E8 ?? ?? ?? ?? 48 8B 44 24 ?? 48 03 E8")] + public partial sbyte ReadWithOffset(void* buffer, ulong size, ulong offset); + + [MemberFunction("E8 ?? ?? ?? ?? 41 3A C7 75 0E")] + public partial sbyte Write(void* buffer, ulong size); + + [MemberFunction("E8 ?? ?? ?? ?? 49 2B C6")] + public partial ulong GetFileSize(); +} diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/FileThread.cs b/FFXIVClientStructs/FFXIV/Client/System/File/FileThread.cs index bd095f0566..35b28cf75b 100644 --- a/FFXIVClientStructs/FFXIV/Client/System/File/FileThread.cs +++ b/FFXIVClientStructs/FFXIV/Client/System/File/FileThread.cs @@ -3,7 +3,9 @@ namespace FFXIVClientStructs.FFXIV.Client.System.File; // Client::System::File::FileThread // Client::System::Threading::Thread // Client::System::Common::NonCopyable +[GenerateInterop] [StructLayout(LayoutKind.Explicit, Size = 0x2518)] -public unsafe struct FileThread { +public unsafe partial struct FileThread { [FieldOffset(0x0008)] public void* SecurityAttributes; // https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-createeventa + [FieldOffset(0x0028), FixedSizeArray] internal FixedSizeArray20> _sqPackManagers; } diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/SqPackHeader.cs b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackHeader.cs new file mode 100644 index 0000000000..552c8078f8 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackHeader.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FFXIVClientStructs.FFXIV.Client.System.File; +// https://github.com/NotAdam/Lumina/blob/12d0e8d418d8dc49f04e6bee1d06bae2905232c6/src/Lumina/Data/Structs/SqPackHeader.cs +public enum PlatformId : byte { + Win32, + PS3, + PS4, + PS5, + Lys // Xbox +} + +[GenerateInterop] +[StructLayout(LayoutKind.Explicit, Size = 0x400)] +public partial struct SqPackHeader { + [FieldOffset(0x000)] internal FixedSizeArray8 Magic; + [FieldOffset(0x008)] public PlatformId PlatformId; + //[FieldOffset(0x009)] internal byte[] Unknown; + [FieldOffset(0x00C)] public uint Size; + [FieldOffset(0x010)] public uint Version; + [FieldOffset(0x014)] public uint Type; +} diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/SqPackIndexHeader.cs b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackIndexHeader.cs new file mode 100644 index 0000000000..91b0504cf5 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackIndexHeader.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace FFXIVClientStructs.FFXIV.Client.System.File; + +//https://github.com/NotAdam/Lumina/blob/12d0e8d418d8dc49f04e6bee1d06bae2905232c6/src/Lumina/Data/Structs/SqPackIndexHeader.cs +[StructLayout(LayoutKind.Explicit, Size = 0x400)] +public unsafe struct SqPackIndexHeader { + [FieldOffset(0x000)] public uint Size; + [FieldOffset(0x004)] public uint Version; + [FieldOffset(0x008)] public uint IndexDataOffset; + [FieldOffset(0x00C)] public uint IndexDataSize; + [FieldOffset(0x010)] public fixed byte IndexDataHash[64]; + [FieldOffset(0x050)] public uint NumberOfDataFile; + [FieldOffset(0x054)] public uint SynonymDataOffset; + [FieldOffset(0x058)] public uint SynonymDataSize; + [FieldOffset(0x05C)] public fixed byte SynonymDataHash[64]; + [FieldOffset(0x09C)] public uint EmptyBlockDataOffset; + [FieldOffset(0x0A0)] public uint EmptyBlockDataSize; + [FieldOffset(0x0A4)] public fixed byte EmptyBlockDataHash[64]; + [FieldOffset(0x0E4)] public uint DirIndexDataOffset; + [FieldOffset(0x0E8)] public uint DirIndexDataSize; + [FieldOffset(0x0EC)] public fixed byte DirIndexDataHash[64]; + [FieldOffset(0x12C)] public uint IndexType; + [FieldOffset(0x130)] internal fixed byte Reserved[656]; + [FieldOffset(0x3C0)] public fixed byte SelfHash[64]; +} diff --git a/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs new file mode 100644 index 0000000000..d4df8193f1 --- /dev/null +++ b/FFXIVClientStructs/FFXIV/Client/System/File/SqPackManager.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Text; +using FFXIVClientStructs.FFXIV.Client.System.Resource; +using FFXIVClientStructs.FFXIV.Component.GUI; + +namespace FFXIVClientStructs.FFXIV.Client.System.File; + +[GenerateInterop] +[StructLayout(LayoutKind.Explicit, Size = 0xAF0)] +public unsafe partial struct SqPackManager { + [FieldOffset(0x000)] public FileManager* FileManager; + [FieldOffset(0x014)] public SqPackIndexHeader IndexHeader; + [FieldOffset(0x414)] public SqPackHeader SqPackHeader; + [FieldOffset(0x814)] public ResourceCategory ResourceCategory; + [FieldOffset(0x818)] public int PackId; + [FieldOffset(0x81C)] public uint DataCount; + [FieldOffset(0x820)] public uint SynonymDataCount; + [FieldOffset(0x824)] public uint DirIndexDataCount; + [FieldOffset(0x834)] public uint FileSize; + [FieldOffset(0x840)] public FileAccessPath FilePath; + + [FieldOffset(0xA50)] public void* IndexData; + [FieldOffset(0xA58)] public void* SynonymData; + [FieldOffset(0xA60)] public void* DirIndexData; + [FieldOffset(0xA88), FixedSizeArray] internal FixedSizeArray10> _dataFiles; + [FieldOffset(0xAD8)] public FileInterface* IndexFile; + [FieldOffset(0xAE8)] public void* GetOffset; + + [MemberFunction("E8 ?? ?? ?? ?? EB 03 49 8B C7 48 89 03 48 83 C3 08")] + public partial void Ctor(); + + [MemberFunction("E8 ?? ?? ?? ?? 49 8D 55 70 49 8B CF")] + public partial bool LoadIndexFile(ResourceCategory category, int packId); + + [MemberFunction("48 89 6C 24 ?? 56 57 41 56 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 8B 69 64")] + public partial bool LoadDataFiles(); + + [MemberFunction("E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 44 38 69 20")] + public partial ulong GetSqPackPath(FileAccessPath* path, int fileId, ResourceCategory category, int packId, byte* platform, byte* a7); + + [MemberFunction("40 55 41 54 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 80 79 0A 00")] + public partial bool GetOffsetFromIndex(CStringPointer path, uint* offset, uint* fileId); + + [MemberFunction("40 53 55 56 57 41 54 41 55 41 56 41 57 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 48 8B EA"), GenerateStringOverloads] + public partial bool GetOffsetFromIndex2(CStringPointer path, uint* offset, uint* fileId); + + [StaticAddress("48 8D 0D ?? ?? ?? ?? 80 3C 08 ?? 0F 85", 3, isPointer: true)] + public static partial byte* GetIndex2Table(); +} + + diff --git a/ida/data.yml b/ida/data.yml index ce71cf5fd7..3e0e790fc9 100644 --- a/ida/data.yml +++ b/ida/data.yml @@ -5102,6 +5102,14 @@ classes: - ea: 0x142096A60 vfuncs: 0: Dtor + funcs: + 0x14045DAC0: ctor + 0x14045DB60: Open + 0x14045DF80: Close + 0x14045DCF0: Read + 0x14045DDA0: ReadWithOffset + 0x14045DE50: Write + 0x14045DF40: GetFileSize Client::System::File::FileThread: vtbls: - ea: 0x142096A80 @@ -5129,6 +5137,14 @@ classes: 0x1400D4370: Copy 0x140095180: SetPathUtf8String 0x140094950: Dtor + Client::System::File::SqPackManager: + funcs: + 0x1417CD170: ctor + 0x1417CD4A0: LoadIndexFile + 0x1417CD8B0: LoadDataFiles + 0x1417CCD40: GetSqPackPath + 0x1417CDA10: GetOffsetFromIndex + 0x1417CDC70: GetOffsetFromIndex2 Client::System::Resource::Handle::ResourceHandle: vtbls: - ea: 0x142078258