Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / ComIntegration / DispatchProxy.cs / 1 / DispatchProxy.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.ComIntegration { using System; using System.ServiceModel.Dispatcher; using System.ServiceModel.Description; using System.IO; using System.Reflection; using System.Collections.Generic; using System.Threading; using System.Collections; using System.ServiceModel.Channels; using System.Runtime.Remoting.Proxies; using System.Runtime.Remoting; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using XmlSch = System.Xml.Serialization; using DcNS = System.Runtime.Serialization; using WsdlNS = System.Web.Services.Description; using DiscoNS = System.Web.Services.Discovery; using System.Diagnostics; using System.ServiceModel.Diagnostics; internal class DispatchProxy : IPseudoDispatch, IDisposable { ContractDescription contract; IProvideChannelBuilderSettings channelBuilderSettings; DictionarydispToName = new Dictionary (); Dictionary nameToDisp = new Dictionary (); Dictionary dispToOperationDescription = new Dictionary (); private DispatchProxy(ContractDescription contract, IProvideChannelBuilderSettings channelBuilderSettings) { if (channelBuilderSettings == null) { DiagnosticUtility.DebugAssert("channelBuilderSettings cannot be null cannot be null"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } if (contract == null) { DiagnosticUtility.DebugAssert("contract cannot be null"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } this.channelBuilderSettings = channelBuilderSettings; this.contract = contract; ProcessContractDescription(); ComPlusDispatchMethodTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationDispatchMethod, SR.TraceCodeComIntegrationDispatchMethod, dispToOperationDescription); } internal static ComProxy Create(IntPtr outer, ContractDescription contract, IProvideChannelBuilderSettings channelBuilderSettings) { DispatchProxy proxy = null; IntPtr inner = IntPtr.Zero; ComProxy comProxy = null; try { proxy = new DispatchProxy(contract, channelBuilderSettings); inner = OuterProxyWrapper.CreateDispatchProxy(outer, proxy); comProxy = new ComProxy(inner, proxy); return comProxy; } finally { if (comProxy == null) { if (proxy != null) { ((IDisposable)proxy).Dispose(); } if (inner != IntPtr.Zero) { Marshal.Release(inner); } } } } [Serializable] internal class ParamInfo { public int inIndex; public int outIndex; public string name; public Type type; public ParamInfo() { inIndex = -1; outIndex = -1; } } internal class MethodInfo { public OperationDescription opDesc; public List paramList; public Dictionary dispIdToParamInfo; public ParamInfo ReturnVal = null; public MethodInfo(OperationDescription opDesc) { this.opDesc = opDesc; paramList = new List (); dispIdToParamInfo = new Dictionary (); } } void ProcessContractDescription() { UInt32 dispIndex = 10; Dictionary paramDictionary = null; foreach (OperationDescription opDesc in contract.Operations) { dispToName[dispIndex] = opDesc.Name; nameToDisp[opDesc.Name] = dispIndex; MethodInfo methodInfo = null; methodInfo = new MethodInfo(opDesc); dispToOperationDescription[dispIndex++] = methodInfo; paramDictionary = new Dictionary (); bool inVars = true; inVars = true; int paramCount = 0; foreach (MessageDescription msgDesc in opDesc.Messages) { paramCount = 0; if (msgDesc.Body.ReturnValue != null) { if (string.IsNullOrEmpty(msgDesc.Body.ReturnValue.BaseType)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.CannotResolveTypeForParamInMessageDescription, "ReturnValue", msgDesc.Body.WrapperName, msgDesc.Body.WrapperNamespace), HR.DISP_E_MEMBERNOTFOUND)); msgDesc.Body.ReturnValue.Type = Type.GetType(msgDesc.Body.ReturnValue.BaseType); } foreach (MessagePartDescription param in msgDesc.Body.Parts) { UInt32 dispID = 0; ParamInfo paramInfo = null; paramInfo = null; if (!nameToDisp.TryGetValue(param.Name, out dispID)) { dispToName[dispIndex] = param.Name; nameToDisp[param.Name] = dispIndex; dispID = dispIndex; dispIndex++; } if (!paramDictionary.TryGetValue(param.Name, out paramInfo)) { paramInfo = new ParamInfo(); methodInfo.paramList.Add(paramInfo); methodInfo.dispIdToParamInfo[dispID] = paramInfo; if (string.IsNullOrEmpty(param.BaseType)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.CannotResolveTypeForParamInMessageDescription, param.Name, msgDesc.Body.WrapperName, msgDesc.Body.WrapperNamespace), HR.DISP_E_MEMBERNOTFOUND)); paramInfo.type = Type.GetType(param.BaseType, true); paramInfo.name = param.Name; paramDictionary[param.Name] = paramInfo; param.Index = paramCount; } param.Type = paramInfo.type; if (inVars) { paramInfo.inIndex = paramCount; } else { paramInfo.outIndex = paramCount; } paramCount++; } inVars = false; } } } void IPseudoDispatch.GetIDsOfNames(UInt32 cNames, // size_is param for rgszNames [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr, SizeParamIndex = 0)] string[] rgszNames, IntPtr pDispID) { for (int index = 0; index < cNames; index++) { UInt32 dispID; if (!nameToDisp.TryGetValue(rgszNames[index], out dispID)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OperationNotFound, rgszNames[index]), HR.DISP_E_UNKNOWNNAME)); Marshal.WriteInt32(pDispID, index * sizeof(int), (int)dispID); } } int IPseudoDispatch.Invoke( UInt32 dispIdMember, UInt32 cArgs, UInt32 cNamedArgs, IntPtr rgvarg, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] UInt32[] rgdispidNamedArgs, IntPtr pVarResult, IntPtr pExcepInfo, out UInt32 pArgErr ) { pArgErr = 0; try { if (cNamedArgs > 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.NamedArgsNotSupported), HR.DISP_E_BADPARAMCOUNT)); MethodInfo mInfo = null; if (!dispToOperationDescription.TryGetValue(dispIdMember, out mInfo)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.BadDispID, dispIdMember), HR.DISP_E_MEMBERNOTFOUND)); object[] ins = null; object[] outs = null; string action = null; if (mInfo.paramList.Count != cArgs) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.BadDispID, dispIdMember), HR.DISP_E_BADPARAMCOUNT)); ins = new object[mInfo.opDesc.Messages[0].Body.Parts.Count]; outs = new object[mInfo.opDesc.Messages[1].Body.Parts.Count]; if (cArgs > 0) { if (mInfo.opDesc.Messages[0].Body.Parts.Count > 0) { for (int index = 0; index < mInfo.opDesc.Messages[0].Body.Parts.Count; index++) ins[index] = null; } if (!mInfo.opDesc.IsOneWay && (mInfo.opDesc.Messages[1].Body.Parts.Count > 0)) { for (int index = 0; index < mInfo.opDesc.Messages[1].Body.Parts.Count; index++) outs[index] = null; } } action = mInfo.opDesc.Messages[0].Action; // First we take care of positional arguments int inCount = 0; for (int index = 0; index < cArgs; index++) { if (mInfo.paramList[index].inIndex != -1) { try { object val = null; if (!mInfo.paramList[index].type.IsArray) val = FetchVariant(rgvarg, (int)(cArgs - index - 1), mInfo.paramList[index].type); else val = FetchVariants(rgvarg, (int)(cArgs - index - 1), mInfo.paramList[index].type); ins[mInfo.paramList[index].inIndex] = val; inCount++; } catch(ArgumentNullException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(SR.GetString(SR.VariantArrayNull, cArgs - index - 1)); } } } if (inCount != ins.Length) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.BadParamCount), HR.DISP_E_BADPARAMCOUNT)); object result = null; try { result = SendMessage(mInfo.opDesc, action, ins, outs); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; if (pExcepInfo != IntPtr.Zero) { System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo = new System.Runtime.InteropServices.ComTypes.EXCEPINFO(); e = e.GetBaseException(); exceptionInfo.bstrDescription = e.Message; exceptionInfo.bstrSource = e.Source; exceptionInfo.scode = Marshal.GetHRForException(e); Marshal.StructureToPtr(exceptionInfo, pExcepInfo, false); } return HR.DISP_E_EXCEPTION; } if (!mInfo.opDesc.IsOneWay) { if (outs != null) { bool[] filled = new bool[outs.Length]; for (UInt32 index = 0; index < filled.Length; index++) filled[index] = false; for (int index = 0; index < cArgs; index++) { if (mInfo.paramList[index].outIndex != -1) { try { if (IsByRef(rgvarg, (int)(cArgs - index - 1))) { PopulateByRef(rgvarg, (int)(cArgs - index - 1), outs[mInfo.paramList[index].outIndex]); } } catch (ArgumentNullException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(SR.GetString(SR.VariantArrayNull, cArgs - index - 1)); } filled[mInfo.paramList[index].outIndex] = true; } } } if ((result != null) && (pVarResult != IntPtr.Zero)) { if (!result.GetType().IsArray) Marshal.GetNativeVariantForObject(result, pVarResult); else { Array arr = result as Array; Array arrDest = Array.CreateInstance(typeof(object), arr.Length); arr.CopyTo(arrDest, 0); Marshal.GetNativeVariantForObject(arrDest, pVarResult); } } } return HR.S_OK; } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; e = e.GetBaseException(); return Marshal.GetHRForException(e); } } object SendMessage(OperationDescription opDesc, string action, object[] ins, object[] outs) { ProxyOperationRuntime operationRuntime = channelBuilderSettings.ServiceChannel.ClientRuntime.GetRuntime().GetOperationByName(opDesc.Name); if (operationRuntime == null) { DiagnosticUtility.DebugAssert("Operation runtime should not be null"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } return channelBuilderSettings.ServiceChannel.Call(action, opDesc.IsOneWay, operationRuntime, ins, outs); } object FetchVariant(IntPtr baseArray, int index, Type type) { if (baseArray == IntPtr.Zero) { DiagnosticUtility.DebugAssert("baseArray should not be null"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("baseArrray"); } uint displacement = (uint)(index * Marshal.SizeOf(typeof(TagVariant))); object ret = Marshal.GetObjectForNativeVariant(GetDisp(baseArray, displacement)); // this is neccessary because unfortunately the CLR is not very forthcomming when it comes // to dynamically converting integer types to other integer types due to boxing // the same goes for the array case if (type == typeof(Int32)) { if (ret.GetType() == typeof(Int16)) ret = (Int32)((Int16)ret); else if (ret.GetType() != typeof(Int32)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.UnsupportedConversion, ret.GetType(), type.GetElementType()), HR.DISP_E_TYPEMISMATCH)); } else if (type == typeof(Int64)) { if (ret.GetType() == typeof(Int16)) ret = (Int64)((Int16)ret); else if (ret.GetType() == typeof(Int32)) ret = (Int64)((Int32)ret); else if (ret.GetType() != typeof(Int64)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.UnsupportedConversion, ret.GetType(), type), HR.DISP_E_TYPEMISMATCH)); } return ret; } object FetchVariants(IntPtr baseArray, int index, Type type) { if (baseArray == IntPtr.Zero) { DiagnosticUtility.DebugAssert("baseArray should not be null"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("baseArrray"); } uint displacement = (uint)(index * Marshal.SizeOf(typeof(TagVariant))); TagVariant varBase = (TagVariant) Marshal.PtrToStructure (GetDisp(baseArray, displacement), typeof (TagVariant)); if ((varBase.vt & (ushort)(VarEnum.VT_VARIANT | VarEnum.VT_BYREF)) == 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyVariantAllowedByRef), HR.DISP_E_TYPEMISMATCH)); TagVariant varActualVariant = (TagVariant) Marshal.PtrToStructure (varBase.ptr, typeof (TagVariant)); if ((varActualVariant.vt & (ushort)(VarEnum.VT_VARIANT | VarEnum.VT_BYREF | VarEnum.VT_ARRAY)) == 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyByRefVariantSafeArraysAllowed), HR.DISP_E_TYPEMISMATCH)); IntPtr ppArray = varActualVariant.ptr; IntPtr pSafeArray = (IntPtr)Marshal.PtrToStructure(ppArray, typeof(IntPtr)); int dimensionsOfSafeArray = SafeNativeMethods.SafeArrayGetDim (pSafeArray); if (dimensionsOfSafeArray != 1) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyOneDimensionalSafeArraysAllowed), HR.DISP_E_TYPEMISMATCH)); int sizeofElement = SafeNativeMethods.SafeArrayGetElemsize (pSafeArray); if (sizeofElement != Marshal.SizeOf(typeof(TagVariant))) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyVariantTypeElementsAllowed), HR.DISP_E_TYPEMISMATCH)); int lBound = SafeNativeMethods.SafeArrayGetLBound(pSafeArray, 1); if (lBound > 0 ) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyZeroLBoundAllowed), HR.DISP_E_TYPEMISMATCH)); int uBound = SafeNativeMethods.SafeArrayGetUBound(pSafeArray, 1); IntPtr pRawData = SafeNativeMethods.SafeArrayAccessData(pSafeArray); try { object[] objects = Marshal.GetObjectsForNativeVariants(pRawData, uBound + 1); Array arr = Array.CreateInstance(type.GetElementType(), objects.Length); if (objects.Length == 0) return arr; if (type.GetElementType() != typeof(Int32) && type.GetElementType() != typeof(Int64)) { try { objects.CopyTo(arr, 0); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) throw; throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.UnsupportedConversion, objects[0].GetType(), type.GetElementType()), HR.DISP_E_TYPEMISMATCH)); } } else { if (type.GetElementType() == typeof(Int32)) { for (int i = 0; i < objects.Length; i++) { if (objects[i].GetType() == typeof(Int16)) arr.SetValue((Int32)((Int16)objects[i]), i); else if (objects[i].GetType() == typeof(Int32)) arr.SetValue(objects[i], i); else throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.UnsupportedConversion, objects[i].GetType(), type.GetElementType()), HR.DISP_E_TYPEMISMATCH)); } } else { for (int i = 0; i < objects.Length; i++) { if (objects[i].GetType() == typeof(Int16)) arr.SetValue((Int64)((Int16)objects[i]), i); else if (objects[i].GetType() == typeof(Int32)) arr.SetValue((Int64)((Int32)objects[i]), i); else if (objects[i].GetType() == typeof(Int64)) arr.SetValue(objects[i], i); else throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.UnsupportedConversion, objects[i].GetType(), type.GetElementType()), HR.DISP_E_TYPEMISMATCH)); } } } return arr; } finally { SafeNativeMethods.SafeArrayUnaccessData(pSafeArray); } } IntPtr GetDisp(IntPtr baseAddress, uint disp) { long address = (long)baseAddress; address += disp; return (IntPtr)address; } void PopulateByRef(IntPtr baseArray, int index, object val) { if (val != null) { if (baseArray == IntPtr.Zero) { DiagnosticUtility.DebugAssert("baseArray should not be null"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("baseArrray"); } uint displacement = (uint)(index * Marshal.SizeOf(typeof(TagVariant))); TagVariant var = (TagVariant)Marshal.PtrToStructure(GetDisp(baseArray, displacement), typeof(TagVariant)); if ((var.vt & (ushort)VarEnum.VT_VARIANT) == 0) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.OnlyVariantAllowedByRef), HR.DISP_E_TYPEMISMATCH)); if (!val.GetType().IsArray) Marshal.GetNativeVariantForObject(val, var.ptr); else { Array arr = val as Array; Array arrDest = Array.CreateInstance(typeof(object), arr.Length); arr.CopyTo(arrDest, 0); Marshal.GetNativeVariantForObject(arrDest, var.ptr); } } } bool IsByRef(IntPtr baseArray, int index) { if (baseArray == IntPtr.Zero) { DiagnosticUtility.DebugAssert("baseArray should not be null"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("baseArrray"); } uint displacement = (uint)(index * Marshal.SizeOf(typeof(TagVariant))); ushort vt = (ushort)Marshal.ReadInt16(GetDisp(baseArray, displacement)); if (0 != (vt & (ushort)(VarEnum.VT_BYREF))) return true; else return false; } void IDisposable.Dispose() { dispToName.Clear(); nameToDisp.Clear(); dispToOperationDescription.Clear(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DataKeyArray.cs
- ProfileModule.cs
- TransactionInterop.cs
- XmlSchemaGroupRef.cs
- _FtpControlStream.cs
- GradientStop.cs
- BindingMAnagerBase.cs
- Msec.cs
- ProgressChangedEventArgs.cs
- TextEditorTyping.cs
- ChtmlFormAdapter.cs
- WebPartRestoreVerb.cs
- ImageAnimator.cs
- XmlCharType.cs
- ADRole.cs
- SkinBuilder.cs
- GeometryValueSerializer.cs
- EntityDataSourceUtil.cs
- IndicShape.cs
- QueryRewriter.cs
- MDIClient.cs
- AmbientProperties.cs
- querybuilder.cs
- OrderedDictionaryStateHelper.cs
- Ref.cs
- WebPartZone.cs
- WaveHeader.cs
- UriSectionReader.cs
- WebConfigManager.cs
- MouseWheelEventArgs.cs
- XamlWriter.cs
- AttachmentCollection.cs
- StateItem.cs
- GridViewUpdateEventArgs.cs
- CfgRule.cs
- Point4D.cs
- ObjectItemNoOpAssemblyLoader.cs
- RecognizerInfo.cs
- WsatServiceAddress.cs
- SimpleHandlerBuildProvider.cs
- RuntimeEnvironment.cs
- SiteMapHierarchicalDataSourceView.cs
- Int16Storage.cs
- HelpKeywordAttribute.cs
- Terminate.cs
- HwndTarget.cs
- Style.cs
- ClosureBinding.cs
- PrimitiveSchema.cs
- ColumnResizeUndoUnit.cs
- DeviceContext2.cs
- Viewport3DVisual.cs
- RuleInfoComparer.cs
- InfocardExtendedInformationCollection.cs
- xsdvalidator.cs
- TreeView.cs
- RayMeshGeometry3DHitTestResult.cs
- EventWaitHandle.cs
- ListBindingHelper.cs
- AlphabeticalEnumConverter.cs
- BinaryParser.cs
- AlphaSortedEnumConverter.cs
- WorkflowMarkupSerializationProvider.cs
- FrameworkTextComposition.cs
- CookieProtection.cs
- XmlSchemaSubstitutionGroup.cs
- Crc32Helper.cs
- ContentFileHelper.cs
- BindingExpressionUncommonField.cs
- AdRotator.cs
- NotSupportedException.cs
- ConfigXmlElement.cs
- AssemblyBuilderData.cs
- HtmlLiteralTextAdapter.cs
- SQLBytesStorage.cs
- BindableTemplateBuilder.cs
- OracleDataReader.cs
- EdmRelationshipRoleAttribute.cs
- ModelTypeConverter.cs
- WebBrowserSiteBase.cs
- CodeParameterDeclarationExpression.cs
- ControlParameter.cs
- BitmapDecoder.cs
- PasswordBoxAutomationPeer.cs
- FixedNode.cs
- FamilyCollection.cs
- ToolStripRendererSwitcher.cs
- HttpCapabilitiesEvaluator.cs
- WrappedOptions.cs
- ToolStripArrowRenderEventArgs.cs
- SafeTimerHandle.cs
- RIPEMD160Managed.cs
- HttpInputStream.cs
- MemoryMappedViewAccessor.cs
- MD5CryptoServiceProvider.cs
- SafeHandle.cs
- WindowsPen.cs
- PartBasedPackageProperties.cs
- ContentValidator.cs
- TabItemAutomationPeer.cs