ComPlusInstanceContextInitializer.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.ComIntegration
  5. {
  6. using System;
  7. using System.EnterpriseServices;
  8. using System.IO;
  9. using System.Reflection;
  10. using System.Runtime;
  11. using System.Runtime.InteropServices;
  12. using System.ServiceModel;
  13. using System.ServiceModel.Channels;
  14. using System.ServiceModel.Dispatcher;
  15. using System.Transactions;
  16. class ComPlusInstanceContextInitializer : IInstanceContextInitializer
  17. {
  18. ServiceInfo info;
  19. static readonly Guid IID_IServiceActivity = new Guid("67532E0C-9E2F-4450-A354-035633944E17");
  20. static readonly Guid DefaultPartitionId = new Guid("41E90F3E-56C1-4633-81C3-6E8BAC8BDD70");
  21. private static object manifestLock = new object();
  22. private static string manifestFileName = Guid.NewGuid().ToString();
  23. static ComPlusInstanceContextInitializer()
  24. {
  25. AppDomain currentDomain = AppDomain.CurrentDomain;
  26. currentDomain.AssemblyResolve += new ResolveEventHandler(ResolveAssembly);
  27. }
  28. public ComPlusInstanceContextInitializer(ServiceInfo info)
  29. {
  30. this.info = info;
  31. if (this.info.HasUdts())
  32. {
  33. string tempPath = String.Empty;
  34. lock (manifestLock)
  35. {
  36. try
  37. {
  38. tempPath = Path.GetTempPath();
  39. }
  40. catch (Exception e)
  41. {
  42. if (Fx.IsFatal(e))
  43. throw;
  44. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(System.ServiceModel.ComIntegration.Error.CannotAccessDirectory(tempPath));
  45. }
  46. string manifestDirectory = tempPath + this.info.AppID.ToString();
  47. if (Directory.Exists(manifestDirectory))
  48. Directory.Delete(manifestDirectory, true);
  49. }
  50. }
  51. }
  52. public void Initialize(InstanceContext instanceContext, Message message)
  53. {
  54. object serviceConfig = null;
  55. serviceConfig = SetupServiceConfig(instanceContext, message);
  56. IServiceActivity activity;
  57. activity = (IServiceActivity)SafeNativeMethods.CoCreateActivity(
  58. serviceConfig,
  59. IID_IServiceActivity);
  60. ComPlusSynchronizationContext syncContext;
  61. bool postSynchronous = (this.info.ThreadingModel ==
  62. ThreadingModel.MTA);
  63. syncContext = new ComPlusSynchronizationContext(activity,
  64. postSynchronous);
  65. instanceContext.SynchronizationContext = syncContext;
  66. instanceContext.Closing += this.OnInstanceContextClosing;
  67. Marshal.ReleaseComObject(serviceConfig);
  68. }
  69. public void OnInstanceContextClosing(object sender, EventArgs args)
  70. {
  71. InstanceContext instanceContext = (InstanceContext)sender;
  72. ComPlusSynchronizationContext syncContext;
  73. syncContext = (ComPlusSynchronizationContext)instanceContext.SynchronizationContext;
  74. syncContext.Dispose();
  75. }
  76. static Assembly ResolveAssembly(object sender, ResolveEventArgs args)
  77. {
  78. int indexOfComma = args.Name.IndexOf(",", StringComparison.Ordinal);
  79. if (indexOfComma != -1)
  80. {
  81. Guid assemblyGuid = Guid.Empty;
  82. string assemblyGuidString = args.Name.Substring(0, indexOfComma).Trim().ToLowerInvariant();
  83. if (Guid.TryParse(assemblyGuidString, out assemblyGuid))
  84. {
  85. return TypeCacheManager.Provider.ResolveAssembly(assemblyGuid);
  86. }
  87. }
  88. return null;
  89. }
  90. object SetupServiceConfig(InstanceContext instanceContext, Message message)
  91. {
  92. object serviceConfig = new CServiceConfig();
  93. // Threading
  94. //
  95. IServiceThreadPoolConfig threadPoolConfig;
  96. threadPoolConfig = (IServiceThreadPoolConfig)(serviceConfig);
  97. switch (this.info.ThreadingModel)
  98. {
  99. case ThreadingModel.MTA:
  100. threadPoolConfig.SelectThreadPool(ThreadPoolOption.MTA);
  101. break;
  102. case ThreadingModel.STA:
  103. threadPoolConfig.SelectThreadPool(ThreadPoolOption.STA);
  104. break;
  105. default:
  106. Fx.Assert("Unexpected threading model");
  107. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(Error.UnexpectedThreadingModel());
  108. }
  109. threadPoolConfig.SetBindingInfo(BindingOption.BindingToPoolThread);
  110. // SxS activation context properties
  111. //
  112. // Manifest for VARIANT UDT types
  113. //
  114. // this only gets executed if we actually have UDTs
  115. if (this.info.HasUdts())
  116. {
  117. IServiceSxsConfig sxsConfig = serviceConfig as IServiceSxsConfig;
  118. if (sxsConfig == null)
  119. {
  120. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(System.ServiceModel.ComIntegration.Error.QFENotPresent());
  121. }
  122. lock (manifestLock)
  123. {
  124. string tempPath = String.Empty;
  125. try
  126. {
  127. tempPath = Path.GetTempPath();
  128. }
  129. catch (Exception e)
  130. {
  131. if (Fx.IsFatal(e))
  132. throw;
  133. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(System.ServiceModel.ComIntegration.Error.CannotAccessDirectory(tempPath));
  134. }
  135. string manifestDirectory = tempPath + this.info.AppID.ToString() + @"\";
  136. if (!Directory.Exists(manifestDirectory))
  137. {
  138. try
  139. {
  140. Directory.CreateDirectory(manifestDirectory);
  141. }
  142. catch (Exception e)
  143. {
  144. if (Fx.IsFatal(e))
  145. throw;
  146. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(System.ServiceModel.ComIntegration.Error.CannotAccessDirectory(manifestDirectory));
  147. }
  148. Guid[] assemblyGuids = this.info.Assemblies;
  149. ComIntegrationManifestGenerator.GenerateManifestCollectionFile(assemblyGuids, manifestDirectory + manifestFileName + @".manifest", manifestFileName);
  150. foreach (Guid g in assemblyGuids)
  151. {
  152. Type[] types = this.info.GetTypes(g);
  153. if (types.Length > 0)
  154. {
  155. String guidStr = g.ToString();
  156. ComIntegrationManifestGenerator.GenerateWin32ManifestFile(types, manifestDirectory + guidStr + @".manifest", guidStr);
  157. }
  158. }
  159. }
  160. sxsConfig.SxsConfig(CSC_SxsConfig.CSC_NewSxs);
  161. sxsConfig.SxsName(manifestFileName + @".manifest");
  162. sxsConfig.SxsDirectory(manifestDirectory);
  163. }
  164. }
  165. // Partitions
  166. //
  167. if (this.info.PartitionId != DefaultPartitionId)
  168. {
  169. IServicePartitionConfig partitionConfig;
  170. partitionConfig = (IServicePartitionConfig)(serviceConfig);
  171. partitionConfig.PartitionConfig(PartitionOption.New);
  172. partitionConfig.PartitionID(this.info.PartitionId);
  173. }
  174. // Transactions
  175. //
  176. IServiceTransactionConfig transactionConfig;
  177. transactionConfig = (IServiceTransactionConfig)(serviceConfig);
  178. transactionConfig.ConfigureTransaction(
  179. TransactionConfig.NoTransaction);
  180. if ((this.info.TransactionOption == TransactionOption.Required) ||
  181. (this.info.TransactionOption == TransactionOption.Supported))
  182. {
  183. Transaction messageTransaction = null;
  184. messageTransaction = MessageUtil.GetMessageTransaction(message);
  185. if (messageTransaction != null)
  186. {
  187. TransactionProxy proxy = new TransactionProxy(info.AppID, info.Clsid);
  188. proxy.SetTransaction(messageTransaction);
  189. instanceContext.Extensions.Add(proxy);
  190. IServiceSysTxnConfig sysTxnconfing = (IServiceSysTxnConfig)transactionConfig;
  191. IntPtr pUnk = TransactionProxyBuilder.CreateTransactionProxyTearOff(proxy);
  192. sysTxnconfing.ConfigureBYOTSysTxn(pUnk);
  193. Marshal.Release(pUnk);
  194. }
  195. }
  196. return serviceConfig;
  197. }
  198. }
  199. }