CreateProcessAsUser fails with ERROR_ELEVATION_REQUIRED for a process with UIAccess="true"

StackOverflow https://stackoverflow.com/questions/23209760

  •  07-07-2023
  •  | 
  •  

سؤال

I'm trying to use the following code to run a user-mode process from my service application (running as a local system.)

The requirement for the user-mode process is to run without elevatation, but to have UIAccess="true" in its manifest to be able to display top-most windows correctly under Windows 8.

So I do this (from my service) to run my user-mode process:

//NOTE: Error checking is omitted for readability
//'dwSessionID' = user session ID to run user-mode process in
//'pUserProcPath' = L"C:\\Program Files (x86)\\Company\\Software\\user_process.exe"

HANDLE hToken = NULL;
WTSQueryUserToken(dwSessionID, &hToken);

HANDLE hToken2;
DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hToken2);

LPVOID pEnvBlock = NULL;
CreateEnvironmentBlock(&pEnvBlock, hToken2, FALSE);

STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = L"winsta0\\default";

PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));

//ImpersonateLoggedOnUser(hToken2);   //Not necessary as suggested below

PVOID OldRedir;
Wow64DisableWow64FsRedirection(&OldRedir);

BOOL bSuccess = CreateProcessAsUser(
    hToken2,           // client's access token
    pUserProcPath,     // file to execute
    NULL,              // command line
    NULL,              // pointer to process SECURITY_ATTRIBUTES
    NULL,              // pointer to thread SECURITY_ATTRIBUTES
    FALSE,             // handles are not inheritable
    NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,   // creation flags
    pEnvBlock,         // pointer to new environment block 
    NULL,              // name of current directory 
    &si,               // pointer to STARTUPINFO structure
    &pi                // receives information about new process
    );

int nOSError = ::GetLastError();

Wow64RevertWow64FsRedirection(OldRedir);
//RevertToSelf();       //Not necessary as suggested below

CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
DestroyEnvironmentBlock(pEnvBlock);
CloseHandle(hToken2);
CloseHandle(hToken);

This runs fine, if UIAccess="false" in the manifest for the user_process.exe.

But if I do the following:

  • Enable UIAccess="true" for the user_process.exe:

enter image description here

  • Sign it with my code-signing certificate and

  • Place it in the "C:\Program Files (x86)\Company\Software" folder.

What I get is that CreateProcessAsUser fails with the error ERROR_ELEVATION_REQUIRED.

Can someone suggest how to make it work?

PS. I tried adjusting my service's privileges to enable SE_DEBUG_NAME and SE_TCB_NAME, but neither helped.

PS2. If I simply double-click my user_process.exe process compiled with UIAccess="true", code-signed, and placed in the C:\Program Files (x86)\Company\Software folder, it starts & runs just fine (not elevated.).

هل كانت مفيدة؟

المحلول

I found the answer. Here it is for whoever runs into it as well:

Add this after DuplicateTokenEx call:

HANDLE hToken2;
DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hToken2);

//ONLY if requiring UIAccess!
DWORD dwUIAccess = 1;
::SetTokenInformation(hToken2, TokenUIAccess, &dwUIAccess, sizeof(dwUIAccess));
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top