/* Copyright (c) Microsoft Corporation */ #include "stdinc.h" #include #include "sxsp.h" #include "actctxgenctxctb.h" #include "sxsexceptionhandling.h" #include "actctxgenctx.h" #define ENSURE_LAST_ERROR_SET() \ do \ { \ ASSERT_NTC(::FusionpGetLastWin32Error() != ERROR_SUCCESS); \ if (::FusionpGetLastWin32Error() == ERROR_SUCCESS) \ ::FusionpSetLastWin32Error(ERROR_INTERNAL_ERROR); \ } while (0) /*----------------------------------------------------------------------------- ACTivation ConTeXt GENneration ConTeXt ConTriButor -----------------------------------------------------------------------------*/ int CActivationContextGenerationContextContributor::Compare( const void *pelem1, const void *pelem2 ) { const CActivationContextGenerationContextContributor *Ctb1 = reinterpret_cast(pelem1); const CActivationContextGenerationContextContributor *Ctb2 = reinterpret_cast(pelem2); if (Ctb1->IsExtendedSection()) { if (!Ctb2->IsExtendedSection()) return -1; // otherwise they're both extended... int i = memcmp(Ctb1->m_ActCtxCtb->GetExtensionGuidPtr(), Ctb2->m_ActCtxCtb->GetExtensionGuidPtr(), sizeof(GUID)); if (i != 0) return i; } else { if (Ctb2->IsExtendedSection()) return +1; } // comparison of unsigned numbers by subtraction does not work, // you can cast them to signed first, but this seems cleaner const ULONG sectionId1 = Ctb1->m_ActCtxCtb->m_SectionId; const ULONG sectionId2 = Ctb2->m_ActCtxCtb->m_SectionId; if (sectionId1 < sectionId2) return -1; if (sectionId1 > sectionId2) return +1; return 0; } CActivationContextGenerationContextContributor::~CActivationContextGenerationContextContributor() { if (m_ActCtxCtb != NULL) { CSxsPreserveLastError ple; m_ActCtxCtb->Release(); ple.Restore(); } } VOID CActivationContextGenerationContextContributor::PopulateCallbackHeader( ACTCTXCTB_CBHEADER &Header, ULONG Reason, PACTCTXGENCTX pActCtxGenCtx ) { Header.Reason = Reason; Header.Flags = pActCtxGenCtx->m_Flags; Header.ManifestOperation = pActCtxGenCtx->m_ManifestOperation; Header.ManifestOperationFlags = pActCtxGenCtx->m_ManifestOperationFlags; Header.InstallationContext = &pActCtxGenCtx->m_InstallationContext; Header.ClsidMappingContext = &pActCtxGenCtx->m_ClsidMappingContext; Header.ExtensionGuid = m_ActCtxCtb->GetExtensionGuidPtr(); Header.SectionId = m_ActCtxCtb->m_SectionId; Header.ContributorContext = m_ActCtxCtb->m_ContributorContext; Header.pOriginalActCtxGenCtx = pActCtxGenCtx; if (m_ManifestParseContextValid) Header.ManifestParseContext = m_ManifestParseContext; else Header.ManifestParseContext = NULL; Header.ActCtxGenContext = m_ActCtxGenContext; } BOOL CActivationContextGenerationContextContributor::Initialize( PACTCTXCTB ActCtxCtb, PVOID ActCtxGenContext ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); INTERNAL_ERROR_CHECK(m_ActCtxCtb == NULL); INTERNAL_ERROR_CHECK(m_ActCtxGenContext == NULL); PARAMETER_CHECK(ActCtxCtb != NULL); ActCtxCtb->AddRef(); m_ActCtxCtb = ActCtxCtb; m_ActCtxGenContext = ActCtxGenContext; m_IsExtendedSection = ActCtxCtb->m_IsExtendedSection; FN_EPILOG } PCWSTR CActivationContextGenerationContextContributor::Name() const { return m_ActCtxCtb->m_ContributorNameBuffer; } const GUID & CActivationContextGenerationContextContributor::ExtensionGuid() const { return m_ActCtxCtb->m_ExtensionGuid; } ULONG CActivationContextGenerationContextContributor::SectionId() const { return m_ActCtxCtb->m_SectionId; } ULONG CActivationContextGenerationContextContributor::SectionFormat() const { return m_ActCtxCtb->m_Format; } BOOL CActivationContextGenerationContextContributor::Fire_AllParsingDone( PACTCTXGENCTX pActCtxGenCtx ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ACTCTXCTB_CBALLPARSINGDONE CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_ALLPARSINGDONE, pActCtxGenCtx); CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_GetSectionSize( PACTCTXGENCTX pActCtxGenCtx ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ACTCTXCTB_CBGETSECTIONSIZE CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_GETSECTIONSIZE, pActCtxGenCtx); CBData.SectionSize = 0; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } m_SectionSize = CBData.SectionSize; FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_GetSectionData( PACTCTXGENCTX pActCtxGenCtx, PVOID Buffer ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ACTCTXCTB_CBGETSECTIONDATA CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_GETSECTIONDATA, pActCtxGenCtx); CBData.SectionSize = m_SectionSize; CBData.SectionDataStart = Buffer; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_ParseEnding( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); if ((m_ActCtxCtb != NULL) && (m_ManifestParseContextValid) && (!m_NoMoreCallbacksThisFile)) { if (m_ManifestParseContextValid) { ACTCTXCTB_CBPARSEENDING CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_PARSEENDING, pActCtxGenCtx); CBData.AssemblyContext = AssemblyContext; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } } } FN_EPILOG } VOID CActivationContextGenerationContextContributor::Fire_ParseEnded( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext ) { FN_TRACE(); if ((m_ActCtxCtb != NULL) && (m_ManifestParseContextValid) && (!m_NoMoreCallbacksThisFile)) { if (m_ManifestParseContextValid) { CSxsPreserveLastError ple; ACTCTXCTB_CBPARSEENDED CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_PARSEENDED, pActCtxGenCtx); CBData.AssemblyContext = AssemblyContext; (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); m_ManifestParseContextValid = FALSE; m_ManifestParseContext = NULL; ple.Restore(); } } } BOOL CActivationContextGenerationContextContributor::Fire_ActCtxGenEnding( PACTCTXGENCTX pActCtxGenCtx ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); if (m_ActCtxCtb != NULL) { ACTCTXCTB_CBACTCTXGENENDING CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_ACTCTXGENENDING, pActCtxGenCtx); CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } } FN_EPILOG } VOID CActivationContextGenerationContextContributor::Fire_ActCtxGenEnded( PACTCTXGENCTX pActCtxGenCtx ) { FN_TRACE(); if (m_ActCtxCtb != NULL) { CSxsPreserveLastError ple; ACTCTXCTB_CBACTCTXGENENDED CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_ACTCTXGENENDED, pActCtxGenCtx); CBData.Success = (BOOL) ((LONG_PTR) -1); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); ASSERT(CBData.Success == (BOOL) ((LONG_PTR) -1)); m_ActCtxGenContext = NULL; ple.Restore(); } } BOOL CActivationContextGenerationContextContributor::Fire_BeginChildren( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext, PCACTCTXCTB_PARSE_CONTEXT ParseContext, PCSXS_NODE_INFO NodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); if (!m_NoMoreCallbacksThisFile) { ACTCTXCTB_CBBEGINCHILDREN CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_BEGINCHILDREN, pActCtxGenCtx); CBData.AssemblyContext = AssemblyContext; CBData.ParseContext = ParseContext; CBData.NodeInfo = NodeInfo; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } } FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_EndChildren( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext, PCACTCTXCTB_PARSE_CONTEXT ParseContext, BOOL Empty, PCSXS_NODE_INFO NodeInfo ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); if (!m_NoMoreCallbacksThisFile) { ACTCTXCTB_CBENDCHILDREN CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_ENDCHILDREN, pActCtxGenCtx); CBData.Empty = Empty; CBData.NodeInfo = NodeInfo; CBData.ParseContext = ParseContext; CBData.AssemblyContext = AssemblyContext; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } } FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_ElementParsed( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext, PCACTCTXCTB_PARSE_CONTEXT ParseContext, USHORT NodeCount, PCSXS_NODE_INFO NodeInfo ) { FN_PROLOG_WIN32 if (!m_NoMoreCallbacksThisFile) { ACTCTXCTB_CBELEMENTPARSED CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_ELEMENTPARSED, pActCtxGenCtx); CBData.NodeCount = NodeCount; CBData.NodeInfo = NodeInfo; CBData.ParseContext = ParseContext; CBData.AssemblyContext = AssemblyContext; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; TRACE_WIN32_FAILURE((*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header)); goto Exit; } } FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_PCDATAParsed( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext, PCACTCTXCTB_PARSE_CONTEXT ParseContext, const WCHAR *String, ULONG Cch ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); if (!m_NoMoreCallbacksThisFile) { ACTCTXCTB_CBPCDATAPARSED CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_PCDATAPARSED, pActCtxGenCtx); CBData.ParseContext = ParseContext; CBData.AssemblyContext = AssemblyContext; CBData.Text = String; CBData.TextCch = Cch; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } } FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_CDATAParsed( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext, PCACTCTXCTB_PARSE_CONTEXT ParseContext, const WCHAR *String, ULONG Cch ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); if (!m_NoMoreCallbacksThisFile) { ACTCTXCTB_CBCDATAPARSED CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_CDATAPARSED, pActCtxGenCtx); CBData.ParseContext = ParseContext; CBData.AssemblyContext = AssemblyContext; CBData.Text = String; CBData.TextCch = Cch; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } } FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_IdentityDetermined( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext, PCACTCTXCTB_PARSE_CONTEXT ParseContext, PCASSEMBLY_IDENTITY AssemblyIdentity ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); if (!m_NoMoreCallbacksThisFile) { ACTCTXCTB_CBIDENTITYDETERMINED CBData; this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_IDENTITYDETERMINED, pActCtxGenCtx); CBData.AssemblyIdentity = AssemblyIdentity; CBData.ParseContext = ParseContext; CBData.AssemblyContext = AssemblyContext; CBData.Success = TRUE; ::FusionpSetLastWin32Error(ERROR_SUCCESS); (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } } FN_EPILOG } BOOL CActivationContextGenerationContextContributor::Fire_ParseBeginning( PACTCTXGENCTX pActCtxGenCtx, PCACTCTXCTB_ASSEMBLY_CONTEXT AssemblyContext, DWORD FileFlags, ULONG ParseType, ULONG FilePathType, PCWSTR FilePath, SIZE_T FilePathCch, const FILETIME &FileLastWriteTime, ULONG FileFormatVersionMajor, ULONG FileFormatVersionMinor, ULONG MetadataSatelliteRosterIndex ) { BOOL fSuccess = FALSE; FN_TRACE_WIN32(fSuccess); ACTCTXCTB_CBPARSEBEGINNING CBData; PARAMETER_CHECK(FilePathType == ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE); INTERNAL_ERROR_CHECK(!m_ManifestParseContextValid); this->PopulateCallbackHeader(CBData.Header, ACTCTXCTB_CBREASON_PARSEBEGINNING, pActCtxGenCtx); CBData.FileFlags = FileFlags; CBData.ParseType = ParseType; CBData.AssemblyContext = AssemblyContext; CBData.FilePath = FilePath; CBData.FilePathCch = FilePathCch; CBData.FilePathType = FilePathType; CBData.FileLastWriteTime = FileLastWriteTime; CBData.FileFormatVersionMajor = FileFormatVersionMajor; CBData.FileFormatVersionMinor = FileFormatVersionMinor; CBData.MetadataSatelliteRosterIndex = MetadataSatelliteRosterIndex; CBData.NoMoreCallbacksThisFile = FALSE; CBData.Success = TRUE; (*(m_ActCtxCtb->m_CallbackFunction))((PACTCTXCTB_CALLBACK_DATA) &CBData.Header); if (!CBData.Success) { ENSURE_LAST_ERROR_SET(); pActCtxGenCtx->m_ManifestOperationFlags |= MANIFEST_OPERATION_INSTALL_FLAG_ABORT; goto Exit; } m_NoMoreCallbacksThisFile = CBData.NoMoreCallbacksThisFile; if (!m_NoMoreCallbacksThisFile) { // If they set the no more callbacks flag, we don't track the parse context. m_ManifestParseContext = CBData.Header.ManifestParseContext; m_ManifestParseContextValid = TRUE; } else { m_ManifestParseContext = NULL; m_ManifestParseContextValid = FALSE; // You can't pass back a per-file parsing context if you don't want any more callbacks for this // file. ASSERT(CBData.Header.ManifestParseContext == NULL); } FN_EPILOG }