diff --git a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs index 2ac75aa..6ad298e 100644 --- a/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs +++ b/src/SharpEmu.Libs/Kernel/KernelMemoryCompatExports.cs @@ -97,6 +97,7 @@ public static partial class KernelMemoryCompatExports private static readonly object _fdGate = new(); private static readonly Dictionary _openFiles = new(); + private static readonly HashSet _randomDeviceDescriptors = new(); private static readonly Dictionary _binkGuestCompletionShims = new(); private static readonly Dictionary _observedBinkGuestFiles = new(); @@ -1453,6 +1454,19 @@ public static partial class KernelMemoryCompatExports return (int)OrbisGen2Result.ORBIS_GEN2_ERROR_MEMORY_FAULT; } + if (IsRandomDevicePath(guestPath) && (flags & O_DIRECTORY) == 0) + { + var randomFd = (int)Interlocked.Increment(ref _nextFileDescriptor); + lock (_fdGate) + { + _randomDeviceDescriptors.Add(randomFd); + } + + LogOpenTrace($"_open random-device path='{guestPath}' flags=0x{flags:X8} fd={randomFd}"); + ctx[CpuRegister.Rax] = unchecked((ulong)randomFd); + return (int)OrbisGen2Result.ORBIS_GEN2_OK; + } + var hostPath = ResolveGuestPath(guestPath); var access = ResolveOpenAccess(flags); var mode = ResolveOpenMode(flags, access); @@ -6947,6 +6961,10 @@ public static partial class KernelMemoryCompatExports return !string.IsNullOrWhiteSpace(hostPath) && TryWriteHostPathStat(ctx, statAddress, hostPath!, isDirectory); } + private static bool IsRandomDevicePath(string path) => + string.Equals(path, "/dev/random", StringComparison.Ordinal) || + string.Equals(path, "/dev/urandom", StringComparison.Ordinal); + private static bool TryWriteHostPathStat(CpuContext ctx, ulong statAddress, string hostPath) { var isDirectory = Directory.Exists(hostPath);