Commit 8cc22a60 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

shell32: Elevate the child process for the "runas" verb.

Like all other verbs, the actual command line template is specified in the registry. The elevation seems to be hardcoded into shell32 for this specific verb. The Foobar2000 installer requires administrator privileges, and elevates itself in this way. Based on a patch by Michael Müller. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50727
parent ec6879b7
...@@ -293,6 +293,21 @@ static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR psz ...@@ -293,6 +293,21 @@ static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR psz
return hr; return hr;
} }
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;
}
/************************************************************************* /*************************************************************************
* SHELL_ExecuteW [Internal] * SHELL_ExecuteW [Internal]
* *
...@@ -306,6 +321,7 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, ...@@ -306,6 +321,7 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
UINT gcdret = 0; UINT gcdret = 0;
WCHAR curdir[MAX_PATH]; WCHAR curdir[MAX_PATH];
DWORD dwCreationFlags; DWORD dwCreationFlags;
HANDLE token = NULL;
TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory)); TRACE("Execute %s from directory %s\n", debugstr_w(lpCmd), debugstr_w(psei->lpDirectory));
...@@ -327,8 +343,12 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, ...@@ -327,8 +343,12 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
dwCreationFlags = CREATE_UNICODE_ENVIRONMENT; dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;
if (!(psei->fMask & SEE_MASK_NO_CONSOLE)) if (!(psei->fMask & SEE_MASK_NO_CONSOLE))
dwCreationFlags |= CREATE_NEW_CONSOLE; dwCreationFlags |= CREATE_NEW_CONSOLE;
if (CreateProcessW(NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE, dwCreationFlags, env,
NULL, &startup, &info)) if (psei->lpVerb && !wcsicmp(psei->lpVerb, L"runas"))
token = get_admin_token();
if (CreateProcessAsUserW(token, NULL, (LPWSTR)lpCmd, NULL, NULL, FALSE,
dwCreationFlags, env, NULL, &startup, &info))
{ {
/* Give 30 seconds to the app to come up, if desired. Probably only needed /* Give 30 seconds to the app to come up, if desired. Probably only needed
when starting app immediately before making a DDE connection. */ when starting app immediately before making a DDE connection. */
...@@ -348,6 +368,8 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, ...@@ -348,6 +368,8 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
retval = ERROR_BAD_FORMAT; retval = ERROR_BAD_FORMAT;
} }
CloseHandle(token);
TRACE("returning %Iu\n", retval); TRACE("returning %Iu\n", retval);
psei_out->hInstApp = (HINSTANCE)retval; psei_out->hInstApp = (HINSTANCE)retval;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment