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.

515 lines
18 KiB

  1. #if !defined(_FUSION_ID_IDP_H_INCLUDED_)
  2. #define _FUSION_ID_IDP_H_INCLUDED_
  3. /*++
  4. Copyright (c) 1989 Microsoft Corporation
  5. Module Name:
  6. idp.h
  7. Abstract:
  8. private definitions for assembly identity
  9. Author:
  10. Michael Grier (MGrier) 7/27/2000
  11. Revision History:
  12. --*/
  13. #pragma once
  14. /* adriaanc
  15. #include "debmacro.h"
  16. #include "fusiontrace.h"
  17. #include "fusionhashstring.h"
  18. #include "fusionheap.h"
  19. #include "util.h"
  20. */
  21. #include <sxstypes.h>
  22. #include <sxsapi.h>
  23. //
  24. // Power of two to which to round the number of allocated attribute
  25. // pointers.
  26. //
  27. #define ROUNDING_FACTOR_BITS (3)
  28. #define WILDCARD_CHAR '*'
  29. //
  30. // Note! Do not change this algorithm lightly. Encoded identities stored in the
  31. // filesystem contain hashes using it. Actually, just do not change it.
  32. //
  33. #define HASH_ALGORITHM HASH_STRING_ALGORITHM_X65599
  34. typedef struct _ASSEMBLY_IDENTITY_NAMESPACE {
  35. ULONG Hash;
  36. DWORD Flags;
  37. SIZE_T NamespaceCch;
  38. const WCHAR *Namespace;
  39. } ASSEMBLY_IDENTITY_NAMESPACE, *PASSEMBLY_IDENTITY_NAMESPACE;
  40. typedef const ASSEMBLY_IDENTITY_NAMESPACE *PCASSEMBLY_IDENTITY_NAMESPACE;
  41. //
  42. // Internal-use ASSEMBLY_IDENTITY_ATTRIBUTE struct that
  43. // also contains the hash of the attribute definition.
  44. //
  45. typedef struct _INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE {
  46. // NOTE!!! It is very important that the Attribute member appear first in this struct;
  47. // there are several places in the code that make this assumption. If it is not true,
  48. // the code will break!
  49. // Note also that the Attribute's namespace string is actually allocated in common
  50. // for all attributes with the same namespace.
  51. ASSEMBLY_IDENTITY_ATTRIBUTE Attribute;
  52. PCASSEMBLY_IDENTITY_NAMESPACE Namespace;
  53. ULONG NamespaceAndNameHash;
  54. ULONG WholeAttributeHash;
  55. } INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE, *PINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE;
  56. C_ASSERT(FIELD_OFFSET(INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE, Attribute) == 0);
  57. typedef const INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE *PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE;
  58. #define ASSEMBLY_IDENTITY_INTERNAL_FLAG_ATTRIBUTE_POINTERS_IN_SEPARATE_ALLOCATION (0x00000001)
  59. #define ASSEMBLY_IDENTITY_INTERNAL_FLAG_SINGLE_ALLOCATION_FOR_EVERYTHING (0x00000002)
  60. #define ASSEMBLY_IDENTITY_INTERNAL_FLAG_NAMESPACE_POINTERS_IN_SEPARATE_ALLOCATION (0x00000004)
  61. //
  62. // Revelation of the ASSEMBLY_IDENTITY struct:
  63. //
  64. typedef struct _ASSEMBLY_IDENTITY {
  65. DWORD Flags;
  66. ULONG InternalFlags;
  67. ULONG Type;
  68. ULONG Hash;
  69. ULONG AttributeCount;
  70. ULONG AttributeArraySize; // preallocated a little larger so that we don't have to keep growing
  71. ULONG NamespaceCount;
  72. ULONG NamespaceArraySize;
  73. BOOL HashDirty;
  74. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE *AttributePointerArray;
  75. PCASSEMBLY_IDENTITY_NAMESPACE *NamespacePointerArray;
  76. } ASSEMBLY_IDENTITY;
  77. //
  78. // Header for encoded/serialized assembly identities:
  79. //
  80. #define ENCODED_ASSEMBLY_IDENTITY_HEADER_MAGIC ((ULONG) 'dIAE')
  81. //
  82. // Encoded assembly identity layout:
  83. //
  84. // ENCODED_ASSEMBLY_IDENTITY_HEADER
  85. // <AttributeCount hashes of the attributes, sorted by the hash value>
  86. // <NamespaceCount ENCODED_ASSEMBLY_IDENTITY_NAMESPACE_HEADER headers, each
  87. // followed by the unicode namespace value>
  88. // <AttributeCount ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER headers, each
  89. // followed by the unicode attribute name and value>
  90. //
  91. //
  92. // e.g.
  93. //
  94. // <begin ENCODED_ASSEMBLY_IDENTITY_HEADER>
  95. // 00000000: 00000038 HeaderSize == sizeof(ENCODED_ASSEMBLY_IDENTITY_HEADER)
  96. // 00000004: 'EAId' Magic (ENCODED_ASSEMBLY_IDENTITY_HEADER_MAGIC)
  97. // 00000008: 0000014C TotalSize
  98. // 0000000C: 00000000 Flags
  99. // 00000010: 00000001 Type (1 = ASSEMBLY_IDENTITY_TYPE_DEFINITION)
  100. // 00000014: 00000000 EncodingFlags
  101. // 00000018: 00000001 HashAlgorithm (1 = HASH_STRING_ALGORITHM_X65599)
  102. // 0000001C: ???????? Logical hash value of entire identity based on hash algorithm
  103. // (algorithm described in more detail below...)
  104. // 00000020: 00000003 AttributeCount
  105. // 00000024: 00000002 NamespaceCount
  106. // 00000028: 00000000 ReservedMustBeZero1
  107. // 0000002C: 00000000 ReservedMustBeZero2
  108. // 00000030: 00000000 00000000 ReservedMustBeZero3
  109. // 00000038: 00000000 00000000 ReservedMustBeZero4
  110. // <end ENCODED_ASSEMBLY_IDENTITY_HEADER>
  111. // <begin sorted attribute hash list>
  112. // 00000040: xxxxxxxx hash of attribute #1
  113. // 00000044: yyyyyyyy hash of attribute #0 - note that yyyyyyyy >= xxxxxxxx
  114. // 00000048: zzzzzzzz hash of attribute #2 - note that zzzzzzzz >= yyyyyyyy
  115. // <end sorted attribute hash list>
  116. // <begin namespace length list>
  117. // 0000004C: 00000015 length (in Unicode chars) of namespace #1 - "http://www.amazon.com" - 21 chars = 0x00000015
  118. // 00000050: 00000018 length (in Unicode chars) of namespace #2 - "http://www.microsoft.com" - 24 chars = 0x00000018
  119. // <end namespace length list>
  120. // <begin attribute headers>
  121. // <begin ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER>
  122. // 00000054: 00000001 NamespaceIndex: 1 (http://www.amazon.com)
  123. // 00000058: 00000004 Name length ("name" - 4 chars = 0x00000004)
  124. // 0000005C: 00000006 Value length ("foobar" - 6 chars = 0x00000006)
  125. // <end ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER>
  126. // <begin ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER>
  127. // 00000060: 00000002 NamespaceIndex: 2 (http://www.microsoft.com)
  128. // 00000064: 00000004 Name length ("guid" - 4 chars = 0x00000004)
  129. // 00000068: 00000026 Value length ("{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}" - 38 chars = 0x00000026)
  130. // <end ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER>
  131. // <begin ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER>
  132. // 0000006C: 00000002 NamespaceIndex: 2 (http://www.microsoft.com)
  133. // 00000070: 00000004 Name length ("type" - 4 chars = 0x00000004)
  134. // 00000074: 00000005 Value length ("win32" - 5 chars = 0x00000005)
  135. // <end ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER>
  136. // <end attribute headers>
  137. // <begin namespace strings>
  138. // 00000078: "http://www.amazon.com"
  139. // 000000A2: "http://www.microsoft.com"
  140. // <end namespace strings>
  141. // <begin attribute values - names and values for each attribute in series>
  142. // 000000D2: "name"
  143. // 000000DA: "foobar"
  144. // 000000E6: "guid"
  145. // 000000EE: "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
  146. // 0000013A: "type"
  147. // 00000142: "win32"
  148. // <end attribute values>
  149. // 0000014C:
  150. //
  151. // Computing the whole identity hash:
  152. //
  153. // The hash of the entire encoded identity is not the hash of the binary form, but
  154. // rather is a combination of the hashes for the various components.
  155. //
  156. // For any Unicode character string, its hash is computed according to HashAlgorithm.
  157. // Currently this must be HASH_STRING_ALGORITHM_X65599 which is a multiply-and-
  158. // accumulate algorithm, implemented essentially as follows:
  159. //
  160. // HashValue = 0;
  161. // for (i=0; i<Chars; i++)
  162. // HashValue = (HashValue * 65599) + OptionalToUpper(String[i]);
  163. //
  164. // Note that the characters are converted to upper case. This is somewhat in
  165. // conflict with the Unicode recommendation to convert to lower case for case
  166. // insensitive operations, but it is what the rest of the Windows NT system
  167. // does, so consistency matters more than doing the "right thing".
  168. //
  169. // Note also that no trailing null characters are included in the hash. This
  170. // is significant because of the fact that applying the loop to another character
  171. // even though its value is zero will significantly change the hash value.
  172. //
  173. // Namespaces and attribute names are case sensitive, derived from the fact
  174. // that they appear in case sensitive contexts in the real world. This is
  175. // unfortunate, but simpler in many ways.
  176. //
  177. // Assembly identity attributes are composed of a triple of:
  178. // - Namespace URI (e.g. http://www.microsoft.com/schemas/side-by-side)
  179. // - Name (e.g. "publicKey")
  180. // - Value (case insensitive Unicode string)
  181. //
  182. // The hash of an attribute is computed by computing the hash of the three
  183. // strings, and then combining them as:
  184. //
  185. // AttributeHashValue = (((NamespaceHash * 65599) + NameHash) * 65599) + ValueHash
  186. //
  187. // Now, sort the attributes based first on namespace, then on name then on
  188. // value (case sensitive, case sensitive and case insensitive respectively),
  189. // and combine their hashes as follows:
  190. //
  191. // IdentityHash = 0;
  192. // for (i=0; i<AttributeCount; i++)
  193. // IdentityHash = (IdentityHash * 65599) + AttributeHashes[i];
  194. //
  195. // IdentityHash is the value stored in the encoded header.
  196. //
  197. // The attribute hash array stored in the encoded data is the attribute
  198. // hashes as described above. The interesting thing is that they are stored
  199. // in order of ascending hash value, not in the canonical ordering for
  200. // attributes.
  201. //
  202. // This is because a common scenario is to find an identity which has a
  203. // superset of a given identity. While the actual attributes have to
  204. // be consulted to verify that the candidate is a true subset, non-
  205. // matches can be very quickly found by sorting both lists of hash
  206. // values and first looping over the smaller reference list, then
  207. // in a single pass walking the larger definition list. Attributes present
  208. // in one but not in the other will be immediately noticable due to
  209. // the missing hashes.
  210. //
  211. // As always with hashes, just because an encoded identity contains a
  212. // superset of the hash values in your candidate assembly reference,
  213. // it does not mean that the actual values appear and you must perform
  214. // real character string comparisons to verify containment.
  215. //
  216. #include <pshpack4.h>
  217. typedef struct _ENCODED_ASSEMBLY_IDENTITY_HEADER {
  218. ULONG HeaderSize; // bytes just in the header
  219. ULONG Magic;
  220. ULONG TotalSize; // bytes for the whole encoded thing
  221. DWORD Flags; // as defined for assembly identity flags
  222. ULONG Type; // type of identity - def, ref or wildcard
  223. ULONG EncodingFlags; // flags describing the encoding itself
  224. ULONG HashAlgorithm; // Algorithm ID for the hashes stored in the identity
  225. ULONG Hash; // Hash value of the entire identity
  226. ULONG AttributeCount; // number of attributes
  227. ULONG NamespaceCount; // number of distinct namespaces
  228. ULONG ReservedMustBeZero1;
  229. ULONG ReservedMustBeZero2;
  230. ULONGLONG ReservedMustBeZero3;
  231. ULONGLONG ReservedMustBeZero4;
  232. } ENCODED_ASSEMBLY_IDENTITY_HEADER, *PENCODED_ASSEMBLY_IDENTITY_HEADER;
  233. typedef const ENCODED_ASSEMBLY_IDENTITY_HEADER *PCENCODED_ASSEMBLY_IDENTITY_HEADER;
  234. typedef struct _ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER {
  235. ULONG NamespaceIndex; // number of the namespace for this attribute
  236. ULONG NameCch; // size in Unicode characters of the name immediately following the
  237. // namespace
  238. ULONG ValueCch; // size in Unicode characters of the value immediately following the
  239. // name.
  240. } ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER, *PENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER;
  241. typedef const ENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER *PCENCODED_ASSEMBLY_IDENTITY_ATTRIBUTE_HEADER;
  242. #include <poppack.h>
  243. #define SXSP_VALIDATE_ASSEMBLY_IDENTITY_FLAGS_MAY_BE_NULL (0x00000001)
  244. BOOL
  245. SxspValidateAssemblyIdentity(
  246. IN DWORD Flags,
  247. IN PCASSEMBLY_IDENTITY AssemblyIdentity
  248. );
  249. BOOL
  250. SxspValidateAssemblyIdentityAttributeNamespace(
  251. IN DWORD Flags,
  252. IN const WCHAR *Namespace,
  253. IN SIZE_T NamespaceCch
  254. );
  255. BOOL
  256. SxspValidateAssemblyIdentityAttributeName(
  257. IN DWORD Flags,
  258. IN const WCHAR *Name,
  259. IN SIZE_T NameCch
  260. );
  261. #define SXSP_VALIDATE_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_WILDCARDS_PERMITTED (0x00000001)
  262. BOOL
  263. SxspValidateAssemblyIdentityAttributeValue(
  264. IN DWORD Flags,
  265. IN const WCHAR *Value,
  266. IN SIZE_T ValueCch
  267. );
  268. BOOL
  269. SxspComputeInternalAssemblyIdentityAttributeBytesRequired(
  270. IN DWORD Flags,
  271. IN const WCHAR *Name,
  272. IN SIZE_T NameCch,
  273. IN const WCHAR *Value,
  274. IN SIZE_T ValueCch,
  275. OUT SIZE_T *BytesRequiredOut
  276. );
  277. BOOL
  278. SxspComputeAssemblyIdentityAttributeBytesRequired(
  279. IN DWORD Flags,
  280. IN PCASSEMBLY_IDENTITY_ATTRIBUTE Source,
  281. OUT SIZE_T *BytesRequiredOut
  282. );
  283. #define SXSP_FIND_ASSEMBLY_IDENTITY_NAMESPACE_IN_ARRAY_FLAG_ADD_IF_NOT_FOUND (0x00000001)
  284. BOOL
  285. SxspFindAssemblyIdentityNamespaceInArray(
  286. IN DWORD Flags,
  287. IN OUT PCASSEMBLY_IDENTITY_NAMESPACE **NamespacePointerArrayPtr,
  288. IN OUT ULONG *NamespaceArraySizePtr,
  289. IN OUT ULONG *NamespaceCountPtr,
  290. IN const WCHAR *Namespace,
  291. IN SIZE_T NamespaceCch,
  292. OUT PCASSEMBLY_IDENTITY_NAMESPACE *NamespaceOut
  293. );
  294. #define SXSP_FIND_ASSEMBLY_IDENTITY_NAMESPACE_FLAG_ADD_IF_NOT_FOUND (0x00000001)
  295. BOOL
  296. SxspFindAssemblyIdentityNamespace(
  297. IN DWORD Flags,
  298. IN struct _ASSEMBLY_IDENTITY* AssemblyIdentity,
  299. IN const WCHAR *Namespace,
  300. IN SIZE_T NamespaceCch,
  301. OUT PCASSEMBLY_IDENTITY_NAMESPACE *NamespaceOut
  302. );
  303. BOOL
  304. SxspAllocateAssemblyIdentityNamespace(
  305. IN DWORD Flags,
  306. IN const WCHAR *NamespaceString,
  307. IN SIZE_T NamespaceCch,
  308. IN ULONG NamespaceHash,
  309. OUT PCASSEMBLY_IDENTITY_NAMESPACE *NamespaceOut
  310. );
  311. VOID
  312. SxspDeallocateAssemblyIdentityNamespace(
  313. IN PCASSEMBLY_IDENTITY_NAMESPACE Namespace
  314. );
  315. BOOL
  316. SxspPopulateInternalAssemblyIdentityAttribute(
  317. IN DWORD Flags,
  318. IN PCASSEMBLY_IDENTITY_NAMESPACE Namespace,
  319. IN const WCHAR *Name,
  320. IN SIZE_T NameCch,
  321. IN const WCHAR *Value,
  322. IN SIZE_T ValueCch,
  323. OUT PINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE Destination
  324. );
  325. BOOL
  326. SxspAllocateInternalAssemblyIdentityAttribute(
  327. IN DWORD Flags,
  328. IN PCASSEMBLY_IDENTITY_NAMESPACE Namespace,
  329. IN const WCHAR *Name,
  330. IN SIZE_T NameCch,
  331. IN const WCHAR *Value,
  332. IN SIZE_T ValueCch,
  333. OUT PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE *Destination
  334. );
  335. VOID
  336. SxspCleanUpAssemblyIdentityNamespaceIfNotReferenced(
  337. IN DWORD Flags,
  338. IN struct _ASSEMBLY_IDENTITY* AssemblyIdentity,
  339. IN PCASSEMBLY_IDENTITY_NAMESPACE Namespace
  340. );
  341. VOID
  342. SxspDeallocateInternalAssemblyIdentityAttribute(
  343. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE Attribute
  344. );
  345. int
  346. __cdecl
  347. SxspCompareInternalAttributesForQsort(
  348. const void *elem1,
  349. const void *elem2
  350. );
  351. int
  352. __cdecl
  353. SxspCompareULONGsForQsort(
  354. const void *elem1,
  355. const void *elem2
  356. );
  357. BOOL
  358. SxspCompareAssemblyIdentityAttributeLists(
  359. DWORD Flags,
  360. ULONG AttributeCount,
  361. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE *List1,
  362. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE *List2,
  363. ULONG *ComparisonResultOut
  364. );
  365. BOOL
  366. SxspHashInternalAssemblyIdentityAttributes(
  367. DWORD Flags,
  368. ULONG Count,
  369. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE *Attributes,
  370. ULONG *HashOut
  371. );
  372. BOOL
  373. SxspCopyInternalAssemblyIdentityAttributeOut(
  374. DWORD Flags,
  375. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE Attribute,
  376. SIZE_T BufferSize,
  377. PASSEMBLY_IDENTITY_ATTRIBUTE DestinationBuffer,
  378. SIZE_T *BytesCopiedOrRequired
  379. );
  380. BOOL
  381. SxspIsInternalAssemblyIdentityAttribute(
  382. IN DWORD Flags,
  383. IN PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE Attribute,
  384. IN const WCHAR *Namespace,
  385. IN SIZE_T NamespaceCch,
  386. IN const WCHAR *Name,
  387. IN SIZE_T NameCch,
  388. OUT BOOL *EqualsOut
  389. );
  390. #define SXSP_COMPUTE_INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE_ENCODED_TEXTUAL_SIZE_FLAG_VALUE_ONLY (0x00000001)
  391. #define SXSP_COMPUTE_INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE_ENCODED_TEXTUAL_SIZE_FLAG_OMIT_QUOTES (0x00000002)
  392. BOOL
  393. SxspComputeInternalAssemblyIdentityAttributeEncodedTextualSize(
  394. IN DWORD Flags,
  395. IN PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE Attribute,
  396. OUT SIZE_T *BytesOut
  397. );
  398. #define SXSP_LOCATE_INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_MATCH_NAMESPACE (0x00000001)
  399. #define SXSP_LOCATE_INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_MATCH_NAME (0x00000002)
  400. #define SXSP_LOCATE_INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_MATCH_VALUE (0x00000004)
  401. #define SXSP_LOCATE_INTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_NOT_FOUND_RETURNS_NULL (0x00000008)
  402. BOOL
  403. SxspLocateInternalAssemblyIdentityAttribute(
  404. IN DWORD Flags,
  405. IN PCASSEMBLY_IDENTITY AssemblyIdentity,
  406. IN PCASSEMBLY_IDENTITY_ATTRIBUTE Attribute,
  407. OUT PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE *InternalAttributeOut,
  408. OUT ULONG *LastIndexSearched OPTIONAL
  409. );
  410. BOOL
  411. SxspComputeQuotedStringSize(
  412. IN DWORD Flags,
  413. IN const WCHAR *StringIn,
  414. IN SIZE_T Cch,
  415. OUT SIZE_T *BytesOut
  416. );
  417. VOID
  418. SxspDbgPrintInternalAssemblyIdentityAttribute(
  419. DWORD dwflags,
  420. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE Attribute
  421. );
  422. VOID
  423. SxspDbgPrintInternalAssemblyIdentityAttributes(
  424. DWORD dwflags,
  425. ULONG AttributeCount,
  426. PCINTERNAL_ASSEMBLY_IDENTITY_ATTRIBUTE const *Attributes
  427. );
  428. VOID
  429. SxspDbgPrintAssemblyIdentityAttribute(
  430. DWORD dwflags,
  431. PCASSEMBLY_IDENTITY_ATTRIBUTE Attribute
  432. );
  433. VOID
  434. SxspDbgPrintAssemblyIdentityAttributes(
  435. DWORD dwflags,
  436. ULONG AttributeCount,
  437. PCASSEMBLY_IDENTITY_ATTRIBUTE const *Attributes
  438. );
  439. BOOL
  440. SxspEnsureAssemblyIdentityHashIsUpToDate(
  441. DWORD dwFlags,
  442. PCASSEMBLY_IDENTITY AssemblyIdentity
  443. );
  444. #endif