/// <summary> /// For a given type, analyze all the functions implemented by it. That means all the argument and return types. /// </summary> private void ScanDefinedFunctions(ITypeInfo typeInfo, TYPEATTR typeAttributes) { for (int definedFuncIndex = 0; definedFuncIndex < typeAttributes.cFuncs; definedFuncIndex++) { IntPtr funcDescHandleToRelease = IntPtr.Zero; try { ComReference.GetFuncDescForDescIndex(typeInfo, definedFuncIndex, out FUNCDESC funcDesc, out funcDescHandleToRelease); int offset = 0; // Analyze the argument types for (int paramIndex = 0; paramIndex < funcDesc.cParams; paramIndex++) { var elemDesc = (ELEMDESC)Marshal.PtrToStructure( new IntPtr(funcDesc.lprgelemdescParam.ToInt64() + offset), typeof(ELEMDESC)); AnalyzeElement(typeInfo, elemDesc); offset += Marshal.SizeOf <ELEMDESC>(); } // Analyze the return value type AnalyzeElement(typeInfo, funcDesc.elemdescFunc); } finally { if (funcDescHandleToRelease != IntPtr.Zero) { typeInfo.ReleaseFuncDesc(funcDescHandleToRelease); } } } }
private void ScanDefinedFunctions(ITypeInfo typeInfo, System.Runtime.InteropServices.ComTypes.TYPEATTR typeAttributes) { for (int i = 0; i < typeAttributes.cFuncs; i++) { IntPtr zero = IntPtr.Zero; try { System.Runtime.InteropServices.ComTypes.FUNCDESC funcdesc; ComReference.GetFuncDescForDescIndex(typeInfo, i, out funcdesc, out zero); int num2 = 0; for (int j = 0; j < funcdesc.cParams; j++) { System.Runtime.InteropServices.ComTypes.ELEMDESC elementDesc = (System.Runtime.InteropServices.ComTypes.ELEMDESC)Marshal.PtrToStructure(new IntPtr(funcdesc.lprgelemdescParam.ToInt64() + num2), typeof(System.Runtime.InteropServices.ComTypes.ELEMDESC)); this.AnalyzeElement(typeInfo, elementDesc); num2 += Marshal.SizeOf(typeof(System.Runtime.InteropServices.ComTypes.ELEMDESC)); } this.AnalyzeElement(typeInfo, funcdesc.elemdescFunc); } finally { if (zero != IntPtr.Zero) { typeInfo.ReleaseFuncDesc(zero); } } } }
internal bool InitializeWithTypeLibAttrs(TaskLoggingHelper log, System.Runtime.InteropServices.ComTypes.TYPELIBATTR tlbAttr, ITaskItem originalTaskItem, string targetProcessorArchitecture) { System.Runtime.InteropServices.ComTypes.TYPELIBATTR typeLibAttr = tlbAttr; ComReference.RemapAdoTypeLib(log, ref typeLibAttr); if (!ComReference.GetPathOfTypeLib(log, ref typeLibAttr, out this.typeLibPath)) { return(false); } return(this.InitializeWithPath(log, this.typeLibPath, originalTaskItem, targetProcessorArchitecture)); }
/// <summary> /// Analyze the given type looking for dependencies on other type libraries /// </summary> /// <param name="typeInfo"></param> private void AnalyzeTypeInfo(ITypeInfo typeInfo) { ITypeLib containingTypeLib = null; int indexInContainingTypeLib; try { typeInfo.GetContainingTypeLib(out containingTypeLib, out indexInContainingTypeLib); TYPELIBATTR containingTypeLibAttributes; ComReference.GetTypeLibAttrForTypeLib(ref containingTypeLib, out containingTypeLibAttributes); // Have we analyzed this type info already? If so skip it. AnalyzedTypesInfoKey typeInfoId = new AnalyzedTypesInfoKey( containingTypeLibAttributes.guid, containingTypeLibAttributes.wMajorVerNum, containingTypeLibAttributes.wMinorVerNum, containingTypeLibAttributes.lcid, indexInContainingTypeLib); // Get enough information about the type to figure out if we want to register it as a dependency TYPEATTR typeAttributes; ComReference.GetTypeAttrForTypeInfo(typeInfo, out typeAttributes); // Is it one of the types we don't care about? if (!CanSkipType(typeInfo, containingTypeLib, typeAttributes, containingTypeLibAttributes)) { _dependencies.Add(containingTypeLibAttributes); if (_analyzedTypes.Add(typeInfoId)) { // We haven't already analyzed this type, so rescan ScanImplementedTypes(typeInfo, typeAttributes); ScanDefinedVariables(typeInfo, typeAttributes); ScanDefinedFunctions(typeInfo, typeAttributes); } } // Make sure if we encounter this type again, we won't rescan it, since we already know we can skip it else { _analyzedTypes.Add(typeInfoId); } } finally { if (containingTypeLib != null) { _marshalReleaseComObject(containingTypeLib); } } }
/// <summary> /// Initialize the object with type library attributes /// </summary> internal bool InitializeWithTypeLibAttrs(TaskLoggingHelper log, bool silent, TYPELIBATTR tlbAttr, ITaskItem originalTaskItem, string targetProcessorArchitecture) { TYPELIBATTR remappableTlbAttr = tlbAttr; ComReference.RemapAdoTypeLib(log, silent, ref remappableTlbAttr); // for attribute references, the path is not specified, so we need to get it from the registry if (!ComReference.GetPathOfTypeLib(log, silent, ref remappableTlbAttr, out this.fullTypeLibPath)) { return(false); } // Now that we have the path, we can call InitializeWithPath to get the correct TYPELIBATTR set up // and the correct ITypeLib pointer. return(InitializeWithPath(log, silent, this.fullTypeLibPath, originalTaskItem, targetProcessorArchitecture)); }
internal bool InitializeWithPath(TaskLoggingHelper log, string path, ITaskItem originalTaskItem, string targetProcessorArchitecture) { Microsoft.Build.Shared.ErrorUtilities.VerifyThrowArgumentNull(path, "path"); this.taskItem = originalTaskItem; this.typeLibPath = ComReference.StripTypeLibNumberFromPath(path, new Microsoft.Build.Shared.FileExists(File.Exists)); string str = targetProcessorArchitecture; if (str != null) { if (!(str == "AMD64") && !(str == "IA64")) { if (str == "x86") { this.typeLibPointer = (ITypeLib)Microsoft.Build.Tasks.NativeMethods.LoadTypeLibEx(path, 0x20); goto Label_00A2; } if (str == "MSIL") { } } else { this.typeLibPointer = (ITypeLib)Microsoft.Build.Tasks.NativeMethods.LoadTypeLibEx(path, 0x40); goto Label_00A2; } } this.typeLibPointer = (ITypeLib)Microsoft.Build.Tasks.NativeMethods.LoadTypeLibEx(path, 2); Label_00A2: try { ComReference.GetTypeLibAttrForTypeLib(ref this.typeLibPointer, out this.attr); if (!ComReference.GetTypeLibNameForITypeLib(log, this.typeLibPointer, this.GetTypeLibId(log), out this.typeLibName)) { this.ReleaseTypeLibPtr(); return(false); } } catch (COMException) { this.ReleaseTypeLibPtr(); throw; } return(true); }
Assembly ITypeLibImporterNotifySink.ResolveRef(object objTypeLib) { System.Runtime.InteropServices.ComTypes.TYPELIBATTR typelibattr; ComReferenceWrapperInfo info; ITypeLib typeLib = (ITypeLib)objTypeLib; ComReference.GetTypeLibAttrForTypeLib(ref typeLib, out typelibattr); if (!base.ResolverCallback.ResolveComClassicReference(typelibattr, base.OutputDirectory, null, null, out info)) { base.Log.LogWarningWithCodeFromResources("ResolveComReference.FailedToResolveDependentComReference", new object[] { typelibattr.guid, typelibattr.wMajorVerNum, typelibattr.wMinorVerNum }); throw new ComReferenceResolutionException(); } if (info.assembly == null) { throw new ComReferenceResolutionException(); } base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvedDependentComReference", new object[] { typelibattr.guid, typelibattr.wMajorVerNum, typelibattr.wMinorVerNum, info.path }); return(info.assembly); }
/// <summary> /// For a given type, analyze all the variables defined by it /// </summary> private void ScanDefinedVariables(ITypeInfo typeInfo, TYPEATTR typeAttributes) { for (int definedVarIndex = 0; definedVarIndex < typeAttributes.cVars; definedVarIndex++) { IntPtr varDescHandleToRelease = IntPtr.Zero; try { ComReference.GetVarDescForVarIndex(typeInfo, definedVarIndex, out VARDESC varDesc, out varDescHandleToRelease); AnalyzeElement(typeInfo, varDesc.elemdescVar); } finally { if (varDescHandleToRelease != IntPtr.Zero) { typeInfo.ReleaseVarDesc(varDescHandleToRelease); } } } }
private void ScanDefinedVariables(ITypeInfo typeInfo, System.Runtime.InteropServices.ComTypes.TYPEATTR typeAttributes) { for (int i = 0; i < typeAttributes.cVars; i++) { IntPtr zero = IntPtr.Zero; try { System.Runtime.InteropServices.ComTypes.VARDESC vardesc; ComReference.GetVarDescForVarIndex(typeInfo, i, out vardesc, out zero); this.AnalyzeElement(typeInfo, vardesc.elemdescVar); } finally { if (zero != IntPtr.Zero) { typeInfo.ReleaseVarDesc(zero); } } } }
/* * Method: ITypeLibImporterNotifySink.ResolveRef * * Implementation of ITypeLibImporterNotifySink.ResolveRef - this method is called by the NDP type lib converter * to resolve dependencies. * We should never return null here - it's not documented as the proper way of failing dependency resolution. * Instead, we use an exception to abort the conversion process. */ Assembly ITypeLibImporterNotifySink.ResolveRef(object objTypeLib) { TYPELIBATTR attr; // get attributes for our dependent typelib ITypeLib typeLib = (ITypeLib)objTypeLib; ComReference.GetTypeLibAttrForTypeLib(ref typeLib, out attr); ComReferenceWrapperInfo wrapperInfo; // call our callback to do the dirty work for us if (!ResolverCallback.ResolveComClassicReference(attr, base.OutputDirectory, null, null, out wrapperInfo)) { if (!Silent) { Log.LogWarningWithCodeFromResources("ResolveComReference.FailedToResolveDependentComReference", attr.guid, attr.wMajorVerNum, attr.wMinorVerNum); } throw new ComReferenceResolutionException(); } Debug.Assert(wrapperInfo.assembly != null, "Successfully resolved assembly cannot be null!"); if (wrapperInfo.assembly == null) { throw new ComReferenceResolutionException(); } if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvedDependentComReference", attr.guid, attr.wMajorVerNum, attr.wMinorVerNum, wrapperInfo.path); } Debug.Assert(wrapperInfo.assembly != null, "Expected a non-null wrapperInfo.assembly. It should have been loaded in GenerateWrapper if it was going to be necessary."); return(wrapperInfo.assembly); }
private void AnalyzeTypeInfo(ITypeInfo typeInfo) { ITypeLib ppTLB = null; try { int num; System.Runtime.InteropServices.ComTypes.TYPELIBATTR typelibattr; System.Runtime.InteropServices.ComTypes.TYPEATTR typeattr; typeInfo.GetContainingTypeLib(out ppTLB, out num); ComReference.GetTypeLibAttrForTypeLib(ref ppTLB, out typelibattr); string key = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}.{3}:{4}", new object[] { typelibattr.guid, typelibattr.wMajorVerNum, typelibattr.wMinorVerNum, typelibattr.lcid, num }); ComReference.GetTypeAttrForTypeInfo(typeInfo, out typeattr); if (!this.CanSkipType(typeInfo, ppTLB, typeattr, typelibattr)) { this.dependencies[typelibattr] = null; if (!this.analyzedTypes.ContainsKey(key)) { this.analyzedTypes.Add(key, null); this.ScanImplementedTypes(typeInfo, typeattr); this.ScanDefinedVariables(typeInfo, typeattr); this.ScanDefinedFunctions(typeInfo, typeattr); } } else if (!this.analyzedTypes.ContainsKey(key)) { this.analyzedTypes.Add(key, null); } } finally { if (ppTLB != null) { this.marshalReleaseComObject(ppTLB); } } }
/// <summary> /// Initialize the object with a type library path /// </summary> internal bool InitializeWithPath(TaskLoggingHelper log, bool silent, string path, ITaskItem originalTaskItem, string targetProcessorArchitecture) { ErrorUtilities.VerifyThrowArgumentNull(path, nameof(path)); this.taskItem = originalTaskItem; // Note that currently we DO NOT remap file ADO references. This is because when pointing to a file on disk, // it seems unnatural to remap it to something else - a file reference means "use THIS component". // This is still under debate though, and may be revised later. // save both the stripped and full path in our object -- for the most part we just need the stripped path, but if // we're using tlbimp.exe, we need to pass the full path w/ type lib number to it, or it won't generate the interop // assembly correctly. this.fullTypeLibPath = path; this.strippedTypeLibPath = ComReference.StripTypeLibNumberFromPath(path, File.Exists); // use the unstripped path to actually load the library switch (targetProcessorArchitecture) { case ProcessorArchitecture.AMD64: case ProcessorArchitecture.IA64: this.typeLibPointer = (ITypeLib)NativeMethods.LoadTypeLibEx(path, (int)NativeMethods.REGKIND.REGKIND_LOAD_TLB_AS_64BIT); break; case ProcessorArchitecture.X86: this.typeLibPointer = (ITypeLib)NativeMethods.LoadTypeLibEx(path, (int)NativeMethods.REGKIND.REGKIND_LOAD_TLB_AS_32BIT); break; case ProcessorArchitecture.ARM: case ProcessorArchitecture.MSIL: default: // Transmit the flag directly from the .targets files and rely on tlbimp.exe to produce a good error message. this.typeLibPointer = (ITypeLib)NativeMethods.LoadTypeLibEx(path, (int)NativeMethods.REGKIND.REGKIND_NONE); break; } try { // get the type lib attributes from the retrieved interface pointer. // do NOT remap file ADO references, since we'd end up with a totally different reference than specified. ComReference.GetTypeLibAttrForTypeLib(ref this.typeLibPointer, out this.attr); // get the type lib name from the retrieved interface pointer if (!ComReference.GetTypeLibNameForITypeLib( log, silent, this.typeLibPointer, GetTypeLibId(log), out this.typeLibName)) { ReleaseTypeLibPtr(); return(false); } } catch (COMException) { ReleaseTypeLibPtr(); throw; } return(true); }