From: Zebediah Figura z.figura12@gmail.com
Dragon Naturally Speaking 12.5 manually validates that the custom action server is elevated.
One might imagine that the right approach here is to add a manifest to msiexec; however, msiexec does not always trigger a UAC prompt on Windows.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51143 --- dlls/msi/custom.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index d1e064f5b65..12a7c3c3676 100644 --- a/dlls/msi/custom.c +++ b/dlls/msi/custom.c @@ -573,12 +573,28 @@ UINT CDECL __wine_msi_call_dll_function(DWORD client_pid, const GUID *guid) return r; }
+static HANDLE get_admin_token(void) +{ + TOKEN_ELEVATION_TYPE type; + TOKEN_LINKED_TOKEN linked; + DWORD size; + + if (!GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenElevationType, &type, sizeof(type), &size) + || type == TokenElevationTypeFull) + return NULL; + + if (!GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenLinkedToken, &linked, sizeof(linked), &size)) + return NULL; + return linked.LinkedToken; +} + static DWORD custom_start_server(MSIPACKAGE *package, DWORD arch) { WCHAR path[MAX_PATH], cmdline[MAX_PATH + 23]; PROCESS_INFORMATION pi = {0}; STARTUPINFOW si = {0}; WCHAR buffer[24]; + HANDLE token; void *cookie; HANDLE pipe;
@@ -600,14 +616,18 @@ static DWORD custom_start_server(MSIPACKAGE *package, DWORD arch) lstrcatW(path, L"\msiexec.exe"); swprintf(cmdline, ARRAY_SIZE(cmdline), L"%s -Embedding %d", path, GetCurrentProcessId());
+ token = get_admin_token(); + if (is_wow64 && arch == SCS_64BIT_BINARY) { Wow64DisableWow64FsRedirection(&cookie); - CreateProcessW(path, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + CreateProcessAsUserW(token, path, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); Wow64RevertWow64FsRedirection(cookie); } else - CreateProcessW(path, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + CreateProcessAsUserW(token, path, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); + + if (token) CloseHandle(token);
CloseHandle(pi.hThread);