PageRenderTime 54ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/mcs/class/referencesource/System.Net/net/PeerToPeer/Collaboration/CollaborationHelperFunctions.cs

https://github.com/pruiz/mono
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
  1. //------------------------------------------------------------------------------
  2. // <copyright file="CollaborationHelperFunctions.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. //------------------------------------------------------------------------------
  6. using System.Security.Permissions;
  7. namespace System.Net.PeerToPeer.Collaboration
  8. {
  9. using System;
  10. using System.Collections.ObjectModel;
  11. using System.Runtime.InteropServices;
  12. using System.Net.Mail;
  13. using System.Security.Cryptography.X509Certificates;
  14. using System.Diagnostics;
  15. using System.Threading;
  16. /// <summary>
  17. /// This class contains some of the common functions needed for peer
  18. /// collaboration
  19. /// </summary>
  20. internal static class CollaborationHelperFunctions
  21. {
  22. private static volatile bool s_Initialized;
  23. private static object s_LockInitialized = new object();
  24. private const short c_CollabVersion = 0x0001;
  25. //
  26. // Initialise windows collab. This has to be called before any collab operation
  27. //
  28. // <SecurityKernel Critical="True" Ring="0">
  29. // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.PeerCollabStartup(System.Int16):System.Int32" />
  30. // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
  31. // </SecurityKernel>
  32. [System.Security.SecurityCritical]
  33. internal static void Initialize()
  34. {
  35. if (!s_Initialized){
  36. lock (s_LockInitialized){
  37. if (!s_Initialized){
  38. if(!PeerToPeerOSHelper.SupportsP2P)
  39. throw new PlatformNotSupportedException(SR.GetString(SR.P2P_NotAvailable));
  40. int errorCode = UnsafeCollabNativeMethods.PeerCollabStartup(c_CollabVersion);
  41. if (errorCode != 0){
  42. Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabStartup returned with errorcode {0}", errorCode);
  43. throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_StartupFailed), errorCode);
  44. }
  45. s_Initialized = true;
  46. }
  47. }
  48. }
  49. }
  50. //
  51. // Converts Guid class to GUID structure that we can pass into native
  52. //
  53. internal static GUID ConvertGuidToGUID(Guid guid)
  54. {
  55. GUID newGuid = new GUID();
  56. if (guid != null){
  57. byte[] guidBytes = guid.ToByteArray();
  58. string guidString = guid.ToString();
  59. int startVal = 0;
  60. int endVal = guidString.IndexOf('-');
  61. newGuid.data1 = (uint)(Convert.ToUInt32(guidString.Substring(startVal, endVal - startVal), 16));
  62. startVal = endVal + 1;
  63. endVal = guidString.IndexOf('-', endVal + 1);
  64. newGuid.data2 = (ushort)(Convert.ToUInt16(guidString.Substring(startVal, endVal - startVal), 16));
  65. startVal = endVal + 1;
  66. endVal = guidString.IndexOf('-', endVal + 1);
  67. newGuid.data3 = (ushort)(Convert.ToUInt16(guidString.Substring(startVal, endVal - startVal), 16));
  68. newGuid.data4 = guidBytes[8];
  69. newGuid.data5 = guidBytes[9];
  70. newGuid.data6 = guidBytes[10];
  71. newGuid.data7 = guidBytes[11];
  72. newGuid.data8 = guidBytes[12];
  73. newGuid.data9 = guidBytes[13];
  74. newGuid.data10 = guidBytes[14];
  75. newGuid.data11 = guidBytes[15];
  76. }
  77. return newGuid;
  78. }
  79. //
  80. // Converts native GUID structure to managed Guid class
  81. //
  82. internal static Guid ConvertGUIDToGuid(GUID guid)
  83. {
  84. byte[] bytes = new byte[8];
  85. bytes[0] = guid.data4;
  86. bytes[1] = guid.data5;
  87. bytes[2] = guid.data6;
  88. bytes[3] = guid.data7;
  89. bytes[4] = guid.data8;
  90. bytes[5] = guid.data9;
  91. bytes[6] = guid.data10;
  92. bytes[7] = guid.data11;
  93. return new Guid((int)guid.data1, (short)guid.data2, (short)guid.data3, bytes);
  94. }
  95. //
  96. // Converts native PEER_CONTACT to PeerContact class
  97. //
  98. // <SecurityKernel Critical="True" Ring="1">
  99. // <ReferencesCritical Name="Method: ConvertPEER_CONTACTToPeerContact(PEER_CONTACT, Boolean):PeerContact" Ring="1" />
  100. // </SecurityKernel>
  101. [System.Security.SecurityCritical]
  102. internal static PeerContact ConvertPEER_CONTACTToPeerContact(PEER_CONTACT pc)
  103. {
  104. return ConvertPEER_CONTACTToPeerContact(pc, false);
  105. }
  106. // <SecurityKernel Critical="True" Ring="0">
  107. // <SatisfiesLinkDemand Name="Marshal.Copy(System.IntPtr,System.Byte[],System.Int32,System.Int32):System.Void" />
  108. // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
  109. // <SatisfiesLinkDemand Name="Marshal.GetLastWin32Error():System.Int32" />
  110. // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
  111. // <SatisfiesLinkDemand Name="X509Store..ctor(System.IntPtr)" />
  112. // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
  113. // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.CertOpenStore(System.IntPtr,System.UInt32,System.IntPtr,System.UInt32,System.Net.PeerToPeer.Collaboration.PEER_DATA&):System.Net.PeerToPeer.Collaboration.SafeCertStore" />
  114. // <ReferencesCritical Name="Local certHandle of type: SafeCertStore" Ring="1" />
  115. // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
  116. // <ReferencesCritical Name="Method: PeerContact..ctor()" Ring="2" />
  117. // <ReferencesCritical Name="Method: MyContact..ctor()" Ring="3" />
  118. // </SecurityKernel>
  119. [System.Security.SecurityCritical]
  120. internal static PeerContact ConvertPEER_CONTACTToPeerContact(PEER_CONTACT pc, bool isMyContact)
  121. {
  122. PeerContact peerContact = (isMyContact ? new MyContact(): new PeerContact());
  123. peerContact.PeerName = new PeerName(pc.pwzPeerName);
  124. peerContact.DisplayName = pc.pwzDisplayName;
  125. peerContact.Nickname = pc.pwzNickname;
  126. peerContact.EmailAddress = (pc.pwzEmailAddress != null) ? new MailAddress(pc.pwzEmailAddress) : null;
  127. if(!isMyContact)
  128. peerContact.SubscribeAllowed = pc.WatcherPermissions;
  129. peerContact.IsSubscribed = (isMyContact ? true : pc.fWatch);
  130. byte[] data = null;
  131. if (pc.credentials.cbData != 0){
  132. data = new byte[pc.credentials.cbData];
  133. Marshal.Copy(pc.credentials.pbData, data, 0, (int)pc.credentials.cbData);
  134. }
  135. if (data != null){
  136. SafeCertStore certHandle = UnsafeCollabNativeMethods.CertOpenStore(new IntPtr(/*CERT_STORE_PROV_PKCS7*/ 5),
  137. 0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/,
  138. IntPtr.Zero,
  139. 0x00000001/*CERT_STORE_NO_CRYPT_RELEASE_FLAG*/,
  140. ref pc.credentials);
  141. if (certHandle == null || certHandle.IsInvalid){
  142. int win32ErrorCode = Marshal.GetLastWin32Error();
  143. throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_CredentialsError), win32ErrorCode);
  144. }
  145. try{
  146. X509Store certStore = new X509Store(certHandle.DangerousGetHandle());
  147. peerContact.Credentials = new X509Certificate2(certStore.Certificates[0]);
  148. }
  149. finally{
  150. if(certHandle != null) certHandle.Dispose();
  151. }
  152. }
  153. return peerContact;
  154. }
  155. // <SecurityKernel Critical="True" Ring="0">
  156. // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
  157. // <SatisfiesLinkDemand Name="Marshal.GetLastWin32Error():System.Int32" />
  158. // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
  159. // <SatisfiesLinkDemand Name="X509Store..ctor(System.IntPtr)" />
  160. // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
  161. // <CallsSuppressUnmanagedCode Name="UnsafeCollabNativeMethods.CertOpenStore(System.IntPtr,System.UInt32,System.IntPtr,System.UInt32,System.IntPtr):System.Net.PeerToPeer.Collaboration.SafeCertStore" />
  162. // <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" />
  163. // <ReferencesCritical Name="Local certHandle of type: SafeCertStore" Ring="1" />
  164. // <ReferencesCritical Name="Parameter safeCredentials of type: SafeCollabMemory" Ring="1" />
  165. // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
  166. // <ReferencesCritical Name="Method: SafeCollabMemory..ctor(System.Int32)" Ring="1" />
  167. // </SecurityKernel>
  168. [System.Security.SecurityCritical]
  169. internal static PEER_CONTACT ConvertPeerContactToPEER_CONTACT(PeerContact peerContact, ref SafeCollabMemory safeCredentials)
  170. {
  171. PEER_CONTACT pc = new PEER_CONTACT();
  172. pc.pwzDisplayName = peerContact.DisplayName;
  173. pc.pwzEmailAddress = (peerContact.EmailAddress == null) ? null : peerContact.EmailAddress.ToString();
  174. pc.pwzNickname = peerContact.Nickname;
  175. pc.pwzPeerName = peerContact.PeerName.ToString();
  176. pc.fWatch = peerContact.IsSubscribed;
  177. pc.WatcherPermissions = peerContact.SubscribeAllowed;
  178. PEER_DATA pd = new PEER_DATA();
  179. if (peerContact.Credentials != null){
  180. SafeCertStore certHandle = UnsafeCollabNativeMethods.CertOpenStore(new IntPtr(/*CERT_STORE_PROV_MEMORY*/ 2),
  181. 0,
  182. IntPtr.Zero,
  183. 0x00002000/*CERT_STORE_CREATE_NEW_FLAG*/ | 0x00000001/*CERT_STORE_NO_CRYPT_RELEASE_FLAG*/,
  184. IntPtr.Zero);
  185. if (certHandle == null || certHandle.IsInvalid){
  186. int win32ErrorCode = Marshal.GetLastWin32Error();
  187. throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_CredentialsError), win32ErrorCode);
  188. }
  189. try{
  190. X509Store certStore = new X509Store(certHandle.DangerousGetHandle());
  191. certStore.Add(peerContact.Credentials as X509Certificate2);
  192. bool returnCode = UnsafeCollabNativeMethods.CertSaveStore(certHandle,
  193. 0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/,
  194. 2 /*CERT_STORE_SAVE_AS_STORE*/,
  195. 2, /*CERT_STORE_SAVE_TO_MEMORY*/
  196. ref pd,
  197. 0);
  198. if ((pd.cbData != 0) && (returnCode)){
  199. safeCredentials = new SafeCollabMemory((int)pd.cbData);
  200. pd.pbData = safeCredentials.DangerousGetHandle();
  201. returnCode = UnsafeCollabNativeMethods.CertSaveStore(certHandle,
  202. 0x00000001/*X509_ASN_ENCODING*/| 0x00010000/*PKCS_7_ASN_ENCODING*/,
  203. 2 /*CERT_STORE_SAVE_AS_STORE*/,
  204. 2, /*CERT_STORE_SAVE_TO_MEMORY*/
  205. ref pd,// Clean up memory from here;
  206. 0);
  207. }
  208. else{
  209. pd.cbData = 0;
  210. pd.pbData = IntPtr.Zero;
  211. }
  212. }
  213. finally{
  214. if (certHandle != null) certHandle.Dispose();
  215. }
  216. }
  217. else{
  218. pd.cbData = 0;
  219. pd.pbData = IntPtr.Zero;
  220. }
  221. pc.credentials = pd;
  222. return pc;
  223. }
  224. //
  225. // Converts address bytes to a SOCKADDR_IN6 that can be passed into
  226. // native
  227. //
  228. internal static void ByteArrayToSin6Addr(byte[] addrBytes, ref SOCKADDR_IN6 sin6)
  229. {
  230. sin6.sin6_addr0 = addrBytes[0];
  231. sin6.sin6_addr1 = addrBytes[1];
  232. sin6.sin6_addr2 = addrBytes[2];
  233. sin6.sin6_addr3 = addrBytes[3];
  234. sin6.sin6_addr4 = addrBytes[4];
  235. sin6.sin6_addr5 = addrBytes[5];
  236. sin6.sin6_addr6 = addrBytes[6];
  237. sin6.sin6_addr7 = addrBytes[7];
  238. sin6.sin6_addr8 = addrBytes[8];
  239. sin6.sin6_addr9 = addrBytes[9];
  240. sin6.sin6_addr10 = addrBytes[10];
  241. sin6.sin6_addr11 = addrBytes[11];
  242. sin6.sin6_addr12 = addrBytes[12];
  243. sin6.sin6_addr13 = addrBytes[13];
  244. sin6.sin6_addr14 = addrBytes[14];
  245. sin6.sin6_addr15 = addrBytes[15];
  246. }
  247. //
  248. // Converts native structure PEER_PEOPLE_NEAR_ME to managed PeerNearMe class
  249. //
  250. // <SecurityKernel Critical="True" Ring="0">
  251. // <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
  252. // <ReferencesCritical Name="Method: ConvertPEER_ENDPOINTToPeerEndPoint(PEER_ENDPOINT):PeerEndPoint" Ring="1" />
  253. // </SecurityKernel>
  254. [System.Security.SecurityCritical]
  255. internal static PeerNearMe PEER_PEOPLE_NEAR_METoPeerNearMe(PEER_PEOPLE_NEAR_ME ppnm)
  256. {
  257. PeerNearMe peerNearMe = new PeerNearMe();
  258. peerNearMe.Id = CollaborationHelperFunctions.ConvertGUIDToGuid(ppnm.id);
  259. peerNearMe.Nickname = Marshal.PtrToStringUni(ppnm.pwzNickname); ;
  260. PEER_ENDPOINT pe = ppnm.endpoint;
  261. PeerEndPoint peerEP = ConvertPEER_ENDPOINTToPeerEndPoint(pe);
  262. peerNearMe.PeerEndPoints.Add(peerEP);
  263. return peerNearMe;
  264. }
  265. //
  266. // Converts native PEER_OBJECT structure into PeerObject class
  267. //
  268. // <SecurityKernel Critical="True" Ring="0">
  269. // <SatisfiesLinkDemand Name="Marshal.Copy(System.IntPtr,System.Byte[],System.Int32,System.Int32):System.Void" />
  270. // </SecurityKernel>
  271. [System.Security.SecurityCritical]
  272. internal static PeerObject ConvertPEER_OBJECTToPeerObject(PEER_OBJECT po)
  273. {
  274. byte[] data = null;
  275. if (po.data.cbData != 0){
  276. data = new byte[po.data.cbData];
  277. Marshal.Copy(po.data.pbData, data, 0, (int)po.data.cbData);
  278. }
  279. return new PeerObject(ConvertGUIDToGuid(po.guid), data, (PeerScope)po.dwPublicationScope);
  280. }
  281. //
  282. // Converts native PEER_APPLICATION structure into PeerApplication class
  283. //
  284. // <SecurityKernel Critical="True" Ring="0">
  285. // <SatisfiesLinkDemand Name="Marshal.Copy(System.IntPtr,System.Byte[],System.Int32,System.Int32):System.Void" />
  286. // <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
  287. // </SecurityKernel>
  288. [System.Security.SecurityCritical]
  289. internal static PeerApplication ConvertPEER_APPLICATIONToPeerApplication(PEER_APPLICATION pa)
  290. {
  291. byte[] data = null;
  292. if (pa.data.cbData != 0){
  293. data = new byte[pa.data.cbData];
  294. Marshal.Copy(pa.data.pbData, data, 0, (int)pa.data.cbData);
  295. }
  296. return new PeerApplication( ConvertGUIDToGuid(pa.guid),
  297. Marshal.PtrToStringUni(pa.pwzDescription),
  298. data,
  299. null, null, PeerScope.None);
  300. }
  301. //
  302. // Converts native PEER_ENDPOINT structure into PeerEndPoint class
  303. //
  304. // <SecurityKernel Critical="True" Ring="0">
  305. // <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
  306. // </SecurityKernel>
  307. [System.Security.SecurityCritical]
  308. internal static PeerEndPoint ConvertPEER_ENDPOINTToPeerEndPoint(PEER_ENDPOINT pe)
  309. {
  310. byte[] addrBytes = new byte[]{ pe.peerAddress.sin6.sin6_addr0, pe.peerAddress.sin6.sin6_addr1,
  311. pe.peerAddress.sin6.sin6_addr2, pe.peerAddress.sin6.sin6_addr3,
  312. pe.peerAddress.sin6.sin6_addr4, pe.peerAddress.sin6.sin6_addr5,
  313. pe.peerAddress.sin6.sin6_addr6, pe.peerAddress.sin6.sin6_addr7,
  314. pe.peerAddress.sin6.sin6_addr8, pe.peerAddress.sin6.sin6_addr9,
  315. pe.peerAddress.sin6.sin6_addr10, pe.peerAddress.sin6.sin6_addr11,
  316. pe.peerAddress.sin6.sin6_addr12, pe.peerAddress.sin6.sin6_addr13,
  317. pe.peerAddress.sin6.sin6_addr14, pe.peerAddress.sin6.sin6_addr15};
  318. IPAddress IPAddr = new IPAddress(addrBytes, (long)pe.peerAddress.sin6.sin6_scope_id);
  319. ushort port;
  320. unchecked{
  321. port = (ushort)IPAddress.NetworkToHostOrder((short)pe.peerAddress.sin6.sin6_port);
  322. }
  323. IPEndPoint IPEndPt = new IPEndPoint(IPAddr, port);
  324. return new PeerEndPoint(IPEndPt, Marshal.PtrToStringUni(pe.pwzEndpointName));
  325. }
  326. //
  327. // Converts IPEndpoint class into native PEER_ADDRESS structure
  328. //
  329. internal static PEER_ADDRESS ConvertIPEndpointToPEER_ADDRESS(IPEndPoint endPoint)
  330. {
  331. PEER_ADDRESS pa = new PEER_ADDRESS();
  332. SOCKADDR_IN6 sin = new SOCKADDR_IN6();
  333. sin.sin6_family = (ushort)endPoint.AddressFamily;
  334. sin.sin6_flowinfo = 0; //
  335. unchecked{
  336. sin.sin6_port = (ushort)IPAddress.HostToNetworkOrder((short)endPoint.Port);
  337. }
  338. sin.sin6_scope_id = (uint)endPoint.Address.ScopeId;
  339. CollaborationHelperFunctions.ByteArrayToSin6Addr(endPoint.Address.GetAddressBytes(), ref sin);
  340. pa.dwSize = 32;
  341. pa.sin6 = sin;
  342. return pa;
  343. }
  344. //
  345. // Cleans up the registered handle and the wait event. Called under lock from events.
  346. //
  347. // <SecurityKernel Critical="True" Ring="0">
  348. // <SatisfiesLinkDemand Name="SafeHandle.get_IsInvalid():System.Boolean" />
  349. // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
  350. // <ReferencesCritical Name="Parameter safeEvent of type: SafeCollabEvent" Ring="1" />
  351. // </SecurityKernel>
  352. [System.Security.SecurityCritical]
  353. [SecurityPermissionAttribute(SecurityAction.LinkDemand, UnmanagedCode = true)]
  354. internal static void CleanEventVars(ref RegisteredWaitHandle waitHandle,
  355. ref SafeCollabEvent safeEvent,
  356. ref AutoResetEvent firedEvent)
  357. {
  358. if (waitHandle != null){
  359. waitHandle.Unregister(null);
  360. waitHandle = null;
  361. }
  362. if ((safeEvent != null) && (!safeEvent.IsInvalid)){
  363. safeEvent.Dispose();
  364. }
  365. if (firedEvent != null){
  366. firedEvent.Close();
  367. firedEvent = null;
  368. }
  369. }
  370. // <SecurityKernel Critical="True" Ring="0">
  371. // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
  372. // <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" />
  373. // <ReferencesCritical Name="Parameter safePresenceChangedEvent of type: SafeCollabEvent" Ring="1" />
  374. // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
  375. // </SecurityKernel>
  376. [System.Security.SecurityCritical]
  377. internal static void AddMyPresenceChanged(EventHandler<PresenceChangedEventArgs> callback,
  378. ref EventHandler<PresenceChangedEventArgs> presenceChanged,
  379. object lockPresenceChangedEvent,
  380. ref RegisteredWaitHandle regPresenceChangedWaitHandle,
  381. ref AutoResetEvent presenceChangedEvent,
  382. ref SafeCollabEvent safePresenceChangedEvent,
  383. WaitOrTimerCallback PresenceChangedCallback)
  384. {
  385. //
  386. // Register a wait handle if one has not been registered already
  387. //
  388. lock (lockPresenceChangedEvent){
  389. if (presenceChanged == null){
  390. presenceChangedEvent = new AutoResetEvent(false);
  391. //
  392. // Register callback with a wait handle
  393. //
  394. regPresenceChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(presenceChangedEvent, //Event that triggers the callback
  395. PresenceChangedCallback, //callback to be called
  396. null, //state to be passed
  397. -1, //Timeout - aplicable only for timers
  398. false //call us everytime the event is set
  399. );
  400. PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
  401. pcer.eventType = PeerCollabEventType.MyPresenceChanged;
  402. pcer.pInstance = IntPtr.Zero;
  403. //
  404. // Register event with collab
  405. //
  406. int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
  407. presenceChangedEvent.SafeWaitHandle,
  408. 1,
  409. ref pcer,
  410. out safePresenceChangedEvent);
  411. if (errorCode != 0){
  412. Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
  413. throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_PresenceChangedRegFailed), errorCode);
  414. }
  415. }
  416. presenceChanged += callback;
  417. }
  418. Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddMyPresenceChanged() successful.");
  419. }
  420. // <SecurityKernel Critical="True" Ring="0">
  421. // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
  422. // <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" />
  423. // <ReferencesCritical Name="Parameter safeAppChangedEvent of type: SafeCollabEvent" Ring="1" />
  424. // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
  425. // </SecurityKernel>
  426. [System.Security.SecurityCritical]
  427. internal static void AddMyApplicationChanged(EventHandler<ApplicationChangedEventArgs> callback,
  428. ref EventHandler<ApplicationChangedEventArgs> applicationChanged,
  429. object lockAppChangedEvent,
  430. ref RegisteredWaitHandle regAppChangedWaitHandle,
  431. ref AutoResetEvent appChangedEvent,
  432. ref SafeCollabEvent safeAppChangedEvent,
  433. WaitOrTimerCallback ApplicationChangedCallback)
  434. {
  435. //
  436. // Register a wait handle if one has not been registered already
  437. //
  438. lock (lockAppChangedEvent){
  439. if (applicationChanged == null){
  440. appChangedEvent = new AutoResetEvent(false);
  441. //
  442. // Register callback with a wait handle
  443. //
  444. regAppChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(appChangedEvent, //Event that triggers the callback
  445. ApplicationChangedCallback, //callback to be called
  446. null, //state to be passed
  447. -1, //Timeout - aplicable only for timers
  448. false //call us everytime the event is set
  449. );
  450. PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
  451. pcer.eventType = PeerCollabEventType.MyApplicationChanged;
  452. pcer.pInstance = IntPtr.Zero;
  453. //
  454. // Register event with collab
  455. //
  456. int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
  457. appChangedEvent.SafeWaitHandle,
  458. 1,
  459. ref pcer,
  460. out safeAppChangedEvent);
  461. if (errorCode != 0){
  462. Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
  463. throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ApplicationChangedRegFailed), errorCode);
  464. }
  465. }
  466. applicationChanged += callback;
  467. }
  468. Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddApplicationChanged() successful.");
  469. }
  470. // <SecurityKernel Critical="True" Ring="0">
  471. // <SatisfiesLinkDemand Name="WaitHandle.get_SafeWaitHandle():Microsoft.Win32.SafeHandles.SafeWaitHandle" />
  472. // <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" />
  473. // <ReferencesCritical Name="Parameter safeObjChangedEvent of type: SafeCollabEvent" Ring="1" />
  474. // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
  475. // </SecurityKernel>
  476. [System.Security.SecurityCritical]
  477. internal static void AddMyObjectChanged(EventHandler<ObjectChangedEventArgs> callback,
  478. ref EventHandler<ObjectChangedEventArgs> objectChanged,
  479. object lockObjChangedEvent,
  480. ref RegisteredWaitHandle regObjChangedWaitHandle,
  481. ref AutoResetEvent objChangedEvent,
  482. ref SafeCollabEvent safeObjChangedEvent,
  483. WaitOrTimerCallback ObjectChangedCallback)
  484. {
  485. //
  486. // Register a wait handle if one has not been registered already
  487. //
  488. lock (lockObjChangedEvent){
  489. if (objectChanged == null){
  490. objChangedEvent = new AutoResetEvent(false);
  491. //
  492. // Register callback with a wait handle
  493. //
  494. regObjChangedWaitHandle = ThreadPool.RegisterWaitForSingleObject(objChangedEvent, //Event that triggers the callback
  495. ObjectChangedCallback, //callback to be called
  496. null, //state to be passed
  497. -1, //Timeout - aplicable only for timers
  498. false //call us everytime the event is set
  499. );
  500. PEER_COLLAB_EVENT_REGISTRATION pcer = new PEER_COLLAB_EVENT_REGISTRATION();
  501. pcer.eventType = PeerCollabEventType.MyObjectChanged;
  502. pcer.pInstance = IntPtr.Zero;
  503. //
  504. // Register event with collab
  505. //
  506. int errorCode = UnsafeCollabNativeMethods.PeerCollabRegisterEvent(
  507. objChangedEvent.SafeWaitHandle,
  508. 1,
  509. ref pcer,
  510. out safeObjChangedEvent);
  511. if (errorCode != 0){
  512. Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "PeerCollabRegisterEvent returned with errorcode {0}", errorCode);
  513. throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Collab_ObjectChangedRegFailed), errorCode);
  514. }
  515. }
  516. objectChanged += callback;
  517. }
  518. Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "AddObjectChanged() successful.");
  519. }
  520. internal static void ThrowIfInvitationResponseInvalid(PeerInvitationResponse response)
  521. {
  522. // throw an exception if the response from the native API was PEER_INVITATION_RESPONSE_ERROR
  523. if (response.PeerInvitationResponseType < PeerInvitationResponseType.Declined ||
  524. response.PeerInvitationResponseType > PeerInvitationResponseType.Expired)
  525. {
  526. throw new PeerToPeerException(SR.GetString(SR.Collab_InviteFailed));
  527. }
  528. }
  529. }
  530. }