Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Brovan/Core/Emulation/Guests/WindowsGuest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ public void OnThreadWaitSatisfied(BinaryEmulator Instance, EmulatedThread Thread
State.AlertByThreadIdAddress = 0;
State.MsgWaitActive = false;
State.MsgWaitMask = 0;
State.WaitMessageActive = false;
State.GetMessageWaitActive = false;
Thread.WaitTimedOut = false;
Thread.WaitSatisfiedIndex = -1;
Expand Down
15 changes: 13 additions & 2 deletions Brovan/Core/Emulation/OS/Windows/BinaryEmulator.WindowsBridge.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Buffers;
using System.Buffers;
using System.Buffers.Binary;
using System.Runtime.InteropServices;
using Brovan.Core.Emulation.OS.Windows;
Expand Down Expand Up @@ -732,6 +732,17 @@ internal bool TrySatisfyThreadWait(EmulatedThread Thread)
return false;
}

if (State != null && State.WaitMessageActive)
{
if (!Win32kHelper.HasQueuedInputEvent(this, Win32kHelper.QS_ALLINPUT))
return false;

State.WaitMessageActive = false;
Thread.WaitSatisfiedIndex = 1;
State.WaitStatus = NTSTATUS.STATUS_SUCCESS;
return true;
}

if (State != null && State.GetMessageWaitActive)
{
if (Win32kHelper.TryGetMessage(this, State.GetMessageHwndFilter, State.GetMessageMinMessage, State.GetMessageMaxMessage, true, out Win32kMessage Message))
Expand Down Expand Up @@ -894,7 +905,7 @@ internal bool HasActiveGetMessageWait()
continue;

WindowsThreadState State = WinEmulatedThread.TryGetState(Thread);
if (State != null && (State.GetMessageWaitActive || State.MsgWaitActive))
if (State != null && (State.GetMessageWaitActive || State.MsgWaitActive || State.WaitMessageActive))
return true;
}

Expand Down
14 changes: 9 additions & 5 deletions Brovan/Core/Emulation/OS/Windows/RPC/Ports/ApiPort.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,11 +311,13 @@ public static bool TryBuildUserConnect(BinaryEmulator Instance, ulong Connection
if (!Instance.WinHelper.EnsureUserSharedInfo(out ulong psi, out ulong aheList, out uint entrySize))
return false;

Instance.WinHelper.PublishDpiServerInfo();

ulong DisplayInfo = Instance.WinHelper.EnsureUserDesktopInfo();
if (DisplayInfo == 0)
return false;

if (!Instance.WinHelper.EnsureUserMessageBitmasks(out ulong Bitmask1, out ulong Bitmask2))
if (!Instance.WinHelper.EnsureUserMessageBitmask(out ulong Bitmask))
return false;

Data.Clear();
Expand All @@ -332,10 +334,12 @@ public static bool TryBuildUserConnect(BinaryEmulator Instance, ulong Connection
WriteU32(Data, UserConnectHeaderSize + 0x10, entrySize);
WriteU64(Data, UserConnectHeaderSize + 0x18, DisplayInfo);

WriteU32(Data, UserConnectHeaderSize + 0x218, 0x3FFu);
WriteU64(Data, UserConnectHeaderSize + 0x220, Bitmask1);
WriteU32(Data, UserConnectHeaderSize + 0x228, 0x3FFu);
WriteU64(Data, UserConnectHeaderSize + 0x230, Bitmask2);
for (int Index = 0; Index < WinSysHelper.UserSharedInfoMessageTableCount; Index++)
{
int Offset = UserConnectHeaderSize + WinSysHelper.UserSharedInfoMessageTableOffset(Index);
WriteU32(Data, Offset, WinSysHelper.UserMessageBitmaskLastMessage);
WriteU64(Data, Offset + 8, Bitmask);
}

return true;
}
Expand Down
4 changes: 2 additions & 2 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiEllipse.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Brovan.Core.Emulation.OS.SharedHelpers;
using Brovan.Core.Emulation.OS.SharedHelpers;
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
Expand All @@ -24,7 +24,7 @@ public NTSTATUS Handle(BinaryEmulator Instance)
Win32kPenBrush Pen = Win32kHelper.ResolvePenBrush(Instance, Instance.WinHelper.ReadDcSelectedPen(Hdc), true);
Win32kPenBrush Brush = Win32kHelper.ResolvePenBrush(Instance, Instance.WinHelper.ReadDcSelectedBrush(Hdc), false);

Instance.WinHelper.EnqueueGdiShape(Hwnd, GdiPrimitiveKind.Ellipse, Left, Top, Right, Bottom, Pen.ColorRef, Pen.PenWidth, Brush.ColorRef);
Instance.WinHelper.EnqueueGdiShape(Hwnd, Hdc, GdiPrimitiveKind.Ellipse, Left, Top, Right, Bottom, Pen.ColorRef, Pen.PenWidth, Brush.ColorRef);

Instance.SetRawSyscallReturn(1);
return NTSTATUS.STATUS_SUCCESS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public NTSTATUS Handle(BinaryEmulator Instance)
RectBottom = (int)Window.Height;
}

