Skip to content

Commit 9194c72

Browse files
authored
provide custom marshaller for USER_INFO_1 (#82350)
* provide custom marshaller for USER_INFO_1
1 parent 8a68f8a commit 9194c72

File tree

1 file changed

+67
-2
lines changed

1 file changed

+67
-2
lines changed

src/libraries/Common/tests/TestUtilities/System/WindowsIdentityFixture.cs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
using System.Linq;
77
using System.Net;
88
using System.Runtime.InteropServices;
9+
#if NET7_0_OR_GREATER
10+
using System.Runtime.InteropServices.Marshalling;
11+
#endif
912
using System.Security.Cryptography;
1013
using System.Security.Principal;
1114
using System.Threading.Tasks;
@@ -118,12 +121,15 @@ private void CreateUser()
118121
[return: MarshalAs(UnmanagedType.Bool)]
119122
private static partial bool LogonUser(string userName, string domain, string password, int logonType, int logonProvider, out SafeAccessTokenHandle safeAccessTokenHandle);
120123

121-
[DllImport("netapi32.dll", SetLastError = true)]
122-
internal static extern uint NetUserAdd([MarshalAs(UnmanagedType.LPWStr)] string servername, uint level, ref USER_INFO_1 buf, out uint parm_err);
124+
[LibraryImport("netapi32.dll", SetLastError = true)]
125+
internal static partial uint NetUserAdd([MarshalAs(UnmanagedType.LPWStr)] string servername, uint level, ref USER_INFO_1 buf, out uint parm_err);
123126

124127
[LibraryImport("netapi32.dll")]
125128
internal static partial uint NetUserDel([MarshalAs(UnmanagedType.LPWStr)] string servername, [MarshalAs(UnmanagedType.LPWStr)] string username);
126129

130+
#if NET7_0_OR_GREATER
131+
[NativeMarshalling(typeof(USER_INFO_1.Marshaller))]
132+
#endif
127133
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
128134
internal struct USER_INFO_1
129135
{
@@ -135,6 +141,65 @@ internal struct USER_INFO_1
135141
public string usri1_comment;
136142
public uint usri1_flags;
137143
public string usri1_script_path;
144+
145+
#if NET7_0_OR_GREATER
146+
[CustomMarshaller(typeof(USER_INFO_1), MarshalMode.Default, typeof(Marshaller))]
147+
public static class Marshaller
148+
{
149+
public static USER_INFO_1Native ConvertToUnmanaged(USER_INFO_1 managed) => new(managed);
150+
public static USER_INFO_1 ConvertToManaged(USER_INFO_1Native native) => native.ToManaged();
151+
public static void Free(USER_INFO_1Native native) => native.FreeNative();
152+
153+
[StructLayout(LayoutKind.Sequential)]
154+
public struct USER_INFO_1Native
155+
{
156+
private IntPtr usri1_name;
157+
private IntPtr usri1_password;
158+
private uint usri1_password_age;
159+
private uint usri1_priv;
160+
private IntPtr usri1_home_dir;
161+
private IntPtr usri1_comment;
162+
private uint usri1_flags;
163+
private IntPtr usri1_script_path;
164+
165+
public USER_INFO_1Native(USER_INFO_1 managed)
166+
{
167+
usri1_name = Marshal.StringToCoTaskMemUni(managed.usri1_name);
168+
usri1_password = Marshal.StringToCoTaskMemUni(managed.usri1_password);
169+
usri1_password_age = managed.usri1_password_age;
170+
usri1_priv = managed.usri1_priv;
171+
usri1_home_dir = Marshal.StringToCoTaskMemUni(managed.usri1_home_dir);
172+
usri1_comment = Marshal.StringToCoTaskMemUni(managed.usri1_comment);
173+
usri1_flags = managed.usri1_flags;
174+
usri1_script_path = Marshal.StringToCoTaskMemUni(managed.usri1_script_path);
175+
}
176+
177+
public USER_INFO_1 ToManaged()
178+
{
179+
return new USER_INFO_1
180+
{
181+
usri1_name = Marshal.PtrToStringUni(usri1_name),
182+
usri1_password = Marshal.PtrToStringUni(usri1_password),
183+
usri1_password_age = usri1_password_age,
184+
usri1_priv = usri1_priv,
185+
usri1_home_dir = Marshal.PtrToStringUni(usri1_home_dir),
186+
usri1_comment = Marshal.PtrToStringUni(usri1_comment),
187+
usri1_flags = usri1_flags,
188+
usri1_script_path = Marshal.PtrToStringUni(usri1_script_path)
189+
};
190+
}
191+
192+
public void FreeNative()
193+
{
194+
Marshal.FreeCoTaskMem(usri1_name);
195+
Marshal.FreeCoTaskMem(usri1_password);
196+
Marshal.FreeCoTaskMem(usri1_home_dir);
197+
Marshal.FreeCoTaskMem(usri1_comment);
198+
Marshal.FreeCoTaskMem(usri1_script_path);
199+
}
200+
}
201+
}
202+
#endif
138203
}
139204

140205
public void Dispose()

0 commit comments

Comments
 (0)