ComProxy.cs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.ComIntegration
  5. {
  6. using System;
  7. using System.Runtime;
  8. using System.Runtime.InteropServices;
  9. using System.ServiceModel;
  10. class ComProxy : IDisposable
  11. {
  12. IntPtr inner;
  13. IDisposable ccw;
  14. internal static ComProxy Create(IntPtr outer, object obj, IDisposable disp)
  15. {
  16. if (outer == IntPtr.Zero)
  17. {
  18. throw Fx.AssertAndThrow("Outer cannot be null");
  19. }
  20. IntPtr inner = IntPtr.Zero;
  21. inner = Marshal.CreateAggregatedObject(outer, obj);
  22. int refCount = Marshal.AddRef(inner);
  23. // Workaround for the CLR ref count issue.
  24. if (3 == refCount)
  25. Marshal.Release(inner);
  26. Marshal.Release(inner);
  27. return new ComProxy(inner, disp);
  28. }
  29. internal ComProxy(IntPtr inner, IDisposable disp)
  30. {
  31. this.inner = inner;
  32. ccw = disp;
  33. }
  34. internal void QueryInterface(ref Guid riid, out IntPtr tearoff)
  35. {
  36. if (inner == IntPtr.Zero)
  37. {
  38. throw Fx.AssertAndThrow("Inner should not be Null at this point");
  39. }
  40. int hr = Marshal.QueryInterface(inner, ref riid, out tearoff);
  41. if (hr != HR.S_OK)
  42. {
  43. throw Fx.AssertAndThrow("QueryInterface should succeed");
  44. }
  45. }
  46. void IDisposable.Dispose()
  47. {
  48. Dispose(true);
  49. }
  50. void Dispose(bool disposing)
  51. {
  52. if (inner == IntPtr.Zero)
  53. {
  54. throw Fx.AssertAndThrow("Inner should not be Null at this point");
  55. }
  56. Marshal.Release(inner);
  57. if (disposing)
  58. {
  59. if (ccw != null)
  60. ccw.Dispose();
  61. }
  62. }
  63. public ComProxy Clone()
  64. {
  65. if (inner == IntPtr.Zero)
  66. {
  67. throw Fx.AssertAndThrow("Inner should not be Null at this point");
  68. }
  69. Marshal.AddRef(inner);
  70. return new ComProxy(inner, null);
  71. }
  72. }
  73. }