PageRenderTime 45ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/DLR_Main/Runtime/Microsoft.Dynamic/ComInterop/ExcepInfo.cs

https://bitbucket.org/mdavid/dlr
C# | 112 lines | 78 code | 15 blank | 19 comment | 16 complexity | 5a943f207e472b9d30820f37835481f1 MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. 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 Apache License, Version 2.0, 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 Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if !SILVERLIGHT // ComObject
  16. using System;
  17. using System.Diagnostics;
  18. using System.Reflection;
  19. using System.Runtime.InteropServices;
  20. using System.Security;
  21. using ComTypes = System.Runtime.InteropServices.ComTypes;
  22. namespace Microsoft.Scripting.ComInterop {
  23. /// <summary>
  24. /// This is similar to ComTypes.EXCEPINFO, but lets us do our own custom marshaling
  25. /// </summary>
  26. [StructLayout(LayoutKind.Sequential)]
  27. internal struct ExcepInfo {
  28. private short wCode;
  29. private short wReserved;
  30. private IntPtr bstrSource;
  31. private IntPtr bstrDescription;
  32. private IntPtr bstrHelpFile;
  33. private int dwHelpContext;
  34. private IntPtr pvReserved;
  35. private IntPtr pfnDeferredFillIn;
  36. private int scode;
  37. #if DEBUG
  38. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2207:InitializeValueTypeStaticFieldsInline")]
  39. static ExcepInfo() {
  40. Debug.Assert(Marshal.SizeOf(typeof(ExcepInfo)) == Marshal.SizeOf(typeof(ComTypes.EXCEPINFO)));
  41. }
  42. #endif
  43. private static string ConvertAndFreeBstr(ref IntPtr bstr) {
  44. if (bstr == IntPtr.Zero) {
  45. return null;
  46. }
  47. string result = Marshal.PtrToStringBSTR(bstr);
  48. Marshal.FreeBSTR(bstr);
  49. bstr = IntPtr.Zero;
  50. return result;
  51. }
  52. internal void Dummy() {
  53. wCode = 0;
  54. wReserved = 0; wReserved++;
  55. bstrSource = IntPtr.Zero;
  56. bstrDescription = IntPtr.Zero;
  57. bstrHelpFile = IntPtr.Zero;
  58. dwHelpContext = 0;
  59. pfnDeferredFillIn = IntPtr.Zero;
  60. pvReserved = IntPtr.Zero;
  61. scode = 0;
  62. throw Error.MethodShouldNotBeCalled();
  63. }
  64. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
  65. internal Exception GetException() {
  66. Debug.Assert(pfnDeferredFillIn == IntPtr.Zero);
  67. #if DEBUG
  68. System.Diagnostics.Debug.Assert(wReserved != -1);
  69. wReserved = -1; // to ensure that the method gets called only once
  70. #endif
  71. int errorCode = (scode != 0) ? scode : wCode;
  72. Exception exception = Marshal.GetExceptionForHR(errorCode);
  73. string message = ConvertAndFreeBstr(ref bstrDescription);
  74. if (message != null) {
  75. // If we have a custom message, create a new Exception object with the message set correctly.
  76. // We need to create a new object because "exception.Message" is a read-only property.
  77. if (exception is COMException) {
  78. exception = new COMException(message, errorCode);
  79. } else {
  80. Type exceptionType = exception.GetType();
  81. ConstructorInfo ctor = exceptionType.GetConstructor(new Type[] { typeof(string) });
  82. if (ctor != null) {
  83. exception = (Exception)ctor.Invoke(new object[] { message });
  84. }
  85. }
  86. }
  87. exception.Source = ConvertAndFreeBstr(ref bstrSource);
  88. string helpLink = ConvertAndFreeBstr(ref bstrHelpFile);
  89. if (helpLink != null && dwHelpContext != 0) {
  90. helpLink += "#" + dwHelpContext;
  91. }
  92. exception.HelpLink = helpLink;
  93. return exception;
  94. }
  95. }
  96. }
  97. #endif