|
|
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include "stdafx.h"
#include "net_view_thread.h"
char* CopyAlloc( const char *pStr ) { char *pRet = new char[ strlen( pStr ) + 1]; strcpy( pRet, pStr ); return pRet; }
CNetViewThread::CNetViewThread() { m_hThread = NULL; m_hThreadExitEvent = NULL; InitializeCriticalSection( &m_ComputerNamesCS ); }
CNetViewThread::~CNetViewThread() { Term(); DeleteCriticalSection( &m_ComputerNamesCS ); }
void CNetViewThread::Init() { Term();
m_hThreadExitEvent = CreateEvent( NULL, false, false, NULL );
DWORD dwThreadID = 0; m_hThread = CreateThread( NULL, 0, &CNetViewThread::StaticThreadFn, this, 0, &dwThreadID ); }
void CNetViewThread::Term() { if ( m_hThread ) { SetEvent( m_hThreadExitEvent ); WaitForSingleObject( m_hThread, INFINITE ); CloseHandle( m_hThread ); m_hThread = NULL; }
if ( m_hThreadExitEvent ) { CloseHandle( m_hThreadExitEvent ); m_hThreadExitEvent = NULL; } }
void CNetViewThread::GetComputerNames( CUtlVector<char*> &computerNames ) { EnterCriticalSection( &m_ComputerNamesCS );
computerNames.Purge(); for ( int i=0; i < m_ComputerNames.Count(); i++ ) { computerNames.AddToTail( CopyAlloc( m_ComputerNames[i] ) ); }
LeaveCriticalSection( &m_ComputerNamesCS ); }
void CNetViewThread::UpdateServicesFromNetView() { HANDLE hChildStdoutRd, hChildStdoutWr; // Set the bInheritHandle flag so pipe handles are inherited.
SECURITY_ATTRIBUTES saAttr; saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL;
if( CreatePipe( &hChildStdoutRd, &hChildStdoutWr, &saAttr, 0 ) ) { STARTUPINFO si; memset(&si, 0, sizeof si); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdOutput = hChildStdoutWr; PROCESS_INFORMATION pi;
if( CreateProcess( NULL, "net view", NULL, // lpProcessAttributes
NULL, // lpThreadAttributes
TRUE, // bInheritHandls
DETACHED_PROCESS, // dwCreationFlags
NULL, // lpEnvironment
NULL, // lpCurrentDirectory
&si, // lpStartupInfo
&pi // lpProcessInformation
) ) { // read from pipe..
#define BUFFER_SIZE 8192
char buffer[BUFFER_SIZE]; BOOL bDone = FALSE; CUtlVector<char> totalBuffer; while(1) { DWORD dwCount = 0; DWORD dwRead = 0; // read from input handle
PeekNamedPipe(hChildStdoutRd, NULL, NULL, NULL, &dwCount, NULL); if (dwCount) { dwCount = min (dwCount, (DWORD)BUFFER_SIZE - 1); ReadFile(hChildStdoutRd, buffer, dwCount, &dwRead, NULL); } if(dwRead) { buffer[dwRead] = 0; totalBuffer.AddMultipleToTail( dwRead, buffer ); } // check process termination
else if( WaitForSingleObject( pi.hProcess, 1000 ) != WAIT_TIMEOUT ) { if ( bDone ) break; bDone = TRUE; // next time we get it
} }
// Now parse the output.
totalBuffer.AddToTail( 0 ); ParseComputerNames( totalBuffer.Base() ); }
CloseHandle( hChildStdoutRd ); CloseHandle( hChildStdoutWr ); } }
void CNetViewThread::ParseComputerNames( const char *pNetViewOutput ) { EnterCriticalSection( &m_ComputerNamesCS );
m_ComputerNames.PurgeAndDeleteElements(); const char *pCur = pNetViewOutput; while ( *pCur != 0 ) { // If we get a \\, then it's a computer name followed by whitespace.
if ( pCur[0] == '\\' && pCur[1] == '\\' ) { char curComputerName[512]; char *pOutPos = curComputerName;
pCur += 2; while ( *pCur && !V_isspace( *pCur ) && (pOutPos-curComputerName < 510) ) { *pOutPos++ = *pCur++; } *pOutPos = 0;
m_ComputerNames.AddToTail( CopyAlloc( curComputerName ) ); } ++pCur; }
LeaveCriticalSection( &m_ComputerNamesCS ); }
DWORD CNetViewThread::ThreadFn() { // Update the services list every 30 seconds.
do { UpdateServicesFromNetView(); } while ( WaitForSingleObject( m_hThreadExitEvent, 30000 ) != WAIT_OBJECT_0 );
return 0; }
DWORD CNetViewThread::StaticThreadFn( LPVOID lpParameter ) { return ((CNetViewThread*)lpParameter)->ThreadFn(); }
|