Instance.WinHelper.EnqueueTextRender(Hwnd, Text, X, Y, RectLeft, RectTop, RectRight, RectBottom, Options);
Instance.WinHelper.EnqueueTextRender(Hwnd, Hdc, Text, X, Y, RectLeft, RectTop, RectRight, RectBottom, Options);

Instance.SetRawSyscallReturn(1);
return NTSTATUS.STATUS_SUCCESS;
Expand Down
30 changes: 30 additions & 0 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiGetCharWidthInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
{
// Brovan draws every glyph inside its advance width, so both side bearings are genuinely zero.
internal class NtGdiGetCharWidthInfo : IWinSyscall
{
private const int CharWidthInfoSize = 12;

public NTSTATUS Handle(BinaryEmulator Instance)
{
ulong Hdc = Instance.WinHelper.GetArg(0);
ulong InfoPtr = Instance.WinHelper.GetArg(1);

if (InfoPtr == 0 || !Win32kHelper.IsKnownDc(Instance, Hdc))
{
Instance.SetLastWinError(Win32kHelper.ERROR_INVALID_HANDLE);
Instance.SetBooleanSyscallReturn(false);
return NTSTATUS.STATUS_SUCCESS;
}

if (!Instance.WinHelper.WriteZeroMemory(InfoPtr, CharWidthInfoSize))
return NTSTATUS.STATUS_ACCESS_VIOLATION;

Instance.SetLastWinError(0);
Instance.SetBooleanSyscallReturn(true);
return NTSTATUS.STATUS_SUCCESS;
}
}
}
39 changes: 39 additions & 0 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiGetTextCharsetInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
{
internal class NtGdiGetTextCharsetInfo : IWinSyscall
{
private const uint AnsiCharset = 0;
private const int FontSignatureSize = 24;
private const uint BasicLatinRangeBit = 1;
private const uint Latin1CodePageBit = 1;

public NTSTATUS Handle(BinaryEmulator Instance)
{
ulong Hdc = Instance.WinHelper.GetArg(0);
ulong SignaturePtr = Instance.WinHelper.GetArg(1);

if (!Win32kHelper.IsKnownDc(Instance, Hdc))
{
Instance.SetLastWinError(Win32kHelper.ERROR_INVALID_HANDLE);
Instance.SetRawSyscallReturn(uint.MaxValue);
return NTSTATUS.STATUS_SUCCESS;
}

// FONTSIGNATURE is four unicode subset masks then two code page masks.
if (SignaturePtr != 0)
{
if (!Instance.WinHelper.WriteZeroMemory(SignaturePtr, FontSignatureSize))
return NTSTATUS.STATUS_ACCESS_VIOLATION;

Instance._emulator.WriteMemory(SignaturePtr, BasicLatinRangeBit, 4);
Instance._emulator.WriteMemory(SignaturePtr + 16, Latin1CodePageBit, 4);
}

Instance.SetLastWinError(0);
Instance.SetRawSyscallReturn(AnsiCharset);
return NTSTATUS.STATUS_SUCCESS;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using static Brovan.Core.Helpers.BinaryHelpers;
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
{
Expand Down
62 changes: 6 additions & 56 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiGetTextMetricsW.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,66 +5,26 @@ namespace Brovan.Core.Emulation.OS.Windows.Win32k
{
internal class NtGdiGetTextMetricsW : IWinSyscall
{
private const int TextMetricWSize = 60;

public NTSTATUS Handle(BinaryEmulator Instance)
{

Instance.WinHelper.GetArg(0);
ulong BufferPtr = Instance.WinHelper.GetArg(1);
uint BufferSize = (uint)Instance.WinHelper.GetArg(2);

if (BufferPtr == 0 || BufferSize < TextMetricWSize)
if (BufferPtr == 0 || BufferSize < Win32kHelper.TextMetricWSize)
{
Instance.SetRawSyscallReturn(0);
return NTSTATUS.STATUS_SUCCESS;
}

TextMetricsData Metrics;
if (!Instance.WinHelper.GetTextMetrics(out Metrics))
{
Metrics = new TextMetricsData
{
Height = 16,
Ascent = 12,
Descent = 4,
AveCharWidth = 8,
MaxCharWidth = 16,
Weight = 400,
DigitizedAspectX = 96,
DigitizedAspectY = 96,
FirstChar = 0x20,
LastChar = 0xFF,
DefaultChar = 0x20,
BreakChar = 0x20,
PitchAndFamily = 0x01,
};
}
if (!Instance.WinHelper.GetTextMetrics(out TextMetricsData Metrics))
Metrics = Win32kHelper.DefaultTextMetrics;

Span<byte> Buffer = Instance.WinHelper.Shared.GetSpan(TextMetricWSize);
Buffer.Clear();
WriteI32(Buffer, 0x00, Metrics.Height);
WriteI32(Buffer, 0x04, Metrics.Ascent);
WriteI32(Buffer, 0x08, Metrics.Descent);
WriteI32(Buffer, 0x0C, Metrics.InternalLeading);
WriteI32(Buffer, 0x10, Metrics.ExternalLeading);
WriteI32(Buffer, 0x14, Metrics.AveCharWidth);
WriteI32(Buffer, 0x18, Metrics.MaxCharWidth);
WriteI32(Buffer, 0x1C, Metrics.Weight);
WriteI32(Buffer, 0x20, Metrics.Overhang);
WriteI32(Buffer, 0x24, Metrics.DigitizedAspectX);
WriteI32(Buffer, 0x28, Metrics.DigitizedAspectY);
WriteU16(Buffer, 0x2C, Metrics.FirstChar);
WriteU16(Buffer, 0x2E, Metrics.LastChar);
WriteU16(Buffer, 0x30, Metrics.DefaultChar);
WriteU16(Buffer, 0x32, Metrics.BreakChar);
Buffer[0x34] = Metrics.Italic;
Buffer[0x35] = Metrics.Underlined;
Buffer[0x36] = Metrics.StruckOut;
Buffer[0x37] = Metrics.PitchAndFamily;
Buffer[0x38] = Metrics.CharSet;
Span<byte> Buffer = Instance.WinHelper.Shared.GetSpan(Win32kHelper.TextMetricWSize);
Win32kHelper.WriteTextMetricsW(Buffer, Metrics);

if (!Instance.WriteMemory(BufferPtr, Buffer.Slice(0, TextMetricWSize)))
if (!Instance.WriteMemory(BufferPtr, Buffer.Slice(0, Win32kHelper.TextMetricWSize)))
{
Instance.SetRawSyscallReturn(0);
return NTSTATUS.STATUS_SUCCESS;
Expand All @@ -73,15 +33,5 @@ public NTSTATUS Handle(BinaryEmulator Instance)
Instance.SetRawSyscallReturn(1);
return NTSTATUS.STATUS_SUCCESS;
}

private static void WriteI32(Span<byte> Buffer, int Offset, int Value)
{
System.Buffers.Binary.BinaryPrimitives.WriteInt32LittleEndian(Buffer.Slice(Offset, 4), Value);
}

private static void WriteU16(Span<byte> Buffer, int Offset, ushort Value)
{
System.Buffers.Binary.BinaryPrimitives.WriteUInt16LittleEndian(Buffer.Slice(Offset, 2), Value);
}
}
}
4 changes: 2 additions & 2 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiLineTo.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using static Brovan.Core.Helpers.BinaryHelpers;
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
{
Expand All @@ -22,7 +22,7 @@ public NTSTATUS Handle(BinaryEmulator Instance)
ulong PenHandle = Instance.WinHelper.ReadDcSelectedPen(Hdc);
Win32kPenBrush Pen = Win32kHelper.ResolvePenBrush(Instance, PenHandle, true);

Instance.WinHelper.EnqueueGdiLine(Hwnd, StartX, StartY, X, Y, Pen.ColorRef, Pen.PenWidth);
Instance.WinHelper.EnqueueGdiLine(Hwnd, Hdc, StartX, StartY, X, Y, Pen.ColorRef, Pen.PenWidth);
Instance.WinHelper.WriteDcCurrentPosition(Hdc, X, Y);

Instance.SetRawSyscallReturn(1);
Expand Down
4 changes: 2 additions & 2 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiPatBlt.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using static Brovan.Core.Helpers.BinaryHelpers;
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
{
Expand All @@ -23,7 +23,7 @@ public NTSTATUS Handle(BinaryEmulator Instance)

ulong BrushHandle = Instance.WinHelper.ReadDcSelectedBrush(Hdc);
Win32kPenBrush Brush = Win32kHelper.ResolvePenBrush(Instance, BrushHandle, false);
Instance.WinHelper.EnqueueGdiFillRect(Hwnd, X, Y, X + Width, Y + Height, Brush.ColorRef, Rop);
Instance.WinHelper.EnqueueGdiFillRect(Hwnd, Hdc, X, Y, X + Width, Y + Height, Brush.ColorRef, Rop);

Instance.SetRawSyscallReturn(1);
return NTSTATUS.STATUS_SUCCESS;
Expand Down
6 changes: 5 additions & 1 deletion Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiPolyPatBlt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,12 @@ public NTSTATUS Handle(BinaryEmulator Instance)
int Height = unchecked((int)Instance.ReadMemoryUInt(EntryAddr + 0x0C));
ulong BrushHandle = Instance.ReadMemoryULong(EntryAddr + 0x10);

// An entry with no brush of its own paints with the one selected into the DC.
if (BrushHandle == 0)
BrushHandle = Instance.WinHelper.ReadDcSelectedBrush(Hdc);

Win32kPenBrush Brush = Win32kHelper.ResolvePenBrush(Instance, BrushHandle, false);
Instance.WinHelper.EnqueueGdiFillRect(Hwnd, X, Y, X + Width, Y + Height, Brush.ColorRef, Rop);
Instance.WinHelper.EnqueueGdiFillRect(Hwnd, Hdc, X, Y, X + Width, Y + Height, Brush.ColorRef, Rop);
}

Instance.SetRawSyscallReturn(1);
Expand Down
10 changes: 7 additions & 3 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiPolyPolyDraw.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Brovan.Core.Emulation.OS.SharedHelpers;
using Brovan.Core.Emulation.OS.SharedHelpers;
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
Expand Down Expand Up @@ -39,18 +39,22 @@ public NTSTATUS Handle(BinaryEmulator Instance)
GdiPrimitiveKind Kind = DrawType == PolygonType ? GdiPrimitiveKind.Polygon : GdiPrimitiveKind.Polyline;

ulong PointOffset = 0;

for (uint Figure = 0; Figure < FigureCount; Figure++)
{
if (!Instance.IsRegionMapped(CountsPtr + (ulong)Figure * 4, 4))
break;

uint PointCount = Instance.ReadMemoryUInt(CountsPtr + (ulong)Figure * 4);
ulong FigureBytes = (ulong)PointCount * PointSize;

// A figure too short to draw still owns its points, and the ones after it are found past them.
if (PointCount < 2)
{
PointOffset += FigureBytes;
continue;
}

ulong FigureBytes = (ulong)PointCount * PointSize;
ulong FigureAddr = PointsPtr + PointOffset;
if (!Instance.IsRegionMapped(FigureAddr, FigureBytes))
break;
Expand All @@ -66,7 +70,7 @@ public NTSTATUS Handle(BinaryEmulator Instance)
};
}

Instance.WinHelper.EnqueueGdiPoly(Hwnd, Kind, Points, Pen.ColorRef, Pen.PenWidth, Brush.ColorRef, DrawType == PolygonType);
Instance.WinHelper.EnqueueGdiPoly(Hwnd, Hdc, Kind, Points, Pen.ColorRef, Pen.PenWidth, Brush.ColorRef, DrawType == PolygonType);

PointOffset += FigureBytes;
}
Expand Down
4 changes: 2 additions & 2 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiRectangle.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Brovan.Core.Emulation.OS.SharedHelpers;
using Brovan.Core.Emulation.OS.SharedHelpers;
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
Expand All @@ -24,7 +24,7 @@ public NTSTATUS Handle(BinaryEmulator Instance)
Win32kPenBrush Pen = Win32kHelper.ResolvePenBrush(Instance, Instance.WinHelper.ReadDcSelectedPen(Hdc), true);
Win32kPenBrush Brush = Win32kHelper.ResolvePenBrush(Instance, Instance.WinHelper.ReadDcSelectedBrush(Hdc), false);

Instance.WinHelper.EnqueueGdiShape(Hwnd, GdiPrimitiveKind.Rectangle, Left, Top, Right, Bottom, Pen.ColorRef, Pen.PenWidth, Brush.ColorRef);
Instance.WinHelper.EnqueueGdiShape(Hwnd, Hdc, GdiPrimitiveKind.Rectangle, Left, Top, Right, Bottom, Pen.ColorRef, Pen.PenWidth, Brush.ColorRef);

Instance.SetRawSyscallReturn(1);
return NTSTATUS.STATUS_SUCCESS;
Expand Down
4 changes: 2 additions & 2 deletions Brovan/Core/Emulation/OS/Windows/Win32k/NtGdiRoundRect.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Brovan.Core.Emulation.OS.SharedHelpers;
using Brovan.Core.Emulation.OS.SharedHelpers;
using static Brovan.Core.Helpers.BinaryHelpers;

namespace Brovan.Core.Emulation.OS.Windows.Win32k
Expand Down Expand Up @@ -26,7 +26,7 @@ public NTSTATUS Handle(BinaryEmulator Instance)
Win32kPenBrush Pen = Win32kHelper.ResolvePenBrush(Instance, Instance.WinHelper.ReadDcSelectedPen(Hdc), true);
Win32kPenBrush Brush = Win32kHelper.ResolvePenBrush(Instance, Instance.WinHelper.ReadDcSelectedBrush(Hdc), false);

Instance.WinHelper.EnqueueGdiShape(Hwnd, GdiPrimitiveKind.RoundRect, Left, Top, Right, Bottom, Pen.ColorRef, Pen.PenWidth, Brush.ColorRef, Width, Height);
Instance.WinHelper.EnqueueGdiShape(Hwnd, Hdc, GdiPrimitiveKind.RoundRect, Left, Top, Right, Bottom, Pen.ColorRef, Pen.PenWidth, Brush.ColorRef, Width, Height);

Instance.SetRawSyscallReturn(1);
return NTSTATUS.STATUS_SUCCESS;
Expand Down
Loading
Loading