windows-nt/Source/XPSP1/NT/enduser/windows.com/wuau/wuaueng/tscompat.cpp
2020-09-26 16:20:57 +08:00

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;
}