summaryrefslogtreecommitdiff
path: root/utils/vmpi/net_view_thread.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/vmpi/net_view_thread.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/vmpi/net_view_thread.cpp')
-rw-r--r--utils/vmpi/net_view_thread.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/utils/vmpi/net_view_thread.cpp b/utils/vmpi/net_view_thread.cpp
new file mode 100644
index 0000000..19ab38d
--- /dev/null
+++ b/utils/vmpi/net_view_thread.cpp
@@ -0,0 +1,208 @@
+//========= 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();
+}
+
+