CollaborationHelperFunctions.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / SystemNet / Net / PeerToPeer / Collaboration / CollaborationHelperFunctions.cs / 2 / CollaborationHelperFunctions.cs

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

using System.Security.Permissions; 
 
namespace System.Net.PeerToPeer.Collaboration
{ 
    using System;
    using System.Collections.ObjectModel;
    using System.Runtime.InteropServices;
    using System.Net.Mail; 
    using System.Security.Cryptography.X509Certificates;
    using System.Diagnostics; 
    using System.Threading; 

    ///  
    /// This class contains some of the common functions needed for peer
    /// collaboration
    /// 
    internal static class CollaborationHelperFunctions 
    {
        private static bool s_Initialized; 
        private static object s_LockInitialized = new object(); 
        private const short c_CollabVersion = 0x0001;
 
        //
        // Initialise windows collab. This has to be called before any collab operation
        //
        //  
        // 
        //  
        //  
        [System.Security.SecurityCritical]
        internal static void Initialize() 
        {
            if (!s_Initialized){
                lock (s_LockInitialized){
                    if (!s_Initialized){ 
                        if(!PeerToPeerOSHelper.SupportsP2P)
                            throw new PlatformNotSupportedException(SR.GetString(SR.P2P_NotAvailable)); 
                        int errorCode = UnsafeCollabNativeMethods.PeerCollabStartup(c_CollabVersion); 
                        if (errorCode != 0){
                            Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabStartup returned with errorcode {0}", errorCode); 
                            throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_StartupFailed), errorCode);
                        }
                        s_Initialized = true;
                    } 
                }
            } 
        } 

        // 
        // Converts Guid class to GUID structure that we can pass into native
        //
        internal static GUID ConvertGuidToGUID(Guid guid)
        { 
            GUID newGuid = new GUID();
 
            if (guid != null){ 
                byte[] guidBytes = guid.ToByteArray();
                string guidString = guid.ToString(); 

                int startVal = 0;
                int endVal = guidString.IndexOf('-');
                newGuid.data1 = (uint)(Convert.ToUInt32(guidString.Substring(startVal, endVal - startVal), 16)); 
                startVal = endVal + 1;
                endVal = guidString.IndexOf('-', endVal + 1); 
                newGuid.data2 = (ushort)(Convert.ToUInt16(guidString.Substring(startVal, endVal - startVal), 16)); 
                startVal = endVal + 1;
                endVal = guidString.IndexOf('-', endVal + 1); 
                newGuid.data3 = (ushort)(Convert.ToUInt16(guidString.Substring(startVal, endVal - startVal), 16));
                newGuid.data4 = guidBytes[8];
                newGuid.data5 = guidBytes[9];
                newGuid.data6 = guidBytes[10]; 
                newGuid.data7 = guidBytes[11];
                newGuid.data8 = guidBytes[12]; 
                newGuid.data9 = guidBytes[13]; 
                newGuid.data10 = guidBytes[14];
                newGuid.data11 = guidBytes[15]; 
            }
            return newGuid;
        }
 
        //
        // Converts native GUID structure to managed Guid class 
        // 
        internal static Guid ConvertGUIDToGuid(GUID guid)
        { 
            byte[] bytes = new byte[8];
            bytes[0] = guid.data4;
            bytes[1] = guid.data5;
            bytes[2] = guid.data6; 
            bytes[3] = guid.data7;
            bytes[4] = guid.data8; 
            bytes[5] = guid.data9; 
            bytes[6] = guid.data10;
            bytes[7] = guid.data11; 

            return new Guid((int)guid.data1, (short)guid.data2, (short)guid.data3, bytes);
        }
 
        //
        // Converts native PEER_CONTACT to PeerContact class 
        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical]
        internal static PeerContact ConvertPEER_CONTACTToPeerContact(PEER_CONTACT pc)
        { 
            return ConvertPEER_CONTACTToPeerContact(pc, false);
        } 
 
        // 
        //  
        // 
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        [System.Security.SecurityCritical]
        internal static PeerContact ConvertPEER_CONTACTToPeerContact(PEER_CONTACT pc, bool isMyContact) 
        {
            PeerContact peerContact = (isMyContact ? new MyContact(): new PeerContact()); 
            peerContact.PeerName = new PeerName(pc.pwzPeerName); 
            peerContact.DisplayName = pc.pwzDisplayName;
            peerContact.Nickname = pc.pwzNickname; 
            peerContact.EmailAddress = (pc.pwzEmailAddress != null) ? new MailAddress(pc.pwzEmailAddress) : null;
            if(!isMyContact)
                peerContact.SubscribeAllowed = pc.WatcherPermissions;
            peerContact.IsSubscribed = (isMyContact ? true : pc.fWatch); 
            byte[] data = null;
 
            if (pc.credentials.cbData != 0){ 
                data = new byte[pc.credentials.cbData];
                Marshal.Copy(pc.credentials.pbData, data, 0, (int)pc.credentials.cbData); 
            }

            if (data != null){
 
                SafeCertStore certHandle = UnsafeCollabNativeMethods.CertOpenStore(new IntPtr(/*CERT_STORE_PROV_PKCS7*/ 5),
                                                    0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/, 
                                                    IntPtr.Zero, 
                                                    0x00000001/*CERT_STORE_NO_CRYPT_RELEASE_FLAG*/,
                                                    ref pc.credentials); 

                if (certHandle == null || certHandle.IsInvalid){
                    int win32ErrorCode = Marshal.GetLastWin32Error();
                    throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_CredentialsError), win32ErrorCode); 
                }
                try{ 
                    X509Store certStore = new X509Store(certHandle.DangerousGetHandle()); 
                    peerContact.Credentials = new X509Certificate2(certStore.Certificates[0]);
                } 
                finally{
                    if(certHandle != null) certHandle.Dispose();
                }
            } 

            return peerContact; 
        } 

        //  
        // 
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        internal static PEER_CONTACT ConvertPeerContactToPEER_CONTACT(PeerContact peerContact, ref SafeCollabMemory safeCredentials)
        { 
            PEER_CONTACT pc = new PEER_CONTACT(); 

            pc.pwzDisplayName = peerContact.DisplayName; 
            pc.pwzEmailAddress = (peerContact.EmailAddress == null) ? null : peerContact.EmailAddress.ToString();
            pc.pwzNickname = peerContact.Nickname;
            pc.pwzPeerName = peerContact.PeerName.ToString();
            pc.fWatch = peerContact.IsSubscribed; 
            pc.WatcherPermissions = peerContact.SubscribeAllowed;
            PEER_DATA pd = new PEER_DATA(); 
 
            if (peerContact.Credentials != null){
                SafeCertStore certHandle = UnsafeCollabNativeMethods.CertOpenStore(new IntPtr(/*CERT_STORE_PROV_MEMORY*/ 2), 
                                    0,
                                    IntPtr.Zero,
                                    0x00002000/*CERT_STORE_CREATE_NEW_FLAG*/ | 0x00000001/*CERT_STORE_NO_CRYPT_RELEASE_FLAG*/,
                                    IntPtr.Zero); 

                if (certHandle == null || certHandle.IsInvalid){ 
                    int win32ErrorCode = Marshal.GetLastWin32Error(); 
                    throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_CredentialsError), win32ErrorCode);
                } 

                try{
                    X509Store certStore = new X509Store(certHandle.DangerousGetHandle());
                    certStore.Add(peerContact.Credentials as X509Certificate2); 
                    bool returnCode = UnsafeCollabNativeMethods.CertSaveStore(certHandle,
                                                     0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/, 
                                                     2 /*CERT_STORE_SAVE_AS_STORE*/, 
                                                     2, /*CERT_STORE_SAVE_TO_MEMORY*/
                                                     ref pd, 
                                                     0);

                    if ((pd.cbData != 0) && (returnCode)){
                        safeCredentials = new SafeCollabMemory((int)pd.cbData); 
                        pd.pbData = safeCredentials.DangerousGetHandle();
                        returnCode = UnsafeCollabNativeMethods.CertSaveStore(certHandle, 
                                                     0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/, 
                                                     2 /*CERT_STORE_SAVE_AS_STORE*/,
                                                     2, /*CERT_STORE_SAVE_TO_MEMORY*/ 
                                                     ref pd,// Clean up memory from here;
                                                     0);

                    } 
                    else{
                        pd.cbData = 0; 
                        pd.pbData = IntPtr.Zero; 
                    }
                } 
                finally{
                    if (certHandle != null) certHandle.Dispose();
                }
            } 
            else{
                pd.cbData = 0; 
                pd.pbData = IntPtr.Zero; 
            }
            pc.credentials = pd; 

            return pc;

        } 

        // 
        // Converts address bytes to a SOCKADDR_IN6 that can be passed into 
        // native
        // 
        internal static void ByteArrayToSin6Addr(byte[] addrBytes, ref SOCKADDR_IN6 sin6)
        {
            sin6.sin6_addr0 = addrBytes[0];
            sin6.sin6_addr1 = addrBytes[1]; 
            sin6.sin6_addr2 = addrBytes[2];
            sin6.sin6_addr3 = addrBytes[3]; 
            sin6.sin6_addr4 = addrBytes[4]; 
            sin6.sin6_addr5 = addrBytes[5];
            sin6.sin6_addr6 = addrBytes[6]; 
            sin6.sin6_addr7 = addrBytes[7];
            sin6.sin6_addr8 = addrBytes[8];
            sin6.sin6_addr9 = addrBytes[9];
            sin6.sin6_addr10 = addrBytes[10]; 
            sin6.sin6_addr11 = addrBytes[11];
            sin6.sin6_addr12 = addrBytes[12]; 
            sin6.sin6_addr13 = addrBytes[13]; 
            sin6.sin6_addr14 = addrBytes[14];
            sin6.sin6_addr15 = addrBytes[15]; 
        }

        //
        // Converts native structure PEER_PEOPLE_NEAR_ME to managed PeerNearMe class 
        //
        //  
        //  
        // 
        //  
        [System.Security.SecurityCritical]
        internal static PeerNearMe PEER_PEOPLE_NEAR_METoPeerNearMe(PEER_PEOPLE_NEAR_ME ppnm)
        {
            PeerNearMe peerNearMe = new PeerNearMe(); 
            peerNearMe.Id = CollaborationHelperFunctions.ConvertGUIDToGuid(ppnm.id);
            peerNearMe.Nickname = Marshal.PtrToStringUni(ppnm.pwzNickname); ; 
 
            PEER_ENDPOINT pe = ppnm.endpoint;
            PeerEndPoint peerEP = ConvertPEER_ENDPOINTToPeerEndPoint(pe); 
            peerNearMe.PeerEndPoints.Add(peerEP);

            return peerNearMe;
        } 

        // 
        // Converts native PEER_OBJECT structure into PeerObject class 
        //
        //  
        // 
        // 
        [System.Security.SecurityCritical]
        internal static PeerObject ConvertPEER_OBJECTToPeerObject(PEER_OBJECT po) 
        {
            byte[] data = null; 
 
            if (po.data.cbData != 0){
                data = new byte[po.data.cbData]; 
                Marshal.Copy(po.data.pbData, data, 0, (int)po.data.cbData);
            }

            return new PeerObject(ConvertGUIDToGuid(po.guid), data, (PeerScope)po.dwPublicationScope); 
        }
 
        // 
        // Converts native PEER_APPLICATION structure into PeerApplication class
        // 

        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        internal static PeerApplication ConvertPEER_APPLICATIONToPeerApplication(PEER_APPLICATION pa) 
        {
            byte[] data = null; 

            if (pa.data.cbData != 0){
                data = new byte[pa.data.cbData];
                Marshal.Copy(pa.data.pbData, data, 0, (int)pa.data.cbData); 
            }
 
            return new PeerApplication( ConvertGUIDToGuid(pa.guid), 
                                        Marshal.PtrToStringUni(pa.pwzDescription),
                                        data, 
                                        null, null, PeerScope.None);
        }

        // 
        // Converts native PEER_ENDPOINT structure into PeerEndPoint class
        // 
 
        // 
        //  
        // 
        [System.Security.SecurityCritical]
        internal static PeerEndPoint ConvertPEER_ENDPOINTToPeerEndPoint(PEER_ENDPOINT pe)
        { 

            byte[] addrBytes = new byte[]{  pe.peerAddress.sin6.sin6_addr0, pe.peerAddress.sin6.sin6_addr1, 
                                            pe.peerAddress.sin6.sin6_addr2, pe.peerAddress.sin6.sin6_addr3, 
                                            pe.peerAddress.sin6.sin6_addr4, pe.peerAddress.sin6.sin6_addr5,
                                            pe.peerAddress.sin6.sin6_addr6, pe.peerAddress.sin6.sin6_addr7, 
                                            pe.peerAddress.sin6.sin6_addr8, pe.peerAddress.sin6.sin6_addr9,
                                            pe.peerAddress.sin6.sin6_addr10, pe.peerAddress.sin6.sin6_addr11,
                                            pe.peerAddress.sin6.sin6_addr12, pe.peerAddress.sin6.sin6_addr13,
                                            pe.peerAddress.sin6.sin6_addr14, pe.peerAddress.sin6.sin6_addr15}; 
            IPAddress IPAddr = new IPAddress(addrBytes, (long)pe.peerAddress.sin6.sin6_scope_id);
            ushort port; 
            unchecked{ 
                port = (ushort)IPAddress.NetworkToHostOrder((short)pe.peerAddress.sin6.sin6_port);
            } 
            IPEndPoint IPEndPt = new IPEndPoint(IPAddr, port);

            return new PeerEndPoint(IPEndPt, Marshal.PtrToStringUni(pe.pwzEndpointName));
        } 

        // 
        // Converts IPEndpoint class into native PEER_ADDRESS structure 
        //
        internal static PEER_ADDRESS ConvertIPEndpointToPEER_ADDRESS(IPEndPoint endPoint) 
        {
            PEER_ADDRESS pa = new PEER_ADDRESS();
            SOCKADDR_IN6 sin = new SOCKADDR_IN6();
            sin.sin6_family = (ushort)endPoint.AddressFamily; 
            sin.sin6_flowinfo = 0; //
            unchecked{ 
                sin.sin6_port = (ushort)IPAddress.HostToNetworkOrder((short)endPoint.Port); 
            }
            sin.sin6_scope_id = (uint)endPoint.Address.ScopeId; 
            CollaborationHelperFunctions.ByteArrayToSin6Addr(endPoint.Address.GetAddressBytes(), ref sin);
            pa.dwSize = 32;
            pa.sin6 = sin;
            return pa; 
        }
 
        // 
        // Cleans up the registered handle and the wait event. Called under lock from events.
        // 
        // 
        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, UnmanagedCode = true)] 
        internal static void CleanEventVars(ref RegisteredWaitHandle waitHandle,
                                            ref SafeCollabEvent safeEvent, 
                                            ref AutoResetEvent firedEvent)
        {
            if (waitHandle != null){
                waitHandle.Unregister(null); 
                waitHandle = null;
            } 
 
            if ((safeEvent != null) && (!safeEvent.IsInvalid)){
                safeEvent.Dispose(); 
            }

            if (firedEvent != null){
                firedEvent.Close(); 
                firedEvent = null;
            } 
        } 

        //  
        // 
        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        internal static void AddMyPresenceChanged(EventHandler callback, 
                                                        ref EventHandler presenceChanged,
                                                        object lockPresenceChangedEvent, 
                                                        ref RegisteredWaitHandle regPresenceChangedWaitHandle,
                                                        ref AutoResetEvent presenceChangedEvent,
                                                        ref SafeCollabEvent safePresenceChangedEvent,
                                                        WaitOrTimerCallback PresenceChangedCallback) 
        {
            // 
            // Register a wait handle if one has not been registered already 
            //
            lock (lockPresenceChangedEvent){ 
                if (presenceChanged == null){

                    presenceChangedEvent = new AutoResetEvent(false);
 
                    //
                    // Register callback with a wait handle 
                    // 

                    regPresenceChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(presenceChangedEvent, //Event that triggers the callback 
                                            PresenceChangedCallback, //callback to be called
                                            null, //state to be passed
                                            -1,   //Timeout - aplicable only for timers
                                            false //call us everytime the event is set 
                                            );
                    PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION(); 
                    pcer.eventType = PeerCollabEventType.MyPresenceChanged; 
                    pcer.pInstance = IntPtr.Zero;
 

                    //
                    // Register event with collab
                    // 

                    int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( 
                                                                        presenceChangedEvent.SafeWaitHandle, 
                                                                        1,
                                                                        ref pcer, 
                                                                        out safePresenceChangedEvent);
                    if (errorCode != 0){
                        Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_PresenceChangedRegFailed), errorCode); 
                    }
                } 
                presenceChanged += callback; 
            }
 
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddMyPresenceChanged() successful.");
        }

        //  
        // 
        //  
        //  
        // 
        //  
        [System.Security.SecurityCritical]
        internal static void AddMyApplicationChanged(EventHandler callback,
                                                ref EventHandler applicationChanged,
                                                object lockAppChangedEvent, 
                                                ref RegisteredWaitHandle regAppChangedWaitHandle,
                                                ref AutoResetEvent appChangedEvent, 
                                                ref SafeCollabEvent safeAppChangedEvent, 
                                                WaitOrTimerCallback ApplicationChangedCallback)
        { 
            //
            // Register a wait handle if one has not been registered already
            //
            lock (lockAppChangedEvent){ 
                if (applicationChanged == null){
 
                    appChangedEvent = new AutoResetEvent(false); 

                    // 
                    // Register callback with a wait handle
                    //

                    regAppChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(appChangedEvent, //Event that triggers the callback 
                                            ApplicationChangedCallback, //callback to be called
                                            null, //state to be passed 
                                            -1,   //Timeout - aplicable only for timers 
                                            false //call us everytime the event is set
                                            ); 
                    PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();

                    pcer.eventType = PeerCollabEventType.MyApplicationChanged;
                    pcer.pInstance = IntPtr.Zero; 

                    // 
                    // Register event with collab 
                    //
 
                    int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
                                                                        appChangedEvent.SafeWaitHandle,
                                                                        1,
                                                                        ref pcer, 
                                                                        out safeAppChangedEvent);
                    if (errorCode != 0){ 
                        Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); 
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ApplicationChangedRegFailed), errorCode);
                    } 
                }
                applicationChanged += callback;
            }
 
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddApplicationChanged() successful.");
        } 
 
        // 
        //  
        // 
        // 
        // 
        //  
        [System.Security.SecurityCritical]
        internal static void AddMyObjectChanged(EventHandler callback, 
                                        ref EventHandler objectChanged, 
                                        object lockObjChangedEvent,
                                        ref RegisteredWaitHandle regObjChangedWaitHandle, 
                                        ref AutoResetEvent objChangedEvent,
                                        ref SafeCollabEvent safeObjChangedEvent,
                                        WaitOrTimerCallback ObjectChangedCallback)
        { 
            //
            // Register a wait handle if one has not been registered already 
            // 
            lock (lockObjChangedEvent){
                if (objectChanged == null){ 

                    objChangedEvent = new AutoResetEvent(false);

                    // 
                    // Register callback with a wait handle
                    // 
 
                    regObjChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(objChangedEvent, //Event that triggers the callback
                                            ObjectChangedCallback, //callback to be called 
                                            null, //state to be passed
                                            -1,   //Timeout - aplicable only for timers
                                            false //call us everytime the event is set
                                            ); 

                    PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION(); 
                    pcer.eventType = PeerCollabEventType.MyObjectChanged; 
                    pcer.pInstance = IntPtr.Zero;
 

                    //
                    // Register event with collab
                    // 

                    int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( 
                                                                        objChangedEvent.SafeWaitHandle, 
                                                                        1,
                                                                        ref pcer, 
                                                                        out safeObjChangedEvent);
                    if (errorCode != 0){
                        Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectChangedRegFailed), errorCode); 
                    }
                } 
                objectChanged += callback; 
            }
 
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful.");

        }
 
        internal static void ThrowIfInvitationResponseInvalid(PeerInvitationResponse response)
        { 
            // throw an exception if the response from the native API was PEER_INVITATION_RESPONSE_ERROR 
            if (response.PeerInvitationResponseType < PeerInvitationResponseType.Declined ||
                response.PeerInvitationResponseType > PeerInvitationResponseType.Expired) 
            {
                throw new PeerToPeerException(SR.GetString(SR.Collab_InviteFailed));
            }
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

using System.Security.Permissions; 
 
namespace System.Net.PeerToPeer.Collaboration
{ 
    using System;
    using System.Collections.ObjectModel;
    using System.Runtime.InteropServices;
    using System.Net.Mail; 
    using System.Security.Cryptography.X509Certificates;
    using System.Diagnostics; 
    using System.Threading; 

    ///  
    /// This class contains some of the common functions needed for peer
    /// collaboration
    /// 
    internal static class CollaborationHelperFunctions 
    {
        private static bool s_Initialized; 
        private static object s_LockInitialized = new object(); 
        private const short c_CollabVersion = 0x0001;
 
        //
        // Initialise windows collab. This has to be called before any collab operation
        //
        //  
        // 
        //  
        //  
        [System.Security.SecurityCritical]
        internal static void Initialize() 
        {
            if (!s_Initialized){
                lock (s_LockInitialized){
                    if (!s_Initialized){ 
                        if(!PeerToPeerOSHelper.SupportsP2P)
                            throw new PlatformNotSupportedException(SR.GetString(SR.P2P_NotAvailable)); 
                        int errorCode = UnsafeCollabNativeMethods.PeerCollabStartup(c_CollabVersion); 
                        if (errorCode != 0){
                            Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabStartup returned with errorcode {0}", errorCode); 
                            throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_StartupFailed), errorCode);
                        }
                        s_Initialized = true;
                    } 
                }
            } 
        } 

        // 
        // Converts Guid class to GUID structure that we can pass into native
        //
        internal static GUID ConvertGuidToGUID(Guid guid)
        { 
            GUID newGuid = new GUID();
 
            if (guid != null){ 
                byte[] guidBytes = guid.ToByteArray();
                string guidString = guid.ToString(); 

                int startVal = 0;
                int endVal = guidString.IndexOf('-');
                newGuid.data1 = (uint)(Convert.ToUInt32(guidString.Substring(startVal, endVal - startVal), 16)); 
                startVal = endVal + 1;
                endVal = guidString.IndexOf('-', endVal + 1); 
                newGuid.data2 = (ushort)(Convert.ToUInt16(guidString.Substring(startVal, endVal - startVal), 16)); 
                startVal = endVal + 1;
                endVal = guidString.IndexOf('-', endVal + 1); 
                newGuid.data3 = (ushort)(Convert.ToUInt16(guidString.Substring(startVal, endVal - startVal), 16));
                newGuid.data4 = guidBytes[8];
                newGuid.data5 = guidBytes[9];
                newGuid.data6 = guidBytes[10]; 
                newGuid.data7 = guidBytes[11];
                newGuid.data8 = guidBytes[12]; 
                newGuid.data9 = guidBytes[13]; 
                newGuid.data10 = guidBytes[14];
                newGuid.data11 = guidBytes[15]; 
            }
            return newGuid;
        }
 
        //
        // Converts native GUID structure to managed Guid class 
        // 
        internal static Guid ConvertGUIDToGuid(GUID guid)
        { 
            byte[] bytes = new byte[8];
            bytes[0] = guid.data4;
            bytes[1] = guid.data5;
            bytes[2] = guid.data6; 
            bytes[3] = guid.data7;
            bytes[4] = guid.data8; 
            bytes[5] = guid.data9; 
            bytes[6] = guid.data10;
            bytes[7] = guid.data11; 

            return new Guid((int)guid.data1, (short)guid.data2, (short)guid.data3, bytes);
        }
 
        //
        // Converts native PEER_CONTACT to PeerContact class 
        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical]
        internal static PeerContact ConvertPEER_CONTACTToPeerContact(PEER_CONTACT pc)
        { 
            return ConvertPEER_CONTACTToPeerContact(pc, false);
        } 
 
        // 
        //  
        // 
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        [System.Security.SecurityCritical]
        internal static PeerContact ConvertPEER_CONTACTToPeerContact(PEER_CONTACT pc, bool isMyContact) 
        {
            PeerContact peerContact = (isMyContact ? new MyContact(): new PeerContact()); 
            peerContact.PeerName = new PeerName(pc.pwzPeerName); 
            peerContact.DisplayName = pc.pwzDisplayName;
            peerContact.Nickname = pc.pwzNickname; 
            peerContact.EmailAddress = (pc.pwzEmailAddress != null) ? new MailAddress(pc.pwzEmailAddress) : null;
            if(!isMyContact)
                peerContact.SubscribeAllowed = pc.WatcherPermissions;
            peerContact.IsSubscribed = (isMyContact ? true : pc.fWatch); 
            byte[] data = null;
 
            if (pc.credentials.cbData != 0){ 
                data = new byte[pc.credentials.cbData];
                Marshal.Copy(pc.credentials.pbData, data, 0, (int)pc.credentials.cbData); 
            }

            if (data != null){
 
                SafeCertStore certHandle = UnsafeCollabNativeMethods.CertOpenStore(new IntPtr(/*CERT_STORE_PROV_PKCS7*/ 5),
                                                    0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/, 
                                                    IntPtr.Zero, 
                                                    0x00000001/*CERT_STORE_NO_CRYPT_RELEASE_FLAG*/,
                                                    ref pc.credentials); 

                if (certHandle == null || certHandle.IsInvalid){
                    int win32ErrorCode = Marshal.GetLastWin32Error();
                    throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_CredentialsError), win32ErrorCode); 
                }
                try{ 
                    X509Store certStore = new X509Store(certHandle.DangerousGetHandle()); 
                    peerContact.Credentials = new X509Certificate2(certStore.Certificates[0]);
                } 
                finally{
                    if(certHandle != null) certHandle.Dispose();
                }
            } 

            return peerContact; 
        } 

        //  
        // 
        // 
        // 
        //  
        // 
        //  
        //  
        // 
        //  
        // 
        // 
        // 
        [System.Security.SecurityCritical] 
        internal static PEER_CONTACT ConvertPeerContactToPEER_CONTACT(PeerContact peerContact, ref SafeCollabMemory safeCredentials)
        { 
            PEER_CONTACT pc = new PEER_CONTACT(); 

            pc.pwzDisplayName = peerContact.DisplayName; 
            pc.pwzEmailAddress = (peerContact.EmailAddress == null) ? null : peerContact.EmailAddress.ToString();
            pc.pwzNickname = peerContact.Nickname;
            pc.pwzPeerName = peerContact.PeerName.ToString();
            pc.fWatch = peerContact.IsSubscribed; 
            pc.WatcherPermissions = peerContact.SubscribeAllowed;
            PEER_DATA pd = new PEER_DATA(); 
 
            if (peerContact.Credentials != null){
                SafeCertStore certHandle = UnsafeCollabNativeMethods.CertOpenStore(new IntPtr(/*CERT_STORE_PROV_MEMORY*/ 2), 
                                    0,
                                    IntPtr.Zero,
                                    0x00002000/*CERT_STORE_CREATE_NEW_FLAG*/ | 0x00000001/*CERT_STORE_NO_CRYPT_RELEASE_FLAG*/,
                                    IntPtr.Zero); 

                if (certHandle == null || certHandle.IsInvalid){ 
                    int win32ErrorCode = Marshal.GetLastWin32Error(); 
                    throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_CredentialsError), win32ErrorCode);
                } 

                try{
                    X509Store certStore = new X509Store(certHandle.DangerousGetHandle());
                    certStore.Add(peerContact.Credentials as X509Certificate2); 
                    bool returnCode = UnsafeCollabNativeMethods.CertSaveStore(certHandle,
                                                     0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/, 
                                                     2 /*CERT_STORE_SAVE_AS_STORE*/, 
                                                     2, /*CERT_STORE_SAVE_TO_MEMORY*/
                                                     ref pd, 
                                                     0);

                    if ((pd.cbData != 0) && (returnCode)){
                        safeCredentials = new SafeCollabMemory((int)pd.cbData); 
                        pd.pbData = safeCredentials.DangerousGetHandle();
                        returnCode = UnsafeCollabNativeMethods.CertSaveStore(certHandle, 
                                                     0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/, 
                                                     2 /*CERT_STORE_SAVE_AS_STORE*/,
                                                     2, /*CERT_STORE_SAVE_TO_MEMORY*/ 
                                                     ref pd,// Clean up memory from here;
                                                     0);

                    } 
                    else{
                        pd.cbData = 0; 
                        pd.pbData = IntPtr.Zero; 
                    }
                } 
                finally{
                    if (certHandle != null) certHandle.Dispose();
                }
            } 
            else{
                pd.cbData = 0; 
                pd.pbData = IntPtr.Zero; 
            }
            pc.credentials = pd; 

            return pc;

        } 

        // 
        // Converts address bytes to a SOCKADDR_IN6 that can be passed into 
        // native
        // 
        internal static void ByteArrayToSin6Addr(byte[] addrBytes, ref SOCKADDR_IN6 sin6)
        {
            sin6.sin6_addr0 = addrBytes[0];
            sin6.sin6_addr1 = addrBytes[1]; 
            sin6.sin6_addr2 = addrBytes[2];
            sin6.sin6_addr3 = addrBytes[3]; 
            sin6.sin6_addr4 = addrBytes[4]; 
            sin6.sin6_addr5 = addrBytes[5];
            sin6.sin6_addr6 = addrBytes[6]; 
            sin6.sin6_addr7 = addrBytes[7];
            sin6.sin6_addr8 = addrBytes[8];
            sin6.sin6_addr9 = addrBytes[9];
            sin6.sin6_addr10 = addrBytes[10]; 
            sin6.sin6_addr11 = addrBytes[11];
            sin6.sin6_addr12 = addrBytes[12]; 
            sin6.sin6_addr13 = addrBytes[13]; 
            sin6.sin6_addr14 = addrBytes[14];
            sin6.sin6_addr15 = addrBytes[15]; 
        }

        //
        // Converts native structure PEER_PEOPLE_NEAR_ME to managed PeerNearMe class 
        //
        //  
        //  
        // 
        //  
        [System.Security.SecurityCritical]
        internal static PeerNearMe PEER_PEOPLE_NEAR_METoPeerNearMe(PEER_PEOPLE_NEAR_ME ppnm)
        {
            PeerNearMe peerNearMe = new PeerNearMe(); 
            peerNearMe.Id = CollaborationHelperFunctions.ConvertGUIDToGuid(ppnm.id);
            peerNearMe.Nickname = Marshal.PtrToStringUni(ppnm.pwzNickname); ; 
 
            PEER_ENDPOINT pe = ppnm.endpoint;
            PeerEndPoint peerEP = ConvertPEER_ENDPOINTToPeerEndPoint(pe); 
            peerNearMe.PeerEndPoints.Add(peerEP);

            return peerNearMe;
        } 

        // 
        // Converts native PEER_OBJECT structure into PeerObject class 
        //
        //  
        // 
        // 
        [System.Security.SecurityCritical]
        internal static PeerObject ConvertPEER_OBJECTToPeerObject(PEER_OBJECT po) 
        {
            byte[] data = null; 
 
            if (po.data.cbData != 0){
                data = new byte[po.data.cbData]; 
                Marshal.Copy(po.data.pbData, data, 0, (int)po.data.cbData);
            }

            return new PeerObject(ConvertGUIDToGuid(po.guid), data, (PeerScope)po.dwPublicationScope); 
        }
 
        // 
        // Converts native PEER_APPLICATION structure into PeerApplication class
        // 

        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        internal static PeerApplication ConvertPEER_APPLICATIONToPeerApplication(PEER_APPLICATION pa) 
        {
            byte[] data = null; 

            if (pa.data.cbData != 0){
                data = new byte[pa.data.cbData];
                Marshal.Copy(pa.data.pbData, data, 0, (int)pa.data.cbData); 
            }
 
            return new PeerApplication( ConvertGUIDToGuid(pa.guid), 
                                        Marshal.PtrToStringUni(pa.pwzDescription),
                                        data, 
                                        null, null, PeerScope.None);
        }

        // 
        // Converts native PEER_ENDPOINT structure into PeerEndPoint class
        // 
 
        // 
        //  
        // 
        [System.Security.SecurityCritical]
        internal static PeerEndPoint ConvertPEER_ENDPOINTToPeerEndPoint(PEER_ENDPOINT pe)
        { 

            byte[] addrBytes = new byte[]{  pe.peerAddress.sin6.sin6_addr0, pe.peerAddress.sin6.sin6_addr1, 
                                            pe.peerAddress.sin6.sin6_addr2, pe.peerAddress.sin6.sin6_addr3, 
                                            pe.peerAddress.sin6.sin6_addr4, pe.peerAddress.sin6.sin6_addr5,
                                            pe.peerAddress.sin6.sin6_addr6, pe.peerAddress.sin6.sin6_addr7, 
                                            pe.peerAddress.sin6.sin6_addr8, pe.peerAddress.sin6.sin6_addr9,
                                            pe.peerAddress.sin6.sin6_addr10, pe.peerAddress.sin6.sin6_addr11,
                                            pe.peerAddress.sin6.sin6_addr12, pe.peerAddress.sin6.sin6_addr13,
                                            pe.peerAddress.sin6.sin6_addr14, pe.peerAddress.sin6.sin6_addr15}; 
            IPAddress IPAddr = new IPAddress(addrBytes, (long)pe.peerAddress.sin6.sin6_scope_id);
            ushort port; 
            unchecked{ 
                port = (ushort)IPAddress.NetworkToHostOrder((short)pe.peerAddress.sin6.sin6_port);
            } 
            IPEndPoint IPEndPt = new IPEndPoint(IPAddr, port);

            return new PeerEndPoint(IPEndPt, Marshal.PtrToStringUni(pe.pwzEndpointName));
        } 

        // 
        // Converts IPEndpoint class into native PEER_ADDRESS structure 
        //
        internal static PEER_ADDRESS ConvertIPEndpointToPEER_ADDRESS(IPEndPoint endPoint) 
        {
            PEER_ADDRESS pa = new PEER_ADDRESS();
            SOCKADDR_IN6 sin = new SOCKADDR_IN6();
            sin.sin6_family = (ushort)endPoint.AddressFamily; 
            sin.sin6_flowinfo = 0; //
            unchecked{ 
                sin.sin6_port = (ushort)IPAddress.HostToNetworkOrder((short)endPoint.Port); 
            }
            sin.sin6_scope_id = (uint)endPoint.Address.ScopeId; 
            CollaborationHelperFunctions.ByteArrayToSin6Addr(endPoint.Address.GetAddressBytes(), ref sin);
            pa.dwSize = 32;
            pa.sin6 = sin;
            return pa; 
        }
 
        // 
        // Cleans up the registered handle and the wait event. Called under lock from events.
        // 
        // 
        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, UnmanagedCode = true)] 
        internal static void CleanEventVars(ref RegisteredWaitHandle waitHandle,
                                            ref SafeCollabEvent safeEvent, 
                                            ref AutoResetEvent firedEvent)
        {
            if (waitHandle != null){
                waitHandle.Unregister(null); 
                waitHandle = null;
            } 
 
            if ((safeEvent != null) && (!safeEvent.IsInvalid)){
                safeEvent.Dispose(); 
            }

            if (firedEvent != null){
                firedEvent.Close(); 
                firedEvent = null;
            } 
        } 

        //  
        // 
        // 
        // 
        //  
        // 
        [System.Security.SecurityCritical] 
        internal static void AddMyPresenceChanged(EventHandler callback, 
                                                        ref EventHandler presenceChanged,
                                                        object lockPresenceChangedEvent, 
                                                        ref RegisteredWaitHandle regPresenceChangedWaitHandle,
                                                        ref AutoResetEvent presenceChangedEvent,
                                                        ref SafeCollabEvent safePresenceChangedEvent,
                                                        WaitOrTimerCallback PresenceChangedCallback) 
        {
            // 
            // Register a wait handle if one has not been registered already 
            //
            lock (lockPresenceChangedEvent){ 
                if (presenceChanged == null){

                    presenceChangedEvent = new AutoResetEvent(false);
 
                    //
                    // Register callback with a wait handle 
                    // 

                    regPresenceChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(presenceChangedEvent, //Event that triggers the callback 
                                            PresenceChangedCallback, //callback to be called
                                            null, //state to be passed
                                            -1,   //Timeout - aplicable only for timers
                                            false //call us everytime the event is set 
                                            );
                    PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION(); 
                    pcer.eventType = PeerCollabEventType.MyPresenceChanged; 
                    pcer.pInstance = IntPtr.Zero;
 

                    //
                    // Register event with collab
                    // 

                    int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( 
                                                                        presenceChangedEvent.SafeWaitHandle, 
                                                                        1,
                                                                        ref pcer, 
                                                                        out safePresenceChangedEvent);
                    if (errorCode != 0){
                        Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_PresenceChangedRegFailed), errorCode); 
                    }
                } 
                presenceChanged += callback; 
            }
 
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddMyPresenceChanged() successful.");
        }

        //  
        // 
        //  
        //  
        // 
        //  
        [System.Security.SecurityCritical]
        internal static void AddMyApplicationChanged(EventHandler callback,
                                                ref EventHandler applicationChanged,
                                                object lockAppChangedEvent, 
                                                ref RegisteredWaitHandle regAppChangedWaitHandle,
                                                ref AutoResetEvent appChangedEvent, 
                                                ref SafeCollabEvent safeAppChangedEvent, 
                                                WaitOrTimerCallback ApplicationChangedCallback)
        { 
            //
            // Register a wait handle if one has not been registered already
            //
            lock (lockAppChangedEvent){ 
                if (applicationChanged == null){
 
                    appChangedEvent = new AutoResetEvent(false); 

                    // 
                    // Register callback with a wait handle
                    //

                    regAppChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(appChangedEvent, //Event that triggers the callback 
                                            ApplicationChangedCallback, //callback to be called
                                            null, //state to be passed 
                                            -1,   //Timeout - aplicable only for timers 
                                            false //call us everytime the event is set
                                            ); 
                    PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();

                    pcer.eventType = PeerCollabEventType.MyApplicationChanged;
                    pcer.pInstance = IntPtr.Zero; 

                    // 
                    // Register event with collab 
                    //
 
                    int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
                                                                        appChangedEvent.SafeWaitHandle,
                                                                        1,
                                                                        ref pcer, 
                                                                        out safeAppChangedEvent);
                    if (errorCode != 0){ 
                        Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode); 
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ApplicationChangedRegFailed), errorCode);
                    } 
                }
                applicationChanged += callback;
            }
 
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddApplicationChanged() successful.");
        } 
 
        // 
        //  
        // 
        // 
        // 
        //  
        [System.Security.SecurityCritical]
        internal static void AddMyObjectChanged(EventHandler callback, 
                                        ref EventHandler objectChanged, 
                                        object lockObjChangedEvent,
                                        ref RegisteredWaitHandle regObjChangedWaitHandle, 
                                        ref AutoResetEvent objChangedEvent,
                                        ref SafeCollabEvent safeObjChangedEvent,
                                        WaitOrTimerCallback ObjectChangedCallback)
        { 
            //
            // Register a wait handle if one has not been registered already 
            // 
            lock (lockObjChangedEvent){
                if (objectChanged == null){ 

                    objChangedEvent = new AutoResetEvent(false);

                    // 
                    // Register callback with a wait handle
                    // 
 
                    regObjChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(objChangedEvent, //Event that triggers the callback
                                            ObjectChangedCallback, //callback to be called 
                                            null, //state to be passed
                                            -1,   //Timeout - aplicable only for timers
                                            false //call us everytime the event is set
                                            ); 

                    PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION(); 
                    pcer.eventType = PeerCollabEventType.MyObjectChanged; 
                    pcer.pInstance = IntPtr.Zero;
 

                    //
                    // Register event with collab
                    // 

                    int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent( 
                                                                        objChangedEvent.SafeWaitHandle, 
                                                                        1,
                                                                        ref pcer, 
                                                                        out safeObjChangedEvent);
                    if (errorCode != 0){
                        Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
                        throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectChangedRegFailed), errorCode); 
                    }
                } 
                objectChanged += callback; 
            }
 
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful.");

        }
 
        internal static void ThrowIfInvitationResponseInvalid(PeerInvitationResponse response)
        { 
            // throw an exception if the response from the native API was PEER_INVITATION_RESPONSE_ERROR 
            if (response.PeerInvitationResponseType < PeerInvitationResponseType.Declined ||
                response.PeerInvitationResponseType > PeerInvitationResponseType.Expired) 
            {
                throw new PeerToPeerException(SR.GetString(SR.Collab_InviteFailed));
            }
        } 
    }
} 

// 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