Skip to content

Instantly share code, notes, and snippets.

@apsun
Last active January 11, 2021 13:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save apsun/b471c2e11dab94ad690d to your computer and use it in GitHub Desktop.
Save apsun/b471c2e11dab94ad690d to your computer and use it in GitHub Desktop.
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#include <SDKDDKVer.h>
#include <Windows.h>
#include <comdef.h>
#include <wuapi.h>
#include <string>
#include <iostream>
void HandleError(LPCWSTR message, HRESULT result)
{
_com_error error(result);
LPCTSTR errorText = error.ErrorMessage();
std::wcerr << message << L": " << errorText << std::endl;
}
int main()
{
IUpdateSession *updateSession = NULL;
IUpdateSearcher *updateSearcher = NULL;
ISearchResult *searchResult = NULL;
IUpdateCollection *updates = NULL;
HRESULT res;
int ret = 1;
res = CoInitializeEx(NULL, 0);
if (FAILED(res)) {
HandleError(L"Failed to initialize COM", res);
return 1;
}
res = CoCreateInstance(CLSID_UpdateSession, NULL, CLSCTX_INPROC_SERVER, IID_IUpdateSession, (LPVOID *)&updateSession);
if (FAILED(res)) {
HandleError(L"Failed to create update session", res);
goto cleanup;
}
res = updateSession->CreateUpdateSearcher(&updateSearcher);
if (FAILED(res)) {
HandleError(L"Failed to create update searcher", res);
goto cleanup;
}
res = updateSearcher->put_IncludePotentiallySupersededUpdates(VARIANT_TRUE);
if (FAILED(res)) {
HandleError(L"Failed to set search options", res);
goto cleanup;
}
BSTR criteria = SysAllocString(L"IsInstalled=1 or IsHidden=1");
res = updateSearcher->Search(criteria, &searchResult);
SysFreeString(criteria);
if (FAILED(res)) {
HandleError(L"Failed to search for updates", res);
goto cleanup;
}
res = searchResult->get_Updates(&updates);
if (FAILED(res)) {
HandleError(L"Failed to retrieve update list from search result", res);
goto cleanup;
}
LONG updateCount;
res = updates->get_Count(&updateCount);
if (FAILED(res)) {
HandleError(L"Failed to get update count", res);
goto cleanup;
}
for (LONG i = 0L; i < updateCount; ++i) {
IUpdate *update = NULL;
IStringCollection *updateKBIDs = NULL;
bool innerError = true;
res = updates->get_Item(i, &update);
if (FAILED(res)) {
HandleError(L"Failed to get update item", res);
goto innerCleanup;
}
res = update->get_KBArticleIDs(&updateKBIDs);
if (FAILED(res)) {
HandleError(L"Failed to get KB article ID list", res);
goto innerCleanup;
}
LONG kbIDCount;
res = updateKBIDs->get_Count(&kbIDCount);
if (FAILED(res)) {
HandleError(L"Failed to get KB article ID count", res);
goto innerCleanup;
}
for (LONG j = 0L; j < kbIDCount; ++j) {
BSTR kbID;
res = updateKBIDs->get_Item(j, &kbID);
if (FAILED(res)) {
HandleError(L"Failed to get KB article ID", res);
goto innerCleanup;
}
std::wcout << L"KB" << kbID << L':' << std::endl;
SysFreeString(kbID);
}
BSTR updateTitle;
res = update->get_Title(&updateTitle);
if (FAILED(res)) {
HandleError(L"Failed to get update title", res);
goto innerCleanup;
}
std::wcout << L" " << updateTitle << std::endl << std::endl;
SysFreeString(updateTitle);
innerError = false;
innerCleanup:
updateKBIDs->Release();
update->Release();
if (innerError) {
goto cleanup;
}
}
ret = 0;
cleanup:
if (updates != NULL) updates->Release();
if (searchResult != NULL) searchResult->Release();
if (updateSearcher != NULL) updateSearcher->Release();
if (updateSession != NULL) updateSession->Release();
CoUninitialize();
return ret;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment