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.

626 lines
26 KiB

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