Markus Steindl
Markus Steindl

Reputation: 93

Visual C++, Windows Update Interface (IUpdate) <wuapi.h>, get_MsrcSeverity

I'm probably just blind, but I cannot see any errors here (and I am looking on this issue already for days now...)

I am trying to get the Patch Priority (Severity) from the Windows Update Interface using the following piece of code in Visual Studio:

#include "stdafx.h"
#include <wuapi.h>
#include <iostream>
#include <ATLComTime.h>
#include <wuerror.h>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{


     HRESULT hr;
    hr = CoInitialize(NULL);

    IUpdateSession* iUpdate;
    IUpdateSearcher* searcher;
    ISearchResult* results;
    BSTR criteria = SysAllocString(L"IsInstalled=0");

    hr = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID*)&iUpdate);
    hr = iUpdate->CreateUpdateSearcher(&searcher);

    wcout << L"Searching for updates ..."<<endl;
    hr = searcher->Search(criteria, &results); 
    SysFreeString(criteria);

    switch(hr)
    {
    case S_OK:
        wcout<<L"List of applicable items on the machine:"<<endl;
        break;
    case WU_E_LEGACYSERVER:
        wcout<<L"No server selection enabled"<<endl;
        return 0;
    case WU_E_INVALID_CRITERIA:
        wcout<<L"Invalid search criteria"<<endl;
        return 0;
    }

    IUpdateCollection *updateList;
    IUpdateCollection *bundledUpdates;
    IUpdate *updateItem;
    IUpdate *bundledUpdateItem;
    LONG updateSize;
    LONG bundledUpdateSize;
    BSTR updateName;
    BSTR severity;

    results->get_Updates(&updateList);
    updateList->get_Count(&updateSize);

    if (updateSize == 0)
    {
        wcout << L"No updates found"<<endl;
    }

    for (LONG i = 0; i < updateSize; i++)
    {
        updateList->get_Item(i,&updateItem);
        updateItem->get_Title(&updateName);

        severity = NULL;
        updateItem->get_MsrcSeverity(&severity);
        if (severity != NULL) 
        {
            wcout << L"update severity: " << severity << endl;
        }

        wcout<<i+1<<" - " << updateName << endl;

        // bundled updates
        updateItem->get_BundledUpdates(&bundledUpdates);
        bundledUpdates->get_Count(&bundledUpdateSize);

        if (bundledUpdateSize != 0) 
        {
            // iterate through bundled updates
            for (LONG ii = 0; ii < bundledUpdateSize; ii++) 
            {
                bundledUpdates->get_Item(ii, &bundledUpdateItem);
                severity = NULL;
                bundledUpdateItem->get_MsrcSeverity(&severity);
                if (severity != NULL) 
                {
                    wcout << L" bundled update severity: " << severity << endl;
                }
            }

        }

    }

    ::CoUninitialize();
    wcin.get();


    return 0;
}

So here's the issue: updateItem->get_MsrcSeverity(&severity); is not returning anything. If I catch the result code with an HRESULT it always returns S_OK.

Link to MSDN IUpdate MsrcSeverity: http://msdn.microsoft.com/en-us/library/windows/desktop/aa386906(v=vs.85).aspx

Can you see what I am doing obviously wrong or is the get_MsrcSeverity function currently broken?

@EDIT: Changed the code to iterate through "BundledUpdates" as suggested.

@EDIT2: the code now outputs the severity value of the updateItem as well as the bundledUpdatesItem, but it's always NULL.

I also know there is one important update waiting for my computer - regarding to Windows Update in the control panel. It is KB2858725.

@EDIT3: Okay, it turns out, KB2858725 is no security update and therefore has no severity rating by Microsoft. But how does Microsoft Windows Update now categorize the updates in "important" and "optional" like you can see it in control panel's update?

Thank you for any hints! // Markus

Upvotes: 3

Views: 2387

Answers (2)

user1094821
user1094821

Reputation: 1835

I've been struggling with the exact same problem for hours now... I finally figured out that Microsoft only seems to set the MsrcSeverity value on some updates. For general Windows updates, it's usually null. For most security updates it's set to one of:

  • "Critical"
  • "Moderate"
  • "Important"
  • "Low"

It seems as though the "Unspecified" value is never used, though it is documented in MSDN (http://msdn.microsoft.com/en-us/library/microsoft.updateservices.administration.msrcseverity(v=vs.85).aspx).

I wrote a small C# program to list all available updates and their reported severity. It requires a reference to WUApiLib:

using System;
using WUApiLib;

namespace EnumerateUpdates
{
    class Program
    {
        static void Main(string[] args)
        {
            var session = new UpdateSession();
            var searcher = session.CreateUpdateSearcher();
            searcher.Online = false;

            // Find all updates that have not yet been installed
            var result = searcher.Search("IsInstalled=0 And IsHidden=0");
            foreach (dynamic update in result.Updates)
            {
                Console.WriteLine(update.Title + ": " + update.Description);
                Console.WriteLine("Severity is " + update.MsrcSeverity);
                Console.WriteLine();
            }

            Console.ReadLine();
        }
    }
}

Hope this helps someone!

Upvotes: 3

51k
51k

Reputation: 1443

Look for bundled updates in the list. The bundled updates does not have some properties or methods as described on this page.

Remarks

If the BundledUpdates property contains an IUpdateCollection, some properties and methods of the update may only be available on the bundled updates, for example, DownloadContents or CopyFromCache.

The update you are processing in is a bundled update. Extract the individual updates from this bundle, it will have the property you are looking out for.

The IUpdate interface has a method get_BundledUpdates which gets you a IUpdateCollection if the size of this collection is greater then 0, this is a bundled update.

Upvotes: 1

Related Questions