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
179 lines
5.4 KiB
/*
|
|
Copyright (c) Microsoft Corporation
|
|
*/
|
|
#include "stdinc.h"
|
|
#include "windows.h"
|
|
#include "stdlib.h"
|
|
#include "sxsp.h"
|
|
#include "util.h"
|
|
#include "fusionhandle.h"
|
|
#include "fusionhash.h"
|
|
#pragma warning(error:4244)
|
|
|
|
#define ASMPROBE_DOT (L".")
|
|
#define ASMPROBE_WILDCARD (L"*")
|
|
|
|
BOOL
|
|
SxsProbeAssemblyInstallation(
|
|
DWORD dwFlags,
|
|
PCWSTR lpAsmIdentSource,
|
|
PDWORD lpDisposition
|
|
)
|
|
{
|
|
FN_PROLOG_WIN32
|
|
|
|
CMediumStringBuffer AssemblyPathBuffer, AssemblyRoot, ManifestPathBuffer;
|
|
CSmartPtrWithNamedDestructor<ASSEMBLY_IDENTITY, ::SxsDestroyAssemblyIdentity> pAssemblyIdentity;
|
|
DWORD dwDisposition = 0;
|
|
BOOL fIsPolicy;
|
|
DWORD dwAttributes, dwLastError;
|
|
|
|
if (lpDisposition != NULL)
|
|
*lpDisposition = 0;
|
|
|
|
IFINVALID_FLAGS_EXIT_WIN32(dwFlags, SXS_PROBE_ASSEMBLY_INSTALLATION_IDENTITY_PRECOMPOSED);
|
|
PARAMETER_CHECK(lpAsmIdentSource != NULL);
|
|
PARAMETER_CHECK(lpDisposition != NULL);
|
|
|
|
//
|
|
// If the lpAsmIdentSource is really a PCASSEMBLY_IDENTITY, then attach (no delete)
|
|
// for use.
|
|
//
|
|
if (dwFlags & SXS_PROBE_ASSEMBLY_INSTALLATION_IDENTITY_PRECOMPOSED)
|
|
{
|
|
pAssemblyIdentity.AttachNoDelete(reinterpret_cast<PASSEMBLY_IDENTITY>(const_cast<PWSTR>(lpAsmIdentSource)));
|
|
}
|
|
//
|
|
// Otherwise, create an assembly identity from the string that was there
|
|
//
|
|
else
|
|
{
|
|
IFW32FALSE_EXIT(::SxspCreateAssemblyIdentityFromTextualString(
|
|
lpAsmIdentSource,
|
|
&pAssemblyIdentity));
|
|
}
|
|
|
|
IFW32FALSE_EXIT(::SxspGetAssemblyRootDirectory(AssemblyRoot));
|
|
|
|
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,
|
|
NULL,
|
|
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,
|
|
NULL,
|
|
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
|
|
}
|
|
|