Source code of Windows XP (NT5)
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.

365 lines
11 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. clrclassinfo.cpp
  5. Abstract:
  6. CLR 'surrogate' contributor for Win32-CLR interop assemblies
  7. Author:
  8. Jon Wiswall (jonwis) March, 2002 (heavily borrowed from comclass.cpp)
  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(name);
  16. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(runtimeVersion);
  17. #define ALLOCATE_BUFFER_SPACE(_bytesNeeded, _bufferCursor, _bytesLeft, _bytesWritten, _typeName, _ptr) \
  18. do { \
  19. if (_bytesLeft < (_bytesNeeded)) \
  20. ORIGINATE_WIN32_FAILURE_AND_EXIT(NoRoom, ERROR_INSUFFICIENT_BUFFER); \
  21. _bytesLeft -= (_bytesNeeded); \
  22. _bytesWritten += (_bytesNeeded); \
  23. _ptr = (_typeName) _bufferCursor; \
  24. _bufferCursor = (PVOID) (((ULONG_PTR) _bufferCursor) + (_bytesNeeded)); \
  25. } while (0)
  26. #define ALLOCATE_BUFFER_SPACE_TYPE(_typeName, _bufferCursor, _bytesLeft, _bytesWritten, _ptr) \
  27. ALLOCATE_BUFFER_SPACE(sizeof(_typeName), _bufferCursor, _bytesLeft, _bytesWritten, _typeName *, _ptr)
  28. typedef struct _CLR_GLOBAL_CONTEXT *PCLR_GLOBAL_CONTEXT;
  29. typedef struct _CLR_SURROGATE_ENTRY *PCLR_SURROGATE_ENTRY;
  30. typedef struct _CLR_GLOBAL_CONTEXT
  31. {
  32. _CLR_GLOBAL_CONTEXT() { }
  33. CSmallStringBuffer m_FileNameBuffer;
  34. PCLR_SURROGATE_ENTRY m_SurrogateList;
  35. ULONG m_SurrogateListCount;
  36. private:
  37. _CLR_GLOBAL_CONTEXT(const _CLR_GLOBAL_CONTEXT &);
  38. void operator =(const _CLR_GLOBAL_CONTEXT &);
  39. } CLR_GLOBAL_CONTEXT;
  40. typedef struct _CLR_SURROGATE_ENTRY
  41. {
  42. public:
  43. _CLR_SURROGATE_ENTRY() { }
  44. PCLR_SURROGATE_ENTRY m_Next;
  45. PCLR_GLOBAL_CONTEXT m_GlobalContext;
  46. GUID m_ReferenceClsid;
  47. CSmallStringBuffer m_TypeName;
  48. CSmallStringBuffer m_RuntimeVersion;
  49. private:
  50. _CLR_SURROGATE_ENTRY(const _CLR_SURROGATE_ENTRY &);
  51. void operator =(const _CLR_SURROGATE_ENTRY &);
  52. } CLR_SURROGATE_ENTRY;
  53. BOOL
  54. SxspClrSurrogateAddSurrogate(
  55. PACTCTXCTB_CBELEMENTPARSED SurrogateParsed,
  56. PCLR_GLOBAL_CONTEXT pGlobalContext,
  57. PGUID_SECTION_GENERATION_CONTEXT pGsGenCtx
  58. );
  59. VOID
  60. WINAPI
  61. SxspClrInteropContributorCallback(
  62. PACTCTXCTB_CALLBACK_DATA Data
  63. )
  64. {
  65. FN_TRACE();
  66. PGUID_SECTION_GENERATION_CONTEXT GSGenContext = (PGUID_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext;
  67. PCLR_GLOBAL_CONTEXT ClrGlobalContext = NULL;
  68. if (GSGenContext != NULL)
  69. ClrGlobalContext = (PCLR_GLOBAL_CONTEXT)SxsGetGuidSectionGenerationContextCallbackContext(GSGenContext);
  70. switch (Data->Header.Reason)
  71. {
  72. case ACTCTXCTB_CBREASON_GETSECTIONDATA:
  73. Data->GetSectionData.Success = FALSE;
  74. INTERNAL_ERROR_CHECK(GSGenContext != NULL);
  75. INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  76. IFW32FALSE_EXIT(::SxsGetGuidSectionGenerationContextSectionData(GSGenContext, Data->GetSectionData.SectionSize, Data->GetSectionData.SectionDataStart, NULL));
  77. Data->GetSectionData.Success = TRUE;
  78. break;
  79. case ACTCTXCTB_CBREASON_ACTCTXGENBEGINNING:
  80. Data->GenBeginning.Success = FALSE;
  81. INTERNAL_ERROR_CHECK(ClrGlobalContext == NULL);
  82. INTERNAL_ERROR_CHECK(GSGenContext == NULL);
  83. IFALLOCFAILED_EXIT(ClrGlobalContext = FUSION_NEW_SINGLETON(CLR_GLOBAL_CONTEXT));
  84. ClrGlobalContext->m_SurrogateList = NULL;
  85. ClrGlobalContext->m_SurrogateListCount = 0;
  86. IFW32FALSE_EXIT(
  87. ::SxsInitGuidSectionGenerationContext(
  88. &GSGenContext,
  89. ACTIVATION_CONTEXT_DATA_CLR_SURROGATE_FORMAT_WHISTLER,
  90. &::SxspClrInteropGuidSectionGenerationCallback,
  91. ClrGlobalContext));
  92. ClrGlobalContext = NULL;
  93. Data->Header.ActCtxGenContext = GSGenContext;
  94. Data->GenBeginning.Success = TRUE;
  95. break;
  96. case ACTCTXCTB_CBREASON_ACTCTXGENENDED:
  97. if (GSGenContext != NULL)
  98. ::SxsDestroyGuidSectionGenerationContext(GSGenContext);
  99. FUSION_DELETE_SINGLETON(ClrGlobalContext);
  100. ClrGlobalContext = NULL;
  101. break;
  102. case ACTCTXCTB_CBREASON_ALLPARSINGDONE:
  103. Data->AllParsingDone.Success = FALSE;
  104. #if 0
  105. if (GSGenContext != NULL)
  106. IFW32FALSE_EXIT(::SxsDoneModifyingGuidSectionGenerationContext(GSGenContext));
  107. #endif
  108. Data->AllParsingDone.Success = TRUE;
  109. break;
  110. case ACTCTXCTB_CBREASON_GETSECTIONSIZE:
  111. Data->GetSectionSize.Success = FALSE;
  112. INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  113. INTERNAL_ERROR_CHECK(GSGenContext != NULL);
  114. IFW32FALSE_EXIT(::SxsGetGuidSectionGenerationContextSectionSize(GSGenContext, &Data->GetSectionSize.SectionSize));
  115. Data->GetSectionSize.Success = TRUE;
  116. break;
  117. case ACTCTXCTB_CBREASON_ELEMENTPARSED:
  118. {
  119. ULONG MappedValue = 0;
  120. bool fFound = false;
  121. enum MappedValues {
  122. eClrSurrogate,
  123. };
  124. static const WCHAR ELEMENT_PATH_BUILTIN_CLR_SURROGATE[] = L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^clrSurrogate";
  125. static const ELEMENT_PATH_MAP_ENTRY s_rgEntries[] =
  126. {
  127. { 2, ELEMENT_PATH_BUILTIN_CLR_SURROGATE, NUMBER_OF(ELEMENT_PATH_BUILTIN_CLR_SURROGATE)-1, eClrSurrogate },
  128. };
  129. Data->ElementParsed.Success = FALSE;
  130. IFW32FALSE_EXIT(::SxspProcessElementPathMap(
  131. Data->ElementParsed.ParseContext,
  132. s_rgEntries,
  133. NUMBER_OF(s_rgEntries),
  134. MappedValue,
  135. fFound));
  136. if (!fFound)
  137. {
  138. Data->ElementParsed.Success = TRUE;
  139. break;
  140. }
  141. switch (MappedValue) {
  142. case eClrSurrogate:
  143. if (SxspClrSurrogateAddSurrogate(&Data->ElementParsed, ClrGlobalContext, GSGenContext))
  144. Data->ElementParsed.Success = TRUE;
  145. break;
  146. }
  147. }
  148. }
  149. FN_EPILOG
  150. }
  151. BOOL
  152. SxspClrSurrogateAddSurrogate(
  153. PACTCTXCTB_CBELEMENTPARSED SurrogateParsed,
  154. PCLR_GLOBAL_CONTEXT pGlobalContext,
  155. PGUID_SECTION_GENERATION_CONTEXT pGsGenCtx
  156. )
  157. {
  158. FN_PROLOG_WIN32;
  159. CSmallStringBuffer RuntimeVersionBuffer;
  160. CSmallStringBuffer SurrogateClassNameBuffer;
  161. CSmallStringBuffer ClsidBuffer;
  162. GUID SurrogateIdent = GUID_NULL;
  163. bool fFound = false;
  164. SIZE_T cbWritten;
  165. PCLR_SURROGATE_ENTRY Entry;
  166. bool fFileContextSelfAllocated = false;
  167. INTERNAL_ERROR_CHECK(pGlobalContext);
  168. IFW32FALSE_EXIT(::SxspGetAttributeValue(
  169. 0,
  170. &s_AttributeName_runtimeVersion,
  171. SurrogateParsed,
  172. fFound,
  173. sizeof(RuntimeVersionBuffer),
  174. &RuntimeVersionBuffer,
  175. cbWritten,
  176. NULL, 0));
  177. IFW32FALSE_EXIT(::SxspGetAttributeValue(
  178. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  179. &s_AttributeName_name,
  180. SurrogateParsed,
  181. fFound,
  182. sizeof(SurrogateClassNameBuffer),
  183. &SurrogateClassNameBuffer,
  184. cbWritten,
  185. NULL, 0));
  186. INTERNAL_ERROR_CHECK(fFound);
  187. IFW32FALSE_EXIT(::SxspGetAttributeValue(
  188. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  189. &s_AttributeName_clsid,
  190. SurrogateParsed,
  191. fFound,
  192. sizeof(ClsidBuffer),
  193. &ClsidBuffer,
  194. cbWritten,
  195. NULL, 0));
  196. INTERNAL_ERROR_CHECK(fFound);
  197. IFW32FALSE_EXIT(SxspParseGUID(ClsidBuffer, ClsidBuffer.Cch(), SurrogateIdent));
  198. //
  199. // If we were doing something other than generating an actctx, then we can leap out.
  200. //
  201. if (SurrogateParsed->Header.ManifestOperation != MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  202. FN_SUCCESSFUL_EXIT();
  203. IFALLOCFAILED_EXIT(Entry = FUSION_NEW_SINGLETON(CLR_SURROGATE_ENTRY));
  204. Entry->m_ReferenceClsid = SurrogateIdent;
  205. IFW32FALSE_EXIT(Entry->m_RuntimeVersion.Win32Assign(RuntimeVersionBuffer));
  206. IFW32FALSE_EXIT(Entry->m_TypeName.Win32Assign(SurrogateClassNameBuffer));
  207. IFW32FALSE_EXIT(::SxsAddGuidToGuidSectionGenerationContext(
  208. pGsGenCtx,
  209. &SurrogateIdent,
  210. Entry,
  211. SurrogateParsed->AssemblyContext->AssemblyRosterIndex,
  212. ERROR_SXS_DUPLICATE_CLSID));
  213. Entry->m_Next = pGlobalContext->m_SurrogateList;
  214. pGlobalContext->m_SurrogateList = Entry->m_Next;
  215. pGlobalContext->m_SurrogateListCount++;
  216. FN_EPILOG;
  217. }
  218. BOOL WINAPI
  219. SxspClrInteropGuidSectionGenerationCallback(
  220. PVOID Context,
  221. ULONG Reason,
  222. PVOID CallbackData
  223. )
  224. {
  225. FN_PROLOG_WIN32
  226. PCLR_GLOBAL_CONTEXT ClrGlobalContext = (PCLR_GLOBAL_CONTEXT) Context;
  227. INTERNAL_ERROR_CHECK(CallbackData != NULL);
  228. switch (Reason)
  229. {
  230. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_ENTRYDELETED:
  231. {
  232. INTERNAL_ERROR_CHECK( ClrGlobalContext != NULL );
  233. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED CBData =
  234. (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED) CallbackData;
  235. PCLR_SURROGATE_ENTRY Entry = (PCLR_SURROGATE_ENTRY) CBData->DataContext;
  236. if (Entry != NULL)
  237. {
  238. FUSION_DELETE_SINGLETON(Entry);
  239. }
  240. break;
  241. }
  242. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATASIZE:
  243. {
  244. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE CBData =
  245. (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE) CallbackData;
  246. PCLR_SURROGATE_ENTRY Entry = (PCLR_SURROGATE_ENTRY) CBData->DataContext;
  247. INTERNAL_ERROR_CHECK(!Entry->m_TypeName.IsEmpty());
  248. CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_CLR_SURROGATE);
  249. CBData->DataSize += (Entry->m_RuntimeVersion.Cch() + 1) * sizeof(WCHAR);
  250. CBData->DataSize += (Entry->m_TypeName.Cch() + 1) * sizeof(WCHAR);
  251. break;
  252. }
  253. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATA:
  254. {
  255. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA CBData =
  256. (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA) CallbackData;
  257. PCLR_SURROGATE_ENTRY Entry = (PCLR_SURROGATE_ENTRY) CBData->DataContext;
  258. PACTIVATION_CONTEXT_DATA_CLR_SURROGATE Info;
  259. PVOID Cursor = CBData->Buffer;
  260. SIZE_T BytesLeft = CBData->BufferSize;
  261. SIZE_T BytesWritten = 0;
  262. ALLOCATE_BUFFER_SPACE_TYPE(ACTIVATION_CONTEXT_DATA_CLR_SURROGATE, Cursor, BytesLeft, BytesWritten, Info);
  263. Info->Size = sizeof(ACTIVATION_CONTEXT_DATA_CLR_SURROGATE);
  264. Info->Flags = 0;
  265. Info->SurrogateIdent = Entry->m_ReferenceClsid;
  266. IFW32FALSE_EXIT(Entry->m_RuntimeVersion.Win32CopyIntoBuffer(
  267. (PWSTR*)&Cursor,
  268. &BytesLeft,
  269. &BytesWritten,
  270. Info,
  271. &Info->VersionOffset,
  272. &Info->VersionLength));
  273. IFW32FALSE_EXIT(Entry->m_TypeName.Win32CopyIntoBuffer(
  274. (PWSTR*)&Cursor,
  275. &BytesLeft,
  276. &BytesWritten,
  277. Info,
  278. &Info->TypeNameOffset,
  279. &Info->TypeNameLength));
  280. CBData->BytesWritten = BytesWritten;
  281. break;
  282. }
  283. }
  284. FN_EPILOG
  285. }