UnsafePeerToPeerMethods.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / SystemNet / Net / PeerToPeer / UnsafePeerToPeerMethods.cs / 1305376 / UnsafePeerToPeerMethods.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

using System.Security.Permissions; 
 
namespace System.Net.PeerToPeer
{ 
    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.Win32.SafeHandles; 
    using System.Security;
    using System.Runtime.InteropServices; 
    using System.Runtime.ConstrainedExecution; 
    using System.Threading;
    using System.Net.Sockets; 
    using Microsoft.Win32;
    using System.Diagnostics;

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    internal struct PEER_PNRP_CLOUD_INFO
    { 
        internal IntPtr pwzCloudName; 
        internal UInt32 dwScope;
        internal UInt32 dwScopeId; 
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    internal struct PEER_PNRP_REGISTRATION_INFO 
    {
        internal string pwszCloudName; 
        internal string pwszPublishingIdentity; 
        internal UInt32 cAddresses;
        internal IntPtr ArrayOfSOCKADDRIN6Pointers; 
        internal ushort wport;
        internal string pwszComment;
        internal PEER_DATA payLoad;
    } 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    internal struct PEER_PNRP_ENDPOINT_INFO 
    {
        internal IntPtr pwszPeerName; 
        internal UInt32 cAddresses;
        internal IntPtr ArrayOfSOCKADDRIN6Pointers;
        internal IntPtr pwszComment;
        internal PEER_DATA payLoad; 
    }
 
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] 
    internal struct PEER_DATA
    { 
        internal UInt32 cbPayload;
        internal IntPtr pbPayload;
    }
 
