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.

264 lines
7.7 KiB

  1. #include "stdinc.h"
  2. #include "idp.h"
  3. #include "sxsapi.h"
  4. #include "sxsid.h"
  5. BOOL
  6. SxspMapAssemblyIdentityToPolicyIdentity(
  7. DWORD Flags,
  8. PCASSEMBLY_IDENTITY AssemblyIdentity,
  9. PASSEMBLY_IDENTITY &PolicyIdentity
  10. )
  11. {
  12. BOOL fSuccess = FALSE;
  13. FN_TRACE_WIN32(fSuccess);
  14. PCWSTR pszTemp;
  15. SIZE_T cchTemp;
  16. PASSEMBLY_IDENTITY NewIdentity = NULL;
  17. CStringBuffer Name;
  18. bool fFirst;
  19. const bool fOmitEntireVersion = ((Flags & SXSP_MAP_ASSEMBLY_IDENTITY_TO_POLICY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION) != 0);
  20. BOOL fIsPolicy = FALSE;
  21. PolicyIdentity = NULL;
  22. PARAMETER_CHECK((Flags & ~(SXSP_MAP_ASSEMBLY_IDENTITY_TO_POLICY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION)) == 0);
  23. PARAMETER_CHECK(AssemblyIdentity != 0);
  24. //
  25. // Determine assembly type. If this wasn't a policy assembly, then map it to one.
  26. //
  27. IFW32FALSE_EXIT(::SxspDetermineAssemblyType(AssemblyIdentity, fIsPolicy));
  28. //
  29. // Now let's duplicate the assembly identity into a policy identity by changing the
  30. // name, and potentially changing the type if it was "win32" into "win32-policy"
  31. //
  32. IFW32FALSE_EXIT(
  33. ::SxsDuplicateAssemblyIdentity(
  34. 0,
  35. AssemblyIdentity,
  36. &NewIdentity));
  37. //
  38. // If we're not a policy assembly, then we have to map type="" to type="policy"
  39. // and type="foo" to type="foo-policy"
  40. //
  41. if (!fIsPolicy)
  42. {
  43. PCWSTR pcwszOriginalType;
  44. SIZE_T cchOriginalType;
  45. IFW32FALSE_EXIT(
  46. ::SxspGetAssemblyIdentityAttributeValue(
  47. SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL,
  48. AssemblyIdentity,
  49. &s_IdentityAttribute_type,
  50. &pcwszOriginalType,
  51. &cchOriginalType));
  52. if (cchOriginalType == 0)
  53. {
  54. IFW32FALSE_EXIT(
  55. ::SxspSetAssemblyIdentityAttributeValue(
  56. SXSP_SET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_OVERWRITE_EXISTING,
  57. NewIdentity,
  58. &s_IdentityAttribute_type,
  59. ASSEMBLY_TYPE_POLICY,
  60. ASSEMBLY_TYPE_POLICY_CCH));
  61. }
  62. else
  63. {
  64. CSmallStringBuffer MappedName;
  65. IFW32FALSE_EXIT(MappedName.Win32Assign(pcwszOriginalType, cchOriginalType));
  66. IFW32FALSE_EXIT(MappedName.Win32Append(ASSEMBLY_TYPE_POLICY_SUFFIX, ASSEMBLY_TYPE_POLICY_SUFFIX_CCH));
  67. IFW32FALSE_EXIT(
  68. ::SxspSetAssemblyIdentityAttributeValue(
  69. SXSP_SET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_OVERWRITE_EXISTING,
  70. NewIdentity,
  71. &s_IdentityAttribute_type,
  72. MappedName));
  73. }
  74. }
  75. IFW32FALSE_EXIT(Name.Win32Assign(L"Policy.", 7));
  76. if (!fOmitEntireVersion)
  77. {
  78. IFW32FALSE_EXIT(
  79. ::SxspGetAssemblyIdentityAttributeValue(
  80. 0,
  81. AssemblyIdentity,
  82. &s_IdentityAttribute_version,
  83. &pszTemp,
  84. &cchTemp));
  85. fFirst = true;
  86. while (cchTemp != 0)
  87. {
  88. if (pszTemp[--cchTemp] == L'.')
  89. {
  90. if (!fFirst)
  91. break;
  92. fFirst = false;
  93. }
  94. }
  95. // This should not be zero; someone prior to this should have validated the version format
  96. // to include three dots.
  97. INTERNAL_ERROR_CHECK(cchTemp != 0);
  98. IFW32FALSE_EXIT(Name.Win32Append(pszTemp, cchTemp + 1));
  99. }
  100. IFW32FALSE_EXIT(
  101. ::SxspGetAssemblyIdentityAttributeValue(
  102. 0,
  103. AssemblyIdentity,
  104. &s_IdentityAttribute_name,
  105. &pszTemp,
  106. &cchTemp));
  107. IFW32FALSE_EXIT(Name.Win32Append(pszTemp, cchTemp));
  108. IFW32FALSE_EXIT(
  109. ::SxspSetAssemblyIdentityAttributeValue(
  110. SXSP_SET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_OVERWRITE_EXISTING,
  111. NewIdentity,
  112. &s_IdentityAttribute_name,
  113. Name));
  114. // finally we whack the version...
  115. IFW32FALSE_EXIT(
  116. ::SxspRemoveAssemblyIdentityAttribute(
  117. SXSP_REMOVE_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_NOT_FOUND_SUCCEEDS,
  118. NewIdentity,
  119. &s_IdentityAttribute_version));
  120. PolicyIdentity = NewIdentity;
  121. NewIdentity = NULL;
  122. fSuccess = TRUE;
  123. Exit:
  124. if (NewIdentity != NULL)
  125. {
  126. ::SxsDestroyAssemblyIdentity(NewIdentity);
  127. NewIdentity = NULL;
  128. }
  129. return fSuccess;
  130. }
  131. BOOL
  132. SxspGenerateTextuallyEncodedPolicyIdentityFromAssemblyIdentity(
  133. DWORD Flags,
  134. PCASSEMBLY_IDENTITY AssemblyIdentity,
  135. CBaseStringBuffer &rbuffEncodedIdentity,
  136. PASSEMBLY_IDENTITY *PolicyIdentityOut
  137. )
  138. {
  139. BOOL fSuccess = FALSE;
  140. FN_TRACE_WIN32(fSuccess);
  141. PASSEMBLY_IDENTITY PolicyIdentity = NULL;
  142. SIZE_T EncodedIdentityBytes = 0;
  143. CStringBufferAccessor acc;
  144. DWORD dwMapFlags = 0;
  145. SIZE_T BytesWritten;
  146. if (PolicyIdentityOut != NULL)
  147. *PolicyIdentityOut = NULL;
  148. PARAMETER_CHECK((Flags & ~(SXSP_GENERATE_TEXTUALLY_ENCODED_POLICY_IDENTITY_FROM_ASSEMBLY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION)) == 0);
  149. PARAMETER_CHECK(AssemblyIdentity != NULL);
  150. if (Flags & SXSP_GENERATE_TEXTUALLY_ENCODED_POLICY_IDENTITY_FROM_ASSEMBLY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION)
  151. dwMapFlags |= SXSP_MAP_ASSEMBLY_IDENTITY_TO_POLICY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION;
  152. IFW32FALSE_EXIT(::SxspMapAssemblyIdentityToPolicyIdentity(dwMapFlags, AssemblyIdentity, PolicyIdentity));
  153. IFW32FALSE_EXIT(
  154. ::SxsComputeAssemblyIdentityEncodedSize(
  155. 0,
  156. PolicyIdentity,
  157. NULL,
  158. SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL,
  159. &EncodedIdentityBytes));
  160. INTERNAL_ERROR_CHECK((EncodedIdentityBytes % sizeof(WCHAR)) == 0);
  161. IFW32FALSE_EXIT(rbuffEncodedIdentity.Win32ResizeBuffer((EncodedIdentityBytes / sizeof(WCHAR)) + 1, eDoNotPreserveBufferContents));
  162. acc.Attach(&rbuffEncodedIdentity);
  163. IFW32FALSE_EXIT(
  164. ::SxsEncodeAssemblyIdentity(
  165. 0,
  166. PolicyIdentity,
  167. NULL,
  168. SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL,
  169. acc.GetBufferCb(),
  170. acc.GetBufferPtr(),
  171. &BytesWritten));
  172. INTERNAL_ERROR_CHECK((BytesWritten % sizeof(WCHAR)) == 0);
  173. INTERNAL_ERROR_CHECK(BytesWritten <= EncodedIdentityBytes);
  174. acc.GetBufferPtr()[BytesWritten / sizeof(WCHAR)] = L'\0';
  175. acc.Detach();
  176. if (PolicyIdentityOut != NULL)
  177. {
  178. *PolicyIdentityOut = PolicyIdentity;
  179. PolicyIdentity = NULL; // so we don't try to clean it up in the exit path
  180. }
  181. fSuccess = TRUE;
  182. Exit:
  183. if (PolicyIdentity != NULL)
  184. SxsDestroyAssemblyIdentity(PolicyIdentity);
  185. return fSuccess;
  186. }
  187. //
  188. // the difference between this func and SxsHashAssemblyIdentity() is that for policy,
  189. // version should not be calcaulated as part of hash
  190. //
  191. BOOL
  192. SxspHashAssemblyIdentityForPolicy(
  193. IN DWORD dwFlags,
  194. IN PCASSEMBLY_IDENTITY AssemblyIdentity,
  195. OUT ULONG & IdentityHash)
  196. {
  197. BOOL fSuccess = FALSE;
  198. FN_TRACE_WIN32(fSuccess);
  199. PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
  200. IFW32FALSE_EXIT(
  201. ::SxsDuplicateAssemblyIdentity(
  202. SXS_DUPLICATE_ASSEMBLY_IDENTITY_FLAG_FREEZE,
  203. AssemblyIdentity,
  204. &pAssemblyIdentity));
  205. IFW32FALSE_EXIT(
  206. ::SxspRemoveAssemblyIdentityAttribute(
  207. SXSP_REMOVE_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_NOT_FOUND_SUCCEEDS,
  208. pAssemblyIdentity,
  209. &s_IdentityAttribute_version));
  210. IFW32FALSE_EXIT(::SxsHashAssemblyIdentity(0, pAssemblyIdentity, &IdentityHash));
  211. fSuccess = TRUE;
  212. Exit:
  213. if (pAssemblyIdentity != NULL)
  214. ::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
  215. return fSuccess;
  216. }