This commit is contained in:
Vichingo455
2025-03-23 15:26:15 +01:00
parent cacf40b6cd
commit ad8366918e
72 changed files with 10255 additions and 2 deletions

43
shared/Exec.c Normal file
View File

@@ -0,0 +1,43 @@
#include "stdafx.h"
#include "Exec.h"
HRESULT Exec(LPWSTR verb, LPWSTR file, LPWSTR params, LPWSTR workingDir, WORD show, BOOL wait, LPDWORD exitCode) {
SHELLEXECUTEINFO execInfo = {0};
execInfo.cbSize = sizeof(execInfo);
execInfo.lpVerb = verb;
execInfo.lpFile = file;
execInfo.lpParameters = params;
execInfo.lpDirectory = workingDir;
execInfo.nShow = show;
return ExecEx(&execInfo, wait, exitCode);
}
HRESULT ExecEx(LPSHELLEXECUTEINFO execInfo, BOOL wait, LPDWORD exitCode) {
if (wait) {
execInfo->fMask |= SEE_MASK_NOCLOSEPROCESS;
}
if (!ShellExecuteEx(execInfo)) {
return HRESULT_FROM_WIN32(GetLastError());
}
HRESULT hr = S_OK;
if (wait) {
if (execInfo->hProcess == NULL) {
TRACE(L"ShellExecuteEx() didn't return a handle: %u", GetLastError());
hr = E_FAIL;
}
WaitForSingleObject(execInfo->hProcess, INFINITE);
if (exitCode != NULL && GetExitCodeProcess(execInfo->hProcess, exitCode) == 0) {
hr = HRESULT_FROM_WIN32(GetLastError());
TRACE(L"GetExitCodeProcess() failed: %p\n", hr);
}
CloseHandle(execInfo->hProcess);
}
return hr;
}

7
shared/Exec.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <windows.h>
#include <shellapi.h>
EXTERN_C HRESULT Exec(LPWSTR verb, LPWSTR file, LPWSTR params, LPWSTR workingDir, WORD show, BOOL wait, LPDWORD exitCode);
EXTERN_C HRESULT ExecEx(LPSHELLEXECUTEINFO execInfo, BOOL wait, LPDWORD exitCode);

36
shared/GetPidForName.c Normal file
View File

@@ -0,0 +1,36 @@
#include "stdafx.h"
#include <psapi.h>
#include "GetPidForName.h"
#pragma comment(lib, "psapi.lib")
DWORD GetPidForName(const LPTSTR process) {
// Yes, eat all of our SHRTs!
DWORD pids[SHRT_MAX];
DWORD bytesReturned;
if (!EnumProcesses(pids, sizeof(pids), &bytesReturned)) {
return 0;
}
DWORD count = bytesReturned / sizeof(DWORD);
for (DWORD i = 0; i < count; ++i) {
HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, pids[i]);
if (handle) {
WCHAR path[MAX_PATH];
if (GetModuleBaseName(handle, NULL, path, ARRAYSIZE(path))) {
LPWSTR basename = wcsrchr(path, L'\\');
if (basename) {
basename += 1;
CharLowerBuffW(basename, (DWORD)wcslen(basename));
if (_wcsicmp(process, basename) == 0) {
CloseHandle(handle);
return pids[i];
}
}
}
CloseHandle(handle);
}
}
return 0;
}

5
shared/GetPidForName.h Normal file
View File

@@ -0,0 +1,5 @@
#pragma once
#include <windows.h>
EXTERN_C DWORD GetPidForName(LPTSTR process);

31
shared/LegacyUpdate.c Normal file
View File

@@ -0,0 +1,31 @@
#include "stdafx.h"
#include <windows.h>
#include "Registry.h"
static LPWSTR _installPath;
EXTERN_C HRESULT GetInstallPath(LPWSTR *path) {
*path = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
HRESULT hr = S_OK;
if (!_installPath) {
DWORD size = 0;
hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\LegacyUpdate", L"InstallLocation", KEY_WOW64_64KEY, &_installPath, &size);
if (SUCCEEDED(hr)) {
lstrcpy(*path, _installPath);
return S_OK;
}
// Do our best to guess where it should be
LPWSTR programFiles;
hr = GetRegistryString(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion", L"ProgramFilesDir", KEY_WOW64_64KEY, &programFiles, &size);
if (SUCCEEDED(hr)) {
_installPath = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
wsprintf(_installPath, L"%ls\\Legacy Update", programFiles);
LocalFree(programFiles);
}
}
lstrcpy(*path, _installPath);
return hr;
}

5
shared/LegacyUpdate.h Normal file
View File

@@ -0,0 +1,5 @@
#pragma once
#include <windows.h>
EXTERN_C HRESULT GetInstallPath(LPWSTR *path);

256
shared/LoadImage.c Normal file
View File

@@ -0,0 +1,256 @@
#include <windows.h>
#include <wincodec.h>
#include <gdiplus.h>
// Adapted from https://faithlife.codes/blog/2008/09/displaying_a_splash_screen_with_c_part_i/
// 1. Get resource as an IStream
// 2. Use Windows Imaging Component to load the PNG
// 3. Convert the WIC bitmap to an HBITMAP
// Why does loading a PNG need to be so difficult?
typedef HRESULT (WINAPI *_WICConvertBitmapSource)(REFWICPixelFormatGUID dstFormat, IWICBitmapSource *pISrc, IWICBitmapSource **ppIDst);
static _WICConvertBitmapSource $WICConvertBitmapSource;
static HGLOBAL GetRawResource(HINSTANCE hInstance, LPWSTR name, LPWSTR type) {
HRSRC resource = FindResource(hInstance, name, type);
if (!resource) {
TRACE(L"FindResource failed: %d", GetLastError());
return NULL;
}
DWORD resourceSize = SizeofResource(hInstance, resource);
HGLOBAL imageHandle = LoadResource(hInstance, resource);
if (!imageHandle) {
TRACE(L"LoadResource failed: %d", GetLastError());
return NULL;
}
LPVOID sourceResourceData = LockResource(imageHandle);
if (!sourceResourceData) {
TRACE(L"LockResource failed: %d", GetLastError());
return NULL;
}
HGLOBAL resourceDataHandle = GlobalAlloc(GMEM_MOVEABLE, resourceSize);
if (!resourceDataHandle) {
TRACE(L"GlobalAlloc failed: %d", GetLastError());
return NULL;
}
LPVOID resourceData = GlobalLock(resourceDataHandle);
if (!resourceData) {
TRACE(L"GlobalLock failed: %d", GetLastError());
GlobalFree(resourceDataHandle);
return NULL;
}
CopyMemory(resourceData, sourceResourceData, resourceSize);
GlobalUnlock(resourceDataHandle);
return resourceDataHandle;
}
static IStream *GetResourceStream(HINSTANCE hInstance, LPWSTR name, LPWSTR type) {
IStream *stream;
HGLOBAL resource = GetRawResource(hInstance, name, type);
if (!resource) {
TRACE(L"GetResource failed: %d", GetLastError());
return NULL;
}
if (SUCCEEDED(CreateStreamOnHGlobal(resource, TRUE, &stream))) {
return stream;
}
GlobalFree(resource);
return NULL;
}
static IWICBitmapSource *GetWICBitmap(IStream *imageStream) {
IWICBitmapSource *bitmap;
IWICBitmapDecoder *decoder;
UINT frameCount;
IWICBitmapFrameDecode *frame;
if (!SUCCEEDED(CoCreateInstance(&CLSID_WICPngDecoder, NULL, CLSCTX_INPROC_SERVER, &IID_IWICBitmapDecoder, (LPVOID *)&decoder))) {
return NULL;
}
if (!SUCCEEDED(IWICBitmapDecoder_Initialize(decoder, imageStream, WICDecodeMetadataCacheOnLoad))) {
goto end;
}
if (!SUCCEEDED(IWICBitmapDecoder_GetFrameCount(decoder, &frameCount)) || frameCount != 1) {
goto end;
}
if (!SUCCEEDED(IWICBitmapDecoder_GetFrame(decoder, 0, &frame))) {
goto end;
}
$WICConvertBitmapSource(&GUID_WICPixelFormat32bppPBGRA, (IWICBitmapSource *)frame, &bitmap);
IWICBitmapFrameDecode_Release(frame);
end:
IWICBitmapDecoder_Release(decoder);
return bitmap;
}
static HBITMAP GetHBitmapForWICBitmap(IWICBitmapSource *bitmap) {
HBITMAP hBitmap;
UINT width, height;
if (!SUCCEEDED(IWICBitmapSource_GetSize(bitmap, &width, &height)) || width == 0 || height == 0) {
return NULL;
}
BITMAPINFO bminfo;
ZeroMemory(&bminfo, sizeof(bminfo));
bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bminfo.bmiHeader.biWidth = width;
bminfo.bmiHeader.biHeight = -(LONG)height;
bminfo.bmiHeader.biPlanes = 1;
bminfo.bmiHeader.biBitCount = 32;
bminfo.bmiHeader.biCompression = BI_RGB;
void *imageBits;
HDC screenDC = GetDC(NULL);
hBitmap = CreateDIBSection(screenDC, &bminfo, DIB_RGB_COLORS, &imageBits, NULL, 0);
ReleaseDC(NULL, screenDC);
if (!hBitmap) {
return NULL;
}
UINT stride = width * 4;
UINT imageSize = stride * height;
if (!SUCCEEDED(IWICBitmapSource_CopyPixels(bitmap, NULL, stride, imageSize, (BYTE*)imageBits))) {
DeleteObject(hBitmap);
return NULL;
}
return hBitmap;
}
HBITMAP LoadPNGResource(HINSTANCE hInstance, LPWSTR resourceName, LPWSTR resourceType) {
if (!$WICConvertBitmapSource) {
$WICConvertBitmapSource = (_WICConvertBitmapSource)GetProcAddress(LoadLibrary(L"windowscodecs.dll"), "WICConvertBitmapSource");
if (!$WICConvertBitmapSource) {
return NULL;
}
}
IStream *imageStream = GetResourceStream(hInstance, resourceName, resourceType);
if (!imageStream) {
TRACE(L"GetResourceStream failed: %d", GetLastError());
return NULL;
}
IWICBitmapSource *bitmap = GetWICBitmap(imageStream);
if (!bitmap) {
TRACE(L"GetWICBitmap failed: %d", GetLastError());
IStream_Release(imageStream);
return NULL;
}
HBITMAP result = GetHBitmapForWICBitmap(bitmap);
IWICBitmapSource_Release(bitmap);
IStream_Release(imageStream);
return result;
}
BOOL ScaleAndWriteToBMP(HBITMAP hBitmap, DWORD width, DWORD height, LPWSTR outputPath) {
BOOL result = FALSE;
if (!hBitmap) {
TRACE(L"Null bitmap");
return FALSE;
}
HDC hdc = GetDC(NULL);
HDC hdcMem = CreateCompatibleDC(hdc);
HBITMAP scaledBitmap = CreateCompatibleBitmap(hdc, width, height);
if (!scaledBitmap) {
TRACE(L"CreateCompatibleBitmap failed: %d", GetLastError());
goto end;
}
BITMAP bmp;
if (!GetObject(hBitmap, sizeof(BITMAP), &bmp)) {
TRACE(L"GetObject failed: %d", GetLastError());
goto end;
}
HBITMAP hOld = (HBITMAP)SelectObject(hdcMem, hBitmap);
HDC hdcMemScaled = CreateCompatibleDC(hdc);
HBITMAP hOldScaled = (HBITMAP)SelectObject(hdcMemScaled, scaledBitmap);
SetStretchBltMode(hdcMemScaled, HALFTONE);
if (!StretchBlt(hdcMemScaled,
0, 0, width, height, hdcMem,
0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY)) {
TRACE(L"StretchBlt failed: %d", GetLastError());
goto end;
}
BITMAPINFOHEADER bmih = {0};
bmih.biSize = sizeof(BITMAPINFOHEADER);
bmih.biWidth = width;
bmih.biHeight = height;
bmih.biPlanes = 1;
bmih.biBitCount = bmp.bmBitsPixel;
bmih.biCompression = BI_RGB;
bmih.biSizeImage = ((width * bmp.bmBitsPixel + 31) / 32) * 4 * height;
BITMAPFILEHEADER bmfh = {0};
bmfh.bfType = 0x4D42;
bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmfh.bfSize = bmfh.bfOffBits + bmih.biSizeImage;
HGLOBAL handle = GlobalAlloc(GMEM_MOVEABLE, bmih.biSizeImage);
if (!handle) {
TRACE(L"GlobalAlloc failed: %d", GetLastError());
goto end;
}
BYTE *bitmapData = (BYTE *)GlobalLock(handle);
if (!bitmapData) {
TRACE(L"GlobalLock failed: %d", GetLastError());
goto end;
}
if (!GetDIBits(hdcMemScaled, scaledBitmap, 0, height, bitmapData, (BITMAPINFO *)&bmih, DIB_RGB_COLORS)) {
TRACE(L"GetDIBits failed: %d", GetLastError());
goto end;
}
HANDLE file = CreateFile(outputPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file == INVALID_HANDLE_VALUE) {
TRACE(L"CreateFile failed: %d", GetLastError());
goto end;
}
DWORD written;
if (!WriteFile(file, &bmfh, sizeof(BITMAPFILEHEADER), &written, NULL) ||
!WriteFile(file, &bmih, sizeof(BITMAPINFOHEADER), &written, NULL) ||
!WriteFile(file, bitmapData, bmih.biSizeImage, &written, NULL)) {
TRACE(L"WriteFile failed: %d", GetLastError());
goto end;
}
result = TRUE;
end:
if (file && file != INVALID_HANDLE_VALUE) {
CloseHandle(file);
}
if (scaledBitmap) {
DeleteObject(scaledBitmap);
}
if (handle) {
GlobalUnlock(handle);
GlobalFree(handle);
}
ReleaseDC(NULL, hdc);
DeleteDC(hdcMem);
DeleteDC(hdcMemScaled);
return result;
}

4
shared/LoadImage.h Normal file
View File

@@ -0,0 +1,4 @@
#include <windows.h>
HBITMAP LoadPNGResource(HINSTANCE hInstance, LPWSTR resourceName, LPWSTR resourceType);
BOOL ScaleAndWriteToBMP(HBITMAP hBitmap, DWORD width, DWORD height, LPWSTR outputPath);

93
shared/Registry.c Normal file
View File

@@ -0,0 +1,93 @@
#include "stdafx.h"
#include "Registry.h"
#include "VersionInfo.h"
#include <malloc.h>
static ALWAYS_INLINE REGSAM GetWow64Flag(REGSAM options) {
#ifdef _WIN64
return options;
#else
if (AtLeastWinXP2002()) {
return options;
}
// Filter out WOW64 keys, which are not supported on Windows 2000
return options & ~(KEY_WOW64_64KEY | KEY_WOW64_32KEY);
#endif
}
HRESULT GetRegistryString(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, REGSAM options, LPWSTR *data, LPDWORD size) {
HKEY subkey;
HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyEx(key, subkeyPath, 0, GetWow64Flag(KEY_READ | options), &subkey));
if (!SUCCEEDED(hr)) {
goto end;
}
if (data) {
DWORD length = 512 * sizeof(WCHAR);
LPWSTR buffer = (LPWSTR)LocalAlloc(LPTR, length);
if (!buffer) {
hr = E_OUTOFMEMORY;
goto end;
}
LSTATUS status;
do {
status = RegQueryValueEx(subkey, valueName, NULL, NULL, (BYTE *)buffer, &length);
if (status == ERROR_MORE_DATA) {
length += 256 * sizeof(WCHAR);
LPWSTR newBuffer = (LPWSTR)LocalReAlloc(buffer, length, LMEM_MOVEABLE);
if (!newBuffer) {
LocalFree(buffer);
hr = E_OUTOFMEMORY;
goto end;
}
buffer = newBuffer;
} else if (status != ERROR_SUCCESS) {
hr = HRESULT_FROM_WIN32(status);
LocalFree(buffer);
goto end;
}
} while (status == ERROR_MORE_DATA);
*data = buffer;
if (size) {
*size = length / sizeof(WCHAR);
}
}
end:
if (subkey) {
RegCloseKey(subkey);
}
if (!SUCCEEDED(hr)) {
if (data) {
*data = NULL;
}
if (size) {
*size = 0;
}
}
return hr;
}
HRESULT GetRegistryDword(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, REGSAM options, LPDWORD data) {
HKEY subkey;
HRESULT hr = HRESULT_FROM_WIN32(RegOpenKeyEx(key, subkeyPath, 0, GetWow64Flag(KEY_READ | options), &subkey));
if (!SUCCEEDED(hr)) {
goto end;
}
if (data) {
DWORD length = sizeof(DWORD);
hr = HRESULT_FROM_WIN32(RegQueryValueEx(subkey, valueName, NULL, NULL, (LPBYTE)data, &length));
}
end:
if (subkey) {
RegCloseKey(subkey);
}
return hr;
}

