You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
778 lines
21 KiB
778 lines
21 KiB
//Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// EnCliSvr.cpp : Implementation of CTlntSvrApp and DLL registration.
|
|
|
|
#include <stdafx.h>
|
|
#include <oleauto.h>
|
|
|
|
#include <Debug.h>
|
|
#include <KillApps.h>
|
|
#include <TlntSvr.h>
|
|
#include <TelntSrv.h>
|
|
#include <EnumData.h>
|
|
#include <EnCliSvr.h>
|
|
#include <TlntUtils.h>
|
|
#include <Ipc.h>
|
|
#include <w4warn.h>
|
|
|
|
// Don't even think about changing the two strings -- BaskarK, they NEED to be in sync with tnadmin\tnadmutl.cpp
|
|
// the separators used to identify various portions of a session as well as session begin/end
|
|
|
|
WCHAR *session_separator = L",";
|
|
WCHAR *session_data_separator = L"\\";
|
|
|
|
boolean called_by_an_admin()
|
|
{
|
|
static PSID administrators = NULL;
|
|
boolean an_admin = false;
|
|
HANDLE token;
|
|
|
|
if (NULL == administrators)
|
|
{
|
|
SID_IDENTIFIER_AUTHORITY local_system_authority = SECURITY_NT_AUTHORITY;
|
|
|
|
//Build administrators alias sid
|
|
if (! AllocateAndInitializeSid(
|
|
&local_system_authority,
|
|
2, /* there are only two sub-authorities */
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0,0,0,0,0,0, /* Don't care about the rest */
|
|
&administrators
|
|
))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (OpenThreadToken(
|
|
GetCurrentThread(),
|
|
TOKEN_QUERY | MAXIMUM_ALLOWED,
|
|
TRUE,
|
|
& token
|
|
))
|
|
{
|
|
TOKEN_GROUPS *tg = NULL;
|
|
DWORD required = 2048; // 2K should be good enough for starters
|
|
DWORD error = NO_ERROR;
|
|
|
|
|
|
for (;;)
|
|
{
|
|
tg = (TOKEN_GROUPS *) new BYTE[required];
|
|
if (! tg)
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (GetTokenInformation(token, TokenGroups, (LPVOID) tg, required, & required))
|
|
{
|
|
error = NO_ERROR;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
error = GetLastError();
|
|
|
|
if (ERROR_INSUFFICIENT_BUFFER != error)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
delete [] tg;
|
|
}
|
|
|
|
if (tg && (NO_ERROR == error))
|
|
{
|
|
DWORD x;
|
|
|
|
for (x = 0; x < tg->GroupCount; x ++)
|
|
{
|
|
if (EqualSid(administrators, & (tg->Groups[x].Sid)) &&
|
|
(tg->Groups[x].Attributes & SE_GROUP_ENABLED) &&
|
|
(!(tg->Groups[x].Attributes & SE_GROUP_USE_FOR_DENY_ONLY))
|
|
)
|
|
{
|
|
an_admin = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (tg)
|
|
{
|
|
delete [] tg;
|
|
}
|
|
|
|
CloseHandle(token);
|
|
}
|
|
|
|
return an_admin;
|
|
}
|
|
|
|
void AddSeparator( LPWSTR *pszSessionData, LPWSTR szString, INT *iSizeOfBuffer )
|
|
{
|
|
_chASSERT( pszSessionData );
|
|
_chASSERT( szString );
|
|
_chASSERT( iSizeOfBuffer );
|
|
|
|
if( !szString )
|
|
{
|
|
szString = L"";
|
|
}
|
|
|
|
_chVERIFY2( *iSizeOfBuffer >= ( INT ) ( wcslen( szString ) + 1 ) );
|
|
|
|
DWORD dwLen = 0;
|
|
if( *iSizeOfBuffer >= ( INT )( wcslen( szString ) + 1 ) )
|
|
{
|
|
dwLen = wcslen( szString );
|
|
wcsncpy( *pszSessionData, szString, dwLen );
|
|
|
|
*pszSessionData += ( dwLen );
|
|
*iSizeOfBuffer -= ( dwLen );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
void WCopyInt( LPWSTR *pszSessionData, INT iNum, INT *iSizeOfBuffer )
|
|
{
|
|
_chASSERT( pszSessionData );
|
|
_chASSERT( iSizeOfBuffer );
|
|
_chVERIFY2( *iSizeOfBuffer >= MAX_STRING_FROM_itow );
|
|
|
|
_itow( iNum, *pszSessionData, 10 );
|
|
*iSizeOfBuffer -= wcslen( *pszSessionData );
|
|
*pszSessionData += wcslen( *pszSessionData );
|
|
|
|
AddSeparator( pszSessionData, session_data_separator, iSizeOfBuffer );
|
|
}
|
|
|
|
void WCopyMbcsString( LPWSTR *pszSessionData, CHAR *szString, INT *iSizeOfBuffer )
|
|
{
|
|
_chASSERT( pszSessionData );
|
|
_chASSERT( szString );
|
|
_chASSERT( iSizeOfBuffer );
|
|
|
|
if( !szString )
|
|
{
|
|
szString = "";
|
|
}
|
|
|
|
_chVERIFY2( *iSizeOfBuffer >= ( INT )( strlen( szString ) + 1 ) );
|
|
|
|
DWORD dwLen = 0;
|
|
dwLen = MultiByteToWideChar( GetOEMCP(), 0, szString, -1, *pszSessionData, *iSizeOfBuffer );
|
|
if( dwLen > 0 )
|
|
{
|
|
*pszSessionData += ( dwLen - 1 );
|
|
*iSizeOfBuffer -= ( dwLen - 1 );
|
|
|
|
AddSeparator( pszSessionData, session_data_separator, iSizeOfBuffer );
|
|
}
|
|
return;
|
|
}
|
|
|
|
void WCopyUnicodeString( LPWSTR *pszSessionData, LPWSTR szString, INT *iSizeOfBuffer )
|
|
{
|
|
_chASSERT( pszSessionData );
|
|
_chASSERT( szString );
|
|
_chASSERT( iSizeOfBuffer );
|
|
|
|
if( !szString )
|
|
{
|
|
szString = L"";
|
|
}
|
|
|
|
_chVERIFY2( *iSizeOfBuffer >= ( INT ) ( wcslen( szString ) + 1 ) );
|
|
|
|
DWORD dwLen = 0;
|
|
if( *iSizeOfBuffer >= ( INT )( wcslen( szString ) + 1 ) )
|
|
{
|
|
dwLen = wcslen( szString );
|
|
wcsncpy( *pszSessionData, szString, dwLen );
|
|
|
|
*pszSessionData += dwLen;
|
|
*iSizeOfBuffer -= dwLen;
|
|
|
|
AddSeparator( pszSessionData, session_data_separator, iSizeOfBuffer );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
extern CTelnetService* g_pTelnetService;
|
|
|
|
//Global variables used to pass data b/n GetSessionProcesses and EnumClients
|
|
CEnumData* g_pEnumData = NULL;
|
|
LONG lUniqueSessionNumber;
|
|
|
|
|
|
//Global variables used to pass data b/n GetTelnetSessionProcesses and GetTelnetSessions
|
|
BSTR g_szSessionData = NULL;
|
|
INT g_iSizeOfBuffer = 0;
|
|
|
|
#ifdef ENUM_PROCESSES
|
|
void
|
|
GetTelnetSessionProcesses
|
|
(
|
|
HANDLE hProc,
|
|
DWORD dwProcessId,
|
|
LPWSTR lpszProcessName
|
|
)
|
|
{
|
|
WCopyInt( &g_szSessionData, dwProcessId, &g_iSizeOfBuffer );
|
|
WCopyUnicodeString( &g_szSessionData, lpszProcessName, &g_iSizeOfBuffer );
|
|
}
|
|
#endif
|
|
|
|
//memory is allocated by this method ( GetTelnetSessions ) and to be freed by the client( telnet admin ).
|
|
//It returns data about each session as a BSTR formatted as below.
|
|
//Each feild is separated by wide char ':'. Each session is separated by ','
|
|
//First entry is count of sessions and only this feild is separated by comma from the rest. This is followed by,
|
|
//dwPid,szDomain,szUserName,szRemoteMachine, wYear, wMonth, wDayOfWeek, wDay,
|
|
//wHour, wMinute, wSecond, wMilliseconds; and pairs of process id, process name.
|
|
|
|
|
|
STDMETHODIMP
|
|
CEnumTelnetClientsSvr::GetTelnetSessions
|
|
(
|
|
BSTR *pszRetVal
|
|
)
|
|
{
|
|
DWORD dwCount = 0;
|
|
CClientInfo *pClientInfo = NULL;
|
|
DWORD dwStatus = S_OK;
|
|
DWORD dwLen = 0;
|
|
INT iBytesToBeAllocated = 0;
|
|
bool bIsDomainCopied = false;
|
|
|
|
// if (! called_by_an_admin())
|
|
// {
|
|
// return S_FALSE;
|
|
// }
|
|
|
|
// DebugBreak();
|
|
if( g_pTelnetService == NULL || pszRetVal == NULL )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
if( WaitForSingleObject( g_pTelnetService->m_hSyncAllClientObjAccess,
|
|
WAIT_TIME ) != WAIT_OBJECT_0 )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
DWORD dwSessionsWithData = 0;
|
|
DWORD dwSaveCount = 0;
|
|
|
|
dwCount = client_list_Count();
|
|
dwSaveCount = dwCount;
|
|
|
|
while( dwCount > 0 )
|
|
{
|
|
pClientInfo = (CClientInfo *)client_list_Get( --dwCount );
|
|
if( pClientInfo && pClientInfo->szUserName )
|
|
{
|
|
//Only if szUserName is non null, the object has session data.
|
|
//Otherwise, still in the process of getting that info
|
|
dwSessionsWithData++;
|
|
}
|
|
}
|
|
|
|
//Restore the count
|
|
dwCount = dwSaveCount;
|
|
|
|
g_iSizeOfBuffer = MAX_STRING_FROM_itow;
|
|
if( dwSessionsWithData > 0 )
|
|
{
|
|
g_iSizeOfBuffer += dwSessionsWithData * SIZE_OF_ONE_SESSION_DATA;
|
|
}
|
|
|
|
iBytesToBeAllocated = g_iSizeOfBuffer * sizeof( WCHAR );
|
|
*pszRetVal = SysAllocStringLen( NULL, iBytesToBeAllocated );
|
|
|
|
g_szSessionData = *pszRetVal;
|
|
|
|
if( g_szSessionData == NULL )
|
|
{
|
|
dwStatus = ( DWORD )S_FALSE;
|
|
goto ExitOnError;
|
|
}
|
|
|
|
WCopyInt( &g_szSessionData, dwSessionsWithData, &g_iSizeOfBuffer );
|
|
|
|
//Remove wide null char from g_szSessionData
|
|
g_iSizeOfBuffer += 1;
|
|
g_szSessionData -= 1;
|
|
AddSeparator( &g_szSessionData, session_separator, &g_iSizeOfBuffer );
|
|
|
|
while( dwCount > 0 )
|
|
{
|
|
pClientInfo = (CClientInfo *)client_list_Get( --dwCount );
|
|
|
|
if( pClientInfo && pClientInfo->szUserName )
|
|
{
|
|
WCopyInt( &g_szSessionData, pClientInfo->dwPid, &g_iSizeOfBuffer );
|
|
|
|
bIsDomainCopied = false;
|
|
if( strcmp( pClientInfo->szDomain, "." ) == 0 )
|
|
{
|
|
if( g_pTelnetService->m_szDomainName[0] )
|
|
{
|
|
WCopyUnicodeString( &g_szSessionData, g_pTelnetService->m_szDomainName, &g_iSizeOfBuffer );
|
|
bIsDomainCopied = true;
|
|
}
|
|
}
|
|
|
|
if( !bIsDomainCopied )
|
|
{
|
|
WCopyMbcsString( &g_szSessionData, pClientInfo->szDomain, &g_iSizeOfBuffer );
|
|
}
|
|
|
|
WCopyMbcsString( &g_szSessionData, pClientInfo->szUserName, &g_iSizeOfBuffer );
|
|
WCopyMbcsString( &g_szSessionData, pClientInfo->szRemoteMachine, &g_iSizeOfBuffer );
|
|
|
|
WCopyInt( &g_szSessionData, pClientInfo->lpLogonTime->wYear, &g_iSizeOfBuffer );
|
|
WCopyInt( &g_szSessionData, pClientInfo->lpLogonTime->wMonth, &g_iSizeOfBuffer );
|
|
WCopyInt( &g_szSessionData, pClientInfo->lpLogonTime->wDayOfWeek, &g_iSizeOfBuffer );
|
|
WCopyInt( &g_szSessionData, pClientInfo->lpLogonTime->wDay, &g_iSizeOfBuffer );
|
|
WCopyInt( &g_szSessionData, pClientInfo->lpLogonTime->wHour, &g_iSizeOfBuffer );
|
|
WCopyInt( &g_szSessionData, pClientInfo->lpLogonTime->wMinute, &g_iSizeOfBuffer );
|
|
WCopyInt( &g_szSessionData, pClientInfo->lpLogonTime->wSecond, &g_iSizeOfBuffer );
|
|
WCopyInt( &g_szSessionData, pClientInfo->lpLogonTime->wMilliseconds,&g_iSizeOfBuffer );
|
|
WCopyInt( &g_szSessionData, pClientInfo->m_dwIdleTime/1000, &g_iSizeOfBuffer );
|
|
|
|
#ifdef ENUM_PROCESSES
|
|
//g_szSessionData, g_iSizeOfBuffer needs to be global for following reason
|
|
//This will add the processes to the list
|
|
EnumSessionProcesses( *( pClientInfo->pAuthId ), GetTelnetSessionProcesses, TO_ENUM );
|
|
#endif
|
|
//To indicate end of a session: ',' indicates end of a session data
|
|
AddSeparator( &g_szSessionData, session_separator, &g_iSizeOfBuffer );
|
|
}
|
|
}
|
|
|
|
ExitOnError:
|
|
_chVERIFY2( ReleaseMutex( g_pTelnetService->m_hSyncAllClientObjAccess ) );
|
|
|
|
return ( dwStatus );
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CEnumTelnetClientsSvr::GetEnumClients
|
|
(
|
|
IEnumClients * * ppretval
|
|
)
|
|
{
|
|
*ppretval = ( IEnumClients* ) this;
|
|
( *ppretval )->AddRef();
|
|
|
|
//Initialize the Telnet Clients list
|
|
if( m_pEnumeration )
|
|
delete m_pEnumeration;
|
|
m_pEnumeration = new CEnumData;
|
|
if( !m_pEnumeration )
|
|
{
|
|
return (S_FALSE);
|
|
}
|
|
|
|
if( !EnumClients( m_pEnumeration ) )
|
|
return (S_FALSE);
|
|
|
|
return ( S_OK );
|
|
}
|
|
|
|
void
|
|
GetSessionProcesses
|
|
(
|
|
HANDLE hProc,
|
|
DWORD dwProcessId,
|
|
LPWSTR lpszProcessName
|
|
)
|
|
{
|
|
g_pEnumData->Add( lUniqueSessionNumber, dwProcessId, lpszProcessName );
|
|
return;
|
|
}
|
|
|
|
bool
|
|
CEnumTelnetClientsSvr::EnumClients
|
|
(
|
|
CEnumData* pEnumData
|
|
)
|
|
{
|
|
WCHAR szUserName[ MAX_STRING_LENGTH + 1 ];
|
|
WCHAR szDomain[ MAX_STRING_LENGTH + 1 ];
|
|
WCHAR szPeer[ MAX_STRING_LENGTH + 1 ];
|
|
|
|
DWORD dwStatus = 0;
|
|
if( g_pTelnetService == NULL || pEnumData == NULL )
|
|
return false;
|
|
|
|
DWORD dwCount = 0;
|
|
CClientInfo *pClientInfo = NULL;
|
|
|
|
dwStatus = WaitForSingleObject(
|
|
g_pTelnetService->m_hSyncAllClientObjAccess, WAIT_TIME );
|
|
if( dwStatus != WAIT_OBJECT_0 )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if( ( dwCount = client_list_Count() ) != 0 )
|
|
{
|
|
while( dwCount > 0 )
|
|
{
|
|
pClientInfo = (CClientInfo *)client_list_Get( --dwCount );
|
|
if( pClientInfo )
|
|
{
|
|
if( !ConvertSChartoWChar( pClientInfo->szUserName, szUserName )
|
|
|| !ConvertSChartoWChar( pClientInfo->szDomain, szDomain ) ||
|
|
!ConvertSChartoWChar( pClientInfo->szRemoteMachine, szPeer ))
|
|
{
|
|
continue;
|
|
}
|
|
pEnumData->Add( szUserName, szDomain, szPeer,
|
|
*( pClientInfo->lpLogonTime ), (LONG) pClientInfo->dwPid );
|
|
|
|
//This will add the processes to the list
|
|
LUID authId = *( pClientInfo->pAuthId );
|
|
g_pEnumData = pEnumData;
|
|
lUniqueSessionNumber = pClientInfo->dwPid;
|
|
EnumSessionProcesses( authId, GetSessionProcesses, TO_ENUM );
|
|
}
|
|
}
|
|
}
|
|
_chVERIFY2( ReleaseMutex( g_pTelnetService->m_hSyncAllClientObjAccess ) );
|
|
|
|
return ( true );
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CEnumTelnetClientsSvr::Next
|
|
(
|
|
ULONG celt,
|
|
TELNET_CLIENT_INFO** rgelt,
|
|
ULONG * pceltFetched
|
|
)
|
|
{
|
|
ULONG ulNumReturned = 0;
|
|
if( NULL == pceltFetched )
|
|
{
|
|
if( celt != 1 )
|
|
return ( S_FALSE );
|
|
}
|
|
else
|
|
*pceltFetched = 0;
|
|
|
|
if( NULL == rgelt )
|
|
return ( E_POINTER );
|
|
|
|
typedef CEnumData::CNode* PNODE;
|
|
PNODE* ppcopy = new PNODE [ celt ];
|
|
|
|
if( NULL == ppcopy )
|
|
{
|
|
return ( S_FALSE );
|
|
}
|
|
|
|
ULONG total = celt;
|
|
|
|
for (celt = 0; celt < total; celt ++)
|
|
{
|
|
ppcopy[celt] = NULL;
|
|
|
|
if (m_pEnumeration->GetNext(&ppcopy[celt]))
|
|
{
|
|
ulNumReturned++;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
celt = 0;
|
|
|
|
while( celt < ulNumReturned )
|
|
{
|
|
rgelt[ celt ] =
|
|
(TELNET_CLIENT_INFO*) CoTaskMemAlloc( sizeof(TELNET_CLIENT_INFO));
|
|
if(! rgelt[ celt ] )
|
|
{
|
|
goto CLEANUP_AND_GET_OUT;
|
|
}
|
|
|
|
lstrcpyW( (*(rgelt[ celt ])).username, ppcopy[ celt ]->lpszUserName ); // Cleared by Prefast - Baskar
|
|
lstrcpyW( (*(rgelt[ celt ])).domain, ppcopy[ celt ]->lpszDomain );
|
|
lstrcpyW( (*(rgelt[ celt ])).peerhostname, ppcopy[ celt ]->lpszPeerHostName );
|
|
|
|
(*(rgelt[ celt ])).logonTime = ppcopy[ celt ]->logonTime;
|
|
(*(rgelt[ celt ])).uniqueId = ppcopy[ celt ]->lUniqueId;
|
|
|
|
PIdNode *pPId = ppcopy[ celt ]->pProcessesHead;
|
|
DWORD dwNoOfProcesses = 0;
|
|
while( pPId )
|
|
{
|
|
dwNoOfProcesses++;
|
|
pPId = pPId->pNextPId;
|
|
}
|
|
(*(rgelt[ celt ])).NoOfPids = dwNoOfProcesses;
|
|
(*(rgelt[ celt ])).pId = ( DWORD * ) CoTaskMemAlloc ( sizeof( DWORD ) *
|
|
( dwNoOfProcesses + 10 ) );
|
|
|
|
if( !(*(rgelt[ celt ])).pId )
|
|
{
|
|
goto CLEANUP_AND_GET_OUT;
|
|
}
|
|
|
|
(*(rgelt[ celt ])).processName = (WCHAR(*)[256]) CoTaskMemAlloc ( sizeof(WCHAR) * dwNoOfProcesses * 256);
|
|
|
|
if( !(*(rgelt[ celt ])).processName )
|
|
{
|
|
goto CLEANUP_AND_GET_OUT;
|
|
}
|
|
|
|
INT ctr = 0;
|
|
pPId = ppcopy[ celt ]->pProcessesHead;
|
|
while( pPId )
|
|
{
|
|
(*(rgelt[ celt ])).pId[ ctr ] = pPId->dwPId;
|
|
lstrcpyW( (*(rgelt[ celt ])).processName[ ctr ], pPId->lpszProcessName ); // Cleared by Prefast - Baskar
|
|
ctr++;
|
|
pPId = pPId->pNextPId;
|
|
}
|
|
|
|
(*(rgelt[ celt ])).pId[ ctr ] = ( DWORD )-1; //Indicates end of processes.
|
|
|
|
celt++;
|
|
}
|
|
{
|
|
ULONG index;
|
|
|
|
for (index = 0; index < total; index ++)
|
|
{
|
|
if (ppcopy[index])
|
|
{
|
|
delete ppcopy[index];
|
|
}
|
|
}
|
|
|
|
delete [] ppcopy;
|
|
}
|
|
|
|
if( pceltFetched != NULL )
|
|
*pceltFetched = ulNumReturned;
|
|
|
|
if( ulNumReturned == 0 )
|
|
return ( S_FALSE );
|
|
|
|
return ( S_OK );
|
|
|
|
CLEANUP_AND_GET_OUT:
|
|
|
|
{
|
|
ULONG index;
|
|
|
|
for (index = 0; index < total; index ++)
|
|
{
|
|
if (ppcopy[index])
|
|
{
|
|
delete ppcopy[index];
|
|
}
|
|
}
|
|
|
|
delete [] ppcopy;
|
|
|
|
for (index = 0; index < total; index ++)
|
|
{
|
|
CoTaskMemFree( (*(rgelt[ index ])).pId );
|
|
CoTaskMemFree( (*(rgelt[ index ])).processName );
|
|
CoTaskMemFree( rgelt[ index ] );
|
|
}
|
|
}
|
|
|
|
return ( S_FALSE );
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CEnumTelnetClientsSvr::Skip
|
|
(
|
|
ULONG celt
|
|
)
|
|
{
|
|
//return ( S_OK );
|
|
return ( E_NOTIMPL );
|
|
}
|
|
|
|
|
|
STDMETHODIMP CEnumTelnetClientsSvr::Reset()
|
|
{
|
|
m_pEnumeration->Reset();
|
|
return ( S_OK );
|
|
}
|
|
|
|
|
|
STDMETHODIMP CEnumTelnetClientsSvr::Clone(IEnumClients * * ppenum)
|
|
{
|
|
//return S_OK;
|
|
return ( E_NOTIMPL );
|
|
}
|
|
|
|
|
|
STDMETHODIMP CEnumTelnetClientsSvr::TerminateSession( DWORD dwUniqueId )
|
|
{
|
|
if( g_pTelnetService == NULL )
|
|
return S_FALSE;
|
|
|
|
LONG dwRetStatus = S_FALSE;
|
|
DWORD dwCount = 0;
|
|
CClientInfo *pClientInfo = NULL;
|
|
DWORD dwStatus = 0;
|
|
dwStatus = WaitForSingleObject( g_pTelnetService->m_hSyncAllClientObjAccess,
|
|
WAIT_TIME );
|
|
if( dwStatus != WAIT_OBJECT_0 )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
if( ( dwCount = client_list_Count() ) != 0 )
|
|
{
|
|
while( dwCount > 0 )
|
|
{
|
|
pClientInfo = (CClientInfo *)client_list_Get( --dwCount );
|
|
if(pClientInfo == NULL)
|
|
goto Done;
|
|
if( pClientInfo->dwPid == dwUniqueId )
|
|
{
|
|
if( AskTheSessionToQuit( pClientInfo ) )
|
|
{
|
|
dwRetStatus = S_OK;
|
|
goto Done;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Done:
|
|
_chVERIFY2( ReleaseMutex( g_pTelnetService->m_hSyncAllClientObjAccess ) );
|
|
return dwRetStatus;
|
|
}
|
|
|
|
bool CEnumTelnetClientsSvr::InformTheSession( CClientInfo *pClientInfo,
|
|
WCHAR szMsg[] )
|
|
{
|
|
UCHAR *szMsgToSend = NULL;
|
|
|
|
DWORD dwLen = 2* ( wcslen( szMsg ) + 1 );
|
|
szMsgToSend = new UCHAR[ IPC_HEADER_SIZE + dwLen ];
|
|
if( !szMsgToSend )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
szMsgToSend[0] = OPERATOR_MESSAGE;
|
|
memcpy( szMsgToSend + 1, &dwLen, sizeof( DWORD ) ); // No size info here - Attack ? Baskar
|
|
memcpy( szMsgToSend + IPC_HEADER_SIZE, szMsg, dwLen );
|
|
|
|
if( WriteToPipe( pClientInfo->hWritingPipe, (LPVOID) szMsgToSend,
|
|
IPC_HEADER_SIZE + dwLen, &( g_pTelnetService->m_oWriteToPipe ) ) )
|
|
{
|
|
delete[] szMsgToSend;
|
|
return true;
|
|
}
|
|
|
|
delete[] szMsgToSend;
|
|
g_pTelnetService->StopServicingClient( pClientInfo, (BOOL)TRUE );
|
|
return false;
|
|
}
|
|
|
|
STDMETHODIMP CEnumTelnetClientsSvr::SendMsgToASession( DWORD dwUniqueId, BSTR szMsgToBeSent )
|
|
{
|
|
if( !SendMsg( dwUniqueId, szMsgToBeSent ) )
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
bool CEnumTelnetClientsSvr::SendMsg( DWORD dwUniqueId, BSTR szMsg )
|
|
{
|
|
bool bRetStatus = false;
|
|
DWORD dwCount = 0;
|
|
CClientInfo *pClientInfo = NULL;
|
|
DWORD dwStatus = 0;
|
|
|
|
if( g_pTelnetService == NULL || szMsg == NULL )
|
|
{
|
|
return bRetStatus;
|
|
}
|
|
|
|
if( SysStringLen( szMsg ) <= 0 )
|
|
{
|
|
return bRetStatus;
|
|
}
|
|
|
|
dwStatus = WaitForSingleObject( g_pTelnetService->m_hSyncAllClientObjAccess, WAIT_TIME );
|
|
if( dwStatus != WAIT_OBJECT_0 )
|
|
{
|
|
return bRetStatus;
|
|
}
|
|
|
|
if( ( dwCount = client_list_Count() ) != 0 )
|
|
{
|
|
while( dwCount > 0 && !bRetStatus )
|
|
{
|
|
pClientInfo = (CClientInfo *)client_list_Get( --dwCount );
|
|
if(pClientInfo == NULL)
|
|
goto Done;
|
|
if( pClientInfo->dwPid == dwUniqueId )
|
|
{
|
|
if( InformTheSession( pClientInfo, szMsg ) )
|
|
{
|
|
bRetStatus = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Done:
|
|
_chVERIFY2( ReleaseMutex( g_pTelnetService->m_hSyncAllClientObjAccess ) );
|
|
return bRetStatus;
|
|
}
|
|
|
|
void CEnumTelnetClientsSvr::FinalRelease()
|
|
{
|
|
delete m_pEnumeration;
|
|
m_pEnumeration = NULL;
|
|
CComObjectRootEx<CComMultiThreadModel>::FinalRelease();
|
|
}
|
|
|
|
bool CEnumTelnetClientsSvr::AskTheSessionToQuit( CClientInfo *pClientInfo )
|
|
{
|
|
bool bRetVal = false;
|
|
BOOL delete_the_class = FALSE;
|
|
DWORD dwRetVal = 0, dwAvail = 0, dwLeft = 0;
|
|
CHAR *szBuffer = NULL;
|
|
if(!PeekNamedPipe(pClientInfo->hReadingPipe,szBuffer,0,&dwRetVal,&dwAvail,&dwLeft))
|
|
{
|
|
dwRetVal = GetLastError();
|
|
if(dwRetVal == ERROR_INVALID_HANDLE)
|
|
{
|
|
delete_the_class = TRUE;
|
|
}
|
|
}
|
|
else if( WriteToPipe( pClientInfo->hWritingPipe, GO_DOWN,
|
|
& ( g_pTelnetService->m_oWriteToPipe ) ) )
|
|
{
|
|
bRetVal = true;
|
|
}
|
|
|
|
g_pTelnetService->StopServicingClient( pClientInfo, delete_the_class );
|
|
return bRetVal;
|
|
}
|