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.

500 lines
18 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. cominterface.cpp
  5. Abstract:
  6. Activation context section contributor for COM interface proxy mapping.
  7. Author:
  8. Michael J. Grier (MGrier) 28-Mar-2000
  9. Revision History:
  10. --*/
  11. #include "stdinc.h"
  12. #include <windows.h>
  13. #include <stdio.h>
  14. #include "sxsp.h"
  15. #include "sxsidp.h"
  16. #include "fusionparser.h"
  17. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(baseInterface);
  18. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(clsid);
  19. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(iid);
  20. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(name);
  21. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(numMethods);
  22. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(proxyStubClsid32);
  23. DECLARE_STD_ATTRIBUTE_NAME_DESCRIPTOR(tlbid);
  24. /*
  25. <file name="foo.dll">
  26. <comInterfaceProxyStub iid="{iid}" tlbid="{tlbid}" numMethods="3" baseInterface="{iid}" name="IFoo"/>
  27. </file>
  28. */
  29. typedef struct _IID_ENTRY
  30. {
  31. _IID_ENTRY() { }
  32. GUID m_clsid;
  33. GUID m_iid;
  34. ULONG m_nMethods;
  35. GUID m_tlbid;
  36. GUID m_iidBase;
  37. CStringBuffer m_buffName;
  38. bool m_fNumMethodsValid;
  39. bool m_fBaseInterfaceValid;
  40. private:
  41. _IID_ENTRY(const _IID_ENTRY &);
  42. void operator =(const _IID_ENTRY &);
  43. } IID_ENTRY, *PIID_ENTRY;
  44. BOOL
  45. SxspComInterfaceRedirectionGuidSectionGenerationCallback(
  46. PVOID Context,
  47. ULONG Reason,
  48. PVOID CallbackData
  49. );
  50. VOID
  51. SxspComInterfaceRedirectionContributorCallback(
  52. PACTCTXCTB_CALLBACK_DATA Data
  53. )
  54. {
  55. FN_TRACE();
  56. PGUID_SECTION_GENERATION_CONTEXT GSGenContext = (PGUID_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext;
  57. switch (Data->Header.Reason)
  58. {
  59. case ACTCTXCTB_CBREASON_ACTCTXGENBEGINNING:
  60. Data->GenBeginning.Success = FALSE;
  61. INTERNAL_ERROR_CHECK(GSGenContext == NULL);
  62. // do everything if we are generating an activation context.
  63. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  64. {
  65. IFW32FALSE_EXIT(
  66. ::SxsInitGuidSectionGenerationContext(
  67. &GSGenContext,
  68. ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FORMAT_WHISTLER,
  69. &::SxspComInterfaceRedirectionGuidSectionGenerationCallback,
  70. NULL));
  71. Data->Header.ActCtxGenContext = GSGenContext;
  72. }
  73. Data->GenBeginning.Success = TRUE;
  74. break;
  75. case ACTCTXCTB_CBREASON_ACTCTXGENENDED:
  76. if (GSGenContext != NULL)
  77. ::SxsDestroyGuidSectionGenerationContext(GSGenContext);
  78. break;
  79. case ACTCTXCTB_CBREASON_ALLPARSINGDONE:
  80. Data->AllParsingDone.Success = FALSE;
  81. #if 0
  82. // this call isn't implemented for guid sections ... yet
  83. if (GSGenContext != NULL)
  84. IFW32FALSE_EXIT(::SxsDoneModifyingGuidSectionGenerationContext(GSGenContext));
  85. #endif
  86. Data->AllParsingDone.Success = TRUE;
  87. break;
  88. case ACTCTXCTB_CBREASON_GETSECTIONSIZE:
  89. Data->GetSectionSize.Success = FALSE;
  90. // Someone shouldn't be asking for the section size if we
  91. // are not generating an activation context.
  92. // These two asserts should be equivalent...
  93. INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  94. INTERNAL_ERROR_CHECK(GSGenContext != NULL);
  95. IFW32FALSE_EXIT(
  96. ::SxsGetGuidSectionGenerationContextSectionSize(
  97. GSGenContext,
  98. &Data->GetSectionSize.SectionSize));
  99. Data->GetSectionSize.Success = TRUE;
  100. break;
  101. case ACTCTXCTB_CBREASON_ELEMENTPARSED:
  102. Data->ElementParsed.Success = FALSE;
  103. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  104. {
  105. ULONG MappedValue = 0;
  106. bool fFound = false;
  107. enum MappedValues
  108. {
  109. eAssemblyInterface = 1,
  110. eAssemblyFileComClassInterface = 2,
  111. };
  112. #define PATH_MAP_ENTRY(_depth, _string, _mv) { (_depth), _string, NUMBER_OF(_string) - 1, (_mv) },
  113. static const ELEMENT_PATH_MAP_ENTRY s_rgEntries[] =
  114. {
  115. PATH_MAP_ENTRY(2, L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^comInterfaceExternalProxyStub", eAssemblyInterface)
  116. PATH_MAP_ENTRY(3, L"urn:schemas-microsoft-com:asm.v1^assembly!urn:schemas-microsoft-com:asm.v1^file!urn:schemas-microsoft-com:asm.v1^comInterfaceProxyStub", eAssemblyFileComClassInterface)
  117. };
  118. #undef PATH_MAP_ENTRY
  119. IFW32FALSE_EXIT(
  120. ::SxspProcessElementPathMap(
  121. Data->ElementParsed.ParseContext,
  122. s_rgEntries,
  123. NUMBER_OF(s_rgEntries),
  124. MappedValue,
  125. fFound));
  126. if (fFound)
  127. {
  128. switch (MappedValue)
  129. {
  130. default:
  131. INTERNAL_ERROR_CHECK2(
  132. FALSE,
  133. "Invalid mapped value returned from SxspProcessElementPathMap");
  134. case eAssemblyInterface:
  135. {
  136. bool fFound = false;
  137. CStringBuffer TempBuffer;
  138. GUID iid, tlbid, iidBase, clsid;
  139. ULONG nMethods = 0;
  140. SIZE_T cb;
  141. bool fNumMethodsValid = false;
  142. bool fBaseInterfaceValid = false;
  143. IFW32FALSE_EXIT(
  144. ::SxspGetAttributeValue(
  145. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  146. &s_AttributeName_iid,
  147. &Data->ElementParsed,
  148. fFound,
  149. sizeof(iid),
  150. &iid,
  151. cb,
  152. &::SxspValidateGuidAttribute,
  153. 0));
  154. INTERNAL_ERROR_CHECK(fFound);
  155. IFW32FALSE_EXIT(
  156. ::SxspGetAttributeValue(
  157. 0,
  158. &s_AttributeName_proxyStubClsid32,
  159. &Data->ElementParsed,
  160. fFound,
  161. sizeof(clsid),
  162. &clsid,
  163. cb,
  164. &::SxspValidateGuidAttribute,
  165. 0));
  166. if (!fFound)
  167. clsid = iid;
  168. IFW32FALSE_EXIT(::SxspGetAttributeValue(0, &s_AttributeName_numMethods, &Data->ElementParsed, fFound, sizeof(TempBuffer), &TempBuffer, cb, NULL, 0));
  169. if (fFound)
  170. {
  171. IFW32FALSE_EXIT(CFusionParser::ParseULONG(nMethods, TempBuffer, TempBuffer.Cch()));
  172. fNumMethodsValid = true;
  173. }
  174. tlbid = GUID_NULL;
  175. IFW32FALSE_EXIT(
  176. ::SxspGetAttributeValue(
  177. 0,
  178. &s_AttributeName_tlbid,
  179. &Data->ElementParsed,
  180. fFound,
  181. sizeof(tlbid),
  182. &tlbid,
  183. cb,
  184. &::SxspValidateGuidAttribute,
  185. 0));
  186. IFW32FALSE_EXIT(
  187. ::SxspGetAttributeValue(
  188. 0,
  189. &s_AttributeName_baseInterface,
  190. &Data->ElementParsed,
  191. fFound,
  192. sizeof(iidBase),
  193. &iidBase,
  194. cb,
  195. &::SxspValidateGuidAttribute,
  196. 0));
  197. if (fFound)
  198. fBaseInterfaceValid = true;
  199. TempBuffer.Clear();
  200. IFW32FALSE_EXIT(::SxspGetAttributeValue(0, &s_AttributeName_name, &Data->ElementParsed, fFound, sizeof(TempBuffer), &TempBuffer, cb, NULL, 0));
  201. // Do more work if generating an activation context.
  202. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  203. {
  204. PIID_ENTRY Entry = NULL;
  205. IFALLOCFAILED_EXIT(Entry = new IID_ENTRY);
  206. Entry->m_clsid = clsid;
  207. Entry->m_tlbid = tlbid;
  208. Entry->m_iid = iid;
  209. Entry->m_iidBase = iidBase;
  210. Entry->m_nMethods = nMethods;
  211. Entry->m_fNumMethodsValid = fNumMethodsValid;
  212. Entry->m_fBaseInterfaceValid = fBaseInterfaceValid;
  213. IFW32FALSE_EXIT(Entry->m_buffName.Win32Assign(TempBuffer));
  214. IFW32FALSE_EXIT(
  215. ::SxsAddGuidToGuidSectionGenerationContext(
  216. (PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  217. &iid,
  218. Entry,
  219. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  220. ERROR_SXS_DUPLICATE_IID));
  221. }
  222. break;
  223. }
  224. case eAssemblyFileComClassInterface:
  225. {
  226. bool fFound = false;
  227. CStringBuffer TempBuffer;
  228. GUID iid, tlbid, iidBase;
  229. ULONG nMethods = 0;
  230. SIZE_T cb;
  231. bool fNumMethodsValid = false;
  232. bool fBaseInterfaceValid = false;
  233. IFW32FALSE_EXIT(
  234. ::SxspGetAttributeValue(
  235. SXSP_GET_ATTRIBUTE_VALUE_FLAG_REQUIRED_ATTRIBUTE,
  236. &s_AttributeName_iid,
  237. &Data->ElementParsed,
  238. fFound,
  239. sizeof(iid),
  240. &iid,
  241. cb,
  242. &::SxspValidateGuidAttribute,
  243. 0));
  244. INTERNAL_ERROR_CHECK(fFound);
  245. IFW32FALSE_EXIT(::SxspGetAttributeValue(0, &s_AttributeName_numMethods, &Data->ElementParsed, fFound, sizeof(TempBuffer), &TempBuffer, cb, NULL, 0));
  246. if (fFound)
  247. {
  248. IFW32FALSE_EXIT(CFusionParser::ParseULONG(nMethods, TempBuffer, TempBuffer.Cch()));
  249. fNumMethodsValid = true;
  250. }
  251. tlbid = GUID_NULL;
  252. IFW32FALSE_EXIT(
  253. ::SxspGetAttributeValue(
  254. 0,
  255. &s_AttributeName_tlbid,
  256. &Data->ElementParsed,
  257. fFound,
  258. sizeof(tlbid),
  259. &tlbid,
  260. cb,
  261. &::SxspValidateGuidAttribute,
  262. 0));
  263. IFW32FALSE_EXIT(
  264. ::SxspGetAttributeValue(
  265. 0,
  266. &s_AttributeName_baseInterface,
  267. &Data->ElementParsed,
  268. fFound,
  269. sizeof(iidBase),
  270. &iidBase,
  271. cb,
  272. &::SxspValidateGuidAttribute,
  273. 0));
  274. if (fFound)
  275. fBaseInterfaceValid = true;
  276. TempBuffer.Clear();
  277. IFW32FALSE_EXIT(::SxspGetAttributeValue(0, &s_AttributeName_name, &Data->ElementParsed, fFound, sizeof(TempBuffer), &TempBuffer, cb, NULL, 0));
  278. // Do more work if generating an activation context.
  279. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  280. {
  281. PIID_ENTRY Entry = NULL;
  282. IFALLOCFAILED_EXIT(Entry = new IID_ENTRY);
  283. Entry->m_clsid = iid;
  284. Entry->m_tlbid = tlbid;
  285. Entry->m_iid = iid;
  286. Entry->m_iidBase = iidBase;
  287. Entry->m_nMethods = nMethods;
  288. Entry->m_fNumMethodsValid = fNumMethodsValid;
  289. Entry->m_fBaseInterfaceValid = fBaseInterfaceValid;
  290. IFW32FALSE_EXIT(Entry->m_buffName.Win32Assign(TempBuffer));
  291. IFW32FALSE_EXIT(
  292. ::SxsAddGuidToGuidSectionGenerationContext(
  293. (PGUID_SECTION_GENERATION_CONTEXT) Data->ElementParsed.Header.ActCtxGenContext,
  294. &iid,
  295. Entry,
  296. Data->ElementParsed.AssemblyContext->AssemblyRosterIndex,
  297. ERROR_SXS_DUPLICATE_IID));
  298. }
  299. break;
  300. }
  301. }
  302. }
  303. }
  304. Data->ElementParsed.Success = TRUE;
  305. break;
  306. case ACTCTXCTB_CBREASON_GETSECTIONDATA:
  307. Data->GetSectionData.Success = FALSE;
  308. INTERNAL_ERROR_CHECK(GSGenContext != NULL);
  309. INTERNAL_ERROR_CHECK(Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT);
  310. IFW32FALSE_EXIT(
  311. ::SxsGetGuidSectionGenerationContextSectionData(
  312. GSGenContext,
  313. Data->GetSectionData.SectionSize,
  314. Data->GetSectionData.SectionDataStart,
  315. NULL));
  316. Data->GetSectionData.Success = TRUE;
  317. break;
  318. }
  319. Exit:
  320. ;
  321. }
  322. BOOL
  323. SxspComInterfaceRedirectionGuidSectionGenerationCallback(
  324. PVOID Context,
  325. ULONG Reason,
  326. PVOID CallbackData
  327. )
  328. {
  329. BOOL fSuccess = FALSE;
  330. FN_TRACE_WIN32(fSuccess);
  331. switch (Reason)
  332. {
  333. default:
  334. break;
  335. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_ENTRYDELETED:
  336. {
  337. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED CBData = (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED) CallbackData;
  338. PIID_ENTRY Entry = (PIID_ENTRY) CBData->DataContext;
  339. if (Entry != NULL)
  340. FUSION_DELETE_SINGLETON(Entry);
  341. break;
  342. }
  343. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATASIZE:
  344. {
  345. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE CBData = (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE) CallbackData;
  346. PIID_ENTRY Entry = (PIID_ENTRY) CBData->DataContext;
  347. CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION);
  348. if (Entry != NULL)
  349. {
  350. if (Entry->m_buffName.Cch() != 0)
  351. {
  352. CBData->DataSize += ((Entry->m_buffName.Cch() + 1) * sizeof(WCHAR));
  353. }
  354. }
  355. break;
  356. }
  357. case GUID_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATA:
  358. {
  359. PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA CBData = (PGUID_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA) CallbackData;
  360. PACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION Info;
  361. PIID_ENTRY Entry = (PIID_ENTRY) CBData->DataContext;
  362. PWSTR Cursor;
  363. SIZE_T BytesLeft = CBData->BufferSize;
  364. SIZE_T BytesWritten = 0;
  365. Info = (PACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION) CBData->Buffer;
  366. if (BytesLeft < sizeof(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION))
  367. {
  368. ::FusionpSetLastWin32Error(ERROR_INSUFFICIENT_BUFFER);
  369. goto Exit;
  370. }
  371. BytesWritten += sizeof(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION);
  372. BytesLeft -= sizeof(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION);
  373. Cursor = (PWSTR) (Info + 1);
  374. Info->Size = sizeof(ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION);
  375. Info->Flags = 0;
  376. Info->ProxyStubClsid32 = Entry->m_clsid;
  377. if (Entry->m_fNumMethodsValid)
  378. {
  379. Info->Flags |= ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_NUM_METHODS_VALID;
  380. Info->NumMethods = Entry->m_nMethods;
  381. }
  382. else
  383. Info->NumMethods = 0;
  384. Info->TypeLibraryId = Entry->m_tlbid;
  385. if (Entry->m_fBaseInterfaceValid)
  386. {
  387. Info->Flags |= ACTIVATION_CONTEXT_DATA_COM_INTERFACE_REDIRECTION_FLAG_BASE_INTERFACE_VALID;
  388. Info->BaseInterface = Entry->m_iidBase;
  389. }
  390. else
  391. Info->BaseInterface = GUID_NULL;
  392. IFW32FALSE_EXIT(
  393. Entry->m_buffName.Win32CopyIntoBuffer(
  394. &Cursor,
  395. &BytesLeft,
  396. &BytesWritten,
  397. Info,
  398. &Info->NameOffset,
  399. &Info->NameLength));
  400. CBData->BytesWritten = BytesWritten;
  401. }
  402. }
  403. fSuccess = TRUE;
  404. Exit:
  405. return fSuccess;
  406. }