6
shared/Registry.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include <windows.h>
EXTERN_C HRESULT GetRegistryString(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, REGSAM options, LPWSTR *data, LPDWORD size);
EXTERN_C HRESULT GetRegistryDword(HKEY key, LPCWSTR subkeyPath, LPCWSTR valueName, REGSAM options, LPDWORD data);

45
shared/Startup.h Normal file
View File

@@ -0,0 +1,45 @@
#pragma once
#include <windows.h>
typedef void (WINAPI *_SetDefaultDllDirectories)(DWORD DirectoryFlags);
typedef BOOL (WINAPI *_SetDllDirectoryW)(LPWSTR);
static inline void HardenDllSearchPaths() {
// Try our best to secure DLL search paths to just system32
WCHAR path[MAX_PATH];
// Reset %windir% and %SystemRoot%
GetWindowsDirectory(path, ARRAYSIZE(path));
SetEnvironmentVariable(L"WINDIR", path);
SetEnvironmentVariable(L"SystemRoot", path);
// Reset %PATH% to just system32
ZeroMemory(path, sizeof(path));
GetSystemDirectory(path, ARRAYSIZE(path));
SetEnvironmentVariable(L"PATH", path);
wcscat(path, L"\\kernel32.dll");
HMODULE kernel32 = GetModuleHandle(path);
if (!kernel32) {
return;
}
// Windows Vista SP2+/7 SP1+ with KB2533623
_SetDefaultDllDirectories $SetDefaultDllDirectories = (_SetDefaultDllDirectories)GetProcAddress(kernel32, "SetDefaultDllDirectories");
if ($SetDefaultDllDirectories) {
$SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_SYSTEM32);
return;
}
// Windows XP SP1+
_SetDllDirectoryW $SetDllDirectoryW = (_SetDllDirectoryW)GetProcAddress(kernel32, "SetDllDirectoryW");
if ($SetDllDirectoryW) {
$SetDllDirectoryW(L"");
return;
}
}
static inline void Startup() {
HardenDllSearchPaths();
}

