Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / PeerUnsafeNativeMethods.cs / 1 / PeerUnsafeNativeMethods.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using Microsoft.Win32.SafeHandles; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Net; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.ServiceModel.Diagnostics; static class PeerWinsock { [DllImport("ws2_32.dll", SetLastError = true, EntryPoint = "WSAIoctl")] internal static extern int WSAIoctl( [In] IntPtr socketHandle, [In] int ioControlCode, [In] IntPtr inBuffer, [In] int inBufferSize, [Out] IntPtr outBuffer, [In] int outBufferSize, [Out] out int bytesTransferred, [In] IntPtr overlapped, [In] IntPtr completionRoutine); } [Serializable, StructLayout(LayoutKind.Sequential)] struct SocketAddress { IntPtr sockAddr; int sockAddrLength; public IntPtr SockAddr { get { return sockAddr; } } public int SockAddrLength { get { return sockAddrLength; } } public void InitializeFromCriticalAllocHandleSocketAddress(CriticalAllocHandleSocketAddress sockAddr) { this.sockAddr = (IntPtr)sockAddr; this.sockAddrLength = sockAddr.Size; } } [StructLayout(LayoutKind.Sequential)] struct SocketAddressList { int count; internal const int maxAddresses = 50; [MarshalAs(UnmanagedType.ByValArray, SizeConst = maxAddresses)] SocketAddress[] addresses; public SocketAddress[] Addresses { get { return addresses; } } public int Count { get { return count; } } public SocketAddressList(SocketAddress[] addresses, int count) { this.addresses = addresses; this.count = count; } public static ReadOnlyCollectionSortAddresses(Socket socket, IPAddress listenAddress, ReadOnlyCollection addresses) { ReadOnlyCollection sortedAddresses = null; // Skip sort if ipv6 isn't installed or if address array has a single address if (socket == null || addresses.Count <= 1) { sortedAddresses = addresses; } else { CriticalAllocHandleSocketAddressList inputBuffer = null; CriticalAllocHandleSocketAddressList outputBuffer = null; try { inputBuffer = CriticalAllocHandleSocketAddressList.FromAddressList(addresses); outputBuffer = CriticalAllocHandleSocketAddressList.FromAddressCount(0); // Invoke ioctl to sort the addresses int realOutputBufferSize; int error = UnsafeNativeMethods.ERROR_SUCCESS; int errorCode = PeerWinsock.WSAIoctl(socket.Handle, unchecked((int)IOControlCode.AddressListSort), (IntPtr)inputBuffer, inputBuffer.Size, (IntPtr)outputBuffer, outputBuffer.Size, out realOutputBufferSize, IntPtr.Zero, IntPtr.Zero); if (errorCode == -1) { // Get the Win32 error code before doing anything else error = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SocketException(error)); } // Marshal the sorted SOCKET_ADDRESS_LIST into IPAddresses sortedAddresses = outputBuffer.ToAddresses(); } finally { if(inputBuffer != null) inputBuffer.Dispose(); if(outputBuffer != null) outputBuffer.Dispose(); } } return sortedAddresses; } } // Type that converts from sockaddr_in6 to IPAddress and vice-versa [Serializable, StructLayout(LayoutKind.Sequential)] struct sockaddr_in6 { short sin6_family; ushort sin6_port; uint sin6_flowinfo; [MarshalAs(UnmanagedType.ByValArray, SizeConst = addrByteCount)] byte[] sin6_addr; uint sin6_scope_id; const int addrByteCount = 16; // if the addr is v4-mapped-v6, 10th and 11th byte contain 0xFF. the last 4 bytes contain the ipv4 address const int v4MapIndex = 10; const int v4Index = v4MapIndex + 2; public sockaddr_in6(IPAddress address) { if (address.AddressFamily == AddressFamily.InterNetworkV6) { this.sin6_addr = address.GetAddressBytes(); this.sin6_scope_id = (uint)address.ScopeId; } else { // Map v4 address to v4-mapped v6 addr (i.e., ::FFFF:XX.XX.XX.XX) byte[] v4AddressBytes = address.GetAddressBytes(); this.sin6_addr = new byte[addrByteCount]; for (int i = 0; i < v4MapIndex; i++) this.sin6_addr[i] = 0; this.sin6_addr[v4MapIndex] = 0xff; this.sin6_addr[v4MapIndex + 1] = 0xff; for (int i = v4Index; i < addrByteCount; i++) this.sin6_addr[i] = v4AddressBytes[i - v4Index]; this.sin6_scope_id = 0; // V4 address doesn't have a scope ID } this.sin6_family = (short)AddressFamily.InterNetworkV6; this.sin6_port = 0; this.sin6_flowinfo = 0; } public short Family { get { return this.sin6_family; } } public uint FlowInfo { get { return this.sin6_flowinfo; } } // Returns true if the address is a v4-mapped v6 address // Adapted from ws2ipdef.w's IN6_IS_ADDR_V4MAPPED macro private bool IsV4Mapped { get { // A v4-mapped v6 address will have the last 4 bytes contain the IPv4 address. // The preceding 2 bytes contain 0xFFFF. All others are 0. if (sin6_addr[v4MapIndex] != 0xff || sin6_addr[v4MapIndex + 1] != 0xff) return false; for (int i = 0; i < v4MapIndex; i++) if (sin6_addr[i] != 0) return false; return true; } } public ushort Port { get { return this.sin6_port; } } // Converts a sockaddr_in6 to IPAddress // A v4 mapped v6 address is converted to a v4 address public IPAddress ToIPAddress() { if (!(this.sin6_family == (short)AddressFamily.InterNetworkV6)) { DiagnosticUtility.DebugAssert("AddressFamily expected to be InterNetworkV6"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } if (IsV4Mapped) { byte[] addr = {this.sin6_addr[v4Index], this.sin6_addr[v4Index + 1], this.sin6_addr[v4Index + 2], this.sin6_addr[v4Index + 3]}; return new IPAddress(addr); } else { return new IPAddress(this.sin6_addr, this.sin6_scope_id); } } } class CriticalAllocHandleSocketAddressList : CriticalAllocHandle { int count; int size; CriticalAllocHandleSocketAddress[] socketHandles; public int Count { get { return count; } } public int Size { get { return size; } } public static CriticalAllocHandleSocketAddressList FromAddressList(ICollection addresses) { if(addresses == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("addresses"); } int count = addresses.Count; CriticalAllocHandleSocketAddress[] socketHandles = new CriticalAllocHandleSocketAddress[SocketAddressList.maxAddresses]; SocketAddressList socketAddressList = new SocketAddressList(new SocketAddress[SocketAddressList.maxAddresses], count); int i = 0; foreach(IPAddress address in addresses) { if (i == SocketAddressList.maxAddresses) break; // due to Marshalling fixed sized array of SocketAddresses. socketHandles[i] = CriticalAllocHandleSocketAddress.FromIPAddress(address); socketAddressList.Addresses[i].InitializeFromCriticalAllocHandleSocketAddress(socketHandles[i]); ++i; } int size = Marshal.SizeOf(socketAddressList); CriticalAllocHandleSocketAddressList result = CriticalAllocHandleSocketAddressList.FromSize(size); result.count = count; result.socketHandles = socketHandles; Marshal.StructureToPtr(socketAddressList, result, false); return result; } public static CriticalAllocHandleSocketAddressList FromAddressCount(int count) { SocketAddressList socketAddressList = new SocketAddressList(new SocketAddress[SocketAddressList.maxAddresses], 0); int size = Marshal.SizeOf(socketAddressList); CriticalAllocHandleSocketAddressList result = CriticalAllocHandleSocketAddressList.FromSize(size); result.count = count; Marshal.StructureToPtr(socketAddressList, result, false); return result; } static new CriticalAllocHandleSocketAddressList FromSize(int size) { CriticalAllocHandleSocketAddressList result = new CriticalAllocHandleSocketAddressList(); RuntimeHelpers.PrepareConstrainedRegions(); try{} finally { result.SetHandle(Marshal.AllocHGlobal(size)); result.size = size; } return result; } public ReadOnlyCollection ToAddresses() { SocketAddressList socketAddressList = (SocketAddressList) Marshal.PtrToStructure(this, typeof(SocketAddressList)); IPAddress[] addresses = new IPAddress[socketAddressList.Count]; for (int i = 0; i < addresses.Length; i++) { if (!(socketAddressList.Addresses[i].SockAddrLength == Marshal.SizeOf(typeof(sockaddr_in6)))) { DiagnosticUtility.DebugAssert("sockAddressLength in SOCKET_ADDRESS expected to be valid"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } sockaddr_in6 sockAddr = (sockaddr_in6)Marshal.PtrToStructure(socketAddressList.Addresses[i].SockAddr, typeof(sockaddr_in6)); addresses[i] = sockAddr.ToIPAddress(); } return Array.AsReadOnly (addresses); } } class CriticalAllocHandleSocketAddress : CriticalAllocHandle { int size; public int Size { get { return size; } } public static CriticalAllocHandleSocketAddress FromIPAddress(IPAddress input) { if(input == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("input"); } CriticalAllocHandleSocketAddress result = null; int size = Marshal.SizeOf(typeof(sockaddr_in6)); result = CriticalAllocHandleSocketAddress.FromSize(size); sockaddr_in6 sa = new sockaddr_in6(input); Marshal.StructureToPtr(sa, (IntPtr)result, false); return result; } public static new CriticalAllocHandleSocketAddress FromSize(int size) { CriticalAllocHandleSocketAddress result = new CriticalAllocHandleSocketAddress(); RuntimeHelpers.PrepareConstrainedRegions(); try{} finally { result.SetHandle(Marshal.AllocHGlobal(size)); result.size = size; } return result; } } class CriticalAllocHandle : CriticalHandleZeroOrMinusOneIsInvalid { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public static implicit operator IntPtr(CriticalAllocHandle safeHandle) { return (safeHandle != null) ? safeHandle.handle : (IntPtr)null; } protected override bool ReleaseHandle() { Marshal.FreeHGlobal(handle); return true; } public static CriticalAllocHandle FromSize(int size) { CriticalAllocHandle result = new CriticalAllocHandle(); RuntimeHelpers.PrepareConstrainedRegions(); try{} finally { result.SetHandle(Marshal.AllocHGlobal(size)); } return result; } } class CriticalAllocHandleBlob : CriticalAllocHandle { public static CriticalAllocHandle FromBlob (T id) { int size = Marshal.SizeOf(typeof(T)); CriticalAllocHandle result = CriticalAllocHandle.FromSize(size); Marshal.StructureToPtr(id, (IntPtr)result, false); return result; } } class CriticalAllocHandleGuid : CriticalAllocHandle { public static CriticalAllocHandle FromGuid(Guid input) { int guidSize = Marshal.SizeOf(typeof(Guid)); CriticalAllocHandle result = CriticalAllocHandle.FromSize(guidSize); Marshal.Copy(input.ToByteArray(),0,(IntPtr)result,guidSize); return result; } } } // 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
- Rect3DValueSerializer.cs
- PropertyMetadata.cs
- FilteredDataSetHelper.cs
- HttpClientChannel.cs
- CommandHelpers.cs
- CodeMemberProperty.cs
- ExtendedProperty.cs
- TaskCanceledException.cs
- Preprocessor.cs
- StandardBindingOptionalReliableSessionElement.cs
- QueryCacheManager.cs
- NonParentingControl.cs
- KeyGesture.cs
- LineServicesCallbacks.cs
- MissingManifestResourceException.cs
- ContractMapping.cs
- CatalogZoneBase.cs
- _FtpDataStream.cs
- RegistrationServices.cs
- CacheHelper.cs
- ParseHttpDate.cs
- ParseChildrenAsPropertiesAttribute.cs
- SqlErrorCollection.cs
- Group.cs
- CommandBindingCollection.cs
- NameService.cs
- RefreshPropertiesAttribute.cs
- XhtmlBasicValidatorAdapter.cs
- PenThread.cs
- CompositeCollection.cs
- XmlSchemaComplexContentRestriction.cs
- UserPersonalizationStateInfo.cs
- HybridObjectCache.cs
- StringUtil.cs
- HtmlFormParameterReader.cs
- CodeStatementCollection.cs
- CollectionViewSource.cs
- BaseParser.cs
- SerializationHelper.cs
- GetCertificateRequest.cs
- PropertyTabAttribute.cs
- WebWorkflowRole.cs
- HttpChannelBindingToken.cs
- MessageVersion.cs
- EdmPropertyAttribute.cs
- Pkcs7Signer.cs
- TypeBuilder.cs
- NotSupportedException.cs
- HandleCollector.cs
- Utils.cs
- ConfigurationProperty.cs
- JsonObjectDataContract.cs
- Metadata.cs
- ArrangedElement.cs
- SessionPageStateSection.cs
- BindingCompleteEventArgs.cs
- ScalarConstant.cs
- QilChoice.cs
- ContourSegment.cs
- SchemaAttDef.cs
- Application.cs
- HttpWebRequestElement.cs
- VectorConverter.cs
- RegistrationServices.cs
- DispatcherObject.cs
- SortKey.cs
- SerialReceived.cs
- CodePropertyReferenceExpression.cs
- EventInfo.cs
- PointLightBase.cs
- DesignerMetadata.cs
- CLRBindingWorker.cs
- SendDesigner.xaml.cs
- SafePEFileHandle.cs
- NamedPipeProcessProtocolHandler.cs
- TypeTypeConverter.cs
- RenderDataDrawingContext.cs
- SizeF.cs
- ToolStripContentPanel.cs
- IPipelineRuntime.cs
- PerformanceCounterTraceRecord.cs
- SqlClientWrapperSmiStream.cs
- BinaryUtilClasses.cs
- HyperLinkStyle.cs
- ControlLocalizer.cs
- XmlSchema.cs
- SourceChangedEventArgs.cs
- RestHandler.cs
- EncodingTable.cs
- RouteParametersHelper.cs
- UTF32Encoding.cs
- GeneralTransform3DGroup.cs
- ValidatorCollection.cs
- ThreadStartException.cs
- InstallerTypeAttribute.cs
- MeshGeometry3D.cs
- Utils.cs
- ExpressionList.cs
- DirectoryObjectSecurity.cs
- DataGridViewLayoutData.cs