File: PeerToPeerException.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 (166 lines) | stat: -rw-r--r-- 8,903 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
//------------------------------------------------------------------------------
// <copyright file="Logging.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.InteropServices;
    using System.ComponentModel;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Threading;
    using System.Runtime.Serialization;
    using System.Security.Permissions;

    /// <remarks>
    /// The PeerToPeerException class encpasulates the exceptions for
    /// PeerToPeer classes. 
    /// NOTE:
    /// This class is marked serializable but does not implement 
    /// ISerializable interface. There are no private/public properties
    /// we keep track across the serialization. The base class message
    /// and inner exceptions are used. 
    /// </remarks>
    [Serializable]
    public class PeerToPeerException : Exception, ISerializable
    {
        private const UInt32 FACILITY_P2P = 99;


        public PeerToPeerException() { }

        /// <summary>
        /// Construtor
        /// </summary>
        /// <param name="message"></param>
        public PeerToPeerException(string message) : base(message) { }

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="message"></param>
        /// <param name="innerException"></param>
        public PeerToPeerException(string message, Exception innerException) : base(message, innerException) { }

        /// <summary>
        /// HRESULT Structure
        ///   3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
        ///   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
        ///  +---+-+-+-----------------------+-------------------------------+
        ///  |Sev|C|R|     Facility          |               Code            |
        ///  +---+-+-+-----------------------+-------------------------------+
        ///
        ///  The intent here is that when we get a HRESULT from a P2P.dll, 
        ///  we need to get the message from the P2p.dll resource table. 
        ///  If the HRESULT is something like E_INVALIDARG, we need to get the 
        ///  message from the SYSTEM table. 
        ///  Apart from the native exception message, we would like to provide
        ///  a friendly message to explain the context under which the exception 
        ///  occurred from managed code developers. 
        ///  So we first try to get the message from the P2P.dll if the HRESULT 
        ///  comes with a facility ID for P2P. Otherwise we get the exception message from 
        ///  system. We then construct a Win32Exception and set this as an inner exception
        ///
        ///  If in case we can't get the message from either system or P2p, then 
        ///  we try the Marshal class and throw a exception from the HRESULT
        ///
        ///  If all else fails we simply throw an exception with no inner 
        ///  exception but still give the HRESULT
        ///
        ///  A note that we are getting the handle for P2p.dll from the LoadLibrary
        ///  we originally did for checking if P2P.dll is present on the system. 
        ///  Since we are getting the underlying handle, there is a possibility that 
        /// the Library is freed [AppDomain shutdown] and we are trying to 
        ///  use the handle. The code is in a try catch block here so that 
        ///  we catch these situations and still recover.
        /// </summary>
        /// <param name="message">The error message that we would like to set as the message for the exception</param>/// 
        /// <param name="hr">The error code</param>
        /// <returns>a PeerToPeerException</returns>
        // <SecurityKernel Critical="True" Ring="0">
        // <CallsSuppressUnmanagedCode Name="UnsafeSystemNativeMethods.FormatMessage(System.Net.FormatMessageFlags,System.IntPtr,System.UInt32,System.UInt32,System.IntPtr&,System.UInt32,System.IntPtr):System.UInt32" />
        // <CallsSuppressUnmanagedCode Name="UnsafeSystemNativeMethods.LocalFree(System.IntPtr):System.UInt32" />
        // <SatisfiesLinkDemand Name="Marshal.PtrToStringUni(System.IntPtr):System.String" />
        // <SatisfiesLinkDemand Name="Win32Exception..ctor(System.Int32,System.String)" />
        // <SatisfiesLinkDemand Name="Marshal.GetExceptionForHR(System.Int32):System.Exception" />
        // <ReferencesCritical Name="Method: PeerToPeerOSHelper.get_P2PModuleHandle():System.IntPtr" Ring="1" />
        // </SecurityKernel>
        [System.Security.SecurityCritical]
        internal static PeerToPeerException CreateFromHr(string message, Int32 hr)
        {
            PeerToPeerException p2pEx = null;
            int facility = ((hr >> 16) & 0x1FFF);
            IntPtr NativeMessagePtr = IntPtr.Zero;
            try
            {
                UInt32 dwLength = UnsafeSystemNativeMethods.FormatMessage(
                        FormatMessageFlags.FORMAT_MESSAGE_ALLOCATE_BUFFER |
                        FormatMessageFlags.FORMAT_MESSAGE_ARGUMENT_ARRAY |
                        (facility == FACILITY_P2P ? FormatMessageFlags.FORMAT_MESSAGE_FROM_HMODULE : FormatMessageFlags.FORMAT_MESSAGE_FROM_SYSTEM),
                        (facility == FACILITY_P2P ? PeerToPeerOSHelper.P2PModuleHandle : IntPtr.Zero),
                        (uint)(hr),
                        0,
                        ref NativeMessagePtr,
                        0,
                        IntPtr.Zero);
                if (dwLength != 0)
                {
                    string NativeMessage = Marshal.PtrToStringUni(NativeMessagePtr);
                    p2pEx = new PeerToPeerException(message, new Win32Exception(hr, NativeMessage));
                }
                else
                {
                    p2pEx = new PeerToPeerException(message, Marshal.GetExceptionForHR(hr));
                }
            }
            catch(Exception ex)
            {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0, "Could not get the error message for error code {0} - Exception {1}", hr, ex);
                if (ex is ThreadAbortException || ex is StackOverflowException || ex is OutOfMemoryException)
                {
                    throw;
                }
            }
            finally
            {
                if (NativeMessagePtr != IntPtr.Zero)
                {
                    UnsafeSystemNativeMethods.LocalFree(NativeMessagePtr);
                }
            }
            if (p2pEx == null)
            {
                Logging.P2PTraceSource.TraceEvent(TraceEventType.Warning, 0, "Could not get the error message for error code {0}", hr);
                p2pEx = new PeerToPeerException(message + "Underlying native error " + hr);
            }
            Logging.P2PTraceSource.TraceEvent(TraceEventType.Error, 0, "Exception: {0}", p2pEx);
            return p2pEx;
       }

        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
        protected PeerToPeerException(SerializationInfo info, StreamingContext context) : base (info, context) {}
        // <SecurityKernel Critical="True" Ring="0">
        // <SatisfiesLinkDemand Name="Exception.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext):System.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]
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
            GetObjectData(info, context);
        }
        // <SecurityKernel Critical="True" Ring="0">
        // <SatisfiesLinkDemand Name="Exception.GetObjectData(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext):System.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]
        [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter)]
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            base.GetObjectData(info, context);
        }
    }
}