16
shared/Trace.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#if defined(ATLTRACE)
#define TRACE ATLTRACE
#elif defined(_DEBUG)
// Yeah, sue me lol
#define TRACE(...) { \
LPWSTR __traceMsg = (LPWSTR)LocalAlloc(LPTR, 4096 * sizeof(WCHAR)); \
wsprintf(__traceMsg, L"%hs(%d): %hs: ", __FILE__, __LINE__, __FUNCTION__); \
wsprintf(__traceMsg + wcslen(__traceMsg), __VA_ARGS__); \
MessageBox(NULL, __traceMsg, L"Debug", MB_OK); \
LocalFree(__traceMsg); \
}
#else
#define TRACE(...)
#endif

20
shared/User.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
#include <windows.h>
static inline BOOL IsUserAdmin() {
SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
PSID adminsSid;
BOOL result = FALSE;
if (!AllocateAndInitializeSid(&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminsSid)) {
return FALSE;
}
if (!CheckTokenMembership(NULL, adminsSid, &result)) {
result = FALSE;
}
FreeSid(adminsSid);
return result;
}

6
shared/Version.h Normal file
View File

@@ -0,0 +1,6 @@
#define VERSION_MAJOR 1
#define VERSION_MINOR 11
#define VERSION_PATCH 0
#define VERSION_BUILD 0
#define VERSION_STRING "1.11"

