diff --git a/src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs b/src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs index 0f0ff0c2cce1e2..b4d9be2a52744d 100644 --- a/src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs +++ b/src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs @@ -6,6 +6,9 @@ using System.Linq; using System.Net; using System.Runtime.InteropServices; +#if NET7_0_OR_GREATER +using System.Runtime.InteropServices.Marshalling; +#endif using System.Security.Cryptography; using System.Security.Principal; using System.Threading.Tasks; @@ -118,12 +121,15 @@ private void CreateUser() [return: MarshalAs(UnmanagedType.Bool)] private static partial bool LogonUser(string userName, string domain, string password, int logonType, int logonProvider, out SafeAccessTokenHandle safeAccessTokenHandle); - [DllImport("netapi32.dll", SetLastError = true)] - internal static extern uint NetUserAdd([MarshalAs(UnmanagedType.LPWStr)] string servername, uint level, ref USER_INFO_1 buf, out uint parm_err); + [LibraryImport("netapi32.dll", SetLastError = true)] + internal static partial uint NetUserAdd([MarshalAs(UnmanagedType.LPWStr)] string servername, uint level, ref USER_INFO_1 buf, out uint parm_err); [LibraryImport("netapi32.dll")] internal static partial uint NetUserDel([MarshalAs(UnmanagedType.LPWStr)] string servername, [MarshalAs(UnmanagedType.LPWStr)] string username); +#if NET7_0_OR_GREATER + [NativeMarshalling(typeof(USER_INFO_1.Marshaller))] +#endif [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct USER_INFO_1 { @@ -135,6 +141,65 @@ internal struct USER_INFO_1 public string usri1_comment; public uint usri1_flags; public string usri1_script_path; + +#if NET7_0_OR_GREATER + [CustomMarshaller(typeof(USER_INFO_1), MarshalMode.Default, typeof(Marshaller))] + public static class Marshaller + { + public static USER_INFO_1Native ConvertToUnmanaged(USER_INFO_1 managed) => new(managed); + public static USER_INFO_1 ConvertToManaged(USER_INFO_1Native native) => native.ToManaged(); + public static void Free(USER_INFO_1Native native) => native.FreeNative(); + + [StructLayout(LayoutKind.Sequential)] + public struct USER_INFO_1Native + { + private IntPtr usri1_name; + private IntPtr usri1_password; + private uint usri1_password_age; + private uint usri1_priv; + private IntPtr usri1_home_dir; + private IntPtr usri1_comment; + private uint usri1_flags; + private IntPtr usri1_script_path; + + public USER_INFO_1Native(USER_INFO_1 managed) + { + usri1_name = Marshal.StringToCoTaskMemUni(managed.usri1_name); + usri1_password = Marshal.StringToCoTaskMemUni(managed.usri1_password); + usri1_password_age = managed.usri1_password_age; + usri1_priv = managed.usri1_priv; + usri1_home_dir = Marshal.StringToCoTaskMemUni(managed.usri1_home_dir); + usri1_comment = Marshal.StringToCoTaskMemUni(managed.usri1_comment); + usri1_flags = managed.usri1_flags; + usri1_script_path = Marshal.StringToCoTaskMemUni(managed.usri1_script_path); + } + + public USER_INFO_1 ToManaged() + { + return new USER_INFO_1 + { + usri1_name = Marshal.PtrToStringUni(usri1_name), + usri1_password = Marshal.PtrToStringUni(usri1_password), + usri1_password_age = usri1_password_age, + usri1_priv = usri1_priv, + usri1_home_dir = Marshal.PtrToStringUni(usri1_home_dir), + usri1_comment = Marshal.PtrToStringUni(usri1_comment), + usri1_flags = usri1_flags, + usri1_script_path = Marshal.PtrToStringUni(usri1_script_path) + }; + } + + public void FreeNative() + { + Marshal.FreeCoTaskMem(usri1_name); + Marshal.FreeCoTaskMem(usri1_password); + Marshal.FreeCoTaskMem(usri1_home_dir); + Marshal.FreeCoTaskMem(usri1_comment); + Marshal.FreeCoTaskMem(usri1_script_path); + } + } + } +#endif } public void Dispose()