    [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
    internal static class UnsafeP2PNativeMethods 
    { 
        internal const string P2P = "p2p.dll";
 
        [DllImport(P2P, CharSet = CharSet.Unicode)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        internal extern static void PeerFreeData(IntPtr dataToFree);
 
        [DllImport(P2P, CharSet = CharSet.Unicode)]
        internal extern static Int32 PeerPnrpGetCloudInfo(out UInt32 pNumClouds, out SafePeerData pArrayOfClouds); 
 
        [DllImport(P2P, CharSet = CharSet.Unicode)]
        internal extern static Int32 PeerPnrpStartup(ushort versionRequired); 

        [DllImport(P2P, CharSet = CharSet.Unicode)]
        internal extern static Int32
            PeerCreatePeerName(string identity, string classfier, out SafePeerData peerName); 

        //[DllImport(P2P, CharSet = CharSet.Unicode)] 
        //internal extern static Int32 PeerCreatePeerName(string identity, string classfier, out SafePeerData peerName); 

        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        internal extern static Int32 PeerIdentityGetDefault(out SafePeerData defaultIdentity);

        /*
        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        internal extern static Int32 PeerIdentityCreate(string classifier, string friendlyName, IntPtr hCryptoProv, out SafePeerData defaultIdentity);
        */ 
        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        internal extern static Int32 PeerNameToPeerHostName(string peerName, out SafePeerData peerHostName);
 
        [DllImport(P2P, CharSet = CharSet.Unicode)]
        internal extern static Int32 PeerHostNameToPeerName(string peerHostName, out SafePeerData peerName);

        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        public extern static Int32 PeerPnrpRegister(string pcwzPeerName,
                                                    ref PEER_PNRP_REGISTRATION_INFO registrationInfo, 
                                                    out SafePeerNameUnregister handle); 

        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        public extern static Int32 PeerPnrpUnregister(IntPtr handle);

        [System.Security.SecurityCritical]
        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        public extern static Int32 PeerPnrpUpdateRegistration(SafePeerNameUnregister hRegistration,
                                                    ref PEER_PNRP_REGISTRATION_INFO registrationInfo); 
 

        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        public extern static Int32 PeerPnrpResolve(string pcwzPeerNAme,
                                                   string pcwzCloudName,
                                                   ref UInt32 pcEndPoints,
                                                   out SafePeerData pEndPoints); 

        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        public extern static Int32 PeerPnrpStartResolve(string pcwzPeerNAme, 
                                                   string pcwzCloudName,
                                                   UInt32 cEndPoints, 
                                                   SafeWaitHandle hEvent,
                                                   out SafePeerNameEndResolve safePeerNameEndResolve);

        [DllImport(P2P, CharSet = CharSet.Unicode)] 
        public extern static Int32 PeerPnrpGetEndpoint(IntPtr Handle,
                                                       out SafePeerData pEndPoint); 
 
        [DllImport(P2P, CharSet = CharSet.Unicode)]
        public extern static Int32 PeerPnrpEndResolve(IntPtr Handle); 

        private static object s_InternalSyncObject;
        private static bool s_Initialized;
        private const int PNRP_VERSION = 2; 
        private static object InternalSyncObject {
            get { 
                if (s_InternalSyncObject == null) { 
                    object o = new object();
                    Interlocked.CompareExchange(ref s_InternalSyncObject, o, null); 
                }
                return s_InternalSyncObject;
            }
        } 
        // 
        //  
        //  
        // 
        [System.Security.SecurityCritical] 
        internal static void PnrpStartup()
        {
            if (!s_Initialized) {
                lock (InternalSyncObject) { 
                    if (!s_Initialized) {
                        Int32 result = PeerPnrpStartup(PNRP_VERSION); 
                        if (result != 0) { 
                            throw new PeerToPeerException(SR.GetString(SR.Pnrp_StartupFailed), Marshal.GetExceptionForHR(result));
                        } 
                        s_Initialized = true;
                    }
                }
            } 
        } //end of method PnrpStartup
 
    } 

 
    // 
    // 
    // 
#pragma warning disable 618    // Have not migrated to v4 transparency yet 
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618 
    [System.Security.SuppressUnmanagedCodeSecurityAttribute()] 
    internal sealed class SafePeerData : SafeHandleZeroOrMinusOneIsInvalid
    { 
        private SafePeerData() : base(true) { }
        //private SafePeerData(bool ownsHandle) : base(ownsHandle) { }
        internal string UnicodeString
        { 
            get
            { 
                return Marshal.PtrToStringUni(handle); 
            }
        } 
        protected override bool ReleaseHandle()
        {
            UnsafeP2PNativeMethods.PeerFreeData(handle);
            SetHandleAsInvalid();   //Mark it closed - This does not change the value of the handle it self 
            SetHandle(IntPtr.Zero); //Mark it invalid - Change the value to Zero
            return true; 
        } 
    }
 

    // 
    // 
    //  
#pragma warning disable 618    // Have not migrated to v4 transparency yet
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)] 
#pragma warning restore 618 
    [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
    internal sealed class SafePeerNameUnregister : SafeHandleZeroOrMinusOneIsInvalid 
    {
        internal SafePeerNameUnregister() : base(true) { }
        //internal SafePeerNameUnregister(bool ownsHandle) : base(ownsHandle) { }
        protected override bool ReleaseHandle() 
        {
            UnsafeP2PNativeMethods.PeerPnrpUnregister(handle); 
            SetHandleAsInvalid(); //Mark it closed - This does not change the value of the handle it self 
            SetHandle(IntPtr.Zero); //Mark it invalid - Change the value to Zero
            return true; 
        }
    }

    //  
    // 
    //  
#pragma warning disable 618    // Have not migrated to v4 transparency yet 
    [System.Security.SecurityCritical(System.Security.SecurityCriticalScope.Everything)]
#pragma warning restore 618 
    [System.Security.SuppressUnmanagedCodeSecurityAttribute()]
    internal sealed class SafePeerNameEndResolve : SafeHandleZeroOrMinusOneIsInvalid
    {
        internal SafePeerNameEndResolve() : base(true) { } 
        //internal SafePeerNameEndResolve(bool ownsHandle) : base(ownsHandle) { }
        protected override bool ReleaseHandle() 
        { 
            UnsafeP2PNativeMethods.PeerPnrpEndResolve(handle);
            SetHandleAsInvalid(); //Mark it closed - This does not change the value of the handle it self 
            SetHandle(IntPtr.Zero); //Mark it invalid - Change the value to Zero
            return true;
        }
    } 

    ///  
    /// Determines whether P2P is installed 
    /// Note static constructors are guaranteed to be
    /// run in a thread safe manner. so no locks are necessary 
    /// 
    internal static class PeerToPeerOSHelper
    {
        private const string OSInstallTypeRegKey = @"Software\Microsoft\Windows NT\CurrentVersion"; 
        private const string OSInstallTypeRegKeyPath = @"HKEY_LOCAL_MACHINE\" + OSInstallTypeRegKey;
        private const string OSInstallTypeRegName = "InstallationType"; 
        private const string InstallTypeStringServerCore = "Server Core"; 

        private static bool s_supportsP2P = false; 
        private static SafeLoadLibrary s_P2PLibrary = null;
        // 
        // 
        //  
        // 
        //  
        //  
        [System.Security.SecurityCritical]
        static PeerToPeerOSHelper() { 

            if (IsSupportedOS()) {

                // if OS is supported, but p2p.dll is not available, P2P is not supported (original behavior) 
                s_P2PLibrary = SafeLoadLibrary.LoadLibraryEx(UnsafeP2PNativeMethods.P2P);
                if (!s_P2PLibrary.IsInvalid) { 
                    IntPtr Address = UnsafeSystemNativeMethods.GetProcAddress(s_P2PLibrary, "PeerCreatePeerName"); 
                    if (Address != IntPtr.Zero) {
                        s_supportsP2P = true; 
                    }
                }
            }
            //else --> the SafeLoadLibrary would have already been marked 
            //          closed by the LoadLibraryEx call above.
        } 
 
        [SecurityCritical]
        private static bool IsSupportedOS() 
        {
            // extend this method when adding further OS/install type restrictions

            // P2P is not supported on Server Core installation type 
            if (IsServerCore()) {
                return false; 
            } 

            return true; 
        }

        [SecurityCritical]
        [RegistryPermission(SecurityAction.Assert, Read = OSInstallTypeRegKeyPath)] 
        private static bool IsServerCore()
        { 
            // This code does the same as System.Net.ComNetOS.GetWindowsInstallType(). Since ComNetOS is internal and 
            // we don't want to add InternalsVisibleToAttribute to System.dll, we have to duplicate the code.
            try { 
                using (RegistryKey installTypeKey = Registry.LocalMachine.OpenSubKey(OSInstallTypeRegKey)) {
                    string installType = installTypeKey.GetValue(OSInstallTypeRegName) as string;

                    if (string.IsNullOrEmpty(installType)) { 
                        Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0,
                            SR.GetString(SR.P2P_empty_osinstalltype, OSInstallTypeRegKey + "\\" + OSInstallTypeRegName)); 
                    } 
                    else {
                        if (String.Compare(installType, InstallTypeStringServerCore, StringComparison.OrdinalIgnoreCase) == 0) { 
                            return true;
                        }
                    }
                } 
            }
            catch (UnauthorizedAccessException e) { 
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0, 
                    SR.GetString(SR.P2P_cant_determine_osinstalltype, OSInstallTypeRegKey, e.Message));
            } 
            catch (SecurityException e) {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0,
                    SR.GetString(SR.P2P_cant_determine_osinstalltype, OSInstallTypeRegKey, e.Message));
            } 

            return false; 
        } 

        internal static bool SupportsP2P { 
            get {
                return s_supportsP2P;
            }
        } 
        internal static IntPtr P2PModuleHandle
        { 
            //  
            // 
            //  
            // 
            // 
            // 
            [System.Security.SecurityCritical] 
            [SecurityPermissionAttribute(SecurityAction.LinkDemand, UnmanagedCode=true)]
            get 
            { 
                if (!s_P2PLibrary.IsClosed && !s_P2PLibrary.IsInvalid)
                    return s_P2PLibrary.DangerousGetHandle(); 
                return IntPtr.Zero;
            }
        }
    } 

} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK