ComPlusInstanceProvider.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.ComIntegration
  5. {
  6. using System;
  7. using System.Diagnostics;
  8. using System.Diagnostics.CodeAnalysis;
  9. using System.EnterpriseServices;
  10. using System.Runtime;
  11. using System.Runtime.Diagnostics;
  12. using System.Runtime.InteropServices;
  13. using System.Security.Principal;
  14. using System.ServiceModel;
  15. using System.ServiceModel.Channels;
  16. using System.ServiceModel.Diagnostics;
  17. using System.ServiceModel.Dispatcher;
  18. using SafeCloseHandle = System.IdentityModel.SafeCloseHandle;
  19. class ComPlusInstanceProvider : IInstanceProvider
  20. {
  21. ServiceInfo info;
  22. static readonly Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
  23. public ComPlusInstanceProvider(ServiceInfo info)
  24. {
  25. this.info = info;
  26. }
  27. public object GetInstance(InstanceContext instanceContext)
  28. {
  29. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ComPlusInstanceProviderRequiresMessage0)));
  30. }
  31. // We call ContextUtil.IsInTransaction and ContextUtil.TransactionId, from a non-APTCA assembly. There is no identified security vulnerability with these properties,
  32. // so we can't justify adding a demand for full trust here. Both properties call code marked as usafe, but no user input is passed to it and results are not
  33. // cached (so there is no leak as a side-effect).
  34. [SuppressMessage(FxCop.Category.Security, FxCop.Rule.AptcaMethodsShouldOnlyCallAptcaMethods)]
  35. public object GetInstance(InstanceContext instanceContext, Message message)
  36. {
  37. object result = null;
  38. Guid incomingTransactionID = Guid.Empty;
  39. if (ContextUtil.IsInTransaction)
  40. incomingTransactionID = ContextUtil.TransactionId;
  41. ComPlusInstanceCreationTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationInstanceCreationRequest,
  42. SR.TraceCodeComIntegrationInstanceCreationRequest, this.info, message, incomingTransactionID);
  43. WindowsIdentity callerIdentity = null;
  44. callerIdentity = MessageUtil.GetMessageIdentity(message);
  45. WindowsImpersonationContext impersonateContext = null;
  46. try
  47. {
  48. try
  49. {
  50. if (this.info.HostingMode ==
  51. HostingMode.WebHostOutOfProcess)
  52. {
  53. if (SecurityUtils.IsAtleastImpersonationToken(new SafeCloseHandle(callerIdentity.Token, false)))
  54. impersonateContext = callerIdentity.Impersonate();
  55. else
  56. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new COMException (SR.GetString(SR.BadImpersonationLevelForOutOfProcWas), HR.ERROR_BAD_IMPERSONATION_LEVEL));
  57. }
  58. CLSCTX clsctx = CLSCTX.SERVER;
  59. if (PlatformSupportsBitness && (this.info.HostingMode ==
  60. HostingMode.WebHostOutOfProcess))
  61. {
  62. if (this.info.Bitness == Bitness.Bitness32)
  63. {
  64. clsctx |= CLSCTX.ACTIVATE_32_BIT_SERVER;
  65. }
  66. else
  67. {
  68. clsctx |= CLSCTX.ACTIVATE_64_BIT_SERVER;
  69. }
  70. }
  71. result = SafeNativeMethods.CoCreateInstance(
  72. info.Clsid,
  73. null,
  74. clsctx,
  75. IID_IUnknown);
  76. }
  77. finally
  78. {
  79. if (impersonateContext != null)
  80. impersonateContext.Undo();
  81. }
  82. }
  83. catch (Exception e)
  84. {
  85. if (Fx.IsFatal(e))
  86. throw;
  87. Uri from = null;
  88. if (message.Headers.From != null)
  89. from = message.Headers.From.Uri;
  90. DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
  91. (ushort)System.Runtime.Diagnostics.EventLogCategory.ComPlus,
  92. (uint)System.Runtime.Diagnostics.EventLogEventId.ComPlusInstanceCreationError,
  93. from == null ? string.Empty : from.ToString(),
  94. this.info.AppID.ToString(),
  95. this.info.Clsid.ToString(),
  96. incomingTransactionID.ToString(),
  97. callerIdentity.Name,
  98. e.ToString());
  99. throw TraceUtility.ThrowHelperError(e, message);
  100. }
  101. TransactionProxy proxy = instanceContext.Extensions.Find<TransactionProxy>();
  102. if (proxy != null)
  103. {
  104. proxy.InstanceID = result.GetHashCode();
  105. }
  106. ComPlusInstanceCreationTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationInstanceCreationSuccess,
  107. SR.TraceCodeComIntegrationInstanceCreationSuccess, this.info, message, result.GetHashCode(), incomingTransactionID);
  108. return result;
  109. }
  110. public void ReleaseInstance(InstanceContext instanceContext, object instance)
  111. {
  112. int instanceID = instance.GetHashCode();
  113. IDisposable disposable = instance as IDisposable;
  114. if (disposable != null)
  115. {
  116. disposable.Dispose();
  117. }
  118. else
  119. {
  120. // All ServicedComponents are disposable, so we don't
  121. // have to worry about getting a ServicedComponent
  122. // here.
  123. //
  124. Marshal.ReleaseComObject(instance);
  125. }
  126. ComPlusInstanceCreationTrace.Trace(TraceEventType.Verbose, TraceCode.ComIntegrationInstanceReleased,
  127. SR.TraceCodeComIntegrationInstanceReleased, this.info, instanceContext, instanceID);
  128. }
  129. static bool platformSupportsBitness;
  130. static bool platformSupportsBitnessSet;
  131. static bool PlatformSupportsBitness
  132. {
  133. get
  134. {
  135. if (!platformSupportsBitnessSet)
  136. {
  137. // Bitness is supported on Windows 2003 Server SP1 or
  138. // greater.
  139. //
  140. if (Environment.OSVersion.Version.Major > 5)
  141. platformSupportsBitness = true;
  142. else if (Environment.OSVersion.Version.Major == 5)
  143. {
  144. if (Environment.OSVersion.Version.Minor > 2)
  145. platformSupportsBitness = true;
  146. else if (Environment.OSVersion.Version.Minor == 2)
  147. {
  148. if (!string.IsNullOrEmpty(Environment.OSVersion.ServicePack))
  149. platformSupportsBitness = true;
  150. }
  151. }
  152. platformSupportsBitnessSet = true;
  153. }
  154. return platformSupportsBitness;
  155. }
  156. }
  157. }
  158. }