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.

388 lines
12 KiB

  1. #include "stdinc.h"
  2. #include <setupapi.h>
  3. #include <sxsapi.h>
  4. #include <stdlib.h>
  5. #include <search.h>
  6. #include "idp.h"
  7. #include "sxsapi.h"
  8. #include "sxsapi.h"
  9. #include "sxsid.h"
  10. BOOL
  11. SxspSetAssemblyIdentityAttributeValue(
  12. DWORD Flags,
  13. PASSEMBLY_IDENTITY AssemblyIdentity,
  14. PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE AttributeReference,
  15. const WCHAR *Value,
  16. SIZE_T ValueCch
  17. )
  18. {
  19. BOOL fSuccess = FALSE;
  20. FN_TRACE_WIN32(fSuccess);
  21. ASSEMBLY_IDENTITY_ATTRIBUTE Attribute;
  22. DWORD FlagsToRealInsert = 0;
  23. PARAMETER_CHECK((Flags & ~(SXSP_SET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_OVERWRITE_EXISTING)) == 0);
  24. PARAMETER_CHECK(AssemblyIdentity != NULL);
  25. //
  26. // the validation of attribute content, such as value, name and namespace, is done within SxsInsertAssemblyIdentityAttribute
  27. // it is good to keep validation in one place.
  28. //
  29. PARAMETER_CHECK(AttributeReference != NULL);
  30. PARAMETER_CHECK(Value != NULL || ValueCch == 0);
  31. Attribute.Flags = 0;
  32. Attribute.Namespace = AttributeReference->Namespace;
  33. Attribute.NamespaceCch = AttributeReference->NamespaceCch;
  34. Attribute.Name = AttributeReference->Name;
  35. Attribute.NameCch = AttributeReference->NameCch;
  36. Attribute.Value = Value;
  37. Attribute.ValueCch = ValueCch;
  38. if (Flags & SXSP_SET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_OVERWRITE_EXISTING)
  39. FlagsToRealInsert |= SXS_INSERT_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_OVERWRITE_EXISTING;
  40. IFW32FALSE_EXIT(::SxsInsertAssemblyIdentityAttribute(FlagsToRealInsert, AssemblyIdentity, &Attribute));
  41. fSuccess = TRUE;
  42. Exit:
  43. return fSuccess;
  44. }
  45. BOOL
  46. SxspSetAssemblyIdentityAttributeValue(
  47. DWORD Flags,
  48. PASSEMBLY_IDENTITY AssemblyIdentity,
  49. PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE AttributeReference,
  50. const CBaseStringBuffer &Value
  51. )
  52. {
  53. BOOL fSuccess = FALSE;
  54. FN_TRACE_WIN32(fSuccess);
  55. IFW32FALSE_EXIT(
  56. ::SxspSetAssemblyIdentityAttributeValue(
  57. Flags,
  58. AssemblyIdentity,
  59. AttributeReference,
  60. static_cast<PCWSTR>(Value),
  61. Value.Cch()));
  62. fSuccess = TRUE;
  63. Exit:
  64. return fSuccess;
  65. }
  66. /////////////////////////////////////////////////////////////////////////////
  67. // Action :
  68. // 1. if (namespace, name) is provided, remove all attributes with such (namespace, name)
  69. // 2. if (namespace, name, value), remove at most 1 attribute from assembly-identity
  70. ///////////////////////////////////////////////////////////////////////////////
  71. BOOL
  72. SxspRemoveAssemblyIdentityAttribute(
  73. DWORD Flags,
  74. PASSEMBLY_IDENTITY pAssemblyIdentity,
  75. PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE AttributeReference
  76. )
  77. {
  78. BOOL fSuccess = FALSE;
  79. FN_TRACE_WIN32(fSuccess);
  80. ASSEMBLY_IDENTITY_ATTRIBUTE Attribute;
  81. ULONG Ordinal;
  82. ULONG Count;
  83. DWORD dwFindAttributeFlags = 0;
  84. PARAMETER_CHECK((Flags & ~(SXSP_REMOVE_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_NOT_FOUND_SUCCEEDS)) == 0);
  85. PARAMETER_CHECK(pAssemblyIdentity != NULL);
  86. PARAMETER_CHECK(AttributeReference != NULL);
  87. Attribute.Flags = 0;
  88. Attribute.Namespace = AttributeReference->Namespace;
  89. Attribute.NamespaceCch = AttributeReference->NamespaceCch;
  90. Attribute.Name = AttributeReference->Name;
  91. Attribute.NameCch = AttributeReference->NameCch;
  92. dwFindAttributeFlags = SXS_FIND_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_MATCH_NAMESPACE | SXS_FIND_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_MATCH_NAME;
  93. // If it's OK for the attribute not to exist, set the flag in the call to find it.
  94. if (Flags & SXSP_REMOVE_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_NOT_FOUND_SUCCEEDS)
  95. dwFindAttributeFlags |= SXS_FIND_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_NOT_FOUND_SUCCEEDS;
  96. IFW32FALSE_EXIT(
  97. ::SxsFindAssemblyIdentityAttribute(
  98. dwFindAttributeFlags,
  99. pAssemblyIdentity,
  100. &Attribute,
  101. &Ordinal,
  102. &Count));
  103. INTERNAL_ERROR_CHECK(Count <= 1);
  104. if (Count > 0)
  105. {
  106. IFW32FALSE_EXIT(
  107. ::SxsRemoveAssemblyIdentityAttributesByOrdinal(
  108. 0, // DWORD Flags,
  109. pAssemblyIdentity,
  110. Ordinal,
  111. Count));
  112. }
  113. fSuccess = TRUE;
  114. Exit:
  115. return fSuccess;
  116. }
  117. /////////////////////////////////////////////////////////////////////////////
  118. // if no such attribure with such (namespace and name), return FALSE with
  119. // ::SetLastError(ERROR_NOT_FOUND);
  120. ///////////////////////////////////////////////////////////////////////////////
  121. BOOL
  122. SxspGetAssemblyIdentityAttributeValue(
  123. DWORD Flags,
  124. PCASSEMBLY_IDENTITY AssemblyIdentity,
  125. PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE AttributeReference,
  126. OUT PCWSTR *StringOut,
  127. OUT SIZE_T *CchOut OPTIONAL
  128. )
  129. {
  130. BOOL fSuccess = FALSE;
  131. FN_TRACE_WIN32(fSuccess);
  132. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE InternalAttribute = NULL;
  133. ASSEMBLY_IDENTITY_ATTRIBUTE Attribute;
  134. DWORD dwLocateFlags = SXSP_LOCATE_INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_MATCH_NAMESPACE | SXSP_LOCATE_INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_MATCH_NAME;
  135. if (StringOut != NULL)
  136. *StringOut = NULL;
  137. if (CchOut != NULL)
  138. *CchOut = 0;
  139. PARAMETER_CHECK((Flags & ~(SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL)) == 0);
  140. PARAMETER_CHECK(AssemblyIdentity != NULL);
  141. PARAMETER_CHECK(AttributeReference != NULL);
  142. Attribute.Flags = 0;
  143. Attribute.Namespace = AttributeReference->Namespace;
  144. Attribute.NamespaceCch = AttributeReference->NamespaceCch;
  145. Attribute.Name = AttributeReference->Name;
  146. Attribute.NameCch = AttributeReference->NameCch;
  147. InternalAttribute =
  148. ::SxspLocateInternalAssemblyIdentityAttribute(
  149. dwLocateFlags,
  150. AssemblyIdentity,
  151. &Attribute,
  152. NULL);
  153. if (InternalAttribute != NULL)
  154. {
  155. if (StringOut != NULL)
  156. *StringOut = InternalAttribute->Attribute.Value;
  157. if (CchOut != NULL)
  158. *CchOut = InternalAttribute->Attribute.ValueCch;
  159. }
  160. else
  161. {
  162. if ((Flags & SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL) == 0)
  163. ORIGINATE_WIN32_FAILURE_AND_EXIT(AttributeNotFound, ERROR_NOT_FOUND);
  164. }
  165. fSuccess = TRUE;
  166. Exit:
  167. return fSuccess;
  168. }
  169. BOOL
  170. SxspGetAssemblyIdentityAttributeValue(
  171. IN DWORD Flags,
  172. IN PCASSEMBLY_IDENTITY AssemblyIdentity,
  173. PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE AttributeReference,
  174. OUT CBaseStringBuffer &Value
  175. )
  176. {
  177. BOOL fSuccess = FALSE;
  178. FN_TRACE_WIN32(fSuccess);
  179. PCWSTR String = NULL;
  180. SIZE_T Cch = 0;
  181. IFW32FALSE_EXIT(
  182. ::SxspGetAssemblyIdentityAttributeValue(
  183. Flags,
  184. AssemblyIdentity,
  185. AttributeReference,
  186. &String,
  187. &Cch));
  188. IFW32FALSE_EXIT(Value.Win32Assign(String, Cch));
  189. fSuccess = TRUE;
  190. Exit:
  191. return fSuccess;
  192. }
  193. BOOL
  194. SxspUpdateAssemblyIdentityHash(
  195. DWORD dwFlags,
  196. PASSEMBLY_IDENTITY AssemblyIdentity
  197. )
  198. {
  199. BOOL fSuccess = FALSE;
  200. FN_TRACE_WIN32(fSuccess);
  201. PARAMETER_CHECK(dwFlags == 0);
  202. PARAMETER_CHECK(AssemblyIdentity != NULL);
  203. if (AssemblyIdentity->HashDirty)
  204. {
  205. IFW32FALSE_EXIT(::SxspHashInternalAssemblyIdentityAttributes(
  206. 0,
  207. AssemblyIdentity->AttributeCount,
  208. AssemblyIdentity->AttributePointerArray,
  209. &AssemblyIdentity->Hash));
  210. AssemblyIdentity->HashDirty = FALSE;
  211. }
  212. fSuccess = TRUE;
  213. Exit:
  214. return fSuccess;
  215. }
  216. BOOL
  217. SxspEnsureAssemblyIdentityHashIsUpToDate(
  218. DWORD dwFlags,
  219. PCASSEMBLY_IDENTITY AssemblyIdentity
  220. )
  221. {
  222. BOOL fSuccess = FALSE;
  223. FN_TRACE_WIN32(fSuccess);
  224. PARAMETER_CHECK(dwFlags == 0);
  225. PARAMETER_CHECK(AssemblyIdentity != NULL);
  226. if (AssemblyIdentity->HashDirty)
  227. IFW32FALSE_EXIT(::SxspUpdateAssemblyIdentityHash(0, const_cast<PASSEMBLY_IDENTITY>(AssemblyIdentity)));
  228. fSuccess = TRUE;
  229. Exit:
  230. return fSuccess;
  231. }
  232. BOOL
  233. SxsHashAssemblyIdentity(
  234. DWORD dwFlags,
  235. PCASSEMBLY_IDENTITY pAssemblyIdentity,
  236. ULONG * pulPseudoKey
  237. )
  238. {
  239. BOOL fSuccess = FALSE;
  240. FN_TRACE_WIN32(fSuccess);
  241. ULONG ulPseudoKey;
  242. if (pulPseudoKey)
  243. *pulPseudoKey = 0;
  244. PARAMETER_CHECK(dwFlags == 0);
  245. if (pAssemblyIdentity == NULL)
  246. ulPseudoKey = 0;
  247. else
  248. {
  249. IFW32FALSE_EXIT(::SxspEnsureAssemblyIdentityHashIsUpToDate(0, pAssemblyIdentity));
  250. ulPseudoKey = pAssemblyIdentity->Hash;
  251. }
  252. if (pulPseudoKey != NULL)
  253. *pulPseudoKey = ulPseudoKey;
  254. fSuccess = TRUE;
  255. Exit:
  256. return fSuccess;
  257. }
  258. // just to find whether Equal or Not
  259. BOOL
  260. SxsAreAssemblyIdentitiesEqual(
  261. DWORD dwFlags,
  262. PCASSEMBLY_IDENTITY pAssemblyIdentity1,
  263. PCASSEMBLY_IDENTITY pAssemblyIdentity2,
  264. BOOL *EqualOut
  265. )
  266. {
  267. BOOL fSuccess = FALSE;
  268. FN_TRACE_WIN32(fSuccess);
  269. BOOL Equal = FALSE;
  270. if (EqualOut != NULL)
  271. *EqualOut = FALSE;
  272. PARAMETER_CHECK((dwFlags & ~(SXS_ARE_ASSEMBLY_IDENTITIES_EQUAL_FLAG_ALLOW_REF_TO_MATCH_DEF)) == 0);
  273. PARAMETER_CHECK(pAssemblyIdentity1 != NULL);
  274. PARAMETER_CHECK(pAssemblyIdentity2 != NULL);
  275. PARAMETER_CHECK(EqualOut != NULL);
  276. // get hash for each assembly identity
  277. IFW32FALSE_EXIT(::SxspEnsureAssemblyIdentityHashIsUpToDate(0, pAssemblyIdentity1));
  278. IFW32FALSE_EXIT(::SxspEnsureAssemblyIdentityHashIsUpToDate(0, pAssemblyIdentity2));
  279. // compare hash value of two identity; it's a quick way to determine they're not equal.
  280. if (pAssemblyIdentity2->Hash == pAssemblyIdentity1->Hash)
  281. {
  282. // Note that two identities which differ only in their internal flags are still semantically
  283. // equal.
  284. if ((pAssemblyIdentity1->Flags == pAssemblyIdentity2->Flags) &&
  285. (pAssemblyIdentity1->Hash == pAssemblyIdentity2->Hash) &&
  286. (pAssemblyIdentity1->NamespaceCount == pAssemblyIdentity2->NamespaceCount) &&
  287. (pAssemblyIdentity1->AttributeCount == pAssemblyIdentity2->AttributeCount))
  288. {
  289. if (dwFlags & SXS_ARE_ASSEMBLY_IDENTITIES_EQUAL_FLAG_ALLOW_REF_TO_MATCH_DEF)
  290. {
  291. if (((pAssemblyIdentity1->Type == ASSEMBLY_IDENTITY_TYPE_DEFINITION) ||
  292. (pAssemblyIdentity1->Type == ASSEMBLY_IDENTITY_TYPE_REFERENCE)) &&
  293. ((pAssemblyIdentity2->Type == ASSEMBLY_IDENTITY_TYPE_DEFINITION) ||
  294. (pAssemblyIdentity2->Type == ASSEMBLY_IDENTITY_TYPE_REFERENCE)))
  295. {
  296. // They match sufficiently...
  297. Equal = TRUE;
  298. }
  299. }
  300. else
  301. Equal = (pAssemblyIdentity1->Type == pAssemblyIdentity2->Type);
  302. if (Equal)
  303. {
  304. ULONG ComparisonResult = SXS_COMPARE_ASSEMBLY_IDENTITY_ATTRIBUTES_COMPARISON_RESULT_INVALID;
  305. // Reset our assumption...
  306. Equal = FALSE;
  307. IFW32FALSE_EXIT(
  308. ::SxspCompareAssemblyIdentityAttributeLists(
  309. 0,
  310. pAssemblyIdentity1->AttributeCount,
  311. pAssemblyIdentity1->AttributePointerArray,
  312. pAssemblyIdentity2->AttributePointerArray,
  313. &ComparisonResult));
  314. INTERNAL_ERROR_CHECK(
  315. (ComparisonResult == SXS_COMPARE_ASSEMBLY_IDENTITY_ATTRIBUTES_COMPARISON_RESULT_LESS_THAN) ||
  316. (ComparisonResult == SXS_COMPARE_ASSEMBLY_IDENTITY_ATTRIBUTES_COMPARISON_RESULT_EQUAL) ||
  317. (ComparisonResult == SXS_COMPARE_ASSEMBLY_IDENTITY_ATTRIBUTES_COMPARISON_RESULT_GREATER_THAN));
  318. if (ComparisonResult == SXS_COMPARE_ASSEMBLY_IDENTITY_ATTRIBUTES_COMPARISON_RESULT_EQUAL)
  319. Equal = TRUE;
  320. }
  321. }
  322. }
  323. *EqualOut = Equal;
  324. fSuccess = TRUE;
  325. Exit:
  326. return fSuccess;
  327. }