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.

512 lines
19 KiB

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