Test
This commit is contained in:
153
launcher/RegisterServer.c
Normal file
153
launcher/RegisterServer.c
Normal file
@@ -0,0 +1,153 @@
|
||||
#include <windows.h>
|
||||
#include "Exec.h"
|
||||
#include "HResult.h"
|
||||
#include "LegacyUpdate.h"
|
||||
#include "MsgBox.h"
|
||||
#include "Registry.h"
|
||||
#include "SelfElevate.h"
|
||||
#include "User.h"
|
||||
#include "VersionInfo.h"
|
||||
#include "Wow64.h"
|
||||
|
||||
static HRESULT RegisterDllInternal(LPWSTR path, BOOL state) {
|
||||
HMODULE module = LoadLibrary(path);
|
||||
if (!module) {
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
FARPROC proc = GetProcAddress(module, state ? "DllRegisterServer" : "DllUnregisterServer");
|
||||
if (!proc) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = ((HRESULT (WINAPI *)())proc)();
|
||||
|
||||
end:
|
||||
if (module) {
|
||||
FreeLibrary(module);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT RegisterDllExternal(LPWSTR path, BOOL state) {
|
||||
WCHAR regsvr32[MAX_PATH];
|
||||
ExpandEnvironmentStrings(L"%SystemRoot%\\System32\\regsvr32.exe", regsvr32, ARRAYSIZE(regsvr32));
|
||||
|
||||
LPWSTR args = (LPWSTR)LocalAlloc(LPTR, (lstrlen(path) + 6) * sizeof(WCHAR));
|
||||
wsprintf(args, L"/s %ls\"%ls\"", state ? L"" : L"/u ", path);
|
||||
|
||||
DWORD status;
|
||||
HRESULT hr = Exec(NULL, regsvr32, args, NULL, SW_HIDE, TRUE, &status);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (status != 0) {
|
||||
// Run again without /s, so the user can see the error
|
||||
wsprintf(args, L"%ls\"%ls\"", state ? L"" : L"/u ", path);
|
||||
hr = Exec(NULL, regsvr32, args, NULL, SW_SHOWDEFAULT, TRUE, &status);
|
||||
}
|
||||
|
||||
return status == 0 ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
HRESULT RegisterServer(HWND hwnd, BOOL state, BOOL forLaunch) {
|
||||
// Ensure elevation
|
||||
HRESULT hr = S_OK;
|
||||
LPWSTR installPath;
|
||||
LPWSTR dllPath;
|
||||
|
||||
if (!IsUserAdmin()) {
|
||||
LPWSTR args = (LPWSTR)LocalAlloc(LPTR, 512 * sizeof(WCHAR));
|
||||
wsprintf(args, L"%ls %i", state ? L"/regserver" : L"/unregserver", hwnd);
|
||||
DWORD code;
|
||||
hr = SelfElevate(args, &code);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
// Ignore error on cancelling UAC dialog
|
||||
if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED)) {
|
||||
hr = S_OK;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = HRESULT_FROM_WIN32(code);
|
||||
goto end;
|
||||
}
|
||||
|
||||
hr = GetInstallPath(&installPath);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
dllPath = (LPWSTR)LocalAlloc(LPTR, MAX_PATH * sizeof(WCHAR));
|
||||
wsprintf(dllPath, L"%ls\\LegacyUpdate.dll", installPath);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Warn if registration path differs, to help with debugging
|
||||
LPWSTR currentPath;
|
||||
hr = GetRegistryString(HKEY_CLASSES_ROOT, L"CLSID\\{AD28E0DF-5F5A-40B5-9432-85EFD97D1F9F}\\InprocServer32", NULL, KEY_WOW64_64KEY, ¤tPath, NULL);
|
||||
if (SUCCEEDED(hr) && wcscmp(currentPath, dllPath) != 0) {
|
||||
if (MsgBox(hwnd, L"DEBUG: Native dll currently registered at a different path. Override?", currentPath, MB_YESNO) != IDYES) {
|
||||
hr = S_OK;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hr = RegisterDllInternal(dllPath, state);
|
||||
if (!SUCCEEDED(hr)) {
|
||||
// Try external registration
|
||||
if (SUCCEEDED(RegisterDllExternal(dllPath, state))) {
|
||||
hr = S_OK;
|
||||
} else {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
#if _WIN64
|
||||
if (!SUCCEEDED(hr)) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
wsprintf(dllPath, L"%ls\\LegacyUpdate32.dll", installPath);
|
||||
|
||||
#ifdef _DEBUG
|
||||
// Warn if registration path differs, to help with debugging
|
||||
hr = GetRegistryString(HKEY_CLASSES_ROOT, L"CLSID\\{AD28E0DF-5F5A-40B5-9432-85EFD97D1F9F}\\InprocServer32", NULL, KEY_WOW64_32KEY, ¤tPath, NULL);
|
||||
if (SUCCEEDED(hr) && wcscmp(currentPath, dllPath) != 0) {
|
||||
if (MsgBox(hwnd, L"DEBUG: 32-bit dll currently registered at a different path. Override?", currentPath, MB_YESNO) != IDYES) {
|
||||
hr = S_OK;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hr = RegisterDllExternal(dllPath, state);
|
||||
#endif
|
||||
|
||||
end:
|
||||
if (installPath) {
|
||||
LocalFree(installPath);
|
||||
}
|
||||
|
||||
if (dllPath) {
|
||||
LocalFree(dllPath);
|
||||
}
|
||||
|
||||
if (!SUCCEEDED(hr)) {
|
||||
LPWSTR title = state
|
||||
? L"Failed to register Legacy Update ActiveX control"
|
||||
: L"Failed to unregister Legacy Update ActiveX control";
|
||||
MsgBox(hwnd, title, GetMessageForHresult(hr), MB_ICONERROR);
|
||||
}
|
||||
|
||||
if (!forLaunch) {
|
||||
PostQuitMessage(hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
Reference in New Issue
Block a user