44
shared/VersionInfo.c Normal file
View File

@@ -0,0 +1,44 @@
#include "stdafx.h"
#include "VersionInfo.h"
static BOOL _loadedOwnVersion = FALSE;
static LPWSTR _version;
HRESULT GetOwnVersion(LPWSTR *version) {
if (!_loadedOwnVersion) {
_loadedOwnVersion = TRUE;
LPWSTR filename;
GetOwnFileName(&filename);
DWORD verHandle;
DWORD verInfoSize = GetFileVersionInfoSize(filename, &verHandle);
if (verInfoSize == 0) {
LocalFree(filename);
return HRESULT_FROM_WIN32(GetLastError());
}
LPVOID verInfo = LocalAlloc(LPTR, verInfoSize);
if (!GetFileVersionInfo(filename, verHandle, verInfoSize, verInfo)) {
LocalFree(filename);
LocalFree(verInfo);
return HRESULT_FROM_WIN32(GetLastError());
}
LocalFree(filename);
LPWSTR value;
UINT size;
if (!VerQueryValue(verInfo, L"\\StringFileInfo\\040904B0\\ProductVersion", (LPVOID *)&value, &size)) {
LocalFree(verInfo);
return HRESULT_FROM_WIN32(GetLastError());
}
_version = (LPWSTR)LocalAlloc(LPTR, (wcslen(value) + 1) * sizeof(WCHAR));
wcscpy(_version, value);
LocalFree(verInfo);
}
*version = _version;
return _version == NULL ? E_FAIL : S_OK;
}

