Skip to content

Use CsWin32 for (most) native win32 bindings#41

Merged
FramePerfection merged 8 commits intoDevelopmentfrom
refac/use-cswin32
Mar 7, 2026
Merged

Use CsWin32 for (most) native win32 bindings#41
FramePerfection merged 8 commits intoDevelopmentfrom
refac/use-cswin32

Conversation

@FramePerfection
Copy link
Copy Markdown
Owner

closes #24

@FramePerfection FramePerfection self-assigned this Mar 6, 2026
@FramePerfection FramePerfection added the infrastructure The code shall be refactored in some way label Mar 6, 2026
@FramePerfection
Copy link
Copy Markdown
Owner Author

Working with the code generators has had an impact for my development experience for this, as I had to dotnet clean a couple times because of stale state of generated files, it appears.
I don't think this outweighs the benefits of having this much simpler to use and more likely to be correct API, though.

Also, the single remaining [DllImport] is used for the DolphinProcessIO, of which I don't know if it even works at the moment anyway.
This could be tackled in a separated issue if desired.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces hand-rolled Win32 P/Invoke bindings (the Kernal32NativeMethods class and other scattered DllImport declarations) with CsWin32-generated bindings, as requested in issue #24. A new STROOP.Win32 project is introduced to host the CsWin32 source generator and provide wrapper methods for APIs that need additional marshalling logic.

Changes:

  • Added a new STROOP.Win32 project with CsWin32 package, NativeMethods.txt declarations, and wrapper methods for complex APIs (ReadProcessMemory, WriteProcessMemory, QueryWorkingSetEx, GetSymbolAddress).
  • Removed Kernal32NativeMethods.cs and CarretlessTextBox.cs, migrating all consumers (WindowsProcessIO, DolphinProcessIO, SigScanSharp, ProcessHelper, RichTextBoxEx, MouseUtility) to use CsWin32-generated types and wrappers.
  • Added a manual VirtualQueryEx binding (in a separate static class) due to a CsWin32 limitation with platform-dependent struct sizes.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
STROOP.Win32/STROOP.Win32.csproj New project hosting CsWin32 package
STROOP.Win32/NativeMethods.txt CsWin32 API declarations
STROOP.Win32/NativeMethods.json CsWin32 configuration (public visibility)
STROOP.Win32/NativeMethodWrappers.cs Wrapper methods for complex P/Invoke calls
STROOP.Win32/VirtualQueryEx.cs Manual VirtualQueryEx binding (CsWin32 can't generate it)
STROOP.sln Added STROOP.Win32 project to solution
STROOP.Core/STROOP.Core.csproj Added project reference to STROOP.Win32
STROOP.Core/ProcessHelper.cs New helper extracted from Kernal32NativeMethods
STROOP.Core/Kernal32NativeMethods.cs Deleted old hand-rolled bindings
STROOP.Core/GameMemoryAccess/WindowsProcessIO.cs Updated to use CsWin32 types and wrappers
STROOP.Core/GameMemoryAccess/SigScanSharp.cs Updated to use NativeMethodWrappers
STROOP.Core/GameMemoryAccess/DolphinProcessIO.cs Updated to use VirtualQueryEx wrapper
STROOP/STROOP.csproj Removed CarretlessTextBox compile entry
STROOP/Controls/CarretlessTextBox.cs Deleted (unused caret functionality)
STROOP/Controls/VariablePanel/VariablePanelValueEditBox.cs Changed base class from CarretlessTextBox to TextBox
STROOP/Controls/RichTextBoxEx.cs Updated to use CsWin32 types for rich edit
STROOP/Utilities/MouseUtility.cs Updated to use CsWin32 for input/metrics

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread STROOP.Win32/NativeMethodWrappers.cs Outdated
MaxNameLen = 2000,
SizeOfStruct = 88,
};
var result = PInvoke.SymFromName(hProcess, "CORE_RDRAM", &symbol);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name parameter is accepted but never used — "CORE_RDRAM" is hardcoded on line 67 instead of using the name argument. This makes the API misleading and will silently ignore any other symbol name passed by callers. The call to PInvoke.SymFromName should use name instead of "CORE_RDRAM".

Suggested change
var result = PInvoke.SymFromName(hProcess, "CORE_RDRAM", &symbol);
var result = PInvoke.SymFromName(hProcess, name, &symbol);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Valid suggestion!

Comment thread STROOP.Win32/NativeMethodWrappers.cs Outdated
public static unsafe bool QueryWorkingSetEx(IntPtr hProcess, UIntPtr lpBaseAddress, out PSAPI_WORKING_SET_EX_INFORMATION wsInfo)
{
PSAPI_WORKING_SET_EX_INFORMATION tmp;
wsInfo.VirtualAddress = (HANDLE)lpBaseAddress;
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

VirtualAddress is set on wsInfo (line 53), but tmp is the variable actually passed to PInvoke.QueryWorkingSetEx (line 55). Then on line 56, wsInfo = tmp overwrites the VirtualAddress you set on line 53. The VirtualAddress should be set on tmp instead of wsInfo so that the API receives the correct input address.

Suggested change
wsInfo.VirtualAddress = (HANDLE)lpBaseAddress;
tmp.VirtualAddress = (HANDLE)lpBaseAddress;

Copilot uses AI. Check for mistakes.
Comment thread STROOP.Win32/VirtualQueryEx.cs Outdated
public MemoryType Type;
}

[DllImport("kernel32.dll")]
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The DllImport will attempt to find an export named Invoke in kernel32.dll (since no EntryPoint is specified, the marshaller uses the C# method name). This will fail at runtime with an EntryPointNotFoundException. You need to either rename the method to VirtualQueryEx or add EntryPoint = "VirtualQueryEx" to the DllImport attribute.

Suggested change
[DllImport("kernel32.dll")]
[DllImport("kernel32.dll", EntryPoint = "VirtualQueryEx")]

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

infrastructure The code shall be refactored in some way

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use CsWin32 for Win32 bindings

3 participants