1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Microsoft Public License. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Microsoft Public License, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Microsoft Public License.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
15 using System; using Microsoft;
18 #if !SILVERLIGHT // ComObject
20 using System.Diagnostics;
21 using System.Reflection;
22 using System.Runtime.InteropServices;
23 using System.Security;
24 using ComTypes = System.Runtime.InteropServices.ComTypes;
27 namespace System.Dynamic {
29 namespace Microsoft.Scripting {
32 /// This is similar to ComTypes.EXCEPINFO, but lets us do our own custom marshaling
34 [StructLayout(LayoutKind.Sequential)]
35 internal struct ExcepInfo {
37 private short wReserved;
38 private IntPtr bstrSource;
39 private IntPtr bstrDescription;
40 private IntPtr bstrHelpFile;
41 private int dwHelpContext;
42 private IntPtr pvReserved;
43 private IntPtr pfnDeferredFillIn;
47 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2207:InitializeValueTypeStaticFieldsInline")]
49 Debug.Assert(Marshal.SizeOf(typeof(ExcepInfo)) == Marshal.SizeOf(typeof(ComTypes.EXCEPINFO)));
54 private static string ConvertAndFreeBstr(ref IntPtr bstr) {
55 if (bstr == IntPtr.Zero) {
59 string result = Marshal.PtrToStringBSTR(bstr);
60 Marshal.FreeBSTR(bstr);
65 internal void Dummy() {
67 wReserved = 0; wReserved++;
68 bstrSource = IntPtr.Zero;
69 bstrDescription = IntPtr.Zero;
70 bstrHelpFile = IntPtr.Zero;
72 pfnDeferredFillIn = IntPtr.Zero;
73 pvReserved = IntPtr.Zero;
76 throw Error.MethodShouldNotBeCalled();
79 [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
81 internal Exception GetException() {
82 Debug.Assert(pfnDeferredFillIn == IntPtr.Zero);
84 System.Diagnostics.Debug.Assert(wReserved != -1);
85 wReserved = -1; // to ensure that the method gets called only once
88 int errorCode = (scode != 0) ? scode : wCode;
89 Exception exception = Marshal.GetExceptionForHR(errorCode);
91 string message = ConvertAndFreeBstr(ref bstrDescription);
92 if (message != null) {
93 // If we have a custom message, create a new Exception object with the message set correctly.
94 // We need to create a new object because "exception.Message" is a read-only property.
95 if (exception is COMException) {
96 exception = new COMException(message, errorCode);
98 Type exceptionType = exception.GetType();
99 ConstructorInfo ctor = exceptionType.GetConstructor(new Type[] { typeof(string) });
101 exception = (Exception)ctor.Invoke(new object[] { message });
106 exception.Source = ConvertAndFreeBstr(ref bstrSource);
108 string helpLink = ConvertAndFreeBstr(ref bstrHelpFile);
109 if (helpLink != null && dwHelpContext != 0) {
110 helpLink += "#" + dwHelpContext;
112 exception.HelpLink = helpLink;