Skip to content

Commit

Permalink
Update custom marshallers for source-generated interop to the V2 shap…
Browse files Browse the repository at this point in the history
…es. (#42619)

* Update custom marshallers for source-generated interop to the V2 shapes.

Update shape to match the final shapes

Fix enum name to match approved name

* Update src/Servers/IIS/IIS/src/Core/IISConfigurationData.cs

Co-authored-by: Aaron Robinson <[email protected]>

* Fix build

Co-authored-by: Aaron Robinson <[email protected]>
  • Loading branch information
jkoritzinsky and AaronRobinsonMSFT authored Jul 9, 2022
1 parent 0e255c5 commit 3e50fe3
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 48 deletions.
74 changes: 35 additions & 39 deletions src/Servers/IIS/IIS/src/Core/IISConfigurationData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ internal struct IISConfigurationData
public string pwzBindings;
public uint maxRequestBodySize;

[CustomTypeMarshaller(typeof(IISConfigurationData), CustomTypeMarshallerKind.Value, Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.TwoStageMarshalling)]
public unsafe ref struct Marshaller
[CustomMarshaller(typeof(IISConfigurationData), MarshalMode.Default, typeof(Marshaller))]
public static class Marshaller
{
public struct Native
{
Expand All @@ -34,53 +34,49 @@ public struct Native
public uint maxRequestBodySize;
}

private Native _native;

public Marshaller(IISConfigurationData managed)
public static Native ConvertToUnmanaged(IISConfigurationData managed)
{
_native.pNativeApplication = managed.pNativeApplication;
_native.pwzFullApplicationPath = managed.pwzFullApplicationPath is null ? IntPtr.Zero : Marshal.StringToBSTR(managed.pwzFullApplicationPath);
_native.pwzVirtualApplicationPath = managed.pwzVirtualApplicationPath is null ? IntPtr.Zero : Marshal.StringToBSTR(managed.pwzVirtualApplicationPath);
_native.fWindowsAuthEnabled = managed.fWindowsAuthEnabled ? 1 : 0;
_native.fBasicAuthEnabled = managed.fBasicAuthEnabled ? 1 : 0;
_native.fAnonymousAuthEnable = managed.fAnonymousAuthEnable ? 1 : 0;
_native.pwzBindings = managed.pwzBindings is null ? IntPtr.Zero : Marshal.StringToBSTR(managed.pwzBindings);
_native.maxRequestBodySize = managed.maxRequestBodySize;
Native native;
native.pNativeApplication = managed.pNativeApplication;
native.pwzFullApplicationPath = managed.pwzFullApplicationPath is null ? IntPtr.Zero : Marshal.StringToBSTR(managed.pwzFullApplicationPath);
native.pwzVirtualApplicationPath = managed.pwzVirtualApplicationPath is null ? IntPtr.Zero : Marshal.StringToBSTR(managed.pwzVirtualApplicationPath);
native.fWindowsAuthEnabled = managed.fWindowsAuthEnabled ? 1 : 0;
native.fBasicAuthEnabled = managed.fBasicAuthEnabled ? 1 : 0;
native.fAnonymousAuthEnable = managed.fAnonymousAuthEnable ? 1 : 0;
native.pwzBindings = managed.pwzBindings is null ? IntPtr.Zero : Marshal.StringToBSTR(managed.pwzBindings);
native.maxRequestBodySize = managed.maxRequestBodySize;
return native;
}

public Native ToNativeValue() => _native;

public void FromNativeValue(Native value) => _native = value;

public IISConfigurationData ToManaged()
public static void Free(Native native)
{
return new()
if (native.pwzFullApplicationPath != IntPtr.Zero)
{
pNativeApplication = _native.pNativeApplication,
pwzFullApplicationPath = _native.pwzFullApplicationPath == IntPtr.Zero ? string.Empty : Marshal.PtrToStringBSTR(_native.pwzFullApplicationPath),
pwzVirtualApplicationPath = _native.pwzVirtualApplicationPath == IntPtr.Zero ? string.Empty : Marshal.PtrToStringBSTR(_native.pwzVirtualApplicationPath),
fWindowsAuthEnabled = _native.fWindowsAuthEnabled != 0,
fBasicAuthEnabled = _native.fBasicAuthEnabled != 0,
fAnonymousAuthEnable = _native.fAnonymousAuthEnable != 0,
pwzBindings = _native.pwzBindings == IntPtr.Zero ? string.Empty : Marshal.PtrToStringBSTR(_native.pwzBindings),
maxRequestBodySize = _native.maxRequestBodySize
};
}

public void FreeNative()
{
if (_native.pwzFullApplicationPath != IntPtr.Zero)
{
Marshal.FreeBSTR(_native.pwzFullApplicationPath);
Marshal.FreeBSTR(native.pwzFullApplicationPath);
}
if (_native.pwzVirtualApplicationPath != IntPtr.Zero)
if (native.pwzVirtualApplicationPath != IntPtr.Zero)
{
Marshal.FreeBSTR(_native.pwzVirtualApplicationPath);
Marshal.FreeBSTR(native.pwzVirtualApplicationPath);
}
if (_native.pwzBindings != IntPtr.Zero)
if (native.pwzBindings != IntPtr.Zero)
{
Marshal.FreeBSTR(_native.pwzBindings);
Marshal.FreeBSTR(native.pwzBindings);
}
}

public static IISConfigurationData ConvertToManaged(Native native)
{
return new()
{
pNativeApplication = native.pNativeApplication,
pwzFullApplicationPath = native.pwzFullApplicationPath == IntPtr.Zero ? string.Empty : Marshal.PtrToStringBSTR(native.pwzFullApplicationPath),
pwzVirtualApplicationPath = native.pwzVirtualApplicationPath == IntPtr.Zero ? string.Empty : Marshal.PtrToStringBSTR(native.pwzVirtualApplicationPath),
fWindowsAuthEnabled = native.fWindowsAuthEnabled != 0,
fBasicAuthEnabled = native.fBasicAuthEnabled != 0,
fAnonymousAuthEnable = native.fAnonymousAuthEnable != 0,
pwzBindings = native.pwzBindings == IntPtr.Zero ? string.Empty : Marshal.PtrToStringBSTR(native.pwzBindings),
maxRequestBodySize = native.maxRequestBodySize
};
}
}
}
25 changes: 16 additions & 9 deletions src/Servers/IIS/IntegrationTesting.IIS/src/IISExpressDeployer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
Expand Down Expand Up @@ -455,19 +456,25 @@ private sealed partial class WindowsNativeMethods
[LibraryImport("user32.dll", EntryPoint = "GetClassNameW", SetLastError = true)]
internal static partial int GetClassName(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U2)] char[] lpClassName, int nMaxCount);

[CustomTypeMarshaller(typeof(HandleRef), Direction = CustomTypeMarshallerDirection.In, Features = CustomTypeMarshallerFeatures.UnmanagedResources | CustomTypeMarshallerFeatures.TwoStageMarshalling)]
internal struct HandleRefMarshaller
[CustomMarshaller(typeof(HandleRef), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToUnmanagedIn))]
internal static class HandleRefMarshaller
{
private readonly HandleRef _handle;

public HandleRefMarshaller(HandleRef handle)
internal struct ManagedToUnmanagedIn
{
_handle = handle;
}
private HandleRef _handle;

public IntPtr ToNativeValue() => _handle.Handle;
public void FromManaged(HandleRef handle)
{
_handle = handle;
}

public void FreeNative() => GC.KeepAlive(_handle.Wrapper);
public IntPtr ToUnmanaged() => _handle.Handle;

public void OnInvoked() => GC.KeepAlive(_handle.Wrapper);

[SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "This method is part of the marshaller shape and is required to be an instance method.")]
public void Free() {}
}
}
}

Expand Down

0 comments on commit 3e50fe3

Please sign in to comment.