From: Katharina Bogad <katharina@hacked.xyz> Services run in a non-interactive session by default; this session is also not enumeratable in WTSEnumerateSessions. Previously, the first part was handled by overwriting the winstation to __wineservice_winstation\Default while leaving the session id to the default 1. Change the default service session to session id 0 when starting a service and fixup WTSEnumerateSessions to never return the service session id. --- dlls/wtsapi32/wtsapi32.c | 7 ++----- programs/services/services.c | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/dlls/wtsapi32/wtsapi32.c b/dlls/wtsapi32/wtsapi32.c index 0a2e25bb9cd..92a4dcdf5b7 100644 --- a/dlls/wtsapi32/wtsapi32.c +++ b/dlls/wtsapi32/wtsapi32.c @@ -351,6 +351,7 @@ BOOL WINAPI WTSEnumerateSessionsW(HANDLE server, DWORD reserved, DWORD version, static const WCHAR session_name[] = L"Console"; FIXME("%p 0x%08lx 0x%08lx %p %p semi-stub.\n", server, reserved, version, session_info, count); + FIXME("Always returning default session id / name\n"); if (!session_info || !count) return FALSE; @@ -359,11 +360,7 @@ BOOL WINAPI WTSEnumerateSessionsW(HANDLE server, DWORD reserved, DWORD version, SetLastError(ERROR_OUTOFMEMORY); return FALSE; } - if (!ProcessIdToSessionId( GetCurrentProcessId(), &(*session_info)->SessionId)) - { - WTSFreeMemory(*session_info); - return FALSE; - } + (*session_info)->SessionId = 1 /* default_session_id, server/process.h */; *count = 1; (*session_info)->State = WTSActive; (*session_info)->pWinStationName = (WCHAR *)((char *)*session_info + sizeof(**session_info)); diff --git a/programs/services/services.c b/programs/services/services.c index dff3cd60040..933e8bb2689 100644 --- a/programs/services/services.c +++ b/programs/services/services.c @@ -918,7 +918,7 @@ static DWORD service_start_process(struct service_entry *service_entry, struct p BOOL is_wow64 = FALSE; HANDLE token; WCHAR *path; - DWORD err; + DWORD err, service_session_id = 0; BOOL r; service_lock(service_entry); @@ -1028,7 +1028,10 @@ found: si.lpDesktop = (WCHAR *)L"__wineservice_winstation\\Default"; } - if (!environment && OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &token)) + r = DuplicateHandle(GetCurrentProcess(), GetCurrentProcessToken(), + GetCurrentProcess(), &token, 0, FALSE, DUPLICATE_SAME_ACCESS); + TRACE("DuplicateHandle %u %lu\n", r, GetLastError()); + if (!environment && r ) { WCHAR val[16]; CreateEnvironmentBlock(&environment, token, FALSE); @@ -1040,7 +1043,6 @@ found: RtlInitUnicodeString( &value, val ); RtlSetEnvironmentVariable( (WCHAR **)&environment, &name, &value ); } - CloseHandle(token); } service_entry->status.dwCurrentState = SERVICE_START_PENDING; @@ -1053,8 +1055,19 @@ found: process->use_count++; service_unlock(service_entry); - r = CreateProcessW(NULL, path, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS, environment, NULL, &si, &pi); + r = SetTokenInformation(token, TokenSessionId, &service_session_id, sizeof(service_session_id)); + + if(!r) + { + err = GetLastError(); + process_terminate(process); + release_process(process); + return err; + } + + r = CreateProcessAsUserW(token, NULL, path, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS, environment, NULL, &si, &pi); free(path); + CloseHandle(token); if (!r) { err = GetLastError(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9843