633 lines
19 KiB
C++
633 lines
19 KiB
C++
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sxsasmname.cpp
|
|
|
|
Abstract:
|
|
|
|
CAssemblyName implementation for installation
|
|
|
|
Author:
|
|
|
|
Xiaoyu Wu (xiaoyuw) May 2000
|
|
|
|
Revision History:
|
|
xiaoyuw 09/20000 rewrite the code to use Assembly Identity
|
|
--*/
|
|
|
|
#include "stdinc.h"
|
|
#include "sxsasmname.h"
|
|
#include "fusionparser.h"
|
|
#include "parse.h"
|
|
#include "sxsp.h"
|
|
#include "sxsid.h"
|
|
#include "sxsidp.h"
|
|
#include "sxsapi.h"
|
|
#include "fusiontrace.h"
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CreateAssemblyNameObject
|
|
// ---------------------------------------------------------------------------
|
|
STDAPI
|
|
CreateAssemblyNameObject(
|
|
LPASSEMBLYNAME *ppAssemblyName,
|
|
LPCOLESTR szAssemblyName,
|
|
DWORD dwFlags,
|
|
LPVOID pvReserved
|
|
)
|
|
{
|
|
|
|
HRESULT hr = S_OK;
|
|
FN_TRACE_HR(hr);
|
|
CSmartRef<CAssemblyName> pName;
|
|
|
|
if (ppAssemblyName)
|
|
*ppAssemblyName = NULL ;
|
|
|
|
// validate dwFlags
|
|
// BUGBUG : the valid value of dwFlags are CANOF_PARSE_DISPLAY_NAME and CANOF_SET_DEFAULT_VALUES, but CANOF_SET_DEFAULT_VALUES
|
|
// is never used...
|
|
// xiaoyuw@10/02/2000
|
|
//
|
|
PARAMETER_CHECK(dwFlags == CANOF_PARSE_DISPLAY_NAME);
|
|
PARAMETER_CHECK(ppAssemblyName != NULL);
|
|
PARAMETER_CHECK(pvReserved == NULL);
|
|
|
|
IFALLOCFAILED_EXIT(pName = new CAssemblyName);
|
|
|
|
if (dwFlags & CANOF_PARSE_DISPLAY_NAME)
|
|
IFCOMFAILED_EXIT(pName->Parse((LPWSTR)szAssemblyName));
|
|
|
|
*ppAssemblyName = pName.Disown();
|
|
|
|
FN_EPILOG
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::SetProperty
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::SetProperty(DWORD PropertyId,
|
|
LPVOID pvProperty, DWORD cbProperty)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE Attribute = NULL;
|
|
|
|
// this function is only called inside fusion, so this fucntion has no impact on Darwin
|
|
// maybe more should be added for Assembly Identity, such as StrongName, or random policies
|
|
//
|
|
if ((!pvProperty) || ((PropertyId != SXS_ASM_NAME_NAME) &&
|
|
(PropertyId != SXS_ASM_NAME_VERSION) &&
|
|
(PropertyId != SXS_ASM_NAME_PROCESSORARCHITECTURE) &&
|
|
(PropertyId != SXS_ASM_NAME_LANGUAGE))){
|
|
hr = E_INVALIDARG;
|
|
goto Exit;
|
|
}
|
|
|
|
// Fail if finalized.
|
|
if (m_fIsFinalized){
|
|
hr = E_UNEXPECTED;
|
|
goto Exit;
|
|
}
|
|
|
|
switch (PropertyId)
|
|
{
|
|
case SXS_ASM_NAME_NAME: Attribute = &s_IdentityAttribute_name; break;
|
|
case SXS_ASM_NAME_VERSION: Attribute = &s_IdentityAttribute_version; break;
|
|
case SXS_ASM_NAME_PROCESSORARCHITECTURE: Attribute = &s_IdentityAttribute_processorArchitecture; break;
|
|
case SXS_ASM_NAME_LANGUAGE: Attribute = &s_IdentityAttribute_language; break;
|
|
}
|
|
|
|
INTERNAL_ERROR_CHECK(Attribute != NULL);
|
|
IFW32FALSE_EXIT(::SxspSetAssemblyIdentityAttributeValue(0, m_pAssemblyIdentity, Attribute, (PCWSTR) pvProperty, cbProperty / sizeof(WCHAR)));
|
|
|
|
hr = NOERROR;
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::GetProperty
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::GetProperty(DWORD PropertyId,
|
|
/* [in] */ LPVOID pvProperty,
|
|
/* [out][in] */ LPDWORD pcbProperty)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
PCWSTR pszAttributeValue = NULL;
|
|
SIZE_T CchAttributeValue = 0;
|
|
PCSXS_ASSEMBLY_IDENTITY_ATTRIBUTE_REFERENCE Attribute = NULL;
|
|
|
|
if ((!pvProperty) || (!pcbProperty) || ((PropertyId != SXS_ASM_NAME_NAME) &&
|
|
(PropertyId != SXS_ASM_NAME_VERSION) &&
|
|
(PropertyId != SXS_ASM_NAME_PROCESSORARCHITECTURE) &&
|
|
(PropertyId != SXS_ASM_NAME_LANGUAGE))){
|
|
hr = E_INVALIDARG;
|
|
goto Exit;
|
|
}
|
|
|
|
switch (PropertyId)
|
|
{
|
|
case SXS_ASM_NAME_NAME: Attribute = &s_IdentityAttribute_name; break;
|
|
case SXS_ASM_NAME_VERSION: Attribute = &s_IdentityAttribute_version; break;
|
|
case SXS_ASM_NAME_PROCESSORARCHITECTURE: Attribute = &s_IdentityAttribute_processorArchitecture; break;
|
|
case SXS_ASM_NAME_LANGUAGE: Attribute = &s_IdentityAttribute_language; break;
|
|
}
|
|
|
|
INTERNAL_ERROR_CHECK(Attribute != NULL);
|
|
|
|
IFW32FALSE_EXIT(::SxspGetAssemblyIdentityAttributeValue(0, m_pAssemblyIdentity, Attribute, &pszAttributeValue, &CchAttributeValue));
|
|
|
|
// check whether we have valid attributes
|
|
if (pszAttributeValue == NULL){ // attributes not set yet
|
|
hr = E_UNEXPECTED;
|
|
goto Exit;
|
|
}
|
|
if (CchAttributeValue * sizeof(WCHAR) > *pcbProperty) { // buffer size is not big enough
|
|
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
|
*pcbProperty = static_cast<DWORD>(CchAttributeValue * sizeof(WCHAR));
|
|
goto Exit;
|
|
}
|
|
|
|
// copy the string into the output buffer
|
|
memcpy(pvProperty, pszAttributeValue, CchAttributeValue *sizeof(WCHAR));
|
|
if (pcbProperty)
|
|
*pcbProperty = static_cast<DWORD>(CchAttributeValue * sizeof(WCHAR));
|
|
|
|
hr = NOERROR;
|
|
Exit:
|
|
return hr;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::GetName
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::GetName(
|
|
/* [out][in] */ LPDWORD lpcwBuffer,
|
|
/* [out] */ WCHAR *pwzName)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
|
|
if (!lpcwBuffer || !pwzName){
|
|
hr = E_INVALIDARG;
|
|
goto Exit;
|
|
}
|
|
|
|
IFCOMFAILED_EXIT(this->GetProperty(SXS_ASM_NAME_NAME, pwzName, lpcwBuffer));
|
|
|
|
FN_EPILOG
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::GetVersion
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::GetVersion(
|
|
/* [out] */ LPDWORD pdwVersionHi,
|
|
/* [out] */ LPDWORD pdwVersionLow)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
PCWSTR pszAttributeValue = NULL;
|
|
SIZE_T CchAttributeValue = 0;
|
|
ASSEMBLY_VERSION ver;
|
|
bool fSyntaxValid = false;
|
|
|
|
if ((!pdwVersionHi) || (!pdwVersionLow)){
|
|
hr = E_INVALIDARG;
|
|
goto Exit;
|
|
}
|
|
|
|
IFW32FALSE_EXIT(::SxspGetAssemblyIdentityAttributeValue(0, m_pAssemblyIdentity, &s_IdentityAttribute_version, &pszAttributeValue, &CchAttributeValue));
|
|
if (pszAttributeValue == NULL)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
goto Exit;
|
|
}
|
|
|
|
IFW32FALSE_EXIT(CFusionParser::ParseVersion(ver, pszAttributeValue, CchAttributeValue, fSyntaxValid));
|
|
if (!fSyntaxValid)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_SXS_MANIFEST_PARSE_ERROR);
|
|
goto Exit;
|
|
}
|
|
|
|
*pdwVersionHi = MAKELONG(ver.Minor, ver.Major);
|
|
*pdwVersionLow = MAKELONG(ver.Build, ver.Revision);
|
|
|
|
FN_EPILOG
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::IsEqual
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::IsEqual(LPASSEMBLYNAME pName, DWORD dwCmpFlags)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
BOOL fEqual = FALSE;
|
|
|
|
PARAMETER_CHECK(pName != NULL);
|
|
IFW32FALSE_EXIT(::SxsAreAssemblyIdentitiesEqual(0, m_pAssemblyIdentity, static_cast<CAssemblyName *>(pName)->m_pAssemblyIdentity, &fEqual));
|
|
if (fEqual == TRUE)
|
|
hr = S_OK;
|
|
else
|
|
hr = E_FAIL; // not acurrate, however, it depends on Darwin caller.
|
|
Exit:
|
|
return hr;
|
|
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName constructor
|
|
// ---------------------------------------------------------------------------
|
|
CAssemblyName::CAssemblyName():m_cRef(0),
|
|
m_fIsFinalized(FALSE),
|
|
m_pAssemblyIdentity(NULL)
|
|
{
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName destructor
|
|
// ---------------------------------------------------------------------------
|
|
CAssemblyName::~CAssemblyName()
|
|
{
|
|
ASSERT_NTC(m_cRef == 0 );
|
|
if (m_pAssemblyIdentity)
|
|
{
|
|
CSxsPreserveLastError ple;
|
|
::SxsDestroyAssemblyIdentity(m_pAssemblyIdentity);
|
|
ple.Restore();
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::Init
|
|
// ---------------------------------------------------------------------------
|
|
HRESULT
|
|
CAssemblyName::Init(LPCWSTR pszAssemblyName, PVOID pamd)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
FN_TRACE_HR(hr);
|
|
SIZE_T CchAssemblyName = 0;
|
|
|
|
UNUSED(pamd);
|
|
//ASSERT(m_pAssemblyIdentity == NULL);
|
|
if (m_pAssemblyIdentity)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
goto Exit;
|
|
}
|
|
|
|
IFW32FALSE_EXIT(::SxsCreateAssemblyIdentity(0, ASSEMBLY_IDENTITY_TYPE_DEFINITION, &m_pAssemblyIdentity, 0, NULL));
|
|
|
|
// set name if present
|
|
if (pszAssemblyName != NULL)
|
|
{
|
|
CchAssemblyName = wcslen(pszAssemblyName);
|
|
IFW32FALSE_EXIT(::SxspSetAssemblyIdentityAttributeValue(0, m_pAssemblyIdentity, &s_IdentityAttribute_name, pszAssemblyName, wcslen(pszAssemblyName)));
|
|
}
|
|
|
|
hr = NOERROR;
|
|
Exit:
|
|
return hr;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::Init
|
|
// ---------------------------------------------------------------------------
|
|
HRESULT CAssemblyName::Clone(IAssemblyName **ppName)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
|
|
CAssemblyName *pName= NULL;
|
|
|
|
if (ppName)
|
|
*ppName = NULL;
|
|
|
|
if (!ppName){
|
|
hr = E_INVALIDARG ;
|
|
goto Exit;
|
|
}
|
|
|
|
if (m_pAssemblyIdentity)
|
|
{
|
|
IFW32FALSE_EXIT(
|
|
::SxsDuplicateAssemblyIdentity(
|
|
0, // DWORD Flags,
|
|
m_pAssemblyIdentity, // PCASSEMBLY_IDENTITY Source,
|
|
&pAssemblyIdentity)); // PASSEMBLY_IDENTITY *Destination
|
|
}
|
|
|
|
IFALLOCFAILED_EXIT(pName = new CAssemblyName);
|
|
pName->m_pAssemblyIdentity = pAssemblyIdentity;
|
|
pAssemblyIdentity = NULL;
|
|
*ppName = pName;
|
|
pName = NULL;
|
|
|
|
hr = NOERROR;
|
|
Exit:
|
|
if (pAssemblyIdentity)
|
|
SxsDestroyAssemblyIdentity(pAssemblyIdentity);
|
|
if (pName)
|
|
FUSION_DELETE_SINGLETON(pName);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::BindToObject
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::BindToObject(
|
|
/* in */ REFIID refIID,
|
|
/* in */ IAssemblyBindSink *pAsmBindSink,
|
|
/* in */ IApplicationContext *pAppCtx,
|
|
/* in */ LPCOLESTR szCodebase,
|
|
/* in */ LONGLONG llFlags,
|
|
/* in */ LPVOID pvReserved,
|
|
/* in */ DWORD cbReserved,
|
|
/* out */ VOID **ppv)
|
|
|
|
{
|
|
if (!ppv)
|
|
return E_INVALIDARG ;
|
|
|
|
*ppv = NULL;
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::Finalize
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::Finalize()
|
|
{
|
|
m_fIsFinalized = TRUE;
|
|
return NOERROR;
|
|
}
|
|
|
|
BOOL SxspIsAssemblyNameAttributeInAssemblyIdentity(PASSEMBLY_IDENTITY_ATTRIBUTE pAttribute)
|
|
{
|
|
if( pAttribute == NULL)
|
|
return FALSE;
|
|
|
|
//compare namespace
|
|
if (::FusionpCompareStrings(
|
|
pAttribute->Namespace,
|
|
pAttribute->NamespaceCch,
|
|
SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE,
|
|
NUMBER_OF(SXS_ASSEMBLY_MANIFEST_STD_NAMESPACE) - 1,
|
|
false) == 0 ){ // case-sensitive comparison
|
|
if (::FusionpCompareStrings(
|
|
pAttribute->Name,
|
|
pAttribute->NameCch,
|
|
SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME,
|
|
NUMBER_OF(SXS_ASSEMBLY_IDENTITY_STD_ATTRIBUTE_NAME_NAME) - 1,
|
|
false) == 0 ){ // case-sensitive comparison
|
|
return TRUE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
}
|
|
else
|
|
return FALSE;
|
|
|
|
}
|
|
//-----------------------------------------------------------------------------------
|
|
// CAssemblyName::GetDisplayName
|
|
// it would be name,ns1:n1="v1",ns2:n2="v2",ns3:n3="v3",ns4:n4="v4"
|
|
// I have to put name first in order not to change Darwin's code
|
|
//
|
|
// xiaoyuw@09/29/2000
|
|
//-----------------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::GetDisplayName(LPOLESTR szDisplayName,
|
|
LPDWORD pccDisplayName, DWORD dwDisplayFlags)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
SIZE_T BufferSize;
|
|
SIZE_T BytesWrittenOrRequired = 0;
|
|
|
|
PARAMETER_CHECK(pccDisplayName != NULL);
|
|
PARAMETER_CHECK((szDisplayName != NULL) || (*pccDisplayName == 0));
|
|
PARAMETER_CHECK(dwDisplayFlags == 0);
|
|
|
|
// Need buffer size in bytes...
|
|
BufferSize = (*pccDisplayName) * sizeof(WCHAR);
|
|
|
|
IFW32FALSE_EXIT(
|
|
::SxsEncodeAssemblyIdentity(
|
|
0,
|
|
m_pAssemblyIdentity,
|
|
NULL,
|
|
SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL,
|
|
BufferSize,
|
|
szDisplayName,
|
|
&BytesWrittenOrRequired));
|
|
|
|
if ((BufferSize - BytesWrittenOrRequired) < sizeof(WCHAR))
|
|
{
|
|
// We actually could fit everything but the trailing null character...
|
|
// the BytesWrittenOrRequired actually has the right value for the exit path below;
|
|
hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
|
goto Exit;
|
|
}else // add the trailing NULL
|
|
{
|
|
szDisplayName[BytesWrittenOrRequired / sizeof (*szDisplayName)] = L'\0';
|
|
}
|
|
|
|
|
|
hr = NOERROR;
|
|
|
|
Exit:
|
|
if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
|
|
*pccDisplayName = static_cast<DWORD>((BytesWrittenOrRequired / sizeof(WCHAR)) + 1);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CAssemblyName::Parse(LPCWSTR szDisplayName)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
|
|
|
|
// Verify display name passed in.
|
|
PARAMETER_CHECK(szDisplayName != NULL);
|
|
PARAMETER_CHECK(szDisplayName[0] != L'\0');
|
|
|
|
IFW32FALSE_EXIT(
|
|
::SxspCreateAssemblyIdentityFromTextualString(
|
|
szDisplayName,
|
|
&pAssemblyIdentity));
|
|
|
|
if (m_pAssemblyIdentity != NULL)
|
|
::SxsDestroyAssemblyIdentity(m_pAssemblyIdentity);
|
|
|
|
m_pAssemblyIdentity = pAssemblyIdentity;
|
|
pAssemblyIdentity = NULL;
|
|
|
|
hr = NOERROR;
|
|
Exit:
|
|
if (pAssemblyIdentity != NULL)
|
|
::SxsDestroyAssemblyIdentity(pAssemblyIdentity);
|
|
|
|
return hr;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::GetInstalledAssemblyName
|
|
// ---------------------------------------------------------------------------
|
|
HRESULT
|
|
CAssemblyName::GetInstalledAssemblyName(
|
|
IN DWORD Flags,
|
|
IN ULONG PathType,
|
|
CBaseStringBuffer &rBufInstallPath
|
|
)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
BOOL fIsPolicy;
|
|
|
|
IFCOMFAILED_EXIT(this->DetermineAssemblyType(fIsPolicy));
|
|
Flags |= (fIsPolicy ? SXSP_GENERATE_SXS_PATH_FLAG_OMIT_VERSION : 0);
|
|
|
|
if (Flags & SXSP_GENERATE_SXS_PATH_FLAG_OMIT_ROOT)
|
|
{
|
|
IFW32FALSE_EXIT(
|
|
::SxspGenerateSxsPath(
|
|
Flags,
|
|
PathType,
|
|
NULL,
|
|
0,
|
|
m_pAssemblyIdentity,
|
|
rBufInstallPath));
|
|
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_MSI_INSTALL,
|
|
"SXS: %s - Generated %Iu character (root omitted) installation path:\n"
|
|
" \"%ls\"\n",
|
|
__FUNCTION__, rBufInstallPath.Cch(),
|
|
static_cast<PCWSTR>(rBufInstallPath));
|
|
}
|
|
else
|
|
{
|
|
CStringBuffer bufRootDir;
|
|
|
|
IFW32FALSE_EXIT(::SxspGetAssemblyRootDirectory(bufRootDir));
|
|
IFW32FALSE_EXIT(bufRootDir.Win32EnsureTrailingPathSeparator());
|
|
|
|
IFW32FALSE_EXIT(
|
|
::SxspGenerateSxsPath(
|
|
Flags,
|
|
PathType,
|
|
bufRootDir,
|
|
bufRootDir.Cch(),
|
|
m_pAssemblyIdentity,
|
|
rBufInstallPath));
|
|
|
|
::FusionpDbgPrintEx(
|
|
FUSION_DBG_LEVEL_MSI_INSTALL,
|
|
"SXS: %s - Generated %Iu character installation path:\n"
|
|
" \"%ls\"\n",
|
|
__FUNCTION__, rBufInstallPath.Cch(),
|
|
static_cast<PCWSTR>(rBufInstallPath));
|
|
}
|
|
|
|
FN_EPILOG
|
|
}
|
|
|
|
// TODO :
|
|
// 1) this function just check the existence of the directory W/O compare the files under the directory
|
|
// 2) this API would return FALSE if something in the middle is wrong, maybe not appropriate
|
|
// xiaoyuw@09/29/2000
|
|
//
|
|
HRESULT CAssemblyName::IsAssemblyInstalled(BOOL &fInstalled)
|
|
{
|
|
HRESULT hr = NOERROR;
|
|
FN_TRACE_HR(hr);
|
|
CStringBuffer buffInstalledDir;
|
|
|
|
fInstalled = FALSE;
|
|
|
|
IFCOMFAILED_EXIT(
|
|
this->GetInstalledAssemblyName(
|
|
0,
|
|
SXSP_GENERATE_SXS_PATH_PATHTYPE_ASSEMBLY,
|
|
buffInstalledDir));
|
|
|
|
if (::GetFileAttributesW(buffInstalledDir) == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
const DWORD dwLastError = ::GetLastError();
|
|
|
|
if (dwLastError != ERROR_FILE_NOT_FOUND)
|
|
ORIGINATE_WIN32_FAILURE_AND_EXIT(GetFileAttributesW, dwLastError);
|
|
}
|
|
else
|
|
fInstalled = TRUE;
|
|
|
|
FN_EPILOG
|
|
}
|
|
|
|
// IUnknown methods
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::AddRef
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP_(ULONG)
|
|
CAssemblyName::AddRef()
|
|
{
|
|
return InterlockedIncrement((LONG*) &m_cRef);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::Release
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP_(ULONG)
|
|
CAssemblyName::Release()
|
|
{
|
|
ULONG lRet = InterlockedDecrement ((PLONG)&m_cRef);
|
|
if (!lRet)
|
|
FUSION_DELETE_SINGLETON(this);
|
|
return lRet;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// CAssemblyName::QueryInterface
|
|
// ---------------------------------------------------------------------------
|
|
STDMETHODIMP
|
|
CAssemblyName::QueryInterface(REFIID riid, void** ppv)
|
|
{
|
|
if ( IsEqualIID(riid, IID_IUnknown)
|
|
|| IsEqualIID(riid, IID_IAssemblyName)){
|
|
*ppv = static_cast<IAssemblyName*> (this);
|
|
AddRef();
|
|
return S_OK;
|
|
}
|
|
else{
|
|
*ppv = NULL;
|
|
return E_NOINTERFACE;
|
|
}
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CAssemblyName::DetermineAssemblyType( BOOL &fIsPolicy )
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
FN_TRACE_HR(hr);
|
|
|
|
INTERNAL_ERROR_CHECK( m_pAssemblyIdentity != NULL );
|
|
IFW32FALSE_EXIT(::SxspDetermineAssemblyType(m_pAssemblyIdentity, fIsPolicy));
|
|
|
|
hr = S_OK;
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|