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.

434 lines
16 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. comprogid.cpp
  5. Abstract:
  6. Activation context section contributor for COM progid mapping.
  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(progid);
  16. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(id);
  17. #define STRING_COMMA_AND_LENGTH(x) (x), NUMBER_OF(x)-1
  18. BOOL
  19. SxspComProgIdRedirectionStringSectionGenerationCallback(
  20. PVOID Context,
  21. ULONG Reason,
  22. PVOID CallbackData
  23. );
  24. typedef struct _COM_PROGID_GLOBAL_CONTEXT *PCOM_PROGID_GLOBAL_CONTEXT;
  25. typedef struct _COM_PROGID_SERVER_CONTEXT *PCOM_PROGID_SERVER_CONTEXT;
  26. typedef struct _COM_PROGID_SERVER_CONTEXT
  27. {
  28. CDequeLinkage m_Linkage;
  29. GUID m_ConfiguredClsid;
  30. LONG m_Offset; // offset from section global data - populated during section generation
  31. } COM_PROGID_SERVER_CONTEXT;
  32. typedef CDeque<COM_PROGID_SERVER_CONTEXT, offsetof(COM_PROGID_SERVER_CONTEXT, m_Linkage)> CComProgIdServerDeque;
  33. typedef CDequeIterator<COM_PROGID_SERVER_CONTEXT, offsetof(COM_PROGID_SERVER_CONTEXT, m_Linkage)> CComProgIdServerDequeIterator;
  34. typedef struct _COM_PROGID_GLOBAL_CONTEXT
  35. {
  36. // Temporary holding buffer for the configured CLSID until the first COM progid entry is
  37. // found, at which time a COM_PROGID_SERVER_CONTEXT is allocated and the clsid moved to it.
  38. GUID m_ConfiguredClsid;
  39. CComProgIdServerDeque m_ServerContextList;
  40. } COM_PROGID_GLOBAL_CONTEXT;
  41. VOID
  42. __fastcall
  43. SxspComProgIdRedirectionContributorCallback(
  44. PACTCTXCTB_CALLBACK_DATA Data
  45. )
  46. {
  47. FN_TRACE();
  48. PSTRING_SECTION_GENERATION_CONTEXT SSGenContext = (PSTRING_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext;
  49. CSmartPtr<COM_PROGID_GLOBAL_CONTEXT> ComGlobalContext;
  50. if (SSGenContext != NULL)
  51. ComGlobalContext.AttachNoDelete((PCOM_PROGID_GLOBAL_CONTEXT) ::SxsGetStringSectionGenerationContextCallbackContext(SSGenContext));
  52. switch (Data->Header.Reason)
  53. {
  54. case ACTCTXCTB_CBREASON_ACTCTXGENBEGINNING:
  55. Data->GenBeginning.Success = FALSE;
  56. INTERNAL_ERROR_CHECK(ComGlobalContext == NULL);
  57. INTERNAL_ERROR_CHECK(SSGenContext == NULL);
  58. IFW32FALSE_EXIT(ComGlobalContext.Win32Allocate(__FILE__, __LINE__));
  59. ComGlobalContext->m_ConfiguredClsid = GUID_NULL;
  60. IFW32FALSE_EXIT(
  61. ::SxsInitStringSectionGenerationContext(
  62. &SSGenContext,
  63. ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION_FORMAT_WHISTLER,
  64. TRUE,
  65. &::SxspComProgIdRedirectionStringSectionGenerationCallback,
  66. ComGlobalContext));
  67. ComGlobalContext.Detach();
  68. Data->Header.ActCtxGenContext = SSGenContext;
  69. Data->GenBeginning.Success = TRUE;
  70. break;
  71. case ACTCTXCTB_CBREASON_ACTCTXGENENDED:
  72. ::SxsDestroyStringSectionGenerationContext(SSGenContext);
  73. if (ComGlobalContext != NULL)
  74. {
  75. ComGlobalContext->m_ServerContextList.ClearAndDeleteAll();
  76. FUSION_DELETE_SINGLETON(ComGlobalContext.Detach());
  77. }
  78. break;
  79. case ACTCTXCTB_CBREASON_ALLPARSINGDONE:
  80. Data->AllParsingDone.Success = FALSE;
  81. if (SSGenContext != NULL)
  82. IFW32FALSE_EXIT(::SxsDoneModifyingStringSectionGenerationContext(SSGenContext));
  83. Data->AllParsingDone.Success = TRUE;
  84. break;
  85. case ACTCTXCTB_CBREASON_PCDATAPARSED:
  86. {
  87. Data->PCDATAParsed.Success = FALSE;
  88. ULONG MappedValue = 0;
  89. bool fFound = false;
  90. enum MappedValues
  91. {
  92. eAssemblyFileComclassProgid = 1,
  93. };
  94. static const ELEMENT_PATH_MAP_ENTRY s_rgEntries[] =
  95. {
  96. { 4, STRING_COMMA_AND_LENGTH(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comClass!urn:schemas-microsoft-com:asm.v1^progid"), eAssemblyFileComclassProgid },
  97. { 3, STRING_COMMA_AND_LENGTH(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^clrClass!urn:schemas-microsoft-com:asm.v1^progid"), eAssemblyFileComclassProgid },
  98. };
  99. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  100. IFW32FALSE_EXIT(
  101. ::SxspProcessElementPathMap(
  102. Data->PCDATAParsed.ParseContext,
  103. s_rgEntries,
  104. NUMBER_OF(s_rgEntries),
  105. MappedValue,
  106. fFound));;
  107. if (fFound)
  108. {
  109. switch (MappedValue)
  110. {
  111. default:
  112. INTERNAL_ERROR2_ACTION(MappedValue, "Invalid mapped value returned from SxspProcessElementPathMap()");
  113. case eAssemblyFileComclassProgid:
  114. {
  115. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  116. {
  117. CComProgIdServerDequeIterator Iterator;
  118. PCOM_PROGID_SERVER_CONTEXT ServerContext = NULL;
  119. INTERNAL_ERROR_CHECK(ComGlobalContext != NULL);
  120. Iterator.Rebind(&ComGlobalContext->m_ServerContextList);
  121. Iterator.Reset();
  122. ServerContext = Iterator;
  123. INTERNAL_ERROR_CHECK(ServerContext != NULL);
  124. IFW32FALSE_EXIT(
  125. ::SxsAddStringToStringSectionGenerationContext(
  126. (PSTRING_SECTION_GENERATION_CONTEXT) Data->PCDATAParsed.Header.ActCtxGenContext,
  127. Data->PCDATAParsed.Text,
  128. Data->PCDATAParsed.TextCch,
  129. ServerContext,
  130. Data->PCDATAParsed.AssemblyContext->AssemblyRosterIndex,
  131. ERROR_SXS_DUPLICATE_PROGID));
  132. }
  133. break;
  134. }
  135. }
  136. }
  137. Data->PCDATAParsed.Success = TRUE;
  138. break;
  139. }
  140. case ACTCTXCTB_CBREASON_ELEMENTPARSED:
  141. {
  142. Data->ElementParsed.Success = FALSE;
  143. ULONG MappedValue = 0;
  144. bool fFound = false;
  145. enum MappedValues
  146. {
  147. eAssemblyFileComclass = 1,
  148. };
  149. static const ELEMENT_PATH_MAP_ENTRY s_rgEntries[] =
  150. {
  151. { 3, STRING_COMMA_AND_LENGTH(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comClass"), eAssemblyFileComclass },
  152. { 2, STRING_COMMA_AND_LENGTH(L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^clrClass"), eAssemblyFileComclass },
  153. };
  154. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  155. IFW32FALSE_EXIT(
  156. ::SxspProcessElementPathMap(
  157. Data->ElementParsed.ParseContext,
  158. s_rgEntries,
  159. NUMBER_OF(s_rgEntries),
  160. MappedValue,
  161. fFound));
  162. if (fFound)
  163. {
  164. switch (MappedValue)
  165. {
  166. default:
  167. INTERNAL_ERROR2_ACTION(MappedValue, "Invalid mapped value returned from SxspProcessElementPathMap()");
  168. case eAssemblyFileComclass:
  169. {
  170. bool fProgIdFound = false;
  171. SIZE_T cb = 0;
  172. CSmallStringBuffer VersionIndependentComClassIdBuffer;
  173. CSmallStringBuffer ProgIdBuffer;
  174. GUID ReferenceClsid, ConfiguredClsid, ImplementedClsid;
  175. INTERNAL_ERROR_CHECK(ComGlobalContext != NULL);
  176. IFW32FALSE_EXIT(
  177. ::SxspGetAttributeValue(
  178. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  179. &s_AttributeName_clsid,
  180. &Data->ElementParsed,
  181. fFound,
  182. sizeof(VersionIndependentComClassIdBuffer),
  183. &VersionIndependentComClassIdBuffer,
  184. cb,
  185. NULL,
  186. 0));
  187. INTERNAL_ERROR_CHECK(fFound);
  188. IFW32FALSE_EXIT(
  189. ::SxspParseGUID(
  190. VersionIndependentComClassIdBuffer,
  191. VersionIndependentComClassIdBuffer.Cch(),
  192. ReferenceClsid));
  193. IFW32FALSE_EXIT(
  194. ::SxspGetAttributeValue(
  195. 0,
  196. &s_AttributeName_progid,
  197. &Data->ElementParsed,
  198. fProgIdFound,
  199. sizeof(ProgIdBuffer),
  200. &ProgIdBuffer,
  201. cb,
  202. NULL,
  203. 0));
  204. //
  205. // Always create a file context for this file, whether or not we end up with
  206. // any progids.
  207. //
  208. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  209. {
  210. CSmartPtr<COM_PROGID_SERVER_CONTEXT> ServerContext;
  211. IFW32FALSE_EXIT(Data->Header.ClsidMappingContext->Map->MapReferenceClsidToConfiguredClsid(
  212. &ReferenceClsid,
  213. Data->ElementParsed.AssemblyContext,
  214. &ConfiguredClsid,
  215. &ImplementedClsid));
  216. //
  217. // Allocate new, set configured CLSID, and add it to the global list
  218. //
  219. IFW32FALSE_EXIT(ServerContext.Win32Allocate(__FILE__, __LINE__));
  220. ServerContext->m_ConfiguredClsid = ConfiguredClsid;
  221. ServerContext->m_Offset = 0;
  222. ComGlobalContext->m_ServerContextList.AddToHead(ServerContext.DetachAndHold());
  223. // Now, if we found a progid attribute, add it to the ss genctx
  224. if (fProgIdFound)
  225. {
  226. IFW32FALSE_EXIT(::SxsAddStringToStringSectionGenerationContext(
  227. (PSTRING_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  228. ProgIdBuffer,
  229. ProgIdBuffer.Cch(),
  230. ServerContext,
  231. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  232. ERROR_SXS_DUPLICATE_PROGID));
  233. }
  234. }
  235. break;
  236. }
  237. }
  238. }
  239. Data->ElementParsed.Success = TRUE;
  240. break;
  241. }
  242. case ACTCTXCTB_CBREASON_GETSECTIONSIZE:
  243. Data->GetSectionSize.Success = FALSE;
  244. // Someone shouldn't be asking for the section size if we
  245. // are generating an activation context.
  246. INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  247. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  248. IFW32FALSE_EXIT(
  249. ::SxsGetStringSectionGenerationContextSectionSize(
  250. SSGenContext,
  251. &Data->GetSectionSize.SectionSize));
  252. Data->GetSectionSize.Success = TRUE;
  253. break;
  254. case ACTCTXCTB_CBREASON_GETSECTIONDATA:
  255. Data->GetSectionData.Success = FALSE;
  256. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  257. INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  258. IFW32FALSE_EXIT(
  259. ::SxsGetStringSectionGenerationContextSectionData(
  260. SSGenContext,
  261. Data->GetSectionData.SectionSize,
  262. Data->GetSectionData.SectionDataStart,
  263. NULL));
  264. Data->GetSectionData.Success = TRUE;
  265. break;
  266. }
  267. Exit:
  268. ;
  269. }
  270. BOOL
  271. SxspComProgIdRedirectionStringSectionGenerationCallback(
  272. PVOID Context,
  273. ULONG Reason,
  274. PVOID CallbackData
  275. )
  276. {
  277. FN_PROLOG_WIN32
  278. PCOM_PROGID_GLOBAL_CONTEXT GlobalContext = (PCOM_PROGID_GLOBAL_CONTEXT) Context;
  279. switch (Reason)
  280. {
  281. default:
  282. INTERNAL_ERROR_CHECK(FALSE);
  283. goto Exit; // never hit this line, INTERNAL_ERROR_CHECK would "goto Exit"
  284. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_ENTRYDELETED:
  285. // do nothing;
  286. break;
  287. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETUSERDATASIZE:
  288. {
  289. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATASIZE CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATASIZE) CallbackData;
  290. CBData->DataSize = sizeof(GUID) * GlobalContext->m_ServerContextList.GetEntryCount();
  291. break;
  292. }
  293. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETUSERDATA:
  294. {
  295. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATA CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATA) CallbackData;
  296. SIZE_T BytesWritten = 0;
  297. SIZE_T BytesLeft = CBData->BufferSize;
  298. GUID *Cursor = (GUID *) CBData->Buffer;
  299. CComProgIdServerDequeIterator Iterator(&GlobalContext->m_ServerContextList);
  300. INTERNAL_ERROR_CHECK(BytesLeft >= (sizeof(GUID) * GlobalContext->m_ServerContextList.GetEntryCount()));
  301. for (Iterator.Reset(); Iterator.More(); Iterator.Next())
  302. {
  303. Iterator->m_Offset = static_cast<LONG>(((LONG_PTR) Cursor) - ((LONG_PTR) CBData->SectionHeader));
  304. *Cursor++ = Iterator->m_ConfiguredClsid;
  305. BytesWritten += sizeof(GUID);
  306. BytesLeft -= sizeof(GUID);
  307. }
  308. CBData->BytesWritten = BytesWritten;
  309. break;
  310. }
  311. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATASIZE:
  312. {
  313. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE) CallbackData;
  314. CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION);
  315. break;
  316. }
  317. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATA:
  318. {
  319. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA) CallbackData;
  320. PACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION Info;
  321. PCOM_PROGID_SERVER_CONTEXT ServerContext = (PCOM_PROGID_SERVER_CONTEXT) CBData->DataContext;
  322. SIZE_T BytesLeft = CBData->BufferSize;
  323. SIZE_T BytesWritten = 0;
  324. Info = (PACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION) CBData->Buffer;
  325. if (BytesLeft < sizeof(ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION))
  326. ORIGINATE_WIN32_FAILURE_AND_EXIT(NoRoom, ERROR_INSUFFICIENT_BUFFER);
  327. BytesWritten += sizeof(ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION);
  328. BytesLeft -= sizeof(ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION);
  329. Info->Size = sizeof(ACTIVATION_CONTEXT_DATA_COM_PROGID_REDIRECTION);
  330. Info->Flags = 0;
  331. Info->ConfiguredClsidOffset = ServerContext->m_Offset;
  332. CBData->BytesWritten = BytesWritten;
  333. break;
  334. }
  335. }
  336. FN_EPILOG
  337. }