Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1002 lines
41 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. comclass.cpp
  5. Abstract:
  6. Activation context section contributor for COM servers.
  7. Author:
  8. Michael J. Grier (MGrier) 23-Feb-2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include <windows.h>
  13. #include "sxsp.h"
  14. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(clsid);
  15. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(iid);
  16. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(name);
  17. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(progid);
  18. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(proxyStubClsid32);
  19. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(runtimeVersion);
  20. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(threadingModel);
  21. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(tlbid);
  22. #define ALLOCATE_BUFFER_SPACE(_bytesNeeded, _bufferCursor, _bytesLeft, _bytesWritten, _typeName, _ptr) \
  23. do { \
  24. if (_bytesLeft < (_bytesNeeded)) \
  25. ORIGINATE_WIN32_FAILURE_AND_EXIT(NoRoom, ERROR_INSUFFICIENT_BUFFER); \
  26. _bytesLeft -= (_bytesNeeded); \
  27. _bytesWritten += (_bytesNeeded); \
  28. _ptr = (_typeName) _bufferCursor; \
  29. _bufferCursor = (PVOID) (((ULONG_PTR) _bufferCursor) + (_bytesNeeded)); \
  30. } while (0)
  31. #define ALLOCATE_BUFFER_SPACE_TYPE(_typeName, _bufferCursor, _bytesLeft, _bytesWritten, _ptr) \
  32. ALLOCATE_BUFFER_SPACE(sizeof(_typeName), _bufferCursor, _bytesLeft, _bytesWritten, _typeName *, _ptr)
  33. typedef struct _COM_GLOBAL_CONTEXT *PCOM_GLOBAL_CONTEXT;
  34. typedef struct _COM_FILE_CONTEXT *PCOM_FILE_CONTEXT;
  35. typedef struct _COM_SERVER_ENTRY *PCOM_SERVER_ENTRY;
  36. typedef struct _COM_SERVER_ENTRY
  37. {
  38. public:
  39. _COM_SERVER_ENTRY() { }
  40. CDequeLinkage m_Linkage;
  41. PCOM_FILE_CONTEXT m_FileContext;
  42. GUID m_ReferenceClsid;
  43. GUID m_ConfiguredClsid;
  44. GUID m_ImplementedClsid;
  45. GUID m_TypeLibraryId;
  46. ULONG m_ThreadingModel;
  47. CSmallStringBuffer m_ProgIdBuffer;
  48. CTinyStringBuffer m_TypeNameBuffer;
  49. CTinyStringBuffer m_ShimNameBuffer;
  50. CTinyStringBuffer m_RuntimeVersionBuffer;
  51. ULONG m_ShimType;
  52. bool m_IsFirstShim;
  53. private:
  54. _COM_SERVER_ENTRY(const _COM_SERVER_ENTRY &);
  55. void operator =(const _COM_SERVER_ENTRY &);
  56. } COM_SERVER_ENTRY;
  57. typedef CDeque<COM_SERVER_ENTRY, offsetof(COM_SERVER_ENTRY, m_Linkage)> CComServerDeque;
  58. typedef CDequeIterator<COM_SERVER_ENTRY, offsetof(COM_SERVER_ENTRY, m_Linkage)> CComServerDequeIterator;
  59. typedef struct _COM_FILE_CONTEXT
  60. {
  61. public:
  62. _COM_FILE_CONTEXT() { }
  63. ~_COM_FILE_CONTEXT() { m_ServerList.ClearAndDeleteAll(); }
  64. CDequeLinkage m_Linkage;
  65. CSmallStringBuffer m_FileNameBuffer;
  66. CComServerDeque m_ServerList;
  67. ULONG m_Offset; // populated during section generation
  68. PCOM_GLOBAL_CONTEXT m_GlobalContext;
  69. private:
  70. _COM_FILE_CONTEXT(const _COM_FILE_CONTEXT &);
  71. void operator =(const _COM_FILE_CONTEXT &);
  72. } COM_FILE_CONTEXT;
  73. typedef CDeque<COM_FILE_CONTEXT, offsetof(COM_FILE_CONTEXT, m_Linkage)> CComFileDeque;
  74. typedef CDequeIterator<COM_FILE_CONTEXT, offsetof(COM_FILE_CONTEXT, m_Linkage)> CComFileDequeIterator;
  75. typedef struct _COM_GLOBAL_CONTEXT
  76. {
  77. _COM_GLOBAL_CONTEXT() { }
  78. ~_COM_GLOBAL_CONTEXT() { m_FileContextList.ClearAndDeleteAll(); }
  79. // Temporary holding buffer for the filename until the first COM server entry is
  80. // found, at which time a COM_FILE_CONTEXT is allocated and the filename moved to it.
  81. CSmallStringBuffer m_FileNameBuffer;
  82. CComFileDeque m_FileContextList;
  83. CTinyStringBuffer m_FirstShimNameBuffer;
  84. ULONG m_FirstShimNameOffset;
  85. ULONG m_FirstShimNameLength;
  86. // When the first clrClass entry is created, its file context is written here for
  87. // easy access in the future. It will exist in the normal list of files as well,
  88. // however, and will get cleaned up when the file list goes away.
  89. PCOM_FILE_CONTEXT m_MscoreeFileContext;
  90. struct _CallBackLocalsStruct
  91. {
  92. CStringBuffer FileNameBuffer;
  93. CSmallStringBuffer VersionIndependentComClassIdBuffer;
  94. CStringBuffer TempBuffer;
  95. CSmallStringBuffer ProgIdBuffer;
  96. CSmallStringBuffer RuntimeVersionBuffer;
  97. CSmallStringBuffer NameBuffer;
  98. } CallbackLocals;
  99. private:
  100. _COM_GLOBAL_CONTEXT(const _COM_GLOBAL_CONTEXT &);
  101. void operator =(const _COM_GLOBAL_CONTEXT &);
  102. } COM_GLOBAL_CONTEXT;
  103. VOID
  104. __fastcall
  105. SxspComClassRedirectionContributorCallback(
  106. PACTCTXCTB_CALLBACK_DATA Data
  107. )
  108. {
  109. FN_TRACE();
  110. PGUID_SECTION_GENERATION_CONTEXT GSGenContext = (PGUID_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext;
  111. CSmartPtr<COM_GLOBAL_CONTEXT> ComGlobalContext;
  112. ULONG ThreadingModel = 0;
  113. GUID ReferenceClsid;
  114. GUID ConfiguredClsid;
  115. GUID ImplementedClsid;
  116. GUID TypeLibraryId = GUID_NULL;
  117. GUID iid;
  118. bool fFound = false;
  119. SIZE_T cb = 0;
  120. if (GSGenContext != NULL)
  121. ComGlobalContext.AttachNoDelete((PCOM_GLOBAL_CONTEXT) ::SxsGetGuidSectionGenerationContextCallbackContext(GSGenContext));
  122. switch (Data->Header.Reason)
  123. {
  124. case ACTCTXCTB_CBREASON_ACTCTXGENBEGINNING:
  125. Data->GenBeginning.Success = FALSE;
  126. INTERNAL_ERROR_CHECK(ComGlobalContext == NULL);
  127. INTERNAL_ERROR_CHECK(GSGenContext == NULL);
  128. IFW32FALSE_EXIT(ComGlobalContext.Win32Allocate(__FILE__, __LINE__));
  129. ComGlobalContext->m_FirstShimNameOffset = 0;
  130. ComGlobalContext->m_FirstShimNameLength = 0;
  131. ComGlobalContext->m_MscoreeFileContext = NULL;
  132. IFW32FALSE_EXIT(
  133. ::SxsInitGuidSectionGenerationContext(
  134. &GSGenContext,
  135. ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_FORMAT_WHISTLER,
  136. &::SxspComClassRedirectionGuidSectionGenerationCallback,
  137. ComGlobalContext));
  138. ComGlobalContext.Detach();
  139. Data->Header.ActCtxGenContext = GSGenContext;
  140. Data->GenBeginning.Success = TRUE;
  141. break;
  142. case ACTCTXCTB_CBREASON_ACTCTXGENENDED:
  143. ::SxsDestroyGuidSectionGenerationContext(GSGenContext);
  144. FUSION_DELETE_SINGLETON(ComGlobalContext.Detach());
  145. break;
  146. case ACTCTXCTB_CBREASON_ALLPARSINGDONE:
  147. Data->AllParsingDone.Success = FALSE;
  148. if (GSGenContext != NULL)
  149. IFW32FALSE_EXIT(::SxsDoneModifyingGuidSectionGenerationContext(GSGenContext));
  150. Data->AllParsingDone.Success = TRUE;
  151. break;
  152. case ACTCTXCTB_CBREASON_GETSECTIONSIZE:
  153. Data->GetSectionSize.Success = FALSE;
  154. // Someone shouldn't be asking for the section size if this is a parse-only
  155. // run. These two asserts should be equivalent...
  156. INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  157. INTERNAL_ERROR_CHECK(GSGenContext != NULL);
  158. IFW32FALSE_EXIT(::SxsGetGuidSectionGenerationContextSectionSize(GSGenContext, &Data->GetSectionSize.SectionSize));
  159. Data->GetSectionSize.Success = TRUE;
  160. break;
  161. case ACTCTXCTB_CBREASON_ELEMENTPARSED:
  162. Data->ElementParsed.Success = FALSE;
  163. if ((Data->ElementParsed.ParseContext->XMLElementDepth == 2) &&
  164. (::FusionpCompareStrings(
  165. Data->ElementParsed.ParseContext->ElementPath,
  166. Data->ElementParsed.ParseContext->ElementPathCch,
  167. L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file",
  168. NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file") - 1,
  169. false) == 0))
  170. {
  171. INTERNAL_ERROR_CHECK2(
  172. ComGlobalContext != NULL,
  173. "context NULL in callback.");
  174. CStringBuffer &FileNameBuffer = ComGlobalContext->CallbackLocals.FileNameBuffer;
  175. SIZE_T cbBytesWritten = 0;
  176. // capture the name of the file
  177. IFW32FALSE_EXIT(
  178. ::SxspGetAttributeValue(
  179. 0,
  180. &s_AttributeName_name,
  181. &Data->ElementParsed,
  182. fFound,
  183. sizeof(FileNameBuffer),
  184. &FileNameBuffer,
  185. cbBytesWritten,
  186. NULL,
  187. NULL));
  188. // If there's no NAME attribute, someone else will puke; we'll handle it
  189. // gracefully.
  190. if (fFound || (FileNameBuffer.Cch() == 0))
  191. {
  192. IFW32FALSE_EXIT(ComGlobalContext->m_FileNameBuffer.Win32Assign(FileNameBuffer));
  193. }
  194. }
  195. else if (
  196. (Data->ElementParsed.ParseContext->XMLElementDepth == 3) &&
  197. (::FusionpCompareStrings(
  198. Data->ElementParsed.ParseContext->ElementPath,
  199. Data->ElementParsed.ParseContext->ElementPathCch,
  200. L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comClass",
  201. NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comClass") - 1,
  202. false) == 0))
  203. {
  204. INTERNAL_ERROR_CHECK2(
  205. ComGlobalContext != NULL,
  206. "COM global context NULL while processing comClass tag");
  207. CSmallStringBuffer &VersionIndependentComClassIdBuffer = ComGlobalContext->CallbackLocals.VersionIndependentComClassIdBuffer;
  208. VersionIndependentComClassIdBuffer.Clear();
  209. CSmartPtr<COM_SERVER_ENTRY> Entry;
  210. CSmartPtr<COM_FILE_CONTEXT> FileContext;
  211. CStringBuffer &TempBuffer = ComGlobalContext->CallbackLocals.TempBuffer;
  212. TempBuffer.Clear();
  213. CSmallStringBuffer &ProgIdBuffer = ComGlobalContext->CallbackLocals.ProgIdBuffer;
  214. ProgIdBuffer.Clear();
  215. IFW32FALSE_EXIT(
  216. ::SxspGetAttributeValue(
  217. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  218. &s_AttributeName_clsid,
  219. &Data->ElementParsed,
  220. fFound,
  221. sizeof(VersionIndependentComClassIdBuffer),
  222. &VersionIndependentComClassIdBuffer,
  223. cb,
  224. NULL,
  225. 0));
  226. INTERNAL_ERROR_CHECK(fFound);
  227. IFW32FALSE_EXIT(::SxspParseGUID(VersionIndependentComClassIdBuffer,
  228. VersionIndependentComClassIdBuffer.Cch(),
  229. ReferenceClsid));
  230. IFW32FALSE_EXIT(
  231. ::SxspGetAttributeValue(
  232. 0,
  233. &s_AttributeName_threadingModel,
  234. &Data->ElementParsed,
  235. fFound,
  236. sizeof(TempBuffer),
  237. &TempBuffer,
  238. cb,
  239. NULL,
  240. 0));
  241. if (fFound)
  242. IFW32FALSE_EXIT(::SxspParseThreadingModel(TempBuffer, TempBuffer.Cch(), &ThreadingModel));
  243. else
  244. ThreadingModel = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_SINGLE;
  245. IFW32FALSE_EXIT(
  246. ::SxspGetAttributeValue(
  247. 0,
  248. &s_AttributeName_progid,
  249. &Data->ElementParsed,
  250. fFound,
  251. sizeof(ProgIdBuffer),
  252. &ProgIdBuffer,
  253. cb,
  254. NULL,
  255. 0));
  256. IFW32FALSE_EXIT(
  257. ::SxspGetAttributeValue(
  258. 0,
  259. &s_AttributeName_tlbid,
  260. &Data->ElementParsed,
  261. fFound,
  262. sizeof(TempBuffer),
  263. &TempBuffer,
  264. cb,
  265. NULL,
  266. 0));
  267. if (fFound)
  268. IFW32FALSE_EXIT(::SxspParseGUID(TempBuffer, TempBuffer.Cch(), TypeLibraryId));
  269. else
  270. TypeLibraryId = GUID_NULL;
  271. // That was sufficient if we are generating a context.
  272. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  273. {
  274. BOOL fNewAllocate = FALSE;
  275. IFW32FALSE_EXIT(Data->Header.ClsidMappingContext->Map->MapReferenceClsidToConfiguredClsid(
  276. &ReferenceClsid,
  277. Data->ElementParsed.AssemblyContext,
  278. &ConfiguredClsid,
  279. &ImplementedClsid));
  280. // See if we already have a file context; if we do not, allocate one.
  281. if (ComGlobalContext->m_FileNameBuffer.Cch() != 0)
  282. {
  283. IFW32FALSE_EXIT(FileContext.Win32Allocate(__FILE__, __LINE__));
  284. fNewAllocate = TRUE;
  285. IFW32FALSE_EXIT(FileContext->m_FileNameBuffer.Win32Assign(ComGlobalContext->m_FileNameBuffer));
  286. ComGlobalContext->m_FileContextList.AddToHead(FileContext.DetachAndHold());
  287. FileContext->m_GlobalContext = ComGlobalContext;
  288. }
  289. else
  290. {
  291. CComFileDequeIterator Iter(&ComGlobalContext->m_FileContextList);
  292. Iter.Reset();
  293. FileContext.AttachNoDelete(Iter);
  294. }
  295. ASSERT(FileContext != NULL);
  296. IFW32FALSE_EXIT(Entry.Win32Allocate(__FILE__, __LINE__));
  297. Entry->m_ShimType = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_OTHER;
  298. Entry->m_ReferenceClsid = ReferenceClsid;
  299. Entry->m_ConfiguredClsid = ConfiguredClsid;
  300. Entry->m_ImplementedClsid = ImplementedClsid;
  301. Entry->m_TypeLibraryId = TypeLibraryId;
  302. Entry->m_ThreadingModel = ThreadingModel;
  303. Entry->m_FileContext = FileContext.DetachAndHold();
  304. IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32Assign(ProgIdBuffer));
  305. IFW32FALSE_EXIT(
  306. ::SxsAddGuidToGuidSectionGenerationContext(
  307. (PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  308. &ReferenceClsid,
  309. Entry,
  310. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  311. ERROR_SXS_DUPLICATE_CLSID));
  312. FileContext->m_ServerList.AddToHead(Entry.Detach());
  313. // And we add another, indexed by the configured clsid
  314. IFW32FALSE_EXIT(Entry.Win32Allocate(__FILE__, __LINE__));
  315. Entry->m_ReferenceClsid = ReferenceClsid;
  316. Entry->m_ConfiguredClsid = ConfiguredClsid;
  317. Entry->m_ImplementedClsid = ImplementedClsid;
  318. Entry->m_TypeLibraryId = TypeLibraryId;
  319. Entry->m_ThreadingModel = ThreadingModel;
  320. Entry->m_FileContext = FileContext;
  321. IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32Assign(ProgIdBuffer));
  322. IFW32FALSE_EXIT(
  323. ::SxsAddGuidToGuidSectionGenerationContext(
  324. (PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  325. &ConfiguredClsid,
  326. Entry,
  327. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  328. ERROR_SXS_DUPLICATE_CLSID));
  329. FileContext->m_ServerList.AddToHead(Entry.Detach());
  330. }
  331. }
  332. else if (
  333. (Data->ElementParsed.ParseContext->XMLElementDepth == 3) &&
  334. (::FusionpCompareStrings(
  335. Data->ElementParsed.ParseContext->ElementPath,
  336. Data->ElementParsed.ParseContext->ElementPathCch,
  337. L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comInterfaceProxyStub",
  338. NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comInterfaceProxyStub") - 1,
  339. false) == 0))
  340. {
  341. INTERNAL_ERROR_CHECK2(
  342. ComGlobalContext != NULL,
  343. "COM global context NULL while processing comInterfaceProxyStub tag");
  344. CSmartPtr<COM_SERVER_ENTRY> Entry;
  345. CSmartPtr<COM_FILE_CONTEXT> FileContext;
  346. CStringBuffer &TempBuffer = ComGlobalContext->CallbackLocals.TempBuffer;
  347. TempBuffer.Clear();
  348. IFW32FALSE_EXIT(
  349. ::SxspGetAttributeValue(
  350. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  351. &s_AttributeName_iid,
  352. &Data->ElementParsed,
  353. fFound,
  354. sizeof(iid),
  355. &iid,
  356. cb,
  357. &::SxspValidateGuidAttribute,
  358. 0));
  359. IFW32FALSE_EXIT(
  360. ::SxspGetAttributeValue(
  361. 0,
  362. &s_AttributeName_proxyStubClsid32,
  363. &Data->ElementParsed,
  364. fFound,
  365. sizeof(ReferenceClsid),
  366. &ReferenceClsid,
  367. cb,
  368. &::SxspValidateGuidAttribute,
  369. 0));
  370. if (!fFound)
  371. ReferenceClsid = iid;
  372. ThreadingModel = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_BOTH;
  373. // That was sufficient if we are generating a context.
  374. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  375. {
  376. IFW32FALSE_EXIT(Data->Header.ClsidMappingContext->Map->MapReferenceClsidToConfiguredClsid(
  377. &ReferenceClsid,
  378. Data->ElementParsed.AssemblyContext,
  379. &ConfiguredClsid,
  380. &ImplementedClsid));
  381. // See if we already have a file context; if we do not, allocate one.
  382. if (ComGlobalContext->m_FileNameBuffer.Cch() != 0)
  383. {
  384. IFW32FALSE_EXIT(FileContext.Win32Allocate(__FILE__, __LINE__));
  385. IFW32FALSE_EXIT(FileContext->m_FileNameBuffer.Win32Assign(ComGlobalContext->m_FileNameBuffer));
  386. ComGlobalContext->m_FileContextList.AddToHead(FileContext.DetachAndHold());
  387. FileContext->m_GlobalContext = ComGlobalContext;
  388. }
  389. else
  390. {
  391. CComFileDequeIterator Iter(&ComGlobalContext->m_FileContextList);
  392. Iter.Reset();
  393. FileContext.AttachNoDelete(Iter);
  394. }
  395. INTERNAL_ERROR_CHECK(FileContext != NULL);
  396. IFW32FALSE_EXIT(Entry.Win32Allocate(__FILE__, __LINE__));
  397. Entry->m_ShimType = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_OTHER;
  398. Entry->m_ReferenceClsid = ReferenceClsid;
  399. Entry->m_ConfiguredClsid = ConfiguredClsid;
  400. Entry->m_ImplementedClsid = ImplementedClsid;
  401. Entry->m_TypeLibraryId = GUID_NULL;
  402. Entry->m_ThreadingModel = ThreadingModel;
  403. Entry->m_FileContext = FileContext;
  404. Entry->m_ProgIdBuffer.Clear();
  405. IFW32FALSE_EXIT(
  406. ::SxsAddGuidToGuidSectionGenerationContext(
  407. (PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  408. &ReferenceClsid,
  409. Entry,
  410. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  411. ERROR_SXS_DUPLICATE_CLSID));
  412. FileContext->m_ServerList.AddToHead(Entry.Detach());
  413. // We don't want to delete the FileContext on exit any more if it was newly allocated
  414. FileContext.DetachAndHold();
  415. // And we add another, indexed by the configured clsid
  416. IFW32FALSE_EXIT(Entry.Win32Allocate(__FILE__, __LINE__));
  417. Entry->m_ReferenceClsid = ReferenceClsid;
  418. Entry->m_ConfiguredClsid = ConfiguredClsid;
  419. Entry->m_ImplementedClsid = ImplementedClsid;
  420. Entry->m_TypeLibraryId = GUID_NULL;
  421. Entry->m_ThreadingModel = ThreadingModel;
  422. Entry->m_FileContext = FileContext;
  423. Entry->m_ProgIdBuffer.Clear();
  424. IFW32FALSE_EXIT(
  425. ::SxsAddGuidToGuidSectionGenerationContext(
  426. (PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  427. &ConfiguredClsid,
  428. Entry,
  429. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  430. ERROR_SXS_DUPLICATE_CLSID));
  431. FileContext->m_ServerList.AddToHead(Entry.Detach());
  432. }
  433. }
  434. else if (
  435. (Data->ElementParsed.ParseContext->XMLElementDepth == 2) &&
  436. (::FusionpCompareStrings(
  437. Data->ElementParsed.ParseContext->ElementPath,
  438. Data->ElementParsed.ParseContext->ElementPathCch,
  439. L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^clrClass",
  440. NUMBER_OF(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^clrClass") - 1,
  441. false) == 0))
  442. {
  443. INTERNAL_ERROR_CHECK2(
  444. ComGlobalContext != NULL,
  445. "COM global context NULL while processing ndpClass tag");
  446. CSmallStringBuffer &VersionIndependentComClassIdBuffer = ComGlobalContext->CallbackLocals.VersionIndependentComClassIdBuffer;
  447. VersionIndependentComClassIdBuffer.Clear();
  448. CSmartPtr<COM_SERVER_ENTRY> Entry;
  449. CSmartPtr<COM_FILE_CONTEXT> FileContext;
  450. CStringBuffer &TempBuffer = ComGlobalContext->CallbackLocals.TempBuffer;
  451. TempBuffer.Clear();
  452. CSmallStringBuffer &ProgIdBuffer = ComGlobalContext->CallbackLocals.ProgIdBuffer;
  453. ProgIdBuffer.Clear();
  454. CSmallStringBuffer &RuntimeVersionBuffer = ComGlobalContext->CallbackLocals.RuntimeVersionBuffer;
  455. RuntimeVersionBuffer.Clear();
  456. CSmallStringBuffer &NameBuffer = ComGlobalContext->CallbackLocals.NameBuffer;
  457. NameBuffer.Clear();
  458. bool fIsFirstShim = false;
  459. IFW32FALSE_EXIT(
  460. ::SxspGetAttributeValue(
  461. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  462. &s_AttributeName_name,
  463. &Data->ElementParsed,
  464. fFound,
  465. sizeof(NameBuffer),
  466. &NameBuffer,
  467. cb,
  468. NULL,
  469. 0));
  470. INTERNAL_ERROR_CHECK(fFound);
  471. IFW32FALSE_EXIT(
  472. ::SxspGetAttributeValue(
  473. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  474. &s_AttributeName_clsid,
  475. &Data->ElementParsed,
  476. fFound,
  477. sizeof(VersionIndependentComClassIdBuffer),
  478. &VersionIndependentComClassIdBuffer,
  479. cb,
  480. NULL,
  481. 0));
  482. INTERNAL_ERROR_CHECK(fFound);
  483. IFW32FALSE_EXIT(
  484. ::SxspParseGUID(
  485. VersionIndependentComClassIdBuffer,
  486. VersionIndependentComClassIdBuffer.Cch(),
  487. ReferenceClsid));
  488. IFW32FALSE_EXIT(
  489. ::SxspGetAttributeValue(
  490. 0,
  491. &s_AttributeName_threadingModel,
  492. &Data->ElementParsed,
  493. fFound,
  494. sizeof(TempBuffer),
  495. &TempBuffer,
  496. cb,
  497. NULL,
  498. 0));
  499. if (fFound)
  500. IFW32FALSE_EXIT(::SxspParseThreadingModel(TempBuffer, TempBuffer.Cch(), &ThreadingModel));
  501. else
  502. ThreadingModel = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_THREADING_MODEL_BOTH;
  503. IFW32FALSE_EXIT(
  504. ::SxspGetAttributeValue(
  505. 0,
  506. &s_AttributeName_progid,
  507. &Data->ElementParsed,
  508. fFound,
  509. sizeof(ProgIdBuffer),
  510. &ProgIdBuffer,
  511. cb,
  512. NULL,
  513. 0));
  514. IFW32FALSE_EXIT(
  515. ::SxspGetAttributeValue(
  516. 0,
  517. &s_AttributeName_tlbid,
  518. &Data->ElementParsed,
  519. fFound,
  520. sizeof(TempBuffer),
  521. &TempBuffer,
  522. cb,
  523. NULL,
  524. 0));
  525. if (fFound)
  526. IFW32FALSE_EXIT(::SxspParseGUID(TempBuffer, TempBuffer.Cch(), TypeLibraryId));
  527. else
  528. TypeLibraryId = GUID_NULL;
  529. IFW32FALSE_EXIT(
  530. ::SxspGetAttributeValue(
  531. 0,
  532. &s_AttributeName_runtimeVersion,
  533. &Data->ElementParsed,
  534. fFound,
  535. sizeof(RuntimeVersionBuffer),
  536. &RuntimeVersionBuffer,
  537. cb,
  538. NULL,
  539. 0));
  540. // That was sufficient if we are generating a context.
  541. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  542. {
  543. if (ComGlobalContext->m_FirstShimNameBuffer.Cch() == 0)
  544. {
  545. fIsFirstShim = true;
  546. IFW32FALSE_EXIT(ComGlobalContext->m_FirstShimNameBuffer.Win32Assign(L"MSCOREE.DLL", 11));
  547. }
  548. else
  549. {
  550. IFW32FALSE_EXIT(
  551. ComGlobalContext->m_FirstShimNameBuffer.Win32Equals(
  552. L"MSCOREE.DLL", 11,
  553. fIsFirstShim,
  554. true));
  555. }
  556. IFW32FALSE_EXIT(
  557. Data->Header.ClsidMappingContext->Map->MapReferenceClsidToConfiguredClsid(
  558. &ReferenceClsid,
  559. Data->ElementParsed.AssemblyContext,
  560. &ConfiguredClsid,
  561. &ImplementedClsid));
  562. // If we don't already have a file context for mscoree, then we have to create a new one.
  563. if (ComGlobalContext->m_MscoreeFileContext == NULL)
  564. {
  565. IFW32FALSE_EXIT(FileContext.Win32Allocate(__FILE__, __LINE__));
  566. IFW32FALSE_EXIT(FileContext->m_FileNameBuffer.Win32Assign("mscoree.dll", 11));
  567. ComGlobalContext->m_FileContextList.AddToHead(FileContext.DetachAndHold());
  568. ComGlobalContext->m_MscoreeFileContext = FileContext;
  569. FileContext->m_GlobalContext = ComGlobalContext;
  570. }
  571. else
  572. {
  573. FileContext.AttachNoDelete(ComGlobalContext->m_MscoreeFileContext);
  574. }
  575. INTERNAL_ERROR_CHECK(FileContext != NULL);
  576. IFW32FALSE_EXIT(Entry.Win32Allocate(__FILE__, __LINE__));
  577. Entry->m_ShimType = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_CLR_CLASS;
  578. Entry->m_ReferenceClsid = ReferenceClsid;
  579. Entry->m_ConfiguredClsid = ConfiguredClsid;
  580. Entry->m_ImplementedClsid = ImplementedClsid;
  581. Entry->m_TypeLibraryId = TypeLibraryId;
  582. Entry->m_ThreadingModel = ThreadingModel;
  583. Entry->m_FileContext = FileContext;
  584. IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32Assign(ProgIdBuffer));
  585. IFW32FALSE_EXIT(Entry->m_ShimNameBuffer.Win32Assign(L"MSCOREE.DLL", 11));
  586. IFW32FALSE_EXIT(Entry->m_RuntimeVersionBuffer.Win32Assign(RuntimeVersionBuffer));
  587. IFW32FALSE_EXIT(Entry->m_TypeNameBuffer.Win32Assign(NameBuffer));
  588. Entry->m_IsFirstShim = fIsFirstShim;
  589. IFW32FALSE_EXIT(
  590. ::SxsAddGuidToGuidSectionGenerationContext(
  591. (PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  592. &ReferenceClsid,
  593. Entry,
  594. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  595. ERROR_SXS_DUPLICATE_CLSID));
  596. FileContext->m_ServerList.AddToHead(Entry.Detach());
  597. // We don't need to delete FileContext on exit any more...
  598. FileContext.DetachAndHold();
  599. // And we add another, indexed by the configured clsid
  600. IFW32FALSE_EXIT(Entry.Win32Allocate(__FILE__, __LINE__));
  601. Entry->m_ShimType = ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM_TYPE_CLR_CLASS;
  602. Entry->m_ReferenceClsid = ReferenceClsid;
  603. Entry->m_ConfiguredClsid = ConfiguredClsid;
  604. Entry->m_ImplementedClsid = ImplementedClsid;
  605. Entry->m_TypeLibraryId = TypeLibraryId;
  606. Entry->m_ThreadingModel = ThreadingModel;
  607. Entry->m_FileContext = FileContext;
  608. IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32Assign(ProgIdBuffer));
  609. IFW32FALSE_EXIT(Entry->m_ShimNameBuffer.Win32Assign(L"MSCOREE.DLL", 11));
  610. IFW32FALSE_EXIT(Entry->m_TypeNameBuffer.Win32Assign(NameBuffer));
  611. IFW32FALSE_EXIT(Entry->m_RuntimeVersionBuffer.Win32Assign(RuntimeVersionBuffer));
  612. Entry->m_IsFirstShim = fIsFirstShim;
  613. IFW32FALSE_EXIT(
  614. ::SxsAddGuidToGuidSectionGenerationContext(
  615. (PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  616. &ConfiguredClsid,
  617. Entry,
  618. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  619. ERROR_SXS_DUPLICATE_CLSID));
  620. FileContext->m_ServerList.AddToHead(Entry.Detach());
  621. }
  622. }
  623. // Everything's groovy!
  624. Data->ElementParsed.Success = TRUE;
  625. break;
  626. case ACTCTXCTB_CBREASON_GETSECTIONDATA:
  627. Data->GetSectionData.Success = FALSE;
  628. INTERNAL_ERROR_CHECK(GSGenContext != NULL);
  629. INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  630. IFW32FALSE_EXIT(::SxsGetGuidSectionGenerationContextSectionData(GSGenContext, Data->GetSectionData.SectionSize, Data->GetSectionData.SectionDataStart, NULL));
  631. Data->GetSectionData.Success = TRUE;
  632. break;
  633. }
  634. Exit:
  635. ;
  636. }
  637. BOOL
  638. SxspComClassRedirectionGuidSectionGenerationCallback(
  639. PVOID Context,
  640. ULONG Reason,
  641. PVOID CallbackData
  642. )
  643. {
  644. BOOL fSuccess = FALSE;
  645. FN_TRACE_WIN32(fSuccess);
  646. PCOM_GLOBAL_CONTEXT ComGlobalContext = (PCOM_GLOBAL_CONTEXT) Context;
  647. INTERNAL_ERROR_CHECK(CallbackData != NULL);
  648. switch (Reason)
  649. {
  650. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETUSERDATASIZE:
  651. {
  652. INTERNAL_ERROR_CHECK(ComGlobalContext != NULL);
  653. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATASIZE CBData =
  654. (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATASIZE) CallbackData;
  655. CComFileDequeIterator Iter(&ComGlobalContext->m_FileContextList);
  656. CBData->DataSize = 0;
  657. // If we have a mscoree shim, add its size to the user data buffer area.
  658. if (ComGlobalContext->m_FirstShimNameBuffer.Cch() != 0)
  659. CBData->DataSize += ((ComGlobalContext->m_FirstShimNameBuffer.Cch() + 1) * sizeof(WCHAR));
  660. for (Iter.Reset(); Iter.More(); Iter.Next())
  661. {
  662. CBData->DataSize += ((Iter->m_FileNameBuffer.Cch() + 1) * sizeof(WCHAR));
  663. }
  664. break;
  665. }
  666. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETUSERDATA:
  667. {
  668. INTERNAL_ERROR_CHECK( ComGlobalContext != NULL );
  669. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATA CBData =
  670. (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATA) CallbackData;
  671. SIZE_T BytesWritten = 0;
  672. SIZE_T BytesLeft = CBData->BufferSize;
  673. PWSTR Cursor = (PWSTR) CBData->Buffer;
  674. CComFileDequeIterator Iter(&ComGlobalContext->m_FileContextList);
  675. if (ComGlobalContext->m_FirstShimNameBuffer.Cch() != 0)
  676. {
  677. IFW32FALSE_EXIT(
  678. ComGlobalContext->m_FirstShimNameBuffer.Win32CopyIntoBuffer(
  679. &Cursor,
  680. &BytesLeft,
  681. &BytesWritten,
  682. CBData->SectionHeader,
  683. &ComGlobalContext->m_FirstShimNameOffset,
  684. &ComGlobalContext->m_FirstShimNameLength));
  685. }
  686. for (Iter.Reset(); Iter.More(); Iter.Next())
  687. {
  688. IFW32FALSE_EXIT(
  689. Iter->m_FileNameBuffer.Win32CopyIntoBuffer(
  690. &Cursor,
  691. &BytesLeft,
  692. &BytesWritten,
  693. CBData->SectionHeader,
  694. &Iter->m_Offset,
  695. NULL)); // the length is tracked elsewhere
  696. }
  697. CBData->BytesWritten = BytesWritten;
  698. break;
  699. }
  700. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_ENTRYDELETED:
  701. {
  702. INTERNAL_ERROR_CHECK( ComGlobalContext != NULL );
  703. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED CBData =
  704. (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED) CallbackData;
  705. PCOM_SERVER_ENTRY Entry = (PCOM_SERVER_ENTRY) CBData->DataContext;
  706. if (Entry != NULL)
  707. {
  708. if (Entry->m_FileContext != NULL)
  709. {
  710. Entry->m_FileContext->m_ServerList.Remove(Entry);
  711. //
  712. // If that was the last entry in the file's server list, destroy the
  713. // file entry (remove from global context, free
  714. //
  715. if (Entry->m_FileContext->m_ServerList.IsEmpty())
  716. {
  717. ComGlobalContext->m_FileContextList.Remove(Entry->m_FileContext);
  718. FUSION_DELETE_SINGLETON(Entry->m_FileContext);
  719. Entry->m_FileContext = NULL;
  720. }
  721. }
  722. FUSION_DELETE_SINGLETON(Entry);
  723. }
  724. break;
  725. }
  726. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATASIZE:
  727. {
  728. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE CBData =
  729. (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE) CallbackData;
  730. PCOM_SERVER_ENTRY Entry = (PCOM_SERVER_ENTRY) CBData->DataContext;
  731. CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION);
  732. if (Entry->m_ProgIdBuffer.Cch() != 0)
  733. CBData->DataSize += ((Entry->m_ProgIdBuffer.Cch() + 1) * sizeof(WCHAR));
  734. if (Entry->m_ShimNameBuffer.Cch() != 0)
  735. {
  736. CBData->DataSize += sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM);
  737. if (Entry->m_RuntimeVersionBuffer.Cch() != 0)
  738. CBData->DataSize += ((Entry->m_RuntimeVersionBuffer.Cch() + 1) * sizeof(WCHAR));
  739. if (!Entry->m_IsFirstShim)
  740. CBData->DataSize += ((Entry->m_ShimNameBuffer.Cch() + 1) * sizeof(WCHAR));
  741. if (Entry->m_TypeNameBuffer.Cch() != 0)
  742. CBData->DataSize += ((Entry->m_TypeNameBuffer.Cch() + 1) * sizeof(WCHAR));
  743. }
  744. break;
  745. }
  746. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATA:
  747. {
  748. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA CBData =
  749. (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA) CallbackData;
  750. PCOM_SERVER_ENTRY Entry = (PCOM_SERVER_ENTRY) CBData->DataContext;
  751. PACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION Info;
  752. PACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM ShimInfo = NULL;
  753. PVOID Cursor = CBData->Buffer;
  754. SIZE_T BytesLeft = CBData->BufferSize;
  755. SIZE_T BytesWritten = 0;
  756. ALLOCATE_BUFFER_SPACE_TYPE(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION, Cursor, BytesLeft, BytesWritten, Info);
  757. Info->Size = sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION);
  758. Info->Flags = 0;
  759. Info->ThreadingModel = Entry->m_ThreadingModel;
  760. Info->ReferenceClsid = Entry->m_ReferenceClsid;
  761. Info->ConfiguredClsid = Entry->m_ConfiguredClsid;
  762. Info->ImplementedClsid = Entry->m_ImplementedClsid;
  763. Info->TypeLibraryId = Entry->m_TypeLibraryId;
  764. if (Entry->m_ShimNameBuffer.Cch() != 0)
  765. {
  766. PWSTR ShimName = NULL;
  767. SIZE_T OldBytesWritten = BytesWritten;
  768. SIZE_T ShimDataSize = 0;
  769. ALLOCATE_BUFFER_SPACE_TYPE(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM, Cursor, BytesLeft, BytesWritten, ShimInfo);
  770. IFW32FALSE_EXIT(
  771. Entry->m_TypeNameBuffer.Win32CopyIntoBuffer(
  772. (PWSTR *) &Cursor,
  773. &BytesLeft,
  774. &BytesWritten,
  775. ShimInfo,
  776. &ShimInfo->TypeOffset,
  777. &ShimInfo->TypeLength));
  778. ShimInfo->ModuleLength = static_cast<ULONG>(Entry->m_FileContext->m_FileNameBuffer.Cch() * sizeof(WCHAR));
  779. ShimInfo->ModuleOffset = Entry->m_FileContext->m_Offset;
  780. IFW32FALSE_EXIT(
  781. Entry->m_RuntimeVersionBuffer.Win32CopyIntoBuffer(
  782. (PWSTR *) &Cursor,
  783. &BytesLeft,
  784. &BytesWritten,
  785. ShimInfo,
  786. &ShimInfo->ShimVersionOffset,
  787. &ShimInfo->ShimVersionLength));
  788. ShimDataSize = BytesWritten - OldBytesWritten;
  789. if (Entry->m_IsFirstShim)
  790. {
  791. Info->ModuleOffset = Entry->m_FileContext->m_GlobalContext->m_FirstShimNameOffset;
  792. Info->ModuleLength = Entry->m_FileContext->m_GlobalContext->m_FirstShimNameLength;
  793. }
  794. else
  795. {
  796. IFW32FALSE_EXIT(
  797. Entry->m_ShimNameBuffer.Win32CopyIntoBuffer(
  798. (PWSTR *) &Cursor,
  799. &BytesLeft,
  800. &BytesWritten,
  801. CBData->SectionHeader,
  802. &Info->ModuleOffset,
  803. &Info->ModuleLength));
  804. }
  805. ShimInfo->Size = sizeof(ACTIVATION_CONTEXT_DATA_COM_SERVER_REDIRECTION_SHIM);
  806. ShimInfo->Flags = 0;
  807. ShimInfo->Type = Entry->m_ShimType;
  808. ShimInfo->DataLength = 0;
  809. ShimInfo->DataOffset = 0;
  810. Info->ShimDataLength = static_cast<ULONG>(ShimDataSize);
  811. Info->ShimDataOffset = static_cast<ULONG>(((ULONG_PTR) ShimInfo) - ((ULONG_PTR) Info));
  812. }
  813. else
  814. {
  815. Info->ModuleLength = static_cast<ULONG>(Entry->m_FileContext->m_FileNameBuffer.Cch() * sizeof(WCHAR));
  816. Info->ModuleOffset = Entry->m_FileContext->m_Offset;
  817. Info->ShimDataLength = 0;
  818. Info->ShimDataOffset = 0;
  819. }
  820. IFW32FALSE_EXIT(Entry->m_ProgIdBuffer.Win32CopyIntoBuffer(
  821. (PWSTR *) &Cursor,
  822. &BytesLeft,
  823. &BytesWritten,
  824. Info,
  825. &Info->ProgIdOffset,
  826. &Info->ProgIdLength));
  827. CBData->BytesWritten = BytesWritten;
  828. }
  829. }
  830. fSuccess = TRUE;
  831. Exit:
  832. return fSuccess;
  833. }