diff --git a/src/AddIns/Debugger/Debugger.Core/Interop/CorSym.cs b/src/AddIns/Debugger/Debugger.Core/Interop/CorSym.cs index 622ad7d545..c27e121254 100644 --- a/src/AddIns/Debugger/Debugger.Core/Interop/CorSym.cs +++ b/src/AddIns/Debugger/Debugger.Core/Interop/CorSym.cs @@ -37,9 +37,8 @@ namespace Debugger.Interop.CorSym public class CorSymBinder_SxSClass : ISymUnmanagedBinder, CorSymBinder_SxS { // Methods - [return: MarshalAs(UnmanagedType.Interface)] - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] - public virtual extern ISymUnmanagedReader __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), PreserveSig] + public virtual extern int __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath, [Out, In, MarshalAs(UnmanagedType.IUnknown)] ref object retVal); [return: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] @@ -215,9 +214,8 @@ namespace Debugger.Interop.CorSym [ComImport, InterfaceType((short) 1), Guid("AA544D42-28CB-11D3-BD22-0000F80849BD")] public interface ISymUnmanagedBinder { - [return: MarshalAs(UnmanagedType.Interface)] - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] - ISymUnmanagedReader __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), PreserveSig] + int __GetReaderForFile([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In] IntPtr filename, [In] IntPtr searchPath, [Out, In, MarshalAs(UnmanagedType.IUnknown)] ref object retVal); [return: MarshalAs(UnmanagedType.Interface)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] ISymUnmanagedReader __GetReaderFromStream([In, MarshalAs(UnmanagedType.IUnknown)] object importer, [In, MarshalAs(UnmanagedType.Interface)] IStream pstream); diff --git a/src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs b/src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs index 0ba2138592..1740965b4d 100644 --- a/src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs +++ b/src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.cs @@ -23,10 +23,17 @@ namespace Debugger.Interop.CorSym { IntPtr pfilename = Marshal.StringToCoTaskMemUni(filename); IntPtr psearchPath = Marshal.StringToCoTaskMemUni(searchPath); - ISymUnmanagedReader res = symBinder.GetReaderForFile(importer, pfilename, psearchPath); + object res = null; + // The method will create the object anyway so we have to use preservesig so that we can release it + // failing to do so would lock the assembly + int code = symBinder.GetReaderForFile(importer, pfilename, psearchPath, ref res); Marshal.FreeCoTaskMem(pfilename); Marshal.FreeCoTaskMem(psearchPath); - return res; + if (code != 0) { + Marshal.FinalReleaseComObject(res); + throw new COMException("", code); + } + return (ISymUnmanagedReader)res; } // ISymUnmanagedDocument diff --git a/src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs b/src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs index 72b1f3f417..599dcede3b 100644 --- a/src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs +++ b/src/AddIns/Debugger/Debugger.Core/Interop/CorSymExtensionMethods.generated.cs @@ -1,4 +1,4 @@ -// +// // // // @@ -13,10 +13,10 @@ namespace Debugger.Interop.CorSym { public static partial class CorSymExtensionMethods { - public static ISymUnmanagedReader GetReaderForFile(this CorSymBinder_SxSClass instance, object importer, IntPtr filename, IntPtr searchPath) + public static int GetReaderForFile(this CorSymBinder_SxSClass instance, object importer, IntPtr filename, IntPtr searchPath, ref object retVal) { - ISymUnmanagedReader returnValue = instance.__GetReaderForFile(importer, filename, searchPath); - ProcessOutParameter(returnValue); + int returnValue = instance.__GetReaderForFile(importer, filename, searchPath, ref retVal); + ProcessOutParameter(retVal); return returnValue; } @@ -86,6 +86,7 @@ namespace Debugger.Interop.CorSym public static void GetNamespaces(this CorSymReader_SxSClass instance, uint cNameSpaces, out uint pcNameSpaces, ISymUnmanagedNamespace[] namespaces) { instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces); + ProcessOutParameter(namespaces); } public static void GetSymAttribute(this CorSymReader_SxSClass instance, uint parent, IntPtr name, uint cBuffer, out uint pcBuffer, IntPtr buffer) @@ -251,10 +252,10 @@ namespace Debugger.Interop.CorSym instance.__UsingNamespace(fullName); } - public static ISymUnmanagedReader GetReaderForFile(this ISymUnmanagedBinder instance, object importer, IntPtr filename, IntPtr searchPath) + public static int GetReaderForFile(this ISymUnmanagedBinder instance, object importer, IntPtr filename, IntPtr searchPath, ref object retVal) { - ISymUnmanagedReader returnValue = instance.__GetReaderForFile(importer, filename, searchPath); - ProcessOutParameter(returnValue); + int returnValue = instance.__GetReaderForFile(importer, filename, searchPath, ref retVal); + ProcessOutParameter(retVal); return returnValue; } @@ -465,6 +466,7 @@ namespace Debugger.Interop.CorSym public static void GetNamespaces(this ISymUnmanagedReader instance, uint cNameSpaces, out uint pcNameSpaces, ISymUnmanagedNamespace[] namespaces) { instance.__GetNamespaces(cNameSpaces, out pcNameSpaces, namespaces); + ProcessOutParameter(namespaces); } public static void Initialize(this ISymUnmanagedReader instance, object importer, IntPtr filename, IntPtr searchPath, IStream pIStream) diff --git a/src/AddIns/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs b/src/AddIns/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs index 14f7341844..7cfac120a4 100644 --- a/src/AddIns/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs +++ b/src/AddIns/Debugger/Debugger.Core/Interop/MetaDataWrapper.cs @@ -41,7 +41,7 @@ namespace Debugger.Interop.MetaData ISymUnmanagedBinder symBinder = new Debugger.Interop.CorSym.CorSymBinder_SxSClass(); TrackedComObjects.Track(symBinder); return symBinder.GetReaderForFile(metaData, fullname, searchPath); - } catch { + } catch (COMException) { return null; } } @@ -52,7 +52,7 @@ namespace Debugger.Interop.MetaData ISymUnmanagedBinder symBinder = new Debugger.Interop.CorSym.CorSymBinder_SxSClass(); TrackedComObjects.Track(symBinder); return symBinder.GetReaderFromStream(metaData, stream); - } catch { + } catch (COMException) { return null; } } @@ -66,7 +66,7 @@ namespace Debugger.Interop.MetaData { IMetaDataImport m = this.metaData; if (m != null) { - Marshal.ReleaseComObject(m); + Marshal.FinalReleaseComObject(m); metaData = null; } } diff --git a/src/Tools/ComExtensionMethodGenerator/ComExtensionMethodGenerator.cs b/src/Tools/ComExtensionMethodGenerator/ComExtensionMethodGenerator.cs index 91f8a2a21c..d550fbad04 100644 --- a/src/Tools/ComExtensionMethodGenerator/ComExtensionMethodGenerator.cs +++ b/src/Tools/ComExtensionMethodGenerator/ComExtensionMethodGenerator.cs @@ -135,6 +135,7 @@ namespace ComExtensionMethodGenerator new MemberReferenceExpression(new IdentifierExpression(ThisParameterName), method.Name) ); // Generate arguments + bool hasProcessOuts = false; foreach(ParameterDeclarationExpression param in method.Parameters) { // Add argument to invocation if (param.ParamModifier == ParameterModifiers.Ref) { @@ -159,6 +160,7 @@ namespace ComExtensionMethodGenerator ) ) ); + hasProcessOuts = true; } } } @@ -167,9 +169,9 @@ namespace ComExtensionMethodGenerator if (method.TypeReference.Type == typeof(void).FullName) { extensionMethod.Body.Children.Insert(0, new ExpressionStatement(invoc)); } else { - if (!ProcessOutParameter || - ProcessOutParameterIgnores.Contains(method.TypeReference.Type)) + if ((!ProcessOutParameter || ProcessOutParameterIgnores.Contains(method.TypeReference.Type)) && !hasProcessOuts) { + // Short version extensionMethod.Body.Children.Insert(0, new ReturnStatement(invoc)); } else { // Declare and get return value @@ -179,14 +181,16 @@ namespace ComExtensionMethodGenerator ) ); // Call ProcessOutParameter - extensionMethod.Body.AddChild( - new ExpressionStatement( - new InvocationExpression( - new IdentifierExpression(ProcessOutParameterMethodName), - new IdentifierExpression(ReturnValueName).ToList() + if (method.TypeReference.Type != typeof(void).FullName && !ProcessOutParameterIgnores.Contains(method.TypeReference.Type)) { + extensionMethod.Body.AddChild( + new ExpressionStatement( + new InvocationExpression( + new IdentifierExpression(ProcessOutParameterMethodName), + new IdentifierExpression(ReturnValueName).ToList() + ) ) - ) - ); + ); + } // Return it extensionMethod.Body.AddChild( new ReturnStatement(new IdentifierExpression(ReturnValueName))