Skip to content

Commit

Permalink
Migrated DllImports to .NET 7 LibraryImports (faster). Some methods u…
Browse files Browse the repository at this point in the history
…sing ref struct have not been updated yet, I have to do some research on this.

Updated all StringBuilders to char pointers as per https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1838
  • Loading branch information
wokhan committed Jan 12, 2023
1 parent 39d0cb2 commit 24a7be2
Show file tree
Hide file tree
Showing 19 changed files with 101 additions and 90 deletions.
1 change: 1 addition & 0 deletions Common/Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
</ItemGroup>
<PropertyGroup>
<RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>TRACE;DEBUG</DefineConstants>
Expand Down
6 changes: 3 additions & 3 deletions Common/Core/Resources/ResourcesLoader.NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Wokhan.WindowsFirewallNotifier.Common.Core.Resources
{
public static partial class ResourcesLoader
{
protected static class NativeMethods
protected static partial class NativeMethods
{
/*[DllImport("Wtsapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
Expand All @@ -15,8 +15,8 @@ protected static class NativeMethods
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint WTSGetActiveConsoleSessionId();
*/
[DllImport("shlwapi.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = false, ThrowOnUnmappableChar = true)]
internal static extern int SHLoadIndirectString(string pszSource, StringBuilder pszOutBuf, uint cchOutBuf, IntPtr ppvReserved);
[LibraryImport("shlwapi.dll", SetLastError = false, StringMarshalling = StringMarshalling.Utf16)] //, ThrowOnUnmappableChar = true)]
internal static unsafe partial int SHLoadIndirectString(string pszSource, char* pszOutBuf, uint cchOutBuf, IntPtr ppvReserved);
}
}
}
10 changes: 6 additions & 4 deletions Common/Core/Resources/ResourcesLoader.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Text;

namespace Wokhan.WindowsFirewallNotifier.Common.Core.Resources
{
Expand All @@ -9,10 +8,13 @@ public static string GetMSResourceString(string src)
{
if (src?.StartsWith("@") ?? false)
{
var sb = new StringBuilder(1024); //FIXME: Hardcoded maximum string size!
if (0 == NativeMethods.SHLoadIndirectString(Environment.ExpandEnvironmentVariables(src), sb, (uint)sb.Capacity, IntPtr.Zero))
unsafe
{
src = sb.ToString();
char* sb = stackalloc char[1024]; //FIXME: Hardcoded maximum string size!
if (0 == NativeMethods.SHLoadIndirectString(Environment.ExpandEnvironmentVariables(src), sb, (uint)1024, IntPtr.Zero))
{
src = new String(sb);
}
}

}
Expand Down
6 changes: 3 additions & 3 deletions Common/IO/Files/PathResolver.NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ namespace Wokhan.WindowsFirewallNotifier.Common.IO.Files
{
public static partial class PathResolver
{
protected static class NativeMethods
protected static partial class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, uint ucchMax);
[LibraryImport("kernel32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
internal static unsafe partial uint QueryDosDevice(string lpDeviceName, char* lpTargetPath, uint ucchMax);
}
}
}
16 changes: 10 additions & 6 deletions Common/IO/Files/PathResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,21 @@ private static void InitDriveMapping()
{
var drives = Directory.GetLogicalDrives();
deviceNameMap = new Dictionary<string, string>(drives.Length);
var sb = new StringBuilder(MAX_PATH + 1);
string trimmedDrive;
var len = MAX_PATH + 1;

foreach (var drive in drives)
unsafe
{
trimmedDrive = drive.TrimEnd('\\');
if (NativeMethods.QueryDosDevice(trimmedDrive, sb, (uint)sb.Capacity) == 0)
char* sb = stackalloc char[len];
foreach (var drive in drives)
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Call to QueryDosDevice failed!");
trimmedDrive = drive.TrimEnd('\\');
if (NativeMethods.QueryDosDevice(trimmedDrive, sb, (uint)len) == 0)
{
throw new Win32Exception(Marshal.GetLastWin32Error(), "Call to QueryDosDevice failed!");
}
deviceNameMap.Add(new String(sb).ToLower() + "\\", trimmedDrive); //FIXME: Switch to ToUpper?
}
deviceNameMap.Add(sb.ToString().ToLower() + "\\", trimmedDrive); //FIXME: Switch to ToUpper?
}
}
catch (Exception e)
Expand Down
6 changes: 3 additions & 3 deletions Common/Net/IP/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ namespace Wokhan.WindowsFirewallNotifier.Common.Net.IP
{
public partial class IPHelper
{
protected static class NativeMethods
protected static partial class NativeMethods
{
[DllImport("kernel32.dll", EntryPoint = "RtlZeroMemory", SetLastError = false)]
internal static extern void ZeroMemory(IntPtr dest, uint size);
[LibraryImport("kernel32.dll", SetLastError = false)]
internal static partial void RtlZeroMemory(IntPtr dest, uint size);
}
}
}
2 changes: 1 addition & 1 deletion Common/Net/IP/TCP/MIB_TCPROW.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace Wokhan.WindowsFirewallNotifier.Common.Net.IP
public partial class TCPHelper
{
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPROW
public class MIB_TCPROW
{
public ConnectionStatus State;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
Expand Down
2 changes: 1 addition & 1 deletion Common/Net/IP/TCP/MIB_TCPROW_OWNER_MODULE.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace Wokhan.WindowsFirewallNotifier.Common.Net.IP
{
[StructLayout(LayoutKind.Sequential)]
public struct MIB_TCPROW_OWNER_MODULE : IConnectionOwnerInfo
public class MIB_TCPROW_OWNER_MODULE : IConnectionOwnerInfo
{
internal ConnectionStatus _state;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
Expand Down
6 changes: 3 additions & 3 deletions Common/Net/IP/TCP/TCPHelper.NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ namespace Wokhan.WindowsFirewallNotifier.Common.Net.IP
{
public partial class TCPHelper
{
protected new static class NativeMethods
protected new static partial class NativeMethods
{
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static extern uint GetOwnerModuleFromTcpEntry(ref MIB_TCPROW_OWNER_MODULE pTcpEntry, TCPIP_OWNER_MODULE_INFO_CLASS Class, IntPtr Buffer, ref uint pdwSize);

[DllImport("iphlpapi.dll", SetLastError = true)]
internal static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref uint dwOutBufLen, [MarshalAs(UnmanagedType.Bool)] bool sort, AF_INET ipVersion, TCP_TABLE_CLASS tblClass, uint reserved);
[LibraryImport("iphlpapi.dll", SetLastError = true)]
internal static partial uint GetExtendedTcpTable(IntPtr pTcpTable, ref uint dwOutBufLen, [MarshalAs(UnmanagedType.Bool)] bool sort, AF_INET ipVersion, TCP_TABLE_CLASS tblClass, uint reserved);

[DllImport("iphlpapi.dll", SetLastError = true)]
internal static extern uint GetPerTcpConnectionEStats(ref MIB_TCPROW Row, TCP_ESTATS_TYPE EstatsType, IntPtr Rw, uint RwVersion, uint RwSize, IntPtr Ros, uint RosVersion, uint RosSize, IntPtr Rod, uint RodVersion, uint RodSize);
Expand Down
2 changes: 1 addition & 1 deletion Common/Net/IP/TCP/TCPHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ public static TCP_ESTATS_DATA_ROD_v0 GetTCPStatistics(MIB_TCPROW_OWNER_MODULE co
buffer = Marshal.AllocHGlobal((int)buffSize);

//GetOwnerModuleFromTcpEntry needs the fields of TCPIP_OWNER_MODULE_INFO_BASIC to be NULL
IPHelper.NativeMethods.ZeroMemory(buffer, buffSize);
IPHelper.NativeMethods.RtlZeroMemory(buffer, buffSize);

var resp = NativeMethods.GetOwnerModuleFromTcpEntry(ref row, TCPIP_OWNER_MODULE_INFO_CLASS.TCPIP_OWNER_MODULE_INFO_BASIC, buffer, ref buffSize);
if (resp == 0)
Expand Down
6 changes: 3 additions & 3 deletions Common/Net/IP/TCP6/TCP6Helper.NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Wokhan.WindowsFirewallNotifier.Common.Net.IP
{
public partial class TCP6Helper
{
protected new static class NativeMethods
protected new static partial class NativeMethods
{
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static extern uint GetOwnerModuleFromTcp6Entry(ref MIB_TCP6ROW_OWNER_MODULE pTcpEntry, TCPIP_OWNER_MODULE_INFO_CLASS Class, IntPtr Buffer, ref uint pdwSize);
Expand All @@ -17,8 +17,8 @@ public partial class TCP6Helper
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static extern uint SetPerTcp6ConnectionEStats(ref MIB_TCP6ROW Row, TCP_ESTATS_TYPE EstatsType, IntPtr Rw, uint RwVersion, uint RwSize, uint Offset);

[DllImport("ntdll.dll", SetLastError = true/*TODO: test this, CharSet = CharSet.Unicode*/)]
internal static extern void RtlIpv6AddressToString(byte[] Addr, out StringBuilder res);
[LibraryImport("ntdll.dll", SetLastError = true/*TODO: test this, CharSet = CharSet.Unicode*/)]
internal static unsafe partial void RtlIpv6AddressToString(byte[] Addr, char* res);
}
}
}
2 changes: 1 addition & 1 deletion Common/Net/IP/TCP6/TCP6Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public static IEnumerable<IConnectionOwnerInfo> GetAllTCP6Connections()
buffer = Marshal.AllocHGlobal((int)buffSize);

//GetOwnerModuleFromTcp6Entry needs the fields of TCPIP_OWNER_MODULE_INFO_BASIC to be NULL
IPHelper.NativeMethods.ZeroMemory(buffer, buffSize);
IPHelper.NativeMethods.RtlZeroMemory(buffer, buffSize);

var resp = NativeMethods.GetOwnerModuleFromTcp6Entry(ref row, TCPIP_OWNER_MODULE_INFO_CLASS.TCPIP_OWNER_MODULE_INFO_BASIC, buffer, ref buffSize);
if (resp == 0)
Expand Down
6 changes: 3 additions & 3 deletions Common/Net/IP/UDP/UDPHelper.NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ namespace Wokhan.WindowsFirewallNotifier.Common.Net.IP.UDP
{
public partial class UDPHelper
{
protected new static class NativeMethods
protected new static partial class NativeMethods
{
[DllImport("iphlpapi.dll", SetLastError = true)]
internal static extern uint GetOwnerModuleFromUdpEntry(ref MIB_UDPROW_OWNER_MODULE pUdpEntry, IPHelper.TCPIP_OWNER_MODULE_INFO_CLASS Class, IntPtr Buffer, ref uint pdwSize);

[DllImport("iphlpapi.dll", SetLastError = true)]
internal static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int dwOutBufLen, bool sort, AF_INET ipVersion, UDP_TABLE_CLASS tblClass, uint reserved);
[LibraryImport("iphlpapi.dll", SetLastError = true)]
internal static partial uint GetExtendedUdpTable(IntPtr pUdpTable, ref int dwOutBufLen, [MarshalAs(UnmanagedType.Bool)] bool sort, AF_INET ipVersion, UDP_TABLE_CLASS tblClass, uint reserved);
}
}
}
2 changes: 1 addition & 1 deletion Common/Net/IP/UDP/UDPHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public static IEnumerable<IConnectionOwnerInfo> GetAllUDPConnections()
buffer = Marshal.AllocHGlobal((int)buffSize);

//GetOwnerModuleFromUdpEntry might want the fields of TCPIP_OWNER_MODULE_INFO_BASIC to be NULL
IPHelper.NativeMethods.ZeroMemory(buffer, buffSize);
IPHelper.NativeMethods.RtlZeroMemory(buffer, buffSize);

var resp = UDPHelper.NativeMethods.GetOwnerModuleFromUdpEntry(ref row, TCPIP_OWNER_MODULE_INFO_CLASS.TCPIP_OWNER_MODULE_INFO_BASIC, buffer, ref buffSize);
if (resp == NO_ERROR)
Expand Down
2 changes: 1 addition & 1 deletion Common/Net/IP/UDP6/UDP6Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public static IEnumerable<IConnectionOwnerInfo> GetAllUDP6Connections()
buffer = Marshal.AllocHGlobal((int)buffSize);

//GetOwnerModuleFromUdp6Entry might want the fields of TCPIP_OWNER_MODULE_INFO_BASIC to be NULL
IPHelper.NativeMethods.ZeroMemory(buffer, buffSize);
IPHelper.NativeMethods.RtlZeroMemory(buffer, buffSize);

var resp = NativeMethods.GetOwnerModuleFromUdp6Entry(ref row, TCPIP_OWNER_MODULE_INFO_CLASS.TCPIP_OWNER_MODULE_INFO_BASIC, buffer, ref buffSize);
if (resp == 0)
Expand Down
54 changes: 27 additions & 27 deletions Common/Processes/ProcessHelper.NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Wokhan.WindowsFirewallNotifier.Common.Processes
{
public static partial class ProcessHelper
{
protected static class NativeMethods
protected static partial class NativeMethods
{
[Flags]
internal enum ProcessAccessFlags : uint
Expand Down Expand Up @@ -84,19 +84,19 @@ internal struct SID_AND_ATTRIBUTES
public int Attributes;
}

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern IntPtr OpenSCManager(string? machineName, string? databaseName, uint dwAccess);
[LibraryImport("advapi32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
internal static partial IntPtr OpenSCManager(string? machineName, string? databaseName, uint dwAccess);

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern uint EnumServicesStatusEx(IntPtr hSCManager,
[LibraryImport("advapi32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
internal static partial uint EnumServicesStatusEx(IntPtr hSCManager,
int infoLevel, uint dwServiceType,
uint dwServiceState, IntPtr lpServices, uint cbBufSize,
out uint pcbBytesNeeded, out uint lpServicesReturned,
ref uint lpResumeHandle, string? pszGroupName);

[DllImport("advapi32.dll", SetLastError = true)]
[LibraryImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseServiceHandle(IntPtr hSCObject);
internal static partial bool CloseServiceHandle(IntPtr hSCObject);

[Flags]
internal enum ACCESS_MASK : uint { DELETE = 0x00010000, READ_CONTROL = 0x00020000, WRITE_DAC = 0x00040000, WRITE_OWNER = 0x00080000, SYNCHRONIZE = 0x00100000, STANDARD_RIGHTS_REQUIRED = 0x000f0000, STANDARD_RIGHTS_READ = 0x00020000, STANDARD_RIGHTS_WRITE = 0x00020000, STANDARD_RIGHTS_EXECUTE = 0x00020000, STANDARD_RIGHTS_ALL = 0x001f0000, SPECIFIC_RIGHTS_ALL = 0x0000ffff, ACCESS_SYSTEM_SECURITY = 0x01000000, MAXIMUM_ALLOWED = 0x02000000, GENERIC_READ = 0x80000000, GENERIC_WRITE = 0x40000000, GENERIC_EXECUTE = 0x20000000, GENERIC_ALL = 0x10000000, DESKTOP_READOBJECTS = 0x00000001, DESKTOP_CREATEWINDOW = 0x00000002, DESKTOP_CREATEMENU = 0x00000004, DESKTOP_HOOKCONTROL = 0x00000008, DESKTOP_JOURNALRECORD = 0x00000010, DESKTOP_JOURNALPLAYBACK = 0x00000020, DESKTOP_ENUMERATE = 0x00000040, DESKTOP_WRITEOBJECTS = 0x00000080, DESKTOP_SWITCHDESKTOP = 0x00000100, WINSTA_ENUMDESKTOPS = 0x00000001, WINSTA_READATTRIBUTES = 0x00000002, WINSTA_ACCESSCLIPBOARD = 0x00000004, WINSTA_CREATEDESKTOP = 0x00000008, WINSTA_WRITEATTRIBUTES = 0x00000010, WINSTA_ACCESSGLOBALATOMS = 0x00000020, WINSTA_EXITWINDOWS = 0x00000040, WINSTA_ENUMERATE = 0x00000100, WINSTA_READSCREEN = 0x00000200, WINSTA_ALL_ACCESS = 0x0000037f }
Expand Down Expand Up @@ -165,47 +165,47 @@ internal enum SC_ENUM_TYPE : uint
internal static extern uint GetPackageFullName(IntPtr hProcess, ref uint packageFullNameLength, StringBuilder packageFullName);*/

//Note: Only exists on Windows 8 and higher
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern uint GetPackageFamilyName(IntPtr hProcess, ref uint packageFamilyNameLength, StringBuilder packageFamilyName);
[LibraryImport("kernel32.dll")]
internal static unsafe partial uint GetPackageFamilyName(IntPtr hProcess, ref uint packageFamilyNameLength, char* packageFamilyName);

//Note: Only exists on Windows 8 and higher
[DllImport("userenv.dll", CharSet = CharSet.Unicode)]
internal static extern uint DeriveAppContainerSidFromAppContainerName(string pszAppContainerName, out IntPtr ppsidAppContainerSid);
[LibraryImport("userenv.dll", StringMarshalling = StringMarshalling.Utf16)]
internal static partial uint DeriveAppContainerSidFromAppContainerName(string pszAppContainerName, out IntPtr ppsidAppContainerSid);

internal const uint ERROR_SUCCESS = 0;
internal const uint APPMODEL_ERROR_NO_PACKAGE = 15700;
internal const uint S_OK = 0x00000000;

[DllImport("kernel32.dll", SetLastError = true)]
internal static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);
[LibraryImport("kernel32.dll", SetLastError = true)]
internal static partial IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId);

internal const int TOKEN_QUERY = 0X00000008;

[DllImport("kernel32.dll", SetLastError = true)]
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);
internal static partial bool OpenProcessToken(IntPtr ProcessHandle, uint DesiredAccess, out IntPtr TokenHandle);

[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Auto)]
[LibraryImport("advapi32", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool GetTokenInformation(IntPtr hToken, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint dwTokenInfoLength, ref uint dwReturnLength);
internal static partial bool GetTokenInformation(IntPtr hToken, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, uint dwTokenInfoLength, ref uint dwReturnLength);

[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Auto)]
[LibraryImport("advapi32", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ConvertSidToStringSid(IntPtr pSID, [MarshalAs(UnmanagedType.LPTStr)] out string pStringSid);
internal static partial bool ConvertSidToStringSid(IntPtr pSID, [MarshalAs(UnmanagedType.LPTStr)] out string pStringSid);

[DllImport("advapi32", CharSet = CharSet.Auto)]
internal static extern IntPtr FreeSid(IntPtr pSid);
[LibraryImport("advapi32")]
internal static partial IntPtr FreeSid(IntPtr pSid);

[DllImport("kernel32.dll", SetLastError = true)]
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseHandle(IntPtr hObject);
internal static partial bool CloseHandle(IntPtr hObject);

[DllImport("user32.dll")]
[LibraryImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool ShowWindow(IntPtr hWnd, ShowWindowEnum flags);
internal static partial bool ShowWindow(IntPtr hWnd, ShowWindowEnum flags);

[DllImport("user32.dll")]
internal static extern int SetForegroundWindow(IntPtr hwnd);
[LibraryImport("user32.dll")]
internal static partial int SetForegroundWindow(IntPtr hwnd);

internal enum ShowWindowEnum
{
Expand Down
Loading

0 comments on commit 24a7be2

Please sign in to comment.