79
shared/WMI.c Normal file
View File

@@ -0,0 +1,79 @@
#include "stdafx.h"
#include "WMI.h"
#include <wbemcli.h>
#pragma comment(lib, "wbemuuid.lib")
#ifdef __cplusplus
#define our_CLSID_WbemLocator CLSID_WbemLocator
#define our_IID_IWbemLocator IID_IWbemLocator
#define IWbemLocator_ConnectServer(obj, ...) obj->ConnectServer(__VA_ARGS__)
#define IWbemServices_ExecQuery(obj, ...) obj->ExecQuery(__VA_ARGS__)
#define IEnumWbemClassObject_Next(obj, ...) obj->Next(__VA_ARGS__)
#define IWbemClassObject_Get(obj, ...) obj->Get(__VA_ARGS__)
#define IWbemClassObject_Release(obj) obj->Release()
#define IEnumWbemClassObject_Release(obj) obj->Release()
#define IWbemServices_Release(obj) obj->Release()
#define IWbemLocator_Release(obj) obj->Release()
#else
#define our_CLSID_WbemLocator &CLSID_WbemLocator
#define our_IID_IWbemLocator &IID_IWbemLocator
#endif
HRESULT QueryWMIProperty(LPWSTR query, LPWSTR property, LPVARIANT value) {
IWbemLocator *locator = NULL;
IWbemServices *services = NULL;
IEnumWbemClassObject *enumerator = NULL;
IWbemClassObject *object = NULL;
HRESULT hr = CoCreateInstance(our_CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, our_IID_IWbemLocator, (void **)&locator);
if (!SUCCEEDED(hr)) {
goto end;
}
BSTR server = SysAllocString(L"ROOT\\CIMV2");
hr = IWbemLocator_ConnectServer(locator, server, NULL, NULL, NULL, 0, NULL, NULL, &services);
SysFreeString(server);
if (!SUCCEEDED(hr)) {
goto end;
}
hr = CoSetProxyBlanket((IUnknown *)services, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if (!SUCCEEDED(hr)) {
goto end;
}
BSTR wql = SysAllocString(L"WQL");
BSTR queryBstr = SysAllocString(query);
hr = IWbemServices_ExecQuery(services, wql, queryBstr, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &enumerator);
SysFreeString(wql);
SysFreeString(queryBstr);
if (!SUCCEEDED(hr)) {
goto end;
}
ULONG uReturn = 0;
hr = IEnumWbemClassObject_Next(enumerator, WBEM_INFINITE, 1, &object, &uReturn);
if (!SUCCEEDED(hr)) {
goto end;
}
BSTR propBstr = SysAllocString(property);
hr = IWbemClassObject_Get(object, propBstr, 0, value, NULL, NULL);
SysFreeString(propBstr);
end:
if (object) {
IWbemClassObject_Release(object);
}
if (enumerator) {
IEnumWbemClassObject_Release(enumerator);
}
if (services) {
IWbemServices_Release(services);
}
if (locator) {
IWbemLocator_Release(locator);
}
return hr;
}

44
shared/WULog.h Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include "stdafx.h"
#include <windows.h>
#include <shlobj.h>
#include "Exec.h"
#include "HResult.h"
#include "VersionInfo.h"
static inline HRESULT ViewWindowsUpdateLog(int nCmdShow) {
WCHAR windir[MAX_PATH];
HRESULT hr = SHGetFolderPath(0, CSIDL_WINDOWS, NULL, 0, windir);
if (!SUCCEEDED(hr)) {
TRACE(L"SHGetFolderPath() failed: %ls\n", GetMessageForHresult(hr));
return hr;
}
LPWSTR workDir = windir;
if (AtLeastWin10()) {
// Windows 10 moves WU/USO logs to ETW. The ETW logs can be converted back to a plain-text .log
// using a cmdlet.
WCHAR powershell[MAX_PATH];
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", powershell, ARRAYSIZE(powershell));
DWORD code;
HRESULT hr = Exec(NULL, powershell, L"-Command Get-WindowsUpdateLog", windir, nCmdShow, TRUE, &code);
if (!SUCCEEDED(hr) || code != 0) {
return hr;
}
// On success, the log is written to Desktop\WindowsUpdate.log.
WCHAR desktop[MAX_PATH];
hr = SHGetFolderPath(0, CSIDL_DESKTOP, NULL, 0, desktop);
if (!SUCCEEDED(hr)) {
TRACE(L"SHGetFolderPath() failed: %ls\n", GetMessageForHresult(hr));
return hr;
}
workDir = desktop;
}
return Exec(L"open", L"WindowsUpdate.log", NULL, workDir, nCmdShow, FALSE, NULL);
}

45
shared/Wow64.c Normal file
View File

@@ -0,0 +1,45 @@
#include "stdafx.h"
#include "Wow64.h"
typedef BOOL (WINAPI *_Wow64DisableWow64FsRedirection)(PVOID *OldValue);
typedef BOOL (WINAPI *_Wow64RevertWow64FsRedirection)(PVOID OldValue);
static BOOL _loadedWow64;
static _Wow64DisableWow64FsRedirection $Wow64DisableWow64FsRedirection;
static _Wow64RevertWow64FsRedirection $Wow64RevertWow64FsRedirection;
#if _WIN64
// Not needed
#define DisableWow64FsRedirection(OldValue) TRUE
#define RevertWow64FsRedirection(OldValue) TRUE
#else
static void LoadWow64Symbols() {
if (!_loadedWow64) {
_loadedWow64 = TRUE;
HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");
$Wow64DisableWow64FsRedirection = (_Wow64DisableWow64FsRedirection)GetProcAddress(kernel32, "Wow64DisableWow64FsRedirection");
$Wow64RevertWow64FsRedirection = (_Wow64RevertWow64FsRedirection)GetProcAddress(kernel32, "Wow64RevertWow64FsRedirection");
}
}
BOOL DisableWow64FsRedirection(PVOID *OldValue) {
LoadWow64Symbols();
if ($Wow64DisableWow64FsRedirection) {
return $Wow64DisableWow64FsRedirection(OldValue);
} else {
return TRUE;
}
}
BOOL RevertWow64FsRedirection(PVOID OldValue) {
LoadWow64Symbols();
if ($Wow64RevertWow64FsRedirection) {
return $Wow64RevertWow64FsRedirection(OldValue);
} else {
return TRUE;
}
}
#endif

6
shared/Wow64.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include <windows.h>
BOOL DisableWow64FsRedirection(PVOID *OldValue);
BOOL RevertWow64FsRedirection(PVOID OldValue);