From 897bcd5d5c6b12d6e69c2a688cfcfd4d42fd1ea0 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Mon, 4 Mar 2024 20:14:29 -0600 Subject: [PATCH] ntdll: Elevate processes if requested in the manifest. Rufus 3.13 Portable requires administrator privileges, and uses a manifest to elevate itself. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51000 --- dlls/ntdll/loader.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index cf9f4ac9a84..765fb5b1617 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -35,6 +35,7 @@ #include "wine/debug.h" #include "wine/list.h" #include "ntdll_misc.h" +#include "ddk/ntddk.h" #include "ddk/wdm.h" WINE_DEFAULT_DEBUG_CHANNEL(module); @@ -4104,7 +4105,40 @@ static void load_global_options(void) } } +static BOOL needs_elevation(void) +{ + ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION run_level; + if (!RtlQueryInformationActivationContext( 0, NULL, NULL, RunlevelInformationInActivationContext, + &run_level, sizeof(run_level), NULL )) + { + TRACE( "image requested run level %#x\n", run_level.RunLevel ); + if (run_level.RunLevel == ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE + || run_level.RunLevel == ACTCTX_RUN_LEVEL_REQUIRE_ADMIN) + return TRUE; + } + return FALSE; +} + +static void elevate_token(void) +{ + PROCESS_ACCESS_TOKEN token; + TOKEN_ELEVATION_TYPE type; + TOKEN_LINKED_TOKEN linked; + + NtQueryInformationToken( GetCurrentThreadEffectiveToken(), + TokenElevationType, &type, sizeof(type), NULL ); + + if (type == TokenElevationTypeFull) return; + + NtQueryInformationToken( GetCurrentThreadEffectiveToken(), + TokenLinkedToken, &linked, sizeof(linked), NULL ); + + token.Thread = NULL; + token.Token = linked.LinkedToken; + NtSetInformationProcess( GetCurrentProcess(), ProcessAccessToken, &token, sizeof(token) ); + NtClose( linked.LinkedToken ); +} #ifdef _WIN64 @@ -4290,6 +4324,8 @@ void loader_init( CONTEXT *context, void **entry ) actctx_init(); locale_init(); + if (needs_elevation()) + elevate_token(); get_env_var( L"WINESYSTEMDLLPATH", 0, &system_dll_path ); if (wm->ldr.Flags & LDR_COR_ILONLY) status = fixup_imports_ilonly( wm, NULL, entry );