/mcs/class/referencesource/System.Net/net/PeerToPeer/Collaboration/CollaborationHelperFunctions.cs
C# | 601 lines | 389 code | 71 blank | 141 comment | 53 complexity | 6cd2fe0ad1e2311cfc6adefd21d7b7e2 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
- //------------------------------------------------------------------------------
- // <copyright file="CollaborationHelperFunctions.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- //------------------------------------------------------------------------------
- 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;
- /// <summary>
- /// This class contains some of the common functions needed for peer
- /// collaboration
- /// </summary>
- internal static class CollaborationHelperFunctions
- {
- private static volatile 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
- //
- // <SecurityKernel Critical="True" Ring="0">
- // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabStartup(System.Int16):System.Int32" />
- // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
- // </SecurityKernel>
- [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
- //
- // <SecurityKernel Critical="True" Ring="1">
- // <ReferencesCritical Name="Method: ConvertPEER_CONTACTToPeerContact(PEER_CONTACT, Boolean):PeerContact" Ring="1" />
- // </SecurityKernel>
- [System.Security.SecurityCritical]
- internal static PeerContact ConvertPEER_CONTACTToPeerContact(PEER_CONTACT pc)
- {
- return ConvertPEER_CONTACTToPeerContact(pc, false);
- }
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="Marshal.Copy(System.IntPtr,System.Byte[],System.Int32,System.Int32):System.Void" />
- // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
- // <SatisfiesLinkDemand Name="Marshal.GetLastWin32Error():System.Int32" />
- // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
- // <SatisfiesLinkDemand Name="X509Store..ctor(System.IntPtr)" />
- // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
- // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.CertOpenStore(System.IntPtr,System.UInt32,System.IntPtr,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_DATA&):System.Net.PeerToPeer.Collaboration.SafeCertStore" />
- // <ReferencesCritical Name="Local certHandle of type: SafeCertStore" Ring="1" />
- // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
- // <ReferencesCritical Name="Method: PeerContact..ctor()" Ring="2" />
- // <ReferencesCritical Name="Method: MyContact..ctor()" Ring="3" />
- // </SecurityKernel>
- [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;
- }
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
- // <SatisfiesLinkDemand Name="Marshal.GetLastWin32Error():System.Int32" />
- // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
- // <SatisfiesLinkDemand Name="X509Store..ctor(System.IntPtr)" />
- // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
- // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.CertOpenStore(System.IntPtr,System.UInt32,System.IntPtr,System.UInt32,System.IntPtr):System.Net.PeerToPeer.Collaboration.SafeCertStore" />
- // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.CertSaveStore(System.Net.PeerToPeer.Collaboration.SafeCertStore,System.UInt32,System.UInt32,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_DATA&,System.UInt32):System.Boolean" />
- // <ReferencesCritical Name="Local certHandle of type: SafeCertStore" Ring="1" />
- // <ReferencesCritical Name="Parameter safeCredentials of type: SafeCollabMemory" Ring="1" />
- // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
- // <ReferencesCritical Name="Method: SafeCollabMemory..ctor(System.Int32)" Ring="1" />
- // </SecurityKernel>
- [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
- //
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
- // <ReferencesCritical Name="Method: ConvertPEER_ENDPOINTToPeerEndPoint(PEER_ENDPOINT):PeerEndPoint" Ring="1" />
- // </SecurityKernel>
- [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
- //
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="Marshal.Copy(System.IntPtr,System.Byte[],System.Int32,System.Int32):System.Void" />
- // </SecurityKernel>
- [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
- //
-
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="Marshal.Copy(System.IntPtr,System.Byte[],System.Int32,System.Int32):System.Void" />
- // <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
- // </SecurityKernel>
- [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
- //
-
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
- // </SecurityKernel>
- [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.
- //
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
- // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
- // <ReferencesCritical Name="Parameter safeEvent of type: SafeCollabEvent" Ring="1" />
- // </SecurityKernel>
- [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;
- }
- }
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
- // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabRegisterEvent(Microsoft.Win32.SafeHandles.SafeWaitHandle,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_COLLAB_EVENT_REGISTRATION&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&):System.Int32" />
- // <ReferencesCritical Name="Parameter safePresenceChangedEvent of type: SafeCollabEvent" Ring="1" />
- // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
- // </SecurityKernel>
- [System.Security.SecurityCritical]
- internal static void AddMyPresenceChanged(EventHandler<PresenceChangedEventArgs> callback,
- ref EventHandler<PresenceChangedEventArgs> 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.");
- }
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
- // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabRegisterEvent(Microsoft.Win32.SafeHandles.SafeWaitHandle,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_COLLAB_EVENT_REGISTRATION&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&):System.Int32" />
- // <ReferencesCritical Name="Parameter safeAppChangedEvent of type: SafeCollabEvent" Ring="1" />
- // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
- // </SecurityKernel>
- [System.Security.SecurityCritical]
- internal static void AddMyApplicationChanged(EventHandler<ApplicationChangedEventArgs> callback,
- ref EventHandler<ApplicationChangedEventArgs> 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.");
- }
- // <SecurityKernel Critical="True" Ring="0">
- // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
- // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabRegisterEvent(Microsoft.Win32.SafeHandles.SafeWaitHandle,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_COLLAB_EVENT_REGISTRATION&,System.Net.PeerToPeer.Collaboration.SafeCollabEvent&):System.Int32" />
- // <ReferencesCritical Name="Parameter safeObjChangedEvent of type: SafeCollabEvent" Ring="1" />
- // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
- // </SecurityKernel>
- [System.Security.SecurityCritical]
- internal static void AddMyObjectChanged(EventHandler<ObjectChangedEventArgs> callback,
- ref EventHandler<ObjectChangedEventArgs> 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));
- }
- }
- }
- }