From 74c982f3de53a99b84829a26e1b107c3c8e1eb3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Fri, 28 Jun 2019 19:42:56 +0200 Subject: [PATCH 1/3] Mark pvBuffer as In/Out This parameter is actually used as in/out. Per https://docs.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types they must be marked as such ("you must apply the InAttribute and OutAttribute attributes if you want to marshal the argument as an In/Out parameter"). The code currently works, because it's taking advantage of the pinning optimization. It will keep working the same, but the metadata will be correct after the change. --- src/Common/src/UnsafeNativeMethods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Common/src/UnsafeNativeMethods.cs b/src/Common/src/UnsafeNativeMethods.cs index 53a95e4b1c8..a87aa5a64c6 100644 --- a/src/Common/src/UnsafeNativeMethods.cs +++ b/src/Common/src/UnsafeNativeMethods.cs @@ -1104,7 +1104,7 @@ public static bool TrySystemParametersInfoForDpi(int nAction, int nParam, [In, O public static extern IntPtr GetProcessWindowStation(); [DllImport(ExternDll.User32, SetLastError = true)] - public static extern bool GetUserObjectInformation(HandleRef hObj, int nIndex, [MarshalAs(UnmanagedType.LPStruct)] NativeMethods.USEROBJECTFLAGS pvBuffer, int nLength, ref int lpnLengthNeeded); + public static extern bool GetUserObjectInformation(HandleRef hObj, int nIndex, [In, Out, MarshalAs(UnmanagedType.LPStruct)] NativeMethods.USEROBJECTFLAGS pvBuffer, int nLength, ref int lpnLengthNeeded); [DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)] public static extern int ClientToScreen(HandleRef hWnd, [In, Out] NativeMethods.POINT pt); From a2a76f372b5af03109ec9992f0a90a2d5bcd4787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 1 Jul 2019 21:21:17 +0200 Subject: [PATCH 2/3] Review feedback --- src/Common/src/NativeMethods.cs | 8 ++++---- src/Common/src/UnsafeNativeMethods.cs | 2 +- .../src/System/Windows/Forms/SystemInformation.cs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Common/src/NativeMethods.cs b/src/Common/src/NativeMethods.cs index b4a24211b69..07bec77157d 100644 --- a/src/Common/src/NativeMethods.cs +++ b/src/Common/src/NativeMethods.cs @@ -2008,11 +2008,11 @@ public PICTDESCemf(System.Drawing.Imaging.Metafile metafile) } [StructLayout(LayoutKind.Sequential)] - public class USEROBJECTFLAGS + public struct USEROBJECTFLAGS { - public int fInherit = 0; - public int fReserved = 0; - public int dwFlags = 0; + public int fInherit; + public int fReserved; + public int dwFlags; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] diff --git a/src/Common/src/UnsafeNativeMethods.cs b/src/Common/src/UnsafeNativeMethods.cs index a87aa5a64c6..8a27a07ea94 100644 --- a/src/Common/src/UnsafeNativeMethods.cs +++ b/src/Common/src/UnsafeNativeMethods.cs @@ -1104,7 +1104,7 @@ public static bool TrySystemParametersInfoForDpi(int nAction, int nParam, [In, O public static extern IntPtr GetProcessWindowStation(); [DllImport(ExternDll.User32, SetLastError = true)] - public static extern bool GetUserObjectInformation(HandleRef hObj, int nIndex, [In, Out, MarshalAs(UnmanagedType.LPStruct)] NativeMethods.USEROBJECTFLAGS pvBuffer, int nLength, ref int lpnLengthNeeded); + public static extern bool GetUserObjectInformation(HandleRef hObj, int nIndex, ref NativeMethods.USEROBJECTFLAGS pvBuffer, int nLength, ref int lpnLengthNeeded); [DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)] public static extern int ClientToScreen(HandleRef hWnd, [In, Out] NativeMethods.POINT pt); diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/SystemInformation.cs b/src/System.Windows.Forms/src/System/Windows/Forms/SystemInformation.cs index 82470af3312..552238f637c 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/SystemInformation.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/SystemInformation.cs @@ -807,7 +807,7 @@ public static bool UserInteractive int lengthNeeded = 0; NativeMethods.USEROBJECTFLAGS flags = new NativeMethods.USEROBJECTFLAGS(); - if (UnsafeNativeMethods.GetUserObjectInformation(new HandleRef(null, hwinsta), NativeMethods.UOI_FLAGS, flags, Marshal.SizeOf(flags), ref lengthNeeded)) + if (UnsafeNativeMethods.GetUserObjectInformation(new HandleRef(null, hwinsta), NativeMethods.UOI_FLAGS, ref flags, Marshal.SizeOf(), ref lengthNeeded)) { if ((flags.dwFlags & NativeMethods.WSF_VISIBLE) == 0) { From 1ba5889ebf38c184d897a5685ddd46a1d3ef1c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Strehovsk=C3=BD?= Date: Mon, 1 Jul 2019 21:34:00 +0200 Subject: [PATCH 3/3] Review feedback --- src/Common/src/NativeMethods.cs | 1 - .../src/System/Windows/Forms/SystemInformation.cs | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Common/src/NativeMethods.cs b/src/Common/src/NativeMethods.cs index 07bec77157d..afcaad845ec 100644 --- a/src/Common/src/NativeMethods.cs +++ b/src/Common/src/NativeMethods.cs @@ -2007,7 +2007,6 @@ public PICTDESCemf(System.Drawing.Imaging.Metafile metafile) } } - [StructLayout(LayoutKind.Sequential)] public struct USEROBJECTFLAGS { public int fInherit; diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/SystemInformation.cs b/src/System.Windows.Forms/src/System/Windows/Forms/SystemInformation.cs index 552238f637c..b6451c345f7 100644 --- a/src/System.Windows.Forms/src/System/Windows/Forms/SystemInformation.cs +++ b/src/System.Windows.Forms/src/System/Windows/Forms/SystemInformation.cs @@ -795,7 +795,7 @@ public static string ComputerName /// Gets a value indicating whether the current process is running in user /// interactive mode. /// - public static bool UserInteractive + public unsafe static bool UserInteractive { get { @@ -807,7 +807,7 @@ public static bool UserInteractive int lengthNeeded = 0; NativeMethods.USEROBJECTFLAGS flags = new NativeMethods.USEROBJECTFLAGS(); - if (UnsafeNativeMethods.GetUserObjectInformation(new HandleRef(null, hwinsta), NativeMethods.UOI_FLAGS, ref flags, Marshal.SizeOf(), ref lengthNeeded)) + if (UnsafeNativeMethods.GetUserObjectInformation(new HandleRef(null, hwinsta), NativeMethods.UOI_FLAGS, ref flags, sizeof(NativeMethods.USEROBJECTFLAGS), ref lengthNeeded)) { if ((flags.dwFlags & NativeMethods.WSF_VISIBLE) == 0) {