bool InstanceSelector::Less()

in src/vswhere.lib/InstanceSelector.cpp [34:96]


bool InstanceSelector::Less(const ISetupInstancePtr& a, const ISetupInstancePtr&  b) const
{
    static ci_less less;

    bstr_t bstrVersionA, bstrVersionB;
    ULONGLONG ullVersionA, ullVersionB;
    FILETIME ftDateA, ftDateB;

    // Compare versions.
    auto hrA = a->GetInstallationVersion(bstrVersionA.GetAddress());
    auto hrB = b->GetInstallationVersion(bstrVersionB.GetAddress());
    if (SUCCEEDED(hrA) && SUCCEEDED(hrB))
    {
        if (m_helper)
        {
            hrA = m_helper->ParseVersion(bstrVersionA, &ullVersionA);
            hrB = m_helper->ParseVersion(bstrVersionB, &ullVersionB);
            if (SUCCEEDED(hrA) && SUCCEEDED(hrB))
            {
                if (ullVersionA != ullVersionB)
                {
                    return ullVersionA < ullVersionB;
                }
            }
            else
            {
                // a is less than b if we can't parse version for a but can for b.
                return SUCCEEDED(hrB);
            }
        }
        else
        {
            // If ISetupHelper is not available we have only legacy products, or very early pre-releases of VS2017.
            // For version 10.0 and newer either should lexigraphically sort correctly.
            return less(wstring(bstrVersionA), wstring(bstrVersionB));
        }
    }
    else
    {
        // a is less than b if we can't get version for a but can for b.
        return SUCCEEDED(hrB);
    }

    // Compare dates.
    hrA = a->GetInstallDate(&ftDateA);
    hrB = b->GetInstallDate(&ftDateB);
    if (SUCCEEDED(hrA) && SUCCEEDED(hrB))
    {
        auto result = ::CompareFileTime(&ftDateA, &ftDateB);
        if (0 == result)
        {
            auto message = ResourceManager::GetString(IDS_E_UNEXPECTEDDATE);
            throw win32_error(E_UNEXPECTED, message);
        }

        return 0 > result;
    }
    else
    {
        // a is less than b if we can't get date for a but can for b.
        return SUCCEEDED(hrB);
    }
}