windows-nt/Source/XPSP1/NT/base/win32/fusion/sxs/sxsprobe.cpp
2020-09-26 16:20:57 +08:00

166 lines
4.6 KiB
C++

#include "stdinc.h"
#include "windows.h"
#include "stdlib.h"
#include "sxsp.h"
#include "util.h"
#include "FusionHandle.h"
#include "fusionhash.h"
#include "comdef.h"
#pragma warning(error: 4244)
#define ASMPROBE_DOT (L".")
#define ASMPROBE_WILDCARD (L"*")
BOOL
SxsProbeAssemblyInstallation(
DWORD dwFlags,
PCWSTR lpIdentity,
PDWORD lpDisposition
)
{
FN_PROLOG_WIN32;
CSxsPointerWithNamedDestructor<ASSEMBLY_IDENTITY, ::SxsDestroyAssemblyIdentity> pAssemblyIdentity;
CStringBuffer AssemblyPathBuffer, AssemblyRoot, ManifestPathBuffer;
DWORD dwDisposition = 0;
BOOL fIsPolicy;
DWORD dwAttributes, dwLastError;
if (lpDisposition != NULL)
*lpDisposition = 0;
PARAMETER_CHECK(dwFlags == 0);
PARAMETER_CHECK(lpIdentity != NULL);
PARAMETER_CHECK(lpDisposition != NULL);
IFW32FALSE_EXIT(::SxspGetAssemblyRootDirectory(AssemblyRoot));
IFW32FALSE_EXIT(
::SxspCreateAssemblyIdentityFromTextualString(
lpIdentity,
&pAssemblyIdentity));
IFW32FALSE_EXIT(
::SxspValidateIdentity(
SXSP_VALIDATE_IDENTITY_FLAG_VERSION_REQUIRED,
ASSEMBLY_IDENTITY_TYPE_REFERENCE,
pAssemblyIdentity));
IFW32FALSE_EXIT(::SxspDetermineAssemblyType(pAssemblyIdentity, fIsPolicy));
// AssemblyIdentity is created, now generate the path
IFW32FALSE_EXIT(
::SxspGenerateSxsPath(
0,
(fIsPolicy ? SXSP_GENERATE_SXS_PATH_PATHTYPE_POLICY : SXSP_GENERATE_SXS_PATH_PATHTYPE_MANIFEST),
AssemblyRoot,
AssemblyRoot.Cch(),
pAssemblyIdentity,
ManifestPathBuffer));
//
// See if the file is there.
//
IFW32FALSE_EXIT(
::SxspGetFileAttributesW(
ManifestPathBuffer,
dwAttributes,
dwLastError,
2,
ERROR_FILE_NOT_FOUND,
ERROR_PATH_NOT_FOUND));
//
// Path not found or file not found means The assembly can't possibly be installed or resident.
//
if (dwLastError != ERROR_SUCCESS)
{
dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_NOT_INSTALLED;
goto DoneLooking;
}
//
// Otherwise, the manifest or policy file was present, so the assembly is installed.
//
else
{
dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_INSTALLED;
}
//
// If this assembly is policy, we need to not look to see if it's resident -
// it's always resident, and we can quit looking.
//
if (fIsPolicy)
{
dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_RESIDENT;
goto DoneLooking;
}
//
// Otherwise, we should look to see if the directory for the assembly is present -
// if it is, then the assembly is "resident".
//
else
{
IFW32FALSE_EXIT(
::SxspGenerateSxsPath(
0,
SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY,
AssemblyRoot,
AssemblyRoot.Cch(),
pAssemblyIdentity,
AssemblyPathBuffer));
IFW32FALSE_EXIT(
::SxspGetFileAttributesW(
AssemblyPathBuffer,
dwAttributes,
dwLastError,
2,
ERROR_FILE_NOT_FOUND,
ERROR_PATH_NOT_FOUND));
//
// We found the path, and it's a directory!
//
if ((dwLastError == ERROR_SUCCESS) && (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_RESIDENT;
}
//
// Hmm... failed to find the directory, looks like we have to see if there were
// any actual files in the assembly before we say that it's not resident.
//
else
{
SXS_MANIFEST_INFORMATION_BASIC ManifestInfo;
SIZE_T cbRequired;
IFW32FALSE_EXIT(
::SxsQueryManifestInformation(
0,
ManifestPathBuffer,
SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC,
SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_IDENTITY |
SXS_QUERY_MANIFEST_INFORMATION_INFOCLASS_BASIC_FLAG_OMIT_SHORTNAME,
sizeof(ManifestInfo),
(PVOID)&ManifestInfo,
&cbRequired));
if (ManifestInfo.ulFileCount == 0)
{
dwDisposition |= SXS_PROBE_ASSEMBLY_INSTALLATION_DISPOSITION_RESIDENT;
}
}
}
DoneLooking:
*lpDisposition = dwDisposition;
FN_EPILOG;
}