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.

165 lines
4.6 KiB

  1. #include "stdinc.h"
  2. #include "windows.h"
  3. #include "stdlib.h"
  4. #include "sxsp.h"
  5. #include "util.h"
  6. #include "FusionHandle.h"
  7. #include "fusionhash.h"
  8. #include "comdef.h"
  9. #pragma warning(error: 4244)
  10. #define ASMPROBE_DOT (L".")
  11. #define ASMPROBE_WILDCARD (L"*")
  12. BOOL
  13. SxsProbeAssemblyInstallation(
  14. DWORD dwFlags,
  15. PCWSTR lpIdentity,
  16. PDWORD lpDisposition
  17. )
  18. {
  19. FN_PROLOG_WIN32;
  20. CSxsPointerWithNamedDestructor<ASSEMBLY_IDENTITY, ::SxsDestroyAssemblyIdentity> pAssemblyIdentity;
  21. CStringBuffer AssemblyPathBuffer, AssemblyRoot, ManifestPathBuffer;
  22. DWORD dwDisposition = 0;
  23. BOOL fIsPolicy;
  24. DWORD dwAttributes, dwLastError;
  25. if (lpDisposition != NULL)
  26. *lpDisposition = 0;
  27. PARAMETER_CHECK(dwFlags == 0);
  28. PARAMETER_CHECK(lpIdentity != NULL);
  29. PARAMETER_CHECK(lpDisposition != NULL);
  30. IFW32FALSE_EXIT(::SxspGetAssemblyRootDirectory(AssemblyRoot));
  31. IFW32FALSE_EXIT(
  32. ::SxspCreateAssemblyIdentityFromTextualString(
  33. lpIdentity,
  34. &pAssemblyIdentity));
  35. IFW32FALSE_EXIT(
  36. ::SxspValidateIdentity(
  37. SXSP_VALIDATE_IDENTITY_FLAG_VERSION_REQUIRED,
  38. ASSEMBLY_IDENTITY_TYPE_REFERENCE,
  39. pAssemblyIdentity));
  40. IFW32FALSE_EXIT(::SxspDetermineAssemblyType(pAssemblyIdentity, fIsPolicy));
  41. // AssemblyIdentity is created, now generate the path
  42. IFW32FALSE_EXIT(
  43. ::SxspGenerateSxsPath(
  44. 0,
  45. (fIsPolicy ? SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY : SXSP_GENERATE_SXS_PATH_PATHTYPE_MANIFEST),
  46. AssemblyRoot,
  47. AssemblyRoot.Cch(),
  48. pAssemblyIdentity,
  49. ManifestPathBuffer));
  50. //
  51. // See if the file is there.
  52. //
  53. IFW32FALSE_EXIT(
  54. ::SxspGetFileAttributesW(
  55. ManifestPathBuffer,
  56. dwAttributes,
  57. dwLastError,
  58. 2,
  59. ERROR_FILE_NOT_FOUND,
  60. ERROR_PATH_NOT_FOUND));
  61. //
  62. // Path not found or file not found means The assembly can't possibly be installed or resident.
  63. //
  64. if (dwLastError != ERROR_SUCCESS)
  65. {
  66. dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_NOT_INSTALLED;
  67. goto DoneLooking;
  68. }
  69. //
  70. // Otherwise, the manifest or policy file was present, so the assembly is installed.
  71. //
  72. else
  73. {
  74. dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_INSTALLED;
  75. }
  76. //
  77. // If this assembly is policy, we need to not look to see if it's resident -
  78. // it's always resident, and we can quit looking.
  79. //
  80. if (fIsPolicy)
  81. {
  82. dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_RESIDENT;
  83. goto DoneLooking;
  84. }
  85. //
  86. // Otherwise, we should look to see if the directory for the assembly is present -
  87. // if it is, then the assembly is "resident".
  88. //
  89. else
  90. {
  91. IFW32FALSE_EXIT(
  92. ::SxspGenerateSxsPath(
  93. 0,
  94. SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY,
  95. AssemblyRoot,
  96. AssemblyRoot.Cch(),
  97. pAssemblyIdentity,
  98. AssemblyPathBuffer));
  99. IFW32FALSE_EXIT(
  100. ::SxspGetFileAttributesW(
  101. AssemblyPathBuffer,
  102. dwAttributes,
  103. dwLastError,
  104. 2,
  105. ERROR_FILE_NOT_FOUND,
  106. ERROR_PATH_NOT_FOUND));
  107. //
  108. // We found the path, and it's a directory!
  109. //
  110. if ((dwLastError == ERROR_SUCCESS) && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
  111. {
  112. dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_RESIDENT;
  113. }
  114. //
  115. // Hmm... failed to find the directory, looks like we have to see if there were
  116. // any actual files in the assembly before we say that it's not resident.
  117. //
  118. else
  119. {
  120. SXS_MANIFEST_INFORMATION_BASIC ManifestInfo;
  121. SIZE_T cbRequired;
  122. IFW32FALSE_EXIT(
  123. ::SxsQueryManifestInformation(
  124. 0,
  125. ManifestPathBuffer,
  126. SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC,
  127. SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_IDENTITY |
  128. SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_SHORTNAME,
  129. sizeof(ManifestInfo),
  130. (PVOID)&ManifestInfo,
  131. &cbRequired));
  132. if (ManifestInfo.ulFileCount == 0)
  133. {
  134. dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_RESIDENT;
  135. }
  136. }
  137. }
  138. DoneLooking:
  139. *lpDisposition = dwDisposition;
  140. FN_EPILOG;
  141. }