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.

623 lines
25 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. asmmetadata.cpp
  5. Abstract:
  6. Activation context section contributor for the assembly metadata section.
  7. Author:
  8. Michael J. Grier (MGrier) 23-Feb-2000
  9. Revision History:
  10. xiaoyuw 09/2000 revise with Assembly Identity
  11. xiaoyuw 10/2000 get rid of initialize-code because constructer has done it
  12. --*/
  13. #include "stdinc.h"
  14. #include <windows.h>
  15. #include "sxsp.h"
  16. typedef struct _ASSEMBLY_METADATA_ENTRY *PASSEMBLY_METADATA_ENTRY;
  17. typedef struct _ASSEMBLY_METADATA_CONTEXT *PASSEMBLY_METADATA_CONTEXT;
  18. typedef struct _ASSEMBLY_METADATA_CONTEXT
  19. {
  20. _ASSEMBLY_METADATA_CONTEXT() { }
  21. ULONG ApplicationDirectoryPathType;
  22. PCWSTR ApplicationDirectory;
  23. SIZE_T ApplicationDirectoryCch;
  24. PASSEMBLY_METADATA_ENTRY pLastMetaDataEntry;
  25. } ASSEMBLY_METADATA_CONTEXT;
  26. typedef struct _ASSEMBLY_METADATA_ENTRY
  27. {
  28. _ASSEMBLY_METADATA_ENTRY() :
  29. AssemblyIdentity(NULL),
  30. ManifestVersionMajor(0),
  31. ManifestVersionMinor(0),
  32. ManifestPathType(ACTIVATION_CONTEXT_PATH_TYPE_NONE),
  33. PolicyPathType(ACTIVATION_CONTEXT_PATH_TYPE_NONE),
  34. AssemblyPolicyApplied(FALSE),
  35. RootPolicyApplied(FALSE),
  36. IsRootAssembly(FALSE),
  37. IsPrivateAssembly(FALSE),
  38. MetadataSatelliteRosterIndex(0),
  39. AssemblyRosterIndex(0)
  40. {
  41. ManifestLastWriteTime.dwLowDateTime = 0;
  42. ManifestLastWriteTime.dwHighDateTime = 0;
  43. PolicyLastWriteTime.dwLowDateTime = 0;
  44. PolicyLastWriteTime.dwHighDateTime = 0;
  45. }
  46. ~_ASSEMBLY_METADATA_ENTRY()
  47. {
  48. CSxsPreserveLastError ple;
  49. ::SxsDestroyAssemblyIdentity(const_cast<PASSEMBLY_IDENTITY>(AssemblyIdentity));
  50. ple.Restore();
  51. }
  52. PCASSEMBLY_IDENTITY AssemblyIdentity; // intermediate data
  53. ULONG ManifestPathType;
  54. FILETIME ManifestLastWriteTime;
  55. ULONG PolicyPathType;
  56. FILETIME PolicyLastWriteTime;
  57. BOOL AssemblyPolicyApplied;
  58. BOOL RootPolicyApplied;
  59. BOOL IsRootAssembly;
  60. BOOL IsPrivateAssembly;
  61. ULONG ManifestVersionMajor;
  62. ULONG ManifestVersionMinor;
  63. CSmallStringBuffer AssemblyDirectoryNameBuffer;
  64. ULONG MetadataSatelliteRosterIndex;
  65. ULONG AssemblyRosterIndex;
  66. ULONG FileNum;
  67. CSmallStringBuffer LanguageBuffer;
  68. CSmallStringBuffer ManifestPathBuffer;
  69. CTinyStringBuffer PolicyPathBuffer;
  70. private:
  71. _ASSEMBLY_METADATA_ENTRY(const _ASSEMBLY_METADATA_ENTRY &);
  72. void operator =(const _ASSEMBLY_METADATA_ENTRY &);
  73. } ASSEMBLY_METADATA_ENTRY;
  74. VOID
  75. WINAPI
  76. SxspAssemblyMetadataContributorCallback(
  77. PACTCTXCTB_CALLBACK_DATA Data
  78. )
  79. {
  80. FN_TRACE();
  81. PSTRING_SECTION_GENERATION_CONTEXT SSGenContext = (PSTRING_SECTION_GENERATION_CONTEXT) Data->Header.ActCtxGenContext;
  82. PASSEMBLY_METADATA_ENTRY Entry = NULL;
  83. PASSEMBLY_METADATA_CONTEXT AssemblyMetadataContext = NULL;
  84. BOOL Found = FALSE;
  85. PASSEMBLY_IDENTITY TempAssemblyIdentity = NULL;
  86. if (SSGenContext != NULL)
  87. AssemblyMetadataContext = (PASSEMBLY_METADATA_CONTEXT) ::SxsGetStringSectionGenerationContextCallbackContext(SSGenContext);
  88. switch (Data->Header.Reason)
  89. {
  90. case ACTCTXCTB_CBREASON_ACTCTXGENBEGINNING:
  91. {
  92. PACTCTXCTB_CBACTCTXGENBEGINNING CBData = (PACTCTXCTB_CBACTCTXGENBEGINNING) Data;
  93. PASSEMBLY_METADATA_CONTEXT AssemblyMetadataContext = NULL;
  94. CBData->Success = FALSE;
  95. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  96. {
  97. IFALLOCFAILED_EXIT(AssemblyMetadataContext = new ASSEMBLY_METADATA_CONTEXT);
  98. AssemblyMetadataContext->ApplicationDirectory = CBData->ApplicationDirectory;
  99. AssemblyMetadataContext->ApplicationDirectoryCch = CBData->ApplicationDirectoryCch;
  100. AssemblyMetadataContext->ApplicationDirectoryPathType = CBData->ApplicationDirectoryPathType;
  101. AssemblyMetadataContext->pLastMetaDataEntry = NULL;
  102. IFW32FALSE_EXIT(::SxsInitStringSectionGenerationContext(
  103. &SSGenContext,
  104. ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_FORMAT_WHISTLER,
  105. TRUE,
  106. SxspAssemblyMetadataStringSectionGenerationCallback,
  107. AssemblyMetadataContext));
  108. }
  109. CBData->Success = TRUE;
  110. CBData->Header.ActCtxGenContext = SSGenContext;
  111. break;
  112. }
  113. case ACTCTXCTB_CBREASON_ACTCTXGENENDED:
  114. if (SSGenContext != NULL)
  115. ::SxsDestroyStringSectionGenerationContext(SSGenContext);
  116. FUSION_DELETE_SINGLETON(AssemblyMetadataContext);
  117. break;
  118. case ACTCTXCTB_CBREASON_ALLPARSINGDONE:
  119. {
  120. PACTCTXCTB_CBACTCTXGENENDED CBData = (PACTCTXCTB_CBACTCTXGENENDED) Data;
  121. CBData->Success = FALSE;
  122. if (SSGenContext != NULL)
  123. IFW32FALSE_EXIT(::SxsDoneModifyingStringSectionGenerationContext(SSGenContext));
  124. CBData->Success = TRUE;
  125. break;
  126. }
  127. case ACTCTXCTB_CBREASON_IDENTITYDETERMINED:
  128. {
  129. PACTCTXCTB_CBIDENTITYDETERMINED CBData = (PACTCTXCTB_CBIDENTITYDETERMINED)Data;
  130. SSGenContext = (PSTRING_SECTION_GENERATION_CONTEXT)CBData->Header.ActCtxGenContext;
  131. SIZE_T cbEncoding = 0;
  132. BOOL Found = FALSE;
  133. CStringBufferAccessor acc;
  134. CSxsPointerWithNamedDestructor<ASSEMBLY_IDENTITY, SxsDestroyAssemblyIdentity> pAsmIdentTemp;
  135. //
  136. // If we're not generating an actctx, then we don't have to do anything for it.
  137. //
  138. if (Data->Header.ManifestOperation != MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  139. {
  140. CBData->Success = TRUE;
  141. FN_SUCCESSFUL_EXIT();
  142. }
  143. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  144. //
  145. // Find the last one that was added, and stamp the new assembly identity into it
  146. //
  147. if (AssemblyMetadataContext->pLastMetaDataEntry != NULL)
  148. {
  149. Entry = AssemblyMetadataContext->pLastMetaDataEntry;
  150. if (Entry->AssemblyIdentity != NULL)
  151. {
  152. SxsDestroyAssemblyIdentity(const_cast<PASSEMBLY_IDENTITY>(Entry->AssemblyIdentity));
  153. Entry->AssemblyIdentity = NULL;
  154. }
  155. IFW32FALSE_EXIT(SxsDuplicateAssemblyIdentity(0, CBData->AssemblyIdentity, &pAsmIdentTemp));
  156. Entry->AssemblyIdentity = pAsmIdentTemp.Detach();
  157. AssemblyMetadataContext->pLastMetaDataEntry = NULL;
  158. }
  159. CBData->Success = TRUE;
  160. break;
  161. }
  162. case ACTCTXCTB_CBREASON_GETSECTIONSIZE:
  163. {
  164. PACTCTXCTB_CBGETSECTIONSIZE CBData = (PACTCTXCTB_CBGETSECTIONSIZE) Data;
  165. SSGenContext = (PSTRING_SECTION_GENERATION_CONTEXT) CBData->Header.ActCtxGenContext;
  166. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  167. IFW32FALSE_EXIT(::SxsGetStringSectionGenerationContextSectionSize(SSGenContext, &CBData->SectionSize));
  168. break;
  169. }
  170. case ACTCTXCTB_CBREASON_PARSEBEGINNING:
  171. {
  172. Data->ParseBeginning.Success = FALSE;
  173. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  174. {
  175. PCWSTR pszAssemblyName = NULL;
  176. SIZE_T CchAssemblyName = 0;
  177. PCASSEMBLY_IDENTITY AssemblyIdentity = Data->ParseBeginning.AssemblyContext->AssemblyIdentity;
  178. if (AssemblyIdentity != NULL)
  179. {
  180. IFW32FALSE_EXIT(
  181. ::SxspGetAssemblyIdentityAttributeValue(
  182. SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL,
  183. AssemblyIdentity,
  184. &s_IdentityAttribute_name,
  185. &pszAssemblyName,
  186. &CchAssemblyName));
  187. }
  188. switch (Data->ParseBeginning.ParseType)
  189. {
  190. case XML_FILE_TYPE_APPLICATION_CONFIGURATION:
  191. if (Data->Header.ManifestOperation == MANIFEST_OPERATION_GENERATE_ACTIVATION_CONTEXT)
  192. {
  193. // If there is a policy file, it will be hit first.
  194. IFALLOCFAILED_EXIT(Entry = new ASSEMBLY_METADATA_ENTRY);
  195. Entry->AssemblyIdentity = NULL;
  196. Entry->PolicyPathType = Data->ParseBeginning.FilePathType;
  197. IFW32FALSE_EXIT(Entry->PolicyPathBuffer.Win32Assign(Data->ParseBeginning.FilePath, Data->ParseBeginning.FilePathCch));
  198. Entry->PolicyLastWriteTime = Data->ParseBeginning.FileLastWriteTime;
  199. Entry->AssemblyRosterIndex = Data->ParseBeginning.AssemblyContext->AssemblyRosterIndex;
  200. IFW32FALSE_EXIT(
  201. ::SxsAddStringToStringSectionGenerationContext(
  202. (PSTRING_SECTION_GENERATION_CONTEXT) Data->ParseBeginning.Header.ActCtxGenContext,
  203. pszAssemblyName,
  204. CchAssemblyName,
  205. Entry,
  206. Data->ParseBeginning.AssemblyContext->AssemblyRosterIndex,
  207. ERROR_SXS_DUPLICATE_ASSEMBLY_NAME));
  208. }
  209. break;
  210. case XML_FILE_TYPE_MANIFEST:
  211. IFW32FALSE_EXIT(
  212. ::SxsFindStringInStringSectionGenerationContext(
  213. (PSTRING_SECTION_GENERATION_CONTEXT) Data->ParseBeginning.Header.ActCtxGenContext,
  214. pszAssemblyName,
  215. CchAssemblyName,
  216. (PVOID *) &Entry,
  217. &Found));
  218. if (!Found)
  219. {
  220. // Haven't seen it before; allocate it!
  221. IFALLOCFAILED_EXIT(Entry = new ASSEMBLY_METADATA_ENTRY);
  222. IFW32FALSE_EXIT(
  223. ::SxsAddStringToStringSectionGenerationContext(
  224. (PSTRING_SECTION_GENERATION_CONTEXT) Data->ParseBeginning.Header.ActCtxGenContext,
  225. pszAssemblyName,
  226. CchAssemblyName,
  227. Entry,
  228. Data->ParseBeginning.AssemblyContext->AssemblyRosterIndex,
  229. ERROR_SXS_DUPLICATE_ASSEMBLY_NAME));
  230. Entry->AssemblyRosterIndex = Data->ParseBeginning.AssemblyContext->AssemblyRosterIndex;
  231. }
  232. else
  233. {
  234. // The linkage between the root manifest's policy entry and the actual entry for it
  235. // is tenuous since the root policy is parsed before we've started keeping track of
  236. // the actual contents of the assembly. So, we would have previously added it
  237. // under XML_FILE_TYPE_APPLICATION_CONFIGURATION, but the code that sets the
  238. // AssemblyRosterIndex (way up the call stack) is making a somewhat random assumption
  239. // that the root is at roster index 1. It's a good assumption but conceptually
  240. // fragile; thus this assert/internal error report if it fails.
  241. INTERNAL_ERROR_CHECK(Entry->AssemblyRosterIndex == Data->ParseBeginning.AssemblyContext->AssemblyRosterIndex);
  242. }
  243. INTERNAL_ERROR_CHECK(Entry->AssemblyIdentity == NULL);
  244. IFW32FALSE_EXIT(
  245. ::SxsDuplicateAssemblyIdentity(
  246. 0,
  247. Data->ParseBeginning.AssemblyContext->AssemblyIdentity, // PCASSEMBLY_IDENTITY Source,
  248. &TempAssemblyIdentity));
  249. Entry->AssemblyIdentity = TempAssemblyIdentity;
  250. TempAssemblyIdentity = NULL;
  251. IFW32FALSE_EXIT(Entry->ManifestPathBuffer.Win32Assign(Data->ParseBeginning.FilePath, Data->ParseBeginning.FilePathCch));
  252. Entry->ManifestPathType = Data->ParseBeginning.FilePathType;
  253. // If the assembly has a name, record its directory
  254. if (CchAssemblyName != 0)
  255. {
  256. IFW32FALSE_EXIT(
  257. ::SxspGenerateSxsPath(
  258. SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT,
  259. SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY,
  260. NULL,
  261. 0,
  262. Data->ParseBeginning.AssemblyContext->AssemblyIdentity,
  263. Entry->AssemblyDirectoryNameBuffer));
  264. }
  265. Entry->ManifestLastWriteTime = Data->ParseBeginning.FileLastWriteTime;
  266. //Entry->Version = Data->ParseBeginning.AssemblyContext->Version;
  267. Entry->ManifestVersionMajor = Data->ParseBeginning.FileFormatVersionMajor;
  268. Entry->ManifestVersionMinor = Data->ParseBeginning.FileFormatVersionMinor;
  269. Entry->MetadataSatelliteRosterIndex = Data->ParseBeginning.MetadataSatelliteRosterIndex;
  270. {
  271. PCWSTR pszLangID = NULL;
  272. SIZE_T CchLangID = 0;
  273. // get pointers to LANGID string in AssemblyIdentity
  274. IFW32FALSE_EXIT(::SxspGetAssemblyIdentityAttributeValue(
  275. SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL,
  276. Data->ElementParsed.AssemblyContext->AssemblyIdentity,
  277. &s_IdentityAttribute_language,
  278. &pszLangID, &CchLangID));
  279. IFW32FALSE_EXIT(Entry->LanguageBuffer.Win32Assign(pszLangID, CchLangID));
  280. }
  281. if (Data->ParseBeginning.AssemblyContext->Flags & ACTCTXCTB_ASSEMBLY_CONTEXT_ASSEMBLY_POLICY_APPLIED)
  282. Entry->AssemblyPolicyApplied = TRUE;
  283. if (Data->ParseBeginning.AssemblyContext->Flags & ACTCTXCTB_ASSEMBLY_CONTEXT_ROOT_POLICY_APPLIED)
  284. Entry->RootPolicyApplied = TRUE;
  285. if (Data->ParseBeginning.AssemblyContext->Flags & ACTCTXCTB_ASSEMBLY_CONTEXT_IS_ROOT_ASSEMBLY)
  286. Entry->IsRootAssembly = TRUE;
  287. if (Data->ParseBeginning.AssemblyContext->Flags & ACTCTXCTB_ASSEMBLY_CONTEXT_IS_PRIVATE_ASSEMBLY)
  288. Entry->IsPrivateAssembly = TRUE;
  289. Entry->FileNum = 0;
  290. AssemblyMetadataContext->pLastMetaDataEntry = Entry;
  291. break;
  292. }
  293. }
  294. Data->ParseBeginning.Success = TRUE;
  295. break;
  296. }
  297. case ACTCTXCTB_CBREASON_GETSECTIONDATA:
  298. {
  299. Data->GetSectionData.Success = FALSE;
  300. INTERNAL_ERROR_CHECK(SSGenContext != NULL);
  301. IFW32FALSE_EXIT(
  302. ::SxsGetStringSectionGenerationContextSectionData(
  303. SSGenContext,
  304. Data->GetSectionData.SectionSize,
  305. Data->GetSectionData.SectionDataStart,
  306. NULL));
  307. Data->GetSectionData.Success = TRUE;
  308. break;
  309. }
  310. }
  311. Exit:
  312. if (TempAssemblyIdentity != NULL)
  313. ::SxsDestroyAssemblyIdentity(TempAssemblyIdentity);
  314. }
  315. BOOL
  316. SxspAssemblyMetadataStringSectionGenerationCallback(
  317. PVOID Context,
  318. ULONG Reason,
  319. PVOID CallbackData
  320. )
  321. {
  322. BOOL fSuccess = FALSE;
  323. FN_TRACE_WIN32(fSuccess);
  324. PASSEMBLY_METADATA_CONTEXT GlobalContext = reinterpret_cast<PASSEMBLY_METADATA_CONTEXT>(Context);
  325. INTERNAL_ERROR_CHECK(GlobalContext != NULL);
  326. switch (Reason)
  327. {
  328. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETUSERDATASIZE:
  329. {
  330. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATASIZE CBData =
  331. (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATASIZE) CallbackData;
  332. CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION);
  333. if (GlobalContext->ApplicationDirectoryCch != 0)
  334. CBData->DataSize += ((GlobalContext->ApplicationDirectoryCch + 1) * sizeof(WCHAR));
  335. break;
  336. }
  337. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETUSERDATA:
  338. {
  339. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATA CBData =
  340. (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETUSERDATA) CallbackData;
  341. PACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION GlobalInfo;
  342. ULONG BytesLeft = static_cast<ULONG>(CBData->BufferSize);
  343. ULONG BytesWritten = 0;
  344. if (BytesLeft < sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION))
  345. {
  346. ::FusionpSetLastWin32Error(ERROR_INSUFFICIENT_BUFFER);
  347. goto Exit;
  348. }
  349. BytesWritten += sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION);
  350. BytesLeft -= sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION);
  351. GlobalInfo = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION) CBData->Buffer;
  352. GlobalInfo->Size = sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION);
  353. GlobalInfo->Flags = 0;
  354. GlobalInfo->PolicyCoherencyGuid = GUID_NULL;
  355. GlobalInfo->PolicyOverrideGuid = GUID_NULL;
  356. GlobalInfo->ApplicationDirectoryLength = 0;
  357. GlobalInfo->ApplicationDirectoryOffset = 0;
  358. if (GlobalContext->ApplicationDirectoryCch != 0)
  359. {
  360. ULONG BytesNeeded = static_cast<ULONG>((GlobalContext->ApplicationDirectoryCch + 1) * sizeof(WCHAR));
  361. if (BytesLeft < BytesNeeded)
  362. ORIGINATE_WIN32_FAILURE_AND_EXIT(NoRoom, ERROR_INSUFFICIENT_BUFFER);
  363. memcpy(
  364. (GlobalInfo + 1),
  365. GlobalContext->ApplicationDirectory,
  366. BytesNeeded);
  367. GlobalInfo->ApplicationDirectoryPathType = GlobalContext->ApplicationDirectoryPathType;
  368. GlobalInfo->ApplicationDirectoryLength = BytesNeeded - sizeof(WCHAR);
  369. GlobalInfo->ApplicationDirectoryOffset = sizeof(*GlobalInfo);
  370. GlobalInfo->Size += BytesNeeded;
  371. BytesWritten += BytesNeeded;
  372. BytesLeft -= BytesNeeded;
  373. }
  374. CBData->BytesWritten = BytesWritten;
  375. break;
  376. }
  377. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_ENTRYDELETED:
  378. {
  379. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_ENTRYDELETED) CallbackData;
  380. PASSEMBLY_METADATA_ENTRY Entry = (PASSEMBLY_METADATA_ENTRY) CBData->DataContext;
  381. FUSION_DELETE_SINGLETON(Entry);
  382. break;
  383. }
  384. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATASIZE:
  385. {
  386. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE CBData = (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATASIZE) CallbackData;
  387. PASSEMBLY_METADATA_ENTRY Entry = (PASSEMBLY_METADATA_ENTRY) CBData->DataContext;
  388. CBData->DataSize = sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION);
  389. if (Entry->AssemblyIdentity != NULL)
  390. {
  391. SIZE_T cbEncodedSize = 0;
  392. IFW32FALSE_EXIT(SxsComputeAssemblyIdentityEncodedSize(
  393. 0,
  394. Entry->AssemblyIdentity,
  395. NULL,
  396. SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL,
  397. &cbEncodedSize));
  398. CBData->DataSize += cbEncodedSize;
  399. }
  400. SIZE_T Cch;
  401. #define GET_BUFFER_SIZE(Buffer) (((Cch = (Buffer).Cch()) != 0) ? ((Cch + 1) * sizeof(WCHAR)) : 0)
  402. CBData->DataSize += GET_BUFFER_SIZE(Entry->ManifestPathBuffer);
  403. CBData->DataSize += GET_BUFFER_SIZE(Entry->PolicyPathBuffer);
  404. CBData->DataSize += GET_BUFFER_SIZE(Entry->AssemblyDirectoryNameBuffer);
  405. CBData->DataSize += GET_BUFFER_SIZE(Entry->LanguageBuffer);
  406. #undef GET_BUFFER_SIZE
  407. break;
  408. }
  409. case STRING_SECTION_GENERATION_CONTEXT_CALLBACK_REASON_GETDATA:
  410. {
  411. PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA CBData =
  412. (PSTRING_SECTION_GENERATION_CONTEXT_CBDATA_GETDATA) CallbackData;
  413. PASSEMBLY_METADATA_ENTRY Entry = (PASSEMBLY_METADATA_ENTRY) CBData->DataContext;
  414. PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION Info;
  415. SIZE_T BytesLeft = (ULONG)(CBData->BufferSize);
  416. SIZE_T BytesWritten = 0;
  417. PWSTR StringCursor;
  418. SIZE_T EncodedIdentityBytesWritten = 0;
  419. Info = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION) CBData->Buffer;
  420. if (BytesLeft < sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION))
  421. {
  422. ::FusionpSetLastWin32Error(ERROR_INSUFFICIENT_BUFFER);
  423. goto Exit;
  424. }
  425. BytesWritten += sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION);
  426. BytesLeft -= sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION);
  427. StringCursor = reinterpret_cast<PWSTR>(Info + 1);
  428. Info->Size = sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION);
  429. Info->Flags =
  430. (Entry->IsRootAssembly ? ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_ASSEMBLY : 0) |
  431. (Entry->IsPrivateAssembly ? ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_PRIVATE_ASSEMBLY : 0) |
  432. ((Entry->AssemblyPolicyApplied ||
  433. Entry->RootPolicyApplied) ? ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_POLICY_APPLIED : 0) |
  434. (Entry->AssemblyPolicyApplied ? ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ASSEMBLY_POLICY_APPLIED : 0) |
  435. (Entry->RootPolicyApplied ? ACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION_ROOT_POLICY_APPLIED : 0);
  436. if (Entry->AssemblyIdentity != NULL)
  437. {
  438. SIZE_T cbWritten = 0;
  439. IFW32FALSE_EXIT(
  440. SxsEncodeAssemblyIdentity(
  441. 0,
  442. Entry->AssemblyIdentity,
  443. NULL,
  444. SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL,
  445. BytesLeft,
  446. StringCursor,
  447. &cbWritten));
  448. INTERNAL_ERROR_CHECK(cbWritten <= MAXULONG);
  449. INTERNAL_ERROR_CHECK(((PBYTE)StringCursor - (PBYTE)CBData->SectionHeader) <= MAXULONG);
  450. Info->EncodedAssemblyIdentityOffset = (ULONG)((PBYTE)StringCursor - (PBYTE)CBData->SectionHeader);
  451. Info->EncodedAssemblyIdentityLength = (ULONG)cbWritten;
  452. BytesLeft -= cbWritten;
  453. BytesWritten += cbWritten;
  454. StringCursor = (PWSTR)(((PBYTE)StringCursor) + cbWritten);
  455. }
  456. else
  457. {
  458. Info->EncodedAssemblyIdentityOffset = 0;
  459. Info->EncodedAssemblyIdentityLength = 0;
  460. }
  461. IFW32FALSE_EXIT(Entry->ManifestPathBuffer.Win32CopyIntoBuffer(
  462. &StringCursor,
  463. &BytesLeft,
  464. &BytesWritten,
  465. CBData->SectionHeader,
  466. &Info->ManifestPathOffset,
  467. &Info->ManifestPathLength));
  468. Info->ManifestPathType = Entry->ManifestPathType;
  469. Info->PolicyPathType = Entry->PolicyPathType;
  470. Info->ManifestLastWriteTime.LowPart = Entry->ManifestLastWriteTime.dwLowDateTime;
  471. Info->ManifestLastWriteTime.HighPart = Entry->ManifestLastWriteTime.dwHighDateTime;
  472. Info->PolicyLastWriteTime.LowPart = Entry->PolicyLastWriteTime.dwLowDateTime;
  473. Info->PolicyLastWriteTime.HighPart = Entry->PolicyLastWriteTime.dwHighDateTime;
  474. IFW32FALSE_EXIT(Entry->PolicyPathBuffer.Win32CopyIntoBuffer(
  475. &StringCursor,
  476. &BytesLeft,
  477. &BytesWritten,
  478. CBData->SectionHeader,
  479. &Info->PolicyPathOffset,
  480. &Info->PolicyPathLength));
  481. IFW32FALSE_EXIT(Entry->AssemblyDirectoryNameBuffer.Win32CopyIntoBuffer(
  482. &StringCursor,
  483. &BytesLeft,
  484. &BytesWritten,
  485. CBData->SectionHeader,
  486. &Info->AssemblyDirectoryNameOffset,
  487. &Info->AssemblyDirectoryNameLength));
  488. Info->ManifestVersionMajor = Entry->ManifestVersionMajor;
  489. Info->ManifestVersionMinor = Entry->ManifestVersionMinor;
  490. Info->MetadataSatelliteRosterIndex = Entry->MetadataSatelliteRosterIndex;
  491. Info->NumOfFilesInAssembly = Entry->FileNum;
  492. IFW32FALSE_EXIT(Entry->LanguageBuffer.Win32CopyIntoBuffer(
  493. &StringCursor,
  494. &BytesLeft,
  495. &BytesWritten,
  496. CBData->SectionHeader,
  497. &Info->LanguageOffset,
  498. &Info->LanguageLength));
  499. CBData->BytesWritten = BytesWritten;
  500. }
  501. }
  502. fSuccess = TRUE;
  503. Exit:
  504. return fSuccess;
  505. }