Beispiel #1
0
extern "C" HRESULT MspEngineDetectInitialize(
    __in BURN_PACKAGES* pPackages
    )
{
    AssertSz(pPackages->cPatchInfo, "MspEngineDetectInitialize() should only be called if there are MSP packages.");

    HRESULT hr = S_OK;
    POSSIBLE_TARGETPRODUCT* rgPossibleTargetProducts = NULL;
    DWORD cPossibleTargetProducts = 0;

#ifdef DEBUG
    // All patch info should be initialized to zero.
    for (DWORD i = 0; i < pPackages->cPatchInfo; ++i)
    {
        BURN_PACKAGE* pPackage = pPackages->rgPatchInfoToPackage[i];
        Assert(!pPackage->Msp.cTargetProductCodes);
        Assert(!pPackage->Msp.rgTargetProducts);
    }
#endif

    // Figure out which product codes to target on the machine. In the worst case all products on the machine
    // will be returned.
    hr = GetPossibleTargetProductCodes(pPackages, &rgPossibleTargetProducts, &cPossibleTargetProducts);
    ExitOnFailure(hr, "Failed to get possible target product codes.");

    // Loop through possible target products, testing the collective patch applicability against each product in
    // the appropriate context. Store the result with the appropriate patch package.
    for (DWORD iSearch = 0; iSearch < cPossibleTargetProducts; ++iSearch)
    {
        const POSSIBLE_TARGETPRODUCT* pPossibleTargetProduct = rgPossibleTargetProducts + iSearch;

        LogId(REPORT_STANDARD, MSG_DETECT_CALCULATE_PATCH_APPLICABILITY, pPossibleTargetProduct->wzProductCode, LoggingMsiInstallContext(pPossibleTargetProduct->context));

        if (pPossibleTargetProduct->pszLocalPackage)
        {
            // Ignores current machine state to determine just patch applicability.
            // Superseded and obsolesced patches will be planned separately.
            hr = WiuDetermineApplicablePatches(pPossibleTargetProduct->pszLocalPackage, pPackages->rgPatchInfo, pPackages->cPatchInfo);
        }
        else
        {
            hr = WiuDeterminePatchSequence(pPossibleTargetProduct->wzProductCode, NULL, pPossibleTargetProduct->context, pPackages->rgPatchInfo, pPackages->cPatchInfo);
        }

        if (SUCCEEDED(hr))
        {
            for (DWORD iPatchInfo = 0; iPatchInfo < pPackages->cPatchInfo; ++iPatchInfo)
            {
                if (ERROR_SUCCESS == pPackages->rgPatchInfo[iPatchInfo].uStatus)
                {
                    BURN_PACKAGE* pMspPackage = pPackages->rgPatchInfoToPackage[iPatchInfo];
                    Assert(BURN_PACKAGE_TYPE_MSP == pMspPackage->type);

                    // Note that we do add superseded and obsolete MSP packages. Package Detect and Plan will sort them out later.
                    hr = AddDetectedTargetProduct(pPackages, pMspPackage, pPackages->rgPatchInfo[iPatchInfo].dwOrder, pPossibleTargetProduct->wzProductCode, pPossibleTargetProduct->context);
                    ExitOnFailure(hr, "Failed to add target product code to package: %ls", pMspPackage->sczId);
                }
                // TODO: should we log something for this error case?
            }
        }
        else
        {
            LogId(REPORT_STANDARD, MSG_DETECT_FAILED_CALCULATE_PATCH_APPLICABILITY, pPossibleTargetProduct->wzProductCode, LoggingMsiInstallContext(pPossibleTargetProduct->context), hr);
        }

        hr = S_OK; // always reset so we test all possible target products.
    }

LExit:
    if (rgPossibleTargetProducts)
    {
        for (DWORD i = 0; i < cPossibleTargetProducts; ++i)
        {
            ReleaseStr(rgPossibleTargetProducts[i].pszLocalPackage);
        }
        MemFree(rgPossibleTargetProducts);
    }

    return hr;
}
Beispiel #2
0
extern "C" HRESULT MspEngineDetectInitialize(
    __in BURN_PACKAGES* pPackages
    )
{
    AssertSz(pPackages->cPatchInfo, "MspEngineDetectInitialize() should only be called if there are MSP packages.");

    static MSIINSTALLCONTEXT rgContexts[] = { MSIINSTALLCONTEXT_USERUNMANAGED, MSIINSTALLCONTEXT_USERMANAGED, MSIINSTALLCONTEXT_MACHINE };

    HRESULT hr = S_OK;
    DWORD iProduct = 0;
    WCHAR wzProductCode[MAX_GUID_CHARS + 1];

#ifdef DEBUG
    // All patch info should be initialized to zero.
    for (DWORD i = 0; i < pPackages->cPatchInfo; ++i)
    {
        BURN_PACKAGE* pPackage = pPackages->rgPatchInfoToPackage[i];
        Assert(!pPackage->Msp.cTargetProductCodes);
        Assert(!pPackage->Msp.rgTargetProducts);
    }
#endif

    // Loop through all products on the machine, testing the collective patch applicability
    // against each product in all contexts. Store the result with the appropriate patch package.
    do
    {
        hr = WiuEnumProducts(iProduct, wzProductCode);
        if (SUCCEEDED(hr))
        {
            for (DWORD i = 0; i < countof(rgContexts); ++i)
            {
                hr = WiuDeterminePatchSequence(wzProductCode, NULL, rgContexts[i], pPackages->rgPatchInfo, pPackages->cPatchInfo);
                if (SUCCEEDED(hr))
                {
                    for (DWORD iPatchInfo = 0; iPatchInfo < pPackages->cPatchInfo; ++iPatchInfo)
                    {
                        if (ERROR_SUCCESS == pPackages->rgPatchInfo[iPatchInfo].uStatus)
                        {
                            BURN_PACKAGE* pMspPackage = pPackages->rgPatchInfoToPackage[iPatchInfo];
                            Assert(BURN_PACKAGE_TYPE_MSP == pMspPackage->type);

                            // Note that we do add superseded and obsolete MSP packages. Package Detect and Plan will sort them out later.
                            hr = AddDetectedTargetProduct(pPackages, pMspPackage, rgContexts[i], pPackages->rgPatchInfo[iPatchInfo].dwOrder, wzProductCode);
                            ExitOnFailure1(hr, "Failed to add target product code to package: %ls", pMspPackage->sczId);
                        }
                        // TODO: should we log something for this error case?
                    }
                }
                // TODO: should we log something for this error case?
            }

            hr = S_OK; // always reset so we test all possible target products.
        }
        else if (E_BADCONFIGURATION == hr)
        {
            // Skip this product and continue.
            LogId(REPORT_STANDARD, MSG_DETECT_BAD_PRODUCT_CONFIGURATION, wzProductCode);

            hr = S_OK;
        }

        ++iProduct;

    } while (SUCCEEDED(hr));

    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "Failed to test patches applicability against all products on the machine.");

LExit:
    return hr;
}