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.

467 lines
14 KiB

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