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.

391 lines
13 KiB

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