File: Cloud.cs

package info (click to toggle)
mono 6.12.0.199%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,296,836 kB
  • sloc: cs: 11,181,803; xml: 2,850,076; ansic: 699,709; cpp: 123,344; perl: 59,361; javascript: 30,841; asm: 21,853; makefile: 20,405; sh: 15,009; python: 4,839; pascal: 925; sql: 859; sed: 16; php: 1
file content (362 lines) | stat: -rw-r--r-- 15,260 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
//------------------------------------------------------------------------------
// <copyright file="Cloud.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Net.PeerToPeer
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.Serialization;
    using System.Security.Permissions;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    
    /// <remarks>
    /// The Cloud class directly represents the native cloud concept in the P2P APIs
    /// There are two special static readonly members we support
    /// Cloud.All and Cloud.AllLinkLocal
    /// Cloud.All is really a notational convinience of null in the native world
    /// Cloud.AllLinkLocal is equivalent to PEER_PNRP_ALL_LINK_CLOUDS const in the header file (declared in p2p.h)
    /// 
    /// This class is serializable.
    /// This class is not sealed because there is no reason for it to be sealed. 
    /// </remarks>
    /// <




    [Serializable]
    public class Cloud : ISerializable, IEquatable<Cloud>
    {
        private const string PEER_PNRP_ALL_LINK_CLOUDS = "PEER_PNRP_ALL_LINKS";

        private string m_CloudName; //name of the cloud
        private PnrpScope m_PnrpScope; //scope of the cloud
        private int m_ScopeId; //scope Id of the scope 

        /// <summary>
        /// Cloud.AllAvailable is a notational convinience. The native side uses a null for cloud parameter
        /// to indicate all clouds. 
        /// </summary>
        public static readonly Cloud Available = new Cloud("AllAvailable", PnrpScope.All, -1);

        /// <summary>
        /// AllLinkLocal is a managed abstraction of the native const PEER_PNRP_ALL_LINK_CLOUDS
        /// </summary>
        public static readonly Cloud AllLinkLocal = new Cloud("AllLinkLocal", PnrpScope.LinkLocal, -1);

        /// <summary>
        /// The static constructor serves the purpose of checking the 
        /// availability of the P2P apis on this platform
        /// </summary>
        static Cloud()
        {
            //-------------------------------------------------
            //Check for the availability of the simpler PNRP APIs
            //-------------------------------------------------
            if (!PeerToPeerOSHelper.SupportsP2P)
            {
                throw new PlatformNotSupportedException(SR.GetString(SR.P2P_NotAvailable));
            }
        }


        /// <summary>
        /// Constructs an instance of a Cloud. 
        /// This is not public and accessible for internal members only
        /// </summary>
        /// <param name="name">Name of the cloud</param>
        /// <param name="pnrpScope">scope</param>
        /// <param name="scopeId">id ofthe scope</param>
        internal Cloud(string name, PnrpScope pnrpScope, int scopeId) {
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Creating cloud with Name: {0}, PnrpScope: {1}, ScopeID: {2}", name, pnrpScope, scopeId);
            m_CloudName = name;
            m_PnrpScope = pnrpScope;
            m_ScopeId = scopeId;
        }

        /// <summary>
        ///     Name 
        /// </summary>
        public string Name {
            get {
                if (this == Cloud.AllLinkLocal || this == Cloud.Available)
                    return null;
                return m_CloudName;
            }
        }

        internal string InternalName
        {
            get
            {
                if (this == Cloud.AllLinkLocal)
                    return  PEER_PNRP_ALL_LINK_CLOUDS;
                else if (this == Cloud.Available)
                    return null;
                return m_CloudName;
            }
        }

        /// <summary>
        ///     Scope
        /// </summary>
        public PnrpScope Scope {
            get {
                return m_PnrpScope;
            }
        }

        /// <summary>
        ///     ScopeId
        /// </summary>
        public int ScopeId {
            get {
                return m_ScopeId;
            }
        }

        public static Cloud Global
        {
            // <SecurityKernel Critical="True" Ring="1">
            // <ReferencesCritical Name="Method: GetCloudOrClouds(String, Boolean, CloudCollection&, Cloud&):Void" Ring="1" />
            // </SecurityKernel>
            //[System.Security.SecurityCritical]
            get
            {
                //throw new PeerToPeerException(SR.GetString(SR.Collab_SubscribeLocalContactFailed));
                CloudCollection dummy = null;
                Cloud cloud = null;
                GetCloudOrClouds(null, true, out dummy, out cloud);
                return cloud;
            }
        }


        // <SecurityKernel Critical="True" Ring="1">
        // <ReferencesCritical Name="Method: GetCloudOrClouds(String, Boolean, CloudCollection&, Cloud&):Void" Ring="1" />
        // </SecurityKernel>
        //[System.Security.SecurityCritical]
        public static Cloud GetCloudByName(string cloudName)
        {
            if (cloudName == null || cloudName.Length == 0)
            {
                throw new ArgumentException(SR.GetString(SR.Pnrp_CloudNameCantBeNull), "cloudName");
            }
            CloudCollection dummy = null;
            Cloud cloud = null;
            GetCloudOrClouds(cloudName, false, out dummy, out cloud);
            return cloud;
        }

        /// <summary>
        /// The static member returns the list of clouds
        /// </summary>
        /// <returns></returns>
        // <SecurityKernel Critical="True" Ring="1">
        // <ReferencesCritical Name="Method: GetCloudOrClouds(String, Boolean, CloudCollection&, Cloud&):Void" Ring="1" />
        // </SecurityKernel>
        //[System.Security.SecurityCritical]
        public static CloudCollection GetAvailableClouds()
        {
            CloudCollection clouds = null;
            Cloud dummy = null;
            GetCloudOrClouds(null, false, out clouds, out dummy);
            return clouds;
        }

        // <SecurityKernel Critical="True" Ring="0">
        // <CallsSuppressUnmanagedCode Name="UnsafeP2PNativeMethods.PeerPnrpGetCloudInfo(System.UInt32&,System.Net.PeerToPeer.SafePeerData&):System.Int32" />
        // <SatisfiesLinkDemand Name="SafeHandle.DangerousGetHandle():System.IntPtr" />
        // <SatisfiesLinkDemand Name="Marshal.PtrToStructure(System.IntPtr,System.Type):System.Object" />
        // <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
        // <SatisfiesLinkDemand Name="Marshal.SizeOf(System.Type):System.Int32" />
        // <SatisfiesLinkDemand Name="SafeHandle.Dispose():System.Void" />
        // <ReferencesCritical Name="Local ArrayOfCloudInfoStructures of type: SafePeerData" Ring="1" />
        // <ReferencesCritical Name="Method: UnsafeP2PNativeMethods.PnrpStartup():System.Void" Ring="1" />
        // <ReferencesCritical Name="Method: PeerToPeerException.CreateFromHr(System.String,System.Int32):System.Net.PeerToPeer.PeerToPeerException" Ring="1" />
        // </SecurityKernel>
        [SuppressMessage("Microsoft.Security","CA2129:SecurityTransparentCodeShouldNotReferenceNonpublicSecurityCriticalCode", Justification="System.Net.dll is still using pre-v4 security model and needs this demand")]
        [System.Security.SecuritySafeCritical]
        private static void GetCloudOrClouds(string cloudName, bool bGlobalCloudOnly,  out CloudCollection clouds, out Cloud cloud)
        {
            cloud = null;
            clouds = null;

            Logging.Enter(Logging.P2PTraceSource, "Cloud::GetCloudOrClouds()");

            //-------------------------------------------------
            //Demand for the Unrestricted Pnrp Permission
            //-------------------------------------------------
            PnrpPermission.UnrestrictedPnrpPermission.Demand();

            Int32 result = 0;
            UInt32 numClouds = 0;
            SafePeerData ArrayOfCloudInfoStructures = null;
            if (cloudName == null)
            {
                //-----------------------------------------
                //We need the collection only when we are not 
                //getting a specific cloud
                //-----------------------------------------
                clouds = new CloudCollection();
            }
            try
            {
                //---------------------------------------------------------------
                //No perf hit here, real native call happens only one time if it 
                //did not already happen
                //---------------------------------------------------------------
                UnsafeP2PNativeMethods.PnrpStartup();

                result = UnsafeP2PNativeMethods.PeerPnrpGetCloudInfo(out numClouds, out ArrayOfCloudInfoStructures);
                if (result != 0)
                {
                    throw PeerToPeerException.CreateFromHr(SR.GetString(SR.Pnrp_CouldNotEnumerateClouds), result);
                }
                if (numClouds != 0)
                {
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "Number of clouds returned {0}", numClouds);
                    IntPtr pPEER_PNRP_CLOUD_INFO = ArrayOfCloudInfoStructures.DangerousGetHandle();
                    for (ulong i = 0; i < numClouds; i++)
                    {
                        PEER_PNRP_CLOUD_INFO cloudinfo = (PEER_PNRP_CLOUD_INFO)Marshal.PtrToStructure(pPEER_PNRP_CLOUD_INFO, typeof(PEER_PNRP_CLOUD_INFO));
                        string nativeCloudName = Marshal.PtrToStringUni(cloudinfo.pwzCloudName);
                        pPEER_PNRP_CLOUD_INFO = (IntPtr)((long)pPEER_PNRP_CLOUD_INFO + Marshal.SizeOf(typeof(PEER_PNRP_CLOUD_INFO)));
                        Cloud c = new Cloud(nativeCloudName, (PnrpScope)((int)cloudinfo.dwScope), (int)cloudinfo.dwScopeId);
                        if (cloudName == null && !bGlobalCloudOnly)
                        {
                            clouds.Add(c);
                            continue;
                        }
                        //If a specific cloud by name is required, then test for name
                        //note that scope is PnrpScope.All but we don't test that now
                        if (cloudName != null && cloudName == nativeCloudName)
                        {
                            cloud = c;
                            break;
                        }

                         if (bGlobalCloudOnly && c.Scope == PnrpScope.Global)
                        {
                            cloud = c;
                            break;
                        }
                    }
                }
                else
                {
                    Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0, "No Clouds returned from the native call");
                }
            }
            finally
            {
                if (ArrayOfCloudInfoStructures != null)
                {
                    ArrayOfCloudInfoStructures.Dispose();
                }
            }
            if (cloudName != null && cloud == null)
            {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Information, 0, "The specific cloud name {0} asked for is not found", cloudName);
            }
            Logging.Leave(Logging.P2PTraceSource, "Cloud::GetCloudOrClouds()");
        }






        /// <summary>
        /// Two Clouds are equal only when all of the information matches
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public bool Equals(Cloud other)
        {
            if (other == null) return false;
            return other.Name == Name && other.Scope == Scope && other.ScopeId == ScopeId;
        }

        public override bool Equals(object obj)
        {
            if (obj == null) return false;
            Cloud other = obj as Cloud;
            if (other == null)
                return false;
            return Equals(other);
            
        }
        /// <summary>
        /// The hash code comes from just the cloud name - for no partular reason.
        /// This implementation seems sufficient - since the cloud names or typically
        /// unique
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return m_CloudName.GetHashCode();
        }

        /// <summary>
        /// A friendly string for the Cloud object
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Cloud Name:");
            sb.Append(Name);
            sb.Append(" Scope:");
            sb.Append(Scope);
            sb.Append(" ScopeId:");
            sb.Append(ScopeId);
            return sb.ToString();
        }

        /// <summary>
        /// Constructor to enable serialization 
        /// </summary>
        /// <param name="serializationInfo"></param>
        /// <param name="streamingContext"></param>
        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
        protected Cloud(SerializationInfo info, StreamingContext context)
        {
            m_CloudName = info.GetString("_CloudName");
            m_PnrpScope = (PnrpScope)info.GetValue("_CloudScope", typeof(PnrpScope));
            m_ScopeId = info.GetInt32("_CloudScopeId");
        }

        // <SecurityKernel Critical="True" Ring="0">
        // <SatisfiesLinkDemand Name="GetObjectData(SerializationInfo, StreamingContext):Void" />
        // </SecurityKernel>
        [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.Net.dll is still using pre-v4 security model and needs this demand")]
        [System.Security.SecurityCritical]
        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter, SerializationFormatter = true)]
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            GetObjectData(info, context);
        }

        /// <summary>
        /// This is made virtual so that derived types can be implemented correctly
        /// </summary>
        /// <param name="serializationInfo"></param>
        /// <param name="streamingContext"></param>
        [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
        protected virtual void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            //Name is tricky since it can be null for AllLinkLocal and Available clouds
            //but internally we represent them with non null strings 
            //so we should use the property here
            info.AddValue("_CloudName", Name);
            info.AddValue("_CloudScope", m_PnrpScope);
            info.AddValue("_CloudScopeId", m_ScopeId);
        }
    }
}