Last active
January 11, 2021 13:44
-
-
Save apsun/b471c2e11dab94ad690d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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