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
- ShutDownListener.cs
- DataTablePropertyDescriptor.cs
- SmtpFailedRecipientException.cs
- ExpressionConverter.cs
- BamlReader.cs
- MinimizableAttributeTypeConverter.cs
- externdll.cs
- SerialReceived.cs
- AnalyzedTree.cs
- ServiceModelStringsVersion1.cs
- UriWriter.cs
- BindableAttribute.cs
- DrawingBrush.cs
- NonValidatingSecurityTokenAuthenticator.cs
- StreamWithDictionary.cs
- TextSyndicationContent.cs
- RegexStringValidator.cs
- XmlHierarchicalEnumerable.cs
- TagPrefixCollection.cs
- CollectionViewProxy.cs
- ProcessInputEventArgs.cs
- ReflectTypeDescriptionProvider.cs
- EmbeddedMailObjectsCollection.cs
- DataGridViewSelectedColumnCollection.cs
- PageVisual.cs
- XmlDataDocument.cs
- StatusBarItemAutomationPeer.cs
- WebZone.cs
- ResolveCompletedEventArgs.cs
- ResourceContainer.cs
- InvalidEnumArgumentException.cs
- DescriptionAttribute.cs
- PlatformCulture.cs
- UInt64Converter.cs
- DragAssistanceManager.cs
- PropertyItem.cs
- PeerDuplexChannelListener.cs
- BitmapVisualManager.cs
- CrossAppDomainChannel.cs
- TouchPoint.cs
- ViewBase.cs
- wgx_commands.cs
- XmlValidatingReaderImpl.cs
- DiagnosticTraceSource.cs
- ObjectQuery_EntitySqlExtensions.cs
- SystemColors.cs
- Debugger.cs
- XhtmlConformanceSection.cs
- SiteMapNodeCollection.cs
- DataGridViewLinkCell.cs
- Freezable.cs
- CapabilitiesAssignment.cs
- SpeechAudioFormatInfo.cs
- Point3DAnimationUsingKeyFrames.cs
- DbProviderSpecificTypePropertyAttribute.cs
- TreeNodeBinding.cs
- MultipleViewPattern.cs
- Literal.cs
- _SecureChannel.cs
- ObjectDesignerDataSourceView.cs
- IndexingContentUnit.cs
- ObjectHandle.cs
- SizeLimitedCache.cs
- VisualCollection.cs
- RedBlackList.cs
- ObsoleteAttribute.cs
- Viewport3DVisual.cs
- CodeAttributeDeclaration.cs
- BinaryObjectReader.cs
- DebugView.cs
- SqlCacheDependencyDatabase.cs
- WriteableBitmap.cs
- SvcMapFile.cs
- DynamicPropertyHolder.cs
- FloaterBaseParagraph.cs
- HScrollBar.cs
- BaseValidator.cs
- SoapExtensionTypeElement.cs
- ChangePassword.cs
- GrabHandleGlyph.cs
- InvalidateEvent.cs
- TimeSpanFormat.cs
- Marshal.cs
- FormatConvertedBitmap.cs
- BindingRestrictions.cs
- MimePart.cs
- SerializationStore.cs
- TypeDelegator.cs
- ManagedFilter.cs
- AutoFocusStyle.xaml.cs
- SecurityHeaderLayout.cs
- CmsUtils.cs
- ProgressBarBrushConverter.cs
- httpstaticobjectscollection.cs
- LicenseException.cs
- DragDeltaEventArgs.cs
- WebZone.cs
- DynamicDocumentPaginator.cs
- ProcessStartInfo.cs
- SafeUserTokenHandle.cs