Skip to content

Outsource Windows API definitions (extern) to CsWin32 #4327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
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
6 changes: 6 additions & 0 deletions BizHawk.sln
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{74391239
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BizHawk.Tests", "src\BizHawk.Tests\BizHawk.Tests.csproj", "{284E19E2-661D-4A7D-864A-AC2FC91E7C25}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Bizware.Externs", "src\BizHawk.Bizware.Externs\BizHawk.Bizware.Externs.csproj", "{DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -99,6 +101,10 @@ Global
{284E19E2-661D-4A7D-864A-AC2FC91E7C25}.Debug|Any CPU.Build.0 = Debug|Any CPU
{284E19E2-661D-4A7D-864A-AC2FC91E7C25}.Release|Any CPU.ActiveCfg = Release|Any CPU
{284E19E2-661D-4A7D-864A-AC2FC91E7C25}.Release|Any CPU.Build.0 = Release|Any CPU
{DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DCB48DE4-8D71-4F8B-ABE4-55E9B62FA511}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
2 changes: 1 addition & 1 deletion Common.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<AnalysisModeReliability>Recommended</AnalysisModeReliability>
<AnalysisModePerformance>Recommended</AnalysisModePerformance>
<AnalysisModeUsage>Recommended</AnalysisModeUsage>
<EmitCompilerGeneratedFiles>false</EmitCompilerGeneratedFiles> <!-- enable to copy Roslyn Source Generators' outputs to $(ProjectDir)/obj/.../generated -->
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles> <!-- enable to copy Roslyn Source Generators' outputs to $(ProjectDir)/obj/.../generated -->
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<ContinuousIntegrationBuild Condition=" '$(GITLAB_CI)' != '' Or '$(APPVEYOR)' != '' ">true</ContinuousIntegrationBuild>
Expand Down
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<PackageVersion Include="Microsoft.Data.Sqlite.Core" Version="8.0.4" />
<PackageVersion Include="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
<PackageVersion Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.183" />
<PackageVersion Include="MSTest" Version="3.8.3" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Nullable" Version="1.3.1" />
Expand Down
17 changes: 17 additions & 0 deletions src/BizHawk.Bizware.Externs/AVIFIL32.dll.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Windows.Win32.Foundation;
using Windows.Win32.Media.Multimedia;

namespace Windows.Win32
{
public static partial class Win32Imports
{
/// <seealso cref="AVISaveOptions(HWND, uint, int, IAVIStream[], AVICOMPRESSOPTIONS**)"/>
public static unsafe nint AVISaveOptions(IAVIStream ppavi, ref AVICOMPRESSOPTIONS opts, HWND owner)
{
fixed (AVICOMPRESSOPTIONS* popts = &opts)
{
return AVISaveOptions(owner, uiFlags: 0, nStreams: 1, [ ppavi ], &popts);
}
}
}
}
11 changes: 11 additions & 0 deletions src/BizHawk.Bizware.Externs/BizHawk.Bizware.Externs.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<Import Project="../MainSlnCommon.props" />
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWin32" />
<PackageReference Include="System.Memory" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" />
</ItemGroup>
</Project>
11 changes: 11 additions & 0 deletions src/BizHawk.Bizware.Externs/GetLastError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Runtime.InteropServices;

namespace Windows.Win32
{
public static partial class Win32Imports
{
/// <remarks>alias for <see cref="Marshal.GetLastWin32Error"/>, per <c>PInvoke003</c>/<see href="https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.marshal.getlastwin32error?view=netstandard-2.0#remarks"/></remarks>
public static uint GetLastError()
=> unchecked((uint) Marshal.GetLastWin32Error());
}
}
56 changes: 56 additions & 0 deletions src/BizHawk.Bizware.Externs/KERNEL32.dll.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Runtime.InteropServices;

using Windows.Win32.Foundation;
using Windows.Win32.System.Memory;

namespace Windows.Win32
{
public static partial class Win32Imports
{
/// <inheritdoc cref="GetShortPathNameW(PCWSTR, PWSTR, uint)"/>
public static unsafe uint GetShortPathNameW(string lpszLongPath)
{
fixed (char* lpszLongPathLocal = lpszLongPath)
{
return Win32Imports.GetShortPathNameW(lpszLongPathLocal, default, 0U);
}
}

/// <seealso cref="HeapAlloc(SafeHandle, HEAP_FLAGS, nuint)"/>
public static unsafe void* HeapAlloc(int dwBytes, HEAP_FLAGS dwFlags = HEAP_FLAGS.HEAP_NONE)
=> HeapAlloc(GetProcessHeap_SafeHandle(), dwFlags, dwBytes: (UIntPtr) dwBytes);

/// <inheritdoc cref="IsWow64Process(HANDLE, BOOL*)"/>
public static unsafe BOOL IsWow64Process(HANDLE hProcess, out BOOL Wow64Process)
{
fixed (BOOL* ptr = &Wow64Process) return IsWow64Process(hProcess, ptr);
}

/// <inheritdoc cref="VirtualAlloc(void*, nuint, VIRTUAL_ALLOCATION_TYPE, PAGE_PROTECTION_FLAGS)"/>
public static unsafe UIntPtr VirtualAlloc(
UIntPtr lpAddress,
UIntPtr dwSize,
VIRTUAL_ALLOCATION_TYPE flAllocationType,
PAGE_PROTECTION_FLAGS flProtect)
=> unchecked((UIntPtr) VirtualAlloc(
lpAddress: (void*) lpAddress,
dwSize: dwSize,
flAllocationType,
flProtect));

/// <inheritdoc cref="VirtualFree(void*, nuint, VIRTUAL_FREE_TYPE)"/>
public static unsafe BOOL VirtualFree(
UIntPtr lpAddress,
UIntPtr dwSize,
VIRTUAL_FREE_TYPE dwFreeType)
=> unchecked(VirtualFree((void*) lpAddress, (nuint) dwSize, dwFreeType));

/// <inheritdoc cref="VirtualProtect(void*, nuint, PAGE_PROTECTION_FLAGS, out PAGE_PROTECTION_FLAGS)"/>
public static unsafe BOOL VirtualProtect(
UIntPtr lpAddress,
UIntPtr dwSize,
PAGE_PROTECTION_FLAGS flNewProtect,
out PAGE_PROTECTION_FLAGS lpflOldProtect)
=> unchecked(VirtualProtect((void*) lpAddress, (nuint) dwSize, flNewProtect, out lpflOldProtect));
}
}
7 changes: 7 additions & 0 deletions src/BizHawk.Bizware.Externs/NativeMethods.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"className": "Win32Imports",
"multiTargetingFriendlyAPIs": true,
"public": true,
"wideCharOnly": false,
"$schema": "https://aka.ms/CsWin32.schema.json"
}
83 changes: 83 additions & 0 deletions src/BizHawk.Bizware.Externs/NativeMethods.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
AVIFileCreateStreamW
AVIFileInit
AVIFileOpenW
AVIFileRelease
AVIIF_KEYFRAME
AVIMakeCompressedStream
AVISaveOptions
AVIStreamRelease
AVIStreamSetFormat
AVIStreamSetFormat
AVIStreamWrite
BFFM_INITIALIZED
BFFM_SETSELECTIONW
BIF_DONTGOBELOWDOMAIN
BIF_EDITBOX
BIF_NEWDIALOGSTYLE
BIF_RETURNONLYFSDIRS
BITMAPINFOHEADER
BROWSEINFOW
ChangeWindowMessageFilter
CMF_EXPLORE
CreatePopupMenu
CreateWindowExW
DefWindowProcW
DeleteFileW
DestroyMenu
DestroyWindow
DispatchMessageW
FormatMessageW
FreeLibrary
GetActiveWindow
GetCurrentDirectoryW
GetCurrentProcess
GetModuleHandleW
GetProcAddress
GetProcessHeap
GetRawInputBuffer
GetRawInputData
GetShortPathNameW
HDITEMW
HDM_GETITEMW
HDM_SETITEMW
HeapAlloc
HeapFree
HideCaret
HWND_MESSAGE
IContextMenu
IContextMenu2
ILFindLastID
IPersistFile
IShellFolder
IShellItem
IShellLinkW
IsWow64Process
LoadLibraryW
LVM_GETHEADER
MAX_PATH
MapVirtualKeyW
PathRelativePathToW
PeekMessageW
PostMessageW
RegisterClassW
RegisterRawInputDevices
SendMessageW
SetCurrentDirectoryW
SetDllDirectoryW
SHBrowseForFolderW
SHCreateItemFromParsingName
ShellLink
SHGetIDListFromObject
SHGetPathFromIDListW
SHGetSpecialFolderLocation
STGM
SystemParametersInfoW
timeBeginPeriod
TrackPopupMenuEx
TranslateMessage
VirtualAlloc
VirtualFree
VirtualProtect
WAVEFORMATEX
WINDOW_LONG_PTR_INDEX
WM_SETREDRAW
23 changes: 23 additions & 0 deletions src/BizHawk.Bizware.Externs/SHLWAPI.dll.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.IO;

using Windows.Win32.Foundation;

namespace Windows.Win32
{
public static partial class Win32Imports
{
/// <inheritdoc cref="PathRelativePathToW(PWSTR, PCWSTR, uint, PCWSTR, uint)"/>
public static BOOL PathRelativePathToW(
Span<char> pszPath,
string pszFrom,
FileAttributes dwAttrFrom,
string pszTo,
FileAttributes dwAttrTo)
=> PathRelativePathToW(
pszPath: pszPath,
pszFrom: pszFrom,
dwAttrFrom: unchecked((uint) dwAttrFrom),
pszTo: pszTo,
dwAttrTo: unchecked((uint) dwAttrTo));
}
}
37 changes: 37 additions & 0 deletions src/BizHawk.Bizware.Externs/TPMFLAGS.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Windows.Win32.Foundation;

namespace Windows.Win32.UI.WindowsAndMessaging
{
/// <summary><see href="https://learn.microsoft.com/windows/win32/api/winuser/nf-winuser-trackpopupmenuex#parameters"/></summary>
/// <seealso cref="Win32Imports.TrackPopupMenuEx(HMENU, TPMFLAGS, int, int, HWND, TPMPARAMS*)"/>
[Flags]
public enum TPMFLAGS : uint
{
CENTERALIGN = 0x0004U,
LEFTALIGN = 0x0000U,
RIGHTALIGN = 0x0008U,

BOTTOMALIGN = 0x0020U,
TOPALIGN = 0x0000U,
VCENTERALIGN = 0x0010U,

NONOTIFY = 0x0080U,
RETURNCMD = 0x0100U,

LEFTBUTTON = 0x0000U,
RIGHTBUTTON = 0x0002U,

HORNEGANIMATION = 0x0800U,
HORPOSANIMATION = 0x0400U,
NOANIMATION = 0x4000U,
VERNEGANIMATION = 0x2000U,
VERPOSANIMATION = 0x1000U,

RECURSE = 0x0001U, // value missing from official docs, but confirmed by https://github.com/microsoft/windows-rs/blob/bb15076311bf185400ecd244d47596b8415450fa/crates/libs/sys/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs#L3461

HORIZONTAL = 0x0000U,
VERTICAL = 0x0040U,

LAYOUTRTL = 0x8000U, // value also missing from official docs, but confirmed by https://github.com/microsoft/windows-rs/blob/bb15076311bf185400ecd244d47596b8415450fa/crates/libs/sys/src/Windows/Win32/UI/WindowsAndMessaging/mod.rs#L3456
}
}
59 changes: 59 additions & 0 deletions src/BizHawk.Bizware.Externs/USER32.dll.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;

namespace Windows.Win32
{
public static partial class Win32Imports
{
/// <summary><see href="https://learn.microsoft.com/windows/win32/api/winbase/nf-winbase-makeintatom"/></summary>
/// <remarks><see href="https://github.com/microsoft/CsWin32/issues/443#issuecomment-964670905"/></remarks>
public static unsafe PCWSTR MAKEINTATOM(uint i)
=> new(unchecked((char*) i));

/// <inheritdoc cref="SendMessageW(HWND, uint, WPARAM, LPARAM)"/>
public static unsafe LRESULT SendMessageW<T>(HWND hWnd, uint Msg, IntPtr wParam, ref T lParam)
where T : unmanaged
{
fixed (void* ptr = &lParam)
{
return SendMessageW(
hWnd,
Msg,
new(unchecked((UIntPtr) wParam.ToPointer())),
new(unchecked((IntPtr) ptr)));
}
}

/// <summary>getter</summary>
/// <seealso cref="SystemParametersInfoW(SYSTEM_PARAMETERS_INFO_ACTION, uint, void*, SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS)"/>
public static unsafe BOOL SystemParametersInfoW(
SYSTEM_PARAMETERS_INFO_ACTION uiAction,
uint uiParam,
out nint pvParam)
{
const SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS NONE = 0;
fixed (void* ptr = &pvParam) return SystemParametersInfoW(uiAction, uiParam, ptr, NONE);
}

/// <summary>setter</summary>
/// <seealso cref="SystemParametersInfoW(SYSTEM_PARAMETERS_INFO_ACTION, uint, void*, SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS)"/>
public static unsafe BOOL SystemParametersInfoW(
SYSTEM_PARAMETERS_INFO_ACTION uiAction,
uint uiParam,
SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS fWinIni)
{
nint pvParam = default;
return SystemParametersInfoW(uiAction, uiParam, &pvParam, fWinIni);
}

/// <inheritdoc cref="TrackPopupMenuEx(HMENU, uint, int, int, HWND, TPMPARAMS*)"/>
public static unsafe BOOL TrackPopupMenuEx(
HMENU hMenu,
TPMFLAGS uFlags,
int x,
int y,
HWND hwnd,
TPMPARAMS* lptpm)
=> TrackPopupMenuEx(hMenu, uFlags: unchecked((uint) uFlags), x: x, y: y, hwnd, lptpm);
}
}
Loading
Loading