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.

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