[Kernel] Return packed directory entries for Quake II

This commit is contained in:
ParantezTech 2026-09-30 00:56:20 +03:00
parent 4d65ff6d51
commit 50198a694b
1 changed files with 29 additions and 15 deletions

View File

@ -6958,7 +6958,7 @@ public static partial class KernelMemoryCompatExports
private static int KernelGetdirentriesCore(CpuContext ctx, int fd, ulong bufferAddress, int requested, ulong basePointerAddress)
{
if (fd < 0 || bufferAddress == 0 || requested < 512)
if (fd < 0 || bufferAddress == 0 || requested < 12)
{
ctx[CpuRegister.Rax] = unchecked((ulong)(int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT);
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT;
@ -6999,27 +6999,41 @@ public static partial class KernelMemoryCompatExports
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
}
var entryName = directory.Entries[currentIndex];
directory.NextIndex = currentIndex + 1;
var payload = new byte[Math.Min(requested, 65536)];
var written = 0;
while (currentIndex < directory.Entries.Length)
{
var entryName = directory.Entries[currentIndex];
var entryBytes = Encoding.UTF8.GetBytes(entryName);
var nameLength = Math.Min(entryBytes.Length, 255);
var recordLength = (8 + nameLength + 1 + 3) & ~3;
if (recordLength > payload.Length - written)
{
if (written == 0)
{
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_INVALID_ARGUMENT;
}
var entryBytes = Encoding.UTF8.GetBytes(entryName);
var nameLength = Math.Min(entryBytes.Length, 255);
var entryPath = Path.Combine(directory.Path, entryName);
var entryType = Directory.Exists(entryPath) ? (byte)4 : (byte)8;
break;
}
var payload = new byte[512];
BinaryPrimitives.WriteUInt32LittleEndian(payload.AsSpan(0, sizeof(uint)), ComputeDirectoryEntryHash(entryBytes.AsSpan(0, nameLength)));
BinaryPrimitives.WriteUInt16LittleEndian(payload.AsSpan(4, sizeof(ushort)), 512);
payload[6] = entryType;
payload[7] = unchecked((byte)nameLength);
entryBytes.AsSpan(0, nameLength).CopyTo(payload.AsSpan(8));
var record = payload.AsSpan(written, recordLength);
BinaryPrimitives.WriteUInt32LittleEndian(record, ComputeDirectoryEntryHash(entryBytes.AsSpan(0, nameLength)));
BinaryPrimitives.WriteUInt16LittleEndian(record[4..], unchecked((ushort)recordLength));
record[6] = Directory.Exists(Path.Combine(directory.Path, entryName)) ? (byte)4 : (byte)8;
record[7] = unchecked((byte)nameLength);
entryBytes.AsSpan(0, nameLength).CopyTo(record[8..]);
written += recordLength;
currentIndex++;
}
if (!TryWriteCompat(ctx, bufferAddress, payload))
if (!TryWriteCompat(ctx, bufferAddress, payload.AsSpan(0, written)))
{
return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT;
}
ctx[CpuRegister.Rax] = 512;
directory.NextIndex = currentIndex;
ctx[CpuRegister.Rax] = unchecked((ulong)written);
return (int)OrbisGen2Result.ORBIS_GEN2_OK;
}