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.

179 lines
5.4 KiB

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