Correct ApiPort and add display info

This commit is contained in:
AdvDebug
2026-06-19 22:49:20 +03:00
parent aae78ffa2c
commit d0b9f65ae9
4 changed files with 144 additions and 6 deletions
@@ -270,7 +270,11 @@ namespace Brovan.Core.Emulation.OS.Windows.RPC.Ports
TryReadClientConnectData(Reply, out uint ServerId, out ulong ConnectionInfo, out uint ConnectionInfoSize);
if (!Instance.WinHelper.EnsureUserSharedInfo(out ulong psi, out ulong aheList, out _))
if (!Instance.WinHelper.EnsureUserSharedInfo(out ulong psi, out ulong aheList, out uint entrySize))
return;
ulong DisplayInfo = Instance.WinHelper.EnsureUserDesktopInfo();
if (DisplayInfo == 0)
return;
const int UserConnectHeaderSize = 0x08;
@@ -289,8 +293,8 @@ namespace Brovan.Core.Emulation.OS.Windows.RPC.Ports
WriteU64(Data, UserConnectHeaderSize + 0x00, psi);
WriteU64(Data, UserConnectHeaderSize + 0x08, aheList);
WriteU64(Data, UserConnectHeaderSize + 0x10, 0UL);
WriteU64(Data, UserConnectHeaderSize + 0x18, 0UL);
WriteU32(Data, UserConnectHeaderSize + 0x10, entrySize);
WriteU64(Data, UserConnectHeaderSize + 0x18, DisplayInfo);
uint UserConnectWriteSize = Math.Max(ConnectionInfoSize, (uint)Data.Length);
TryWriteClientConnectData(Reply, Instance, Data, ServerId, ConnectionInfo, UserConnectWriteSize);
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Brovan.Core.Helpers;
using static Brovan.Core.Helpers.BinaryHelpers;
@@ -17,6 +18,64 @@ namespace Brovan.Core.Emulation.OS.Windows
public ulong Information;
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct UserSharedDisplayInfo
{
[FieldOffset(0x00)]
public uint Type;
[FieldOffset(0x08)]
public ulong PrimaryMonitor;
}
[StructLayout(LayoutKind.Explicit, Pack = 1)]
public struct UserPrimaryMonitorInfo
{
public const int Size = 0x40;
[FieldOffset(0x00)]
public ulong Header;
[FieldOffset(0x08)]
public ulong Reserved1;
[FieldOffset(0x10)]
public ulong Reserved2;
[FieldOffset(0x18)]
public uint Padding18;
[FieldOffset(0x1C)]
public int MonitorLeft;
[FieldOffset(0x20)]
public int MonitorTop;
[FieldOffset(0x24)]
public int MonitorRight;
[FieldOffset(0x28)]
public int MonitorBottom;
[FieldOffset(0x2C)]
public int WorkLeft;
[FieldOffset(0x30)]
public int WorkTop;
[FieldOffset(0x34)]
public int WorkRight;
[FieldOffset(0x38)]
public int WorkBottom;
[FieldOffset(0x3C)]
public ushort DpiX;
[FieldOffset(0x3E)]
public ushort DpiY;
}
public class WinModule
{
public BinaryArchitecture Architecture;
@@ -985,12 +985,15 @@ namespace Brovan.Core.Emulation.OS.Windows
private const ulong UserWindowObjectSize = 0x200;
private const ulong UserClassObjectSize = 0x100;
private const ulong UserDesktopInfoSize = 0x48;
private const ulong UserPrimaryMonitorSize = 0x1000;
private const ulong Win32ClientInfoX64Base = 0x800;
private const ulong Win32ClientInfoX86Base = 0x6CC;
private const int Win32ClientInfoDesktopSlot = 4;
private const int Win32ClientInfoActiveWindowSlot = 8;
private const int Win32ClientInfoActiveWindowPointerSlot = 9;
private const ulong UserSharedInfoMirrorSize = 0x1B54;
private const int SmCxScreen = 0;
private const int SmCyScreen = 1;
private const byte UserHandleTypeWindow = 1;
private ushort NextUserHandleIndex = 1;
private ushort NextUserHandleUniq = 1;
@@ -998,6 +1001,7 @@ namespace Brovan.Core.Emulation.OS.Windows
private ulong UserHandleTableAddress;
private ulong UserDesktopInfoAddress;
private ulong UserDesktopOwnerAddress;
private ulong UserPrimaryMonitorAddress;
private ulong UserSharedInfoMirrorAddress;
private ulong UserSharedDelta;
public ulong ActiveWindow;
@@ -2469,7 +2473,64 @@ namespace Brovan.Core.Emulation.OS.Windows
return Delta;
}
private ulong EnsureUserDesktopInfo()
private ulong EnsureUserPrimaryMonitor()
{
if (UserPrimaryMonitorAddress != 0 && Emulator.IsRegionMapped(UserPrimaryMonitorAddress, UserPrimaryMonitorSize))
return UserPrimaryMonitorAddress;
ulong Monitor = Emulator.MapUniqueAddress(UserPrimaryMonitorSize, MemoryProtection.ReadWrite);
if (Monitor == 0)
return 0;
if (!WriteZeroMemory(Monitor, (uint)UserPrimaryMonitorSize))
return 0;
(int Width, int Height) = GetHostPrimaryMonitorSize();
UserPrimaryMonitorInfo MonitorInfo = new UserPrimaryMonitorInfo
{
Header = 1UL,
MonitorLeft = 0,
MonitorTop = 0,
MonitorRight = Width,
MonitorBottom = Height,
WorkLeft = 0,
WorkTop = 0,
WorkRight = Width,
WorkBottom = Height,
DpiX = 96,
DpiY = 96
};
Span<byte> Buffer = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref MonitorInfo, 1));
if (!Emulator._emulator.WriteMemory(Monitor, Buffer))
return 0;
UserPrimaryMonitorAddress = Monitor;
return UserPrimaryMonitorAddress;
}
private static (int Width, int Height) GetHostPrimaryMonitorSize()
{
try
{
if (OperatingSystem.IsWindows())
{
int Width = NativeWinImports.GetSystemMetrics(SmCxScreen);
int Height = NativeWinImports.GetSystemMetrics(SmCyScreen);
if (Width > 0 && Height > 0)
return (Width, Height);
}
}
catch
{
}
return (1920, 1080);
}
public ulong EnsureUserDesktopInfo()
{
if (UserDesktopInfoAddress != 0 && Emulator.IsRegionMapped(UserDesktopInfoAddress, UserDesktopInfoSize))
return UserDesktopInfoAddress;
@@ -2483,6 +2544,10 @@ namespace Brovan.Core.Emulation.OS.Windows
WriteZeroMemory(UserDesktopOwnerAddress, 0x1000);
}
ulong PrimaryMonitor = EnsureUserPrimaryMonitor();
if (PrimaryMonitor == 0)
return 0;
ulong DesktopInfo = Emulator.MapUniqueAddress(0x1000, MemoryProtection.ReadWrite);
if (DesktopInfo == 0)
return 0;
@@ -2490,8 +2555,15 @@ namespace Brovan.Core.Emulation.OS.Windows
if (!WriteZeroMemory(DesktopInfo, 0x1000))
return 0;
Emulator._emulator.WriteMemory(DesktopInfo + 0x00, UserDesktopOwnerAddress, 8);
Emulator._emulator.WriteMemory(DesktopInfo + 0x10, 0u, 4);
UserSharedDisplayInfo DisplayInfo = new UserSharedDisplayInfo
{
Type = 1u,
PrimaryMonitor = PrimaryMonitor
};
Span<byte> Buffer = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref DisplayInfo, 1));
if (!Emulator._emulator.WriteMemory(DesktopInfo, Buffer))
return 0;
UserDesktopInfoAddress = DesktopInfo;
return UserDesktopInfoAddress;
+3
View File
@@ -134,6 +134,9 @@ namespace Brovan
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool DeviceIoControl(SafeFileHandle Handle, uint IoControlCode, IntPtr InBuffer, int InBufferSize, byte[] OutBuffer, int OutBufferSize, out int BytesReturned, IntPtr Overlapped);
[DllImport("user32.dll")]
public static extern int GetSystemMetrics(int nIndex);
}
internal class NativeUnixImports