136 lines
3.8 KiB
C++
136 lines
3.8 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 2001.
|
|
//
|
|
// tscompat.cpp
|
|
//
|
|
// This module include functions that were introduced to replace missing
|
|
// functions/functionality from Windows XP to Windows 2000.
|
|
//
|
|
// 10/11/2001 annah Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#include "tscompat.h"
|
|
#include "service.h"
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Replacements for TS functions
|
|
//----------------------------------------------------------------------------
|
|
|
|
//
|
|
// Copied from TS sources, as this function is not available on the
|
|
// win2k wtsapi32.dll. The function has the same functionality as WTSQueryUserToken().
|
|
//
|
|
BOOL WINAPI _WTSQueryUserToken(/* in */ ULONG SessionId, /* out */ PHANDLE phToken)
|
|
{
|
|
BOOL IsTsUp = FALSE;
|
|
BOOL Result, bHasPrivilege;
|
|
ULONG ReturnLength;
|
|
WINSTATIONUSERTOKEN Info;
|
|
HANDLE hUserToken = NULL;
|
|
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
|
|
|
|
// Do parameter Validation
|
|
if (NULL == phToken) {
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return(FALSE);
|
|
}
|
|
|
|
// If it is session 0, don't call winsta. Use GetCurrentUserToken instead.
|
|
if (SessionId == 0)
|
|
{
|
|
hUserToken = GetCurrentUserTokenW(L"WinSta0",
|
|
TOKEN_QUERY |
|
|
TOKEN_DUPLICATE |
|
|
TOKEN_ASSIGN_PRIMARY
|
|
);
|
|
|
|
if (hUserToken == NULL)
|
|
return FALSE;
|
|
else
|
|
*phToken = hUserToken;
|
|
}
|
|
else // Non-zero sessions
|
|
{
|
|
// No one except TS has any idea about non-zero sessions. So, check if the TS is running.
|
|
IsTsUp = _IsTerminalServiceRunning();
|
|
if (IsTsUp)
|
|
{ // This is so that CSRSS can dup the handle to our process
|
|
Info.ProcessId = LongToHandle(GetCurrentProcessId());
|
|
Info.ThreadId = LongToHandle(GetCurrentThreadId());
|
|
|
|
Result = WinStationQueryInformation(
|
|
SERVERNAME_CURRENT,
|
|
SessionId,
|
|
WinStationUserToken,
|
|
&Info,
|
|
sizeof(Info),
|
|
&ReturnLength
|
|
);
|
|
|
|
if( !Result )
|
|
return FALSE;
|
|
else
|
|
*phToken = Info.UserToken ;
|
|
}
|
|
else
|
|
{ // TS is not running. So, set error for non-zero sessions: WINSTATION_NOT_FOUND.
|
|
SetLastError(ERROR_CTX_WINSTATION_NOT_FOUND);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// This function determines if the Terminal Service is currently Running.
|
|
// Copied from TS sources, as it is required on the _WTSQueryUserToken() function.
|
|
//
|
|
BOOL _IsTerminalServiceRunning (VOID)
|
|
{
|
|
|
|
BOOL bReturn = FALSE;
|
|
SC_HANDLE hServiceController;
|
|
|
|
hServiceController = OpenSCManager(NULL, NULL, GENERIC_READ);
|
|
if (hServiceController)
|
|
{
|
|
SC_HANDLE hTermServ ;
|
|
hTermServ = OpenService(hServiceController, L"TermService", SERVICE_QUERY_STATUS);
|
|
if (hTermServ)
|
|
{
|
|
SERVICE_STATUS tTermServStatus;
|
|
if (QueryServiceStatus(hTermServ, &tTermServStatus))
|
|
{
|
|
bReturn = (tTermServStatus.dwCurrentState == SERVICE_RUNNING);
|
|
}
|
|
else
|
|
{
|
|
CloseServiceHandle(hTermServ);
|
|
CloseServiceHandle(hServiceController);
|
|
return FALSE;
|
|
}
|
|
|
|
CloseServiceHandle(hTermServ);
|
|
}
|
|
else
|
|
{
|
|
CloseServiceHandle(hServiceController);
|
|
return FALSE;
|
|
}
|
|
CloseServiceHandle(hServiceController);
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return bReturn;
|
|
}
|
|
|