|
|
#include "stdinc.h"
#include "idp.h"
#include "sxsapi.h"
#include "sxsid.h"
BOOL SxspMapAssemblyIdentityToPolicyIdentity( DWORD Flags, PCASSEMBLY_IDENTITY AssemblyIdentity, PASSEMBLY_IDENTITY &PolicyIdentity ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PCWSTR pszTemp; SIZE_T cchTemp; PASSEMBLY_IDENTITY NewIdentity = NULL; CStringBuffer Name; bool fFirst; const bool fOmitEntireVersion = ((Flags & SXSP_MAP_ASSEMBLY_IDENTITY_TO_POLICY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION) != 0); BOOL fIsPolicy = FALSE;
PolicyIdentity = NULL;
PARAMETER_CHECK((Flags & ~(SXSP_MAP_ASSEMBLY_IDENTITY_TO_POLICY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION)) == 0); PARAMETER_CHECK(AssemblyIdentity != 0);
//
// Determine assembly type. If this wasn't a policy assembly, then map it to one.
//
IFW32FALSE_EXIT(::SxspDetermineAssemblyType(AssemblyIdentity, fIsPolicy));
//
// Now let's duplicate the assembly identity into a policy identity by changing the
// name, and potentially changing the type if it was "win32" into "win32-policy"
//
IFW32FALSE_EXIT( ::SxsDuplicateAssemblyIdentity( 0, AssemblyIdentity, &NewIdentity));
//
// If we're not a policy assembly, then we have to map type="" to type="policy"
// and type="foo" to type="foo-policy"
//
if (!fIsPolicy) { PCWSTR pcwszOriginalType; SIZE_T cchOriginalType;
IFW32FALSE_EXIT( ::SxspGetAssemblyIdentityAttributeValue( SXSP_GET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_NOT_FOUND_RETURNS_NULL, AssemblyIdentity, &s_IdentityAttribute_type, &pcwszOriginalType, &cchOriginalType));
if (cchOriginalType == 0) { IFW32FALSE_EXIT( ::SxspSetAssemblyIdentityAttributeValue( SXSP_SET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_OVERWRITE_EXISTING, NewIdentity, &s_IdentityAttribute_type, ASSEMBLY_TYPE_POLICY, ASSEMBLY_TYPE_POLICY_CCH)); } else { CSmallStringBuffer MappedName; IFW32FALSE_EXIT(MappedName.Win32Assign(pcwszOriginalType, cchOriginalType)); IFW32FALSE_EXIT(MappedName.Win32Append(ASSEMBLY_TYPE_POLICY_SUFFIX, ASSEMBLY_TYPE_POLICY_SUFFIX_CCH));
IFW32FALSE_EXIT( ::SxspSetAssemblyIdentityAttributeValue( SXSP_SET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_OVERWRITE_EXISTING, NewIdentity, &s_IdentityAttribute_type, MappedName)); } } IFW32FALSE_EXIT(Name.Win32Assign(L"Policy.", 7));
if (!fOmitEntireVersion) { IFW32FALSE_EXIT( ::SxspGetAssemblyIdentityAttributeValue( 0, AssemblyIdentity, &s_IdentityAttribute_version, &pszTemp, &cchTemp));
fFirst = true;
while (cchTemp != 0) { if (pszTemp[--cchTemp] == L'.') { if (!fFirst) break;
fFirst = false; } }
// This should not be zero; someone prior to this should have validated the version format
// to include three dots.
INTERNAL_ERROR_CHECK(cchTemp != 0);
IFW32FALSE_EXIT(Name.Win32Append(pszTemp, cchTemp + 1)); }
IFW32FALSE_EXIT( ::SxspGetAssemblyIdentityAttributeValue( 0, AssemblyIdentity, &s_IdentityAttribute_name, &pszTemp, &cchTemp));
IFW32FALSE_EXIT(Name.Win32Append(pszTemp, cchTemp));
IFW32FALSE_EXIT( ::SxspSetAssemblyIdentityAttributeValue( SXSP_SET_ASSEMBLY_IDENTITY_ATTRIBUTE_VALUE_FLAG_OVERWRITE_EXISTING, NewIdentity, &s_IdentityAttribute_name, Name));
// finally we whack the version...
IFW32FALSE_EXIT( ::SxspRemoveAssemblyIdentityAttribute( SXSP_REMOVE_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_NOT_FOUND_SUCCEEDS, NewIdentity, &s_IdentityAttribute_version));
PolicyIdentity = NewIdentity; NewIdentity = NULL;
fSuccess = TRUE; Exit: if (NewIdentity != NULL) { ::SxsDestroyAssemblyIdentity(NewIdentity); NewIdentity = NULL; }
return fSuccess;
}
BOOL SxspGenerateTextuallyEncodedPolicyIdentityFromAssemblyIdentity( DWORD Flags, PCASSEMBLY_IDENTITY AssemblyIdentity, CBaseStringBuffer &rbuffEncodedIdentity, PASSEMBLY_IDENTITY *PolicyIdentityOut ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); PASSEMBLY_IDENTITY PolicyIdentity = NULL; SIZE_T EncodedIdentityBytes = 0; CStringBufferAccessor acc; DWORD dwMapFlags = 0; SIZE_T BytesWritten;
if (PolicyIdentityOut != NULL) *PolicyIdentityOut = NULL;
PARAMETER_CHECK((Flags & ~(SXSP_GENERATE_TEXTUALLY_ENCODED_POLICY_IDENTITY_FROM_ASSEMBLY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION)) == 0); PARAMETER_CHECK(AssemblyIdentity != NULL);
if (Flags & SXSP_GENERATE_TEXTUALLY_ENCODED_POLICY_IDENTITY_FROM_ASSEMBLY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION) dwMapFlags |= SXSP_MAP_ASSEMBLY_IDENTITY_TO_POLICY_IDENTITY_FLAG_OMIT_ENTIRE_VERSION;
IFW32FALSE_EXIT(::SxspMapAssemblyIdentityToPolicyIdentity(dwMapFlags, AssemblyIdentity, PolicyIdentity));
IFW32FALSE_EXIT( ::SxsComputeAssemblyIdentityEncodedSize( 0, PolicyIdentity, NULL, SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL, &EncodedIdentityBytes));
INTERNAL_ERROR_CHECK((EncodedIdentityBytes % sizeof(WCHAR)) == 0);
IFW32FALSE_EXIT(rbuffEncodedIdentity.Win32ResizeBuffer((EncodedIdentityBytes / sizeof(WCHAR)) + 1, eDoNotPreserveBufferContents));
acc.Attach(&rbuffEncodedIdentity);
IFW32FALSE_EXIT( ::SxsEncodeAssemblyIdentity( 0, PolicyIdentity, NULL, SXS_ASSEMBLY_IDENTITY_ENCODING_DEFAULTGROUP_TEXTUAL, acc.GetBufferCb(), acc.GetBufferPtr(), &BytesWritten));
INTERNAL_ERROR_CHECK((BytesWritten % sizeof(WCHAR)) == 0); INTERNAL_ERROR_CHECK(BytesWritten <= EncodedIdentityBytes);
acc.GetBufferPtr()[BytesWritten / sizeof(WCHAR)] = L'\0';
acc.Detach();
if (PolicyIdentityOut != NULL) { *PolicyIdentityOut = PolicyIdentity; PolicyIdentity = NULL; // so we don't try to clean it up in the exit path
}
fSuccess = TRUE; Exit: if (PolicyIdentity != NULL) SxsDestroyAssemblyIdentity(PolicyIdentity);
return fSuccess; }
//
// the difference between this func and SxsHashAssemblyIdentity() is that for policy,
// version should not be calcaulated as part of hash
//
BOOL SxspHashAssemblyIdentityForPolicy( IN DWORD dwFlags, IN PCASSEMBLY_IDENTITY AssemblyIdentity, OUT ULONG & IdentityHash) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess);
PASSEMBLY_IDENTITY pAssemblyIdentity = NULL;
IFW32FALSE_EXIT( ::SxsDuplicateAssemblyIdentity( SXS_DUPLICATE_ASSEMBLY_IDENTITY_FLAG_FREEZE, AssemblyIdentity, &pAssemblyIdentity));
IFW32FALSE_EXIT( ::SxspRemoveAssemblyIdentityAttribute( SXSP_REMOVE_ASSEMBLY_IDENTITY_ATTRIBUTE_FLAG_NOT_FOUND_SUCCEEDS, pAssemblyIdentity, &s_IdentityAttribute_version));
IFW32FALSE_EXIT(::SxsHashAssemblyIdentity(0, pAssemblyIdentity, &IdentityHash));
fSuccess = TRUE; Exit: if (pAssemblyIdentity != NULL) ::SxsDestroyAssemblyIdentity(pAssemblyIdentity); return fSuccess; }
|