OuterProxyWrapper.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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.Channels;
  10. using System.Threading;
  11. using System.Runtime.Versioning;
  12. class ProxySupportWrapper
  13. {
  14. internal delegate int DelegateDllGetClassObject([In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid, ref IClassFactory ppv);
  15. const string fileName = @"ServiceMonikerSupport.dll";
  16. const string functionName = @"DllGetClassObject";
  17. static readonly Guid ClsidProxyInstanceProvider = new Guid("(BF0514FB-6912-4659-AD69-B727E5B7ADD4)");
  18. // Double-checked locking pattern requires volatile for read/write synchronization
  19. volatile SafeLibraryHandle monikerSupportLibrary;
  20. // Double-checked locking pattern requires volatile for read/write synchronization
  21. volatile DelegateDllGetClassObject getCODelegate;
  22. internal ProxySupportWrapper()
  23. {
  24. monikerSupportLibrary = null;
  25. getCODelegate = null;
  26. }
  27. ~ProxySupportWrapper()
  28. {
  29. if (null != monikerSupportLibrary)
  30. {
  31. monikerSupportLibrary.Close();
  32. monikerSupportLibrary = null;
  33. }
  34. }
  35. [ResourceConsumption(ResourceScope.Process)]
  36. internal IProxyProvider GetProxyProvider()
  37. {
  38. if (null == monikerSupportLibrary)
  39. {
  40. lock (this)
  41. {
  42. if (null == monikerSupportLibrary)
  43. {
  44. getCODelegate = null;
  45. using (RegistryHandle regKey = RegistryHandle.GetCorrectBitnessHKLMSubkey((IntPtr.Size == 8), ServiceModelInstallStrings.WinFXRegistryKey))
  46. {
  47. string file = regKey.GetStringValue(ServiceModelInstallStrings.RuntimeInstallPathName).TrimEnd('\0') + "\\" + fileName;
  48. SafeLibraryHandle tempLibrary = UnsafeNativeMethods.LoadLibrary(file);
  49. tempLibrary.DoNotFreeLibraryOnRelease();
  50. monikerSupportLibrary = tempLibrary;
  51. if (monikerSupportLibrary.IsInvalid)
  52. {
  53. monikerSupportLibrary.SetHandleAsInvalid();
  54. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.ServiceMonikerSupportLoadFailed(file));
  55. }
  56. }
  57. }
  58. }
  59. }
  60. if (null == getCODelegate)
  61. {
  62. lock (this)
  63. {
  64. if (null == getCODelegate)
  65. {
  66. try
  67. {
  68. IntPtr procaddr = UnsafeNativeMethods.GetProcAddress(monikerSupportLibrary, functionName);
  69. getCODelegate = (DelegateDllGetClassObject)Marshal.GetDelegateForFunctionPointer(procaddr, typeof(DelegateDllGetClassObject));
  70. }
  71. catch (Exception e)
  72. {
  73. if (Fx.IsFatal(e))
  74. throw;
  75. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ComPlusProxyProviderException(SR.GetString(SR.FailedProxyProviderCreation), e));
  76. }
  77. }
  78. }
  79. }
  80. IClassFactory cf = null;
  81. IProxyProvider proxyProvider = null;
  82. try
  83. {
  84. getCODelegate(ClsidProxyInstanceProvider, typeof(IClassFactory).GUID, ref cf);
  85. proxyProvider = cf.CreateInstance(null, typeof(IProxyProvider).GUID) as IProxyProvider;
  86. Thread.MemoryBarrier();
  87. }
  88. catch (Exception e)
  89. {
  90. if (Fx.IsFatal(e))
  91. throw;
  92. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ComPlusProxyProviderException(SR.GetString(SR.FailedProxyProviderCreation), e));
  93. }
  94. finally
  95. {
  96. if (null != cf)
  97. {
  98. Marshal.ReleaseComObject(cf);
  99. cf = null;
  100. }
  101. }
  102. return proxyProvider;
  103. }
  104. }
  105. internal static class OuterProxyWrapper
  106. {
  107. static ProxySupportWrapper proxySupport = new ProxySupportWrapper();
  108. public static IntPtr CreateOuterProxyInstance(IProxyManager proxyManager, ref Guid riid)
  109. {
  110. IntPtr pOuter = IntPtr.Zero;
  111. IProxyProvider proxyProvider = proxySupport.GetProxyProvider();
  112. if (proxyProvider == null)
  113. {
  114. throw Fx.AssertAndThrowFatal("Proxy Provider cannot be NULL");
  115. }
  116. Guid riid2 = riid;
  117. int hr = proxyProvider.CreateOuterProxyInstance(proxyManager, ref riid2, out pOuter);
  118. Marshal.ReleaseComObject(proxyProvider);
  119. if (hr != HR.S_OK)
  120. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.FailedProxyProviderCreation), hr));
  121. return pOuter;
  122. }
  123. public static IntPtr CreateDispatchProxy(IntPtr pOuter, IPseudoDispatch proxy)
  124. {
  125. IntPtr pInner = IntPtr.Zero;
  126. IProxyProvider proxyProvider = proxySupport.GetProxyProvider();
  127. if (proxyProvider == null)
  128. {
  129. throw Fx.AssertAndThrowFatal("Proxy Provider cannot be NULL");
  130. }
  131. int hr = proxyProvider.CreateDispatchProxyInstance(pOuter, proxy, out pInner);
  132. Marshal.ReleaseComObject(proxyProvider);
  133. if (hr != HR.S_OK)
  134. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException(SR.GetString(SR.FailedProxyProviderCreation), hr));
  135. return pInner;
  136. }
  137. }
  138. }