diff options
Diffstat (limited to 'utils/vmpi/vmpi_service_ui')
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/StdAfx.cpp | 15 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/StdAfx.h | 30 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/idi_busy_icon.ico | bin | 0 -> 318 bytes | |||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/idi_disabled_icon.ico | bin | 0 -> 318 bytes | |||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/idi_waiting_icon.ico | bin | 0 -> 318 bytes | |||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/resource.h | 47 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/shell_icon_mgr.cpp | 187 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/shell_icon_mgr.h | 66 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/unconnec.ico | bin | 0 -> 318 bytes | |||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/vmpi_service.ico | bin | 0 -> 1078 bytes | |||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/vmpi_service_ui.cpp | 617 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/vmpi_service_ui.rc | 171 | ||||
| -rw-r--r-- | utils/vmpi/vmpi_service_ui/vmpi_service_ui.vpc | 58 |
13 files changed, 1191 insertions, 0 deletions
diff --git a/utils/vmpi/vmpi_service_ui/StdAfx.cpp b/utils/vmpi/vmpi_service_ui/StdAfx.cpp new file mode 100644 index 0000000..d22d5d4 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/StdAfx.cpp @@ -0,0 +1,15 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.cpp : source file that includes just the standard includes +// vmpi_service_ui.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/utils/vmpi/vmpi_service_ui/StdAfx.h b/utils/vmpi/vmpi_service_ui/StdAfx.h new file mode 100644 index 0000000..31b5d12 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/StdAfx.h @@ -0,0 +1,30 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#if !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) +#define AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include <windows.h> + + +// TODO: reference additional headers your program requires here + +//{{AFX_INSERT_LOCATION}} +// Microsoft Visual C++ will insert additional declarations immediately before the previous line. + +#endif // !defined(AFX_STDAFX_H__A9DB83DB_A9FD_11D0_BFD1_444553540000__INCLUDED_) diff --git a/utils/vmpi/vmpi_service_ui/idi_busy_icon.ico b/utils/vmpi/vmpi_service_ui/idi_busy_icon.ico Binary files differnew file mode 100644 index 0000000..ac62654 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/idi_busy_icon.ico diff --git a/utils/vmpi/vmpi_service_ui/idi_disabled_icon.ico b/utils/vmpi/vmpi_service_ui/idi_disabled_icon.ico Binary files differnew file mode 100644 index 0000000..e49e952 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/idi_disabled_icon.ico diff --git a/utils/vmpi/vmpi_service_ui/idi_waiting_icon.ico b/utils/vmpi/vmpi_service_ui/idi_waiting_icon.ico Binary files differnew file mode 100644 index 0000000..a52165d --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/idi_waiting_icon.ico diff --git a/utils/vmpi/vmpi_service_ui/resource.h b/utils/vmpi/vmpi_service_ui/resource.h new file mode 100644 index 0000000..95b752b --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/resource.h @@ -0,0 +1,47 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by vmpi_service_ui.rc +// +#define IDC_MYICON 2 +#define IDI_DISABLED_ICON 101 +#define IDD_VMPI_SERVICE_DIALOG 102 +#define IDI_BUSY_ICON 102 +#define IDD_ABOUTBOX 103 +#define IDS_APP_TITLE 103 +#define IDR_POPUP_MENU 103 +#define IDM_ABOUT 104 +#define IDM_EXIT 105 +#define IDI_WAITING_ICON 105 +#define IDS_HELLO 106 +#define IDI_VMPI_SERVICE 107 +#define IDI_SMALL 108 +#define IDC_VMPI_SERVICE 109 +#define IDR_MAINFRAME 128 +#define IDD_VMPI_SERVICE 129 +#define IDD_SET_PASSWORD 130 +#define IDI_UNCONNECTED 132 +#define ID_KILLCURRENTJOB 133 +#define IDC_DEBUG_OUTPUT 1000 +#define IDC_PASSWORD 1001 +#define ID_SET_PASSWORD 32771 +#define ID_IGNORECSXCOMPILES 32772 +#define ID_HIGHLIGHT_ICON_WHEN_BUSY 32773 +#define ID_SCREENSAVER_MODE 32774 +#define ID_ENABLE_WORKER 40001 +#define ID_DISABLE_WORKER 40003 +#define ID_EXIT_SERVICE 40004 +#define ID_SHOW_CONSOLE_WINDOW 40005 +#define ID_HIDE_CONSOLE_WINDOW 40006 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 133 +#define _APS_NEXT_COMMAND_VALUE 32775 +#define _APS_NEXT_CONTROL_VALUE 1002 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/utils/vmpi/vmpi_service_ui/shell_icon_mgr.cpp b/utils/vmpi/vmpi_service_ui/shell_icon_mgr.cpp new file mode 100644 index 0000000..cfdf759 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/shell_icon_mgr.cpp @@ -0,0 +1,187 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#include "stdafx.h" +#include "shell_icon_mgr.h" +#include "tier1/strtools.h" +#include "tier0/dbg.h" +#include "shellapi.h" + + +#define SHELLICONMGR_CLASSNAME "VMPI_ShellIconMgr" + + + +CShellIconMgr::CShellIconMgr() +{ + m_hWnd = NULL; + m_hWndClass = NULL; + m_uTaskbarRestart = (UINT)-1; + m_iCurIconResourceID = 0; + m_pHelper = NULL; +} + + +CShellIconMgr::~CShellIconMgr() +{ + Term(); +} + + +bool CShellIconMgr::Init( + IShellIconMgrHelper *pHelper, + const char *pToolTip, + int iCallbackMessage, + int iIconResourceID ) +{ + Term(); + + m_pHelper = pHelper; + m_iCallbackMessage = iCallbackMessage; + m_pToolTip = pToolTip; + + // Create the window class. + WNDCLASS wndclass; + memset( &wndclass, 0, sizeof( wndclass ) ); + wndclass.lpfnWndProc = &CShellIconMgr::StaticWindowProc; + wndclass.hInstance = (HINSTANCE)pHelper->GetHInstance(); + wndclass.hIcon = NULL; + wndclass.hCursor = LoadCursor( NULL, IDC_ARROW ); + wndclass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH ); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = SHELLICONMGR_CLASSNAME; + m_hWndClass = RegisterClass( &wndclass ); + if ( !m_hWndClass ) + { + Assert( false ); + Warning( "RegisterClass failed.\n" ); + Term(); + return false; + } + + + // Create the window. + m_hWnd = CreateWindow( + SHELLICONMGR_CLASSNAME, + SHELLICONMGR_CLASSNAME, + WS_DISABLED, // we only want shell notify messages + 0, 0, 0, 0, // position + NULL, // parent + NULL, // menu + pHelper->GetHInstance(), // hInstance + this // lpParam + ); + if ( !m_hWnd ) + { + Assert( false ); + Warning( "CreateWindow failed.\n" ); + Term(); + return false; + } + + m_uTaskbarRestart = RegisterWindowMessage( TEXT( "TaskbarCreated" ) ); + SetWindowLong( m_hWnd, GWL_USERDATA, (LONG)this ); + UpdateWindow( m_hWnd ); + + // Don't handle errors here because the taskbar may not be created yet if we are a service. + m_iCurIconResourceID = iIconResourceID; + CreateTrayIcon(); + return true; +} + + +void CShellIconMgr::Term() +{ + if ( m_hWndClass ) + { + UnregisterClass( SHELLICONMGR_CLASSNAME, m_pHelper->GetHInstance() ); + m_hWndClass = NULL; + } + + if ( m_hWnd ) + { + // Remove the shell icon if there is one. + NOTIFYICONDATA data; + memset( &data, 0, sizeof( data ) ); + data.cbSize = sizeof( data ); + data.hWnd = m_hWnd; + Shell_NotifyIcon( NIM_DELETE, &data ); + + DestroyWindow( m_hWnd ); + m_hWnd = NULL; + } +} + + +void CShellIconMgr::ChangeIcon( int iIconResourceID ) +{ + NOTIFYICONDATA data; + + memset( &data, 0, sizeof( data ) ); + data.cbSize = sizeof( data ); + data.uFlags = NIF_ICON; + data.hWnd = m_hWnd; + data.hIcon = LoadIcon( m_pHelper->GetHInstance(), MAKEINTRESOURCE( iIconResourceID ) ); + + Shell_NotifyIcon( NIM_MODIFY, &data ); + + m_iCurIconResourceID = iIconResourceID; +} + + +void CShellIconMgr::CreateTrayIcon() +{ + // Now create the shell icon. + NOTIFYICONDATA data; + + memset( &data, 0, sizeof( data ) ); + data.cbSize = sizeof( data ); + data.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; + data.uCallbackMessage = m_iCallbackMessage; + data.hWnd = m_hWnd; + data.hIcon = LoadIcon( m_pHelper->GetHInstance(), MAKEINTRESOURCE( m_iCurIconResourceID ) ); + Q_strncpy( data.szTip, m_pToolTip, sizeof( data.szTip ) ); + + Shell_NotifyIcon( NIM_ADD, &data ); +} + + +LRESULT CShellIconMgr::WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + if ( hWnd != m_hWnd ) + { + return DefWindowProc( hWnd, uMsg, wParam, lParam ); + } + + if ( uMsg == m_uTaskbarRestart ) + { + CreateTrayIcon(); + return 0; + } + + return m_pHelper->WindowProc( hWnd, uMsg, wParam, lParam ); +} + + +LRESULT CShellIconMgr::StaticWindowProc( + HWND hwnd, // handle to window + UINT uMsg, // message identifier + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ) +{ + CShellIconMgr *pMgr = (CShellIconMgr*)GetWindowLong( hwnd, GWL_USERDATA ); + if ( pMgr ) + { + return pMgr->WindowProc( hwnd, uMsg, wParam, lParam ); + } + else + { + return DefWindowProc( hwnd, uMsg, wParam, lParam ); + } +} + diff --git a/utils/vmpi/vmpi_service_ui/shell_icon_mgr.h b/utils/vmpi/vmpi_service_ui/shell_icon_mgr.h new file mode 100644 index 0000000..81188d4 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/shell_icon_mgr.h @@ -0,0 +1,66 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SHELL_ICON_MGR_H +#define SHELL_ICON_MGR_H +#ifdef _WIN32 +#pragma once +#endif + + +class IShellIconMgrHelper +{ +public: + virtual HINSTANCE GetHInstance() = 0; + virtual int WindowProc( void *hWnd, int uMsg, long wParam, long lParam ) = 0; +}; + +class CShellIconMgr +{ +public: + + CShellIconMgr(); + ~CShellIconMgr(); + + bool Init( + IShellIconMgrHelper *pHelper, + const char *pToolTip, // This must be allocated by the caller and must be valid as + // long as the CShellIconMgr exists. + int iCallbackMessage, + int iIconResourceID ); + + void Term(); + + void ChangeIcon( int iIconResourceID ); + + +private: + + void CreateTrayIcon(); + + LRESULT WindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + static LRESULT CALLBACK StaticWindowProc( + HWND hwnd, // handle to window + UINT uMsg, // message identifier + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter + ); + + HWND m_hWnd; // Invisible window to get timer and shell icon messages. + ATOM m_hWndClass; + + UINT m_uTaskbarRestart; // This message is sent to us when the taskbar is created. + int m_iCurIconResourceID; + int m_iCallbackMessage; + const char *m_pToolTip; + + IShellIconMgrHelper *m_pHelper; +}; + + +#endif // SHELL_ICON_MGR_H diff --git a/utils/vmpi/vmpi_service_ui/unconnec.ico b/utils/vmpi/vmpi_service_ui/unconnec.ico Binary files differnew file mode 100644 index 0000000..5cfdcdb --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/unconnec.ico diff --git a/utils/vmpi/vmpi_service_ui/vmpi_service.ico b/utils/vmpi/vmpi_service_ui/vmpi_service.ico Binary files differnew file mode 100644 index 0000000..3868835 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/vmpi_service.ico diff --git a/utils/vmpi/vmpi_service_ui/vmpi_service_ui.cpp b/utils/vmpi/vmpi_service_ui/vmpi_service_ui.cpp new file mode 100644 index 0000000..7bb756f --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/vmpi_service_ui.cpp @@ -0,0 +1,617 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// vmpi_service_ui.cpp : Defines the entry point for the application. +// + +#include "stdafx.h" +#include "consolewnd.h" +#include "resource.h" +#include "tier0/dbg.h" +#include "tier1/strtools.h" +#include "shell_icon_mgr.h" +#include "vmpi.h" +#include "service_conn_mgr.h" +#include <io.h> +#include <time.h> + + + +void UpdatePopupMenuState(); + + + +const char *g_pIconTooltip = VMPI_SERVICE_NAME; + +IConsoleWnd *g_pConsoleWnd = NULL; +HINSTANCE g_hInstance = NULL; + + +#define MYWM_NOTIFYICON (WM_APP+100) +CShellIconMgr g_ShellIconMgr; + +bool g_bHighlightIconWhenBusy = false; + + +// STATE THE SERVICE OWNS. +int g_iCurState = 0; // One of the VMPI_SERVICE_STATE_ defines. +char *g_pPassword = NULL; +bool g_bScreensaverMode = false; + + +void LogString( const char *pStr, ... ) +{ +#ifdef VMPI_SERVICE_LOGS + char str[4096]; + va_list marker; + va_start( marker, pStr ); + _vsnprintf( str, sizeof( str ), pStr, marker ); + va_end( marker ); + + static FILE *fp = fopen( "c:\\vmpi_service_ui.log", "wt" ); + if ( fp ) + { + fprintf( fp, "%s", str ); + fflush( fp ); + } +#endif +} + +char* GetLastErrorString() +{ + static char err[2048]; + + LPVOID lpMsgBuf; + FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); + strncpy( err, (char*)lpMsgBuf, sizeof( err ) ); + LocalFree( lpMsgBuf ); + + err[ sizeof( err ) - 1 ] = 0; + return err; +} + + +// ------------------------------------------------------------------------------------------ // +// Persistent state in the registry. +// ------------------------------------------------------------------------------------------ // +void LoadStateFromRegistry() +{ + HKEY hKey = NULL; + RegCreateKey( HKEY_LOCAL_MACHINE, VMPI_SERVICE_KEY, &hKey ); + if ( hKey ) + { + DWORD val = 0; + DWORD type = REG_DWORD; + DWORD size = sizeof( val ); + if ( RegQueryValueEx( + hKey, + "HighlightIconWhenBusy", + 0, + &type, + (unsigned char*)&val, + &size ) == ERROR_SUCCESS && + type == REG_DWORD && + size == sizeof( val ) ) + { + g_bHighlightIconWhenBusy = (val != 0); + } + } +} + +void SaveStateToRegistry() +{ + HKEY hKey = NULL; + RegCreateKey( HKEY_LOCAL_MACHINE, VMPI_SERVICE_KEY, &hKey ); + if ( hKey ) + { + DWORD val = g_bHighlightIconWhenBusy; + RegSetValueEx( + hKey, + "HighlightIconWhenBusy", + 0, + REG_DWORD, + (unsigned char*)&val, + sizeof( val ) ); + } +} + + +// ------------------------------------------------------------------------------------------ // +// Our CServiceConnMgr packet handler. +// ------------------------------------------------------------------------------------------ // + +void UpdateAppIcon() +{ + if ( g_iCurState == VMPI_SERVICE_STATE_IDLE ) + { + g_ShellIconMgr.ChangeIcon( IDI_WAITING_ICON ); + } + else if ( g_iCurState == VMPI_SERVICE_STATE_BUSY ) + { + if ( g_bHighlightIconWhenBusy ) + g_ShellIconMgr.ChangeIcon( IDI_BUSY_ICON ); + else + g_ShellIconMgr.ChangeIcon( IDI_WAITING_ICON ); + } + else + { + g_ShellIconMgr.ChangeIcon( IDI_DISABLED_ICON ); + } +} + + +class CUIConnMgr : public CServiceConnMgr +{ +public: + virtual void HandlePacket( const char *pData, int len ); +}; + + +void CUIConnMgr::HandlePacket( const char *pData, int len ) +{ + if ( pData[0] != VMPI_SERVICE_UI_PROTOCOL_VERSION ) + return; + + int packetID = pData[1]; + + int offset = 2; + if ( packetID == VMPI_SERVICE_TO_UI_CONSOLE_TEXT ) + { + Msg( &pData[offset] ); + } + else if ( packetID == VMPI_SERVICE_TO_UI_STATE ) + { + // Get the new state out.. + g_iCurState = *((int*)&pData[offset]); + offset += 4; + + LogString( "New UI state: %d.\n", g_iCurState ); + + // Update our icon. + UpdateAppIcon(); + + g_bScreensaverMode = (*((char*)&pData[offset]) != 0); + ++offset; + + // Store the current password. + if ( g_pPassword ) + delete [] g_pPassword; + + const char *pStr = &pData[offset]; + g_pPassword = new char[ strlen( pStr ) + 1 ]; + strcpy( g_pPassword, pStr ); + offset += strlen( pStr ) + 1; + + UpdatePopupMenuState(); + } + else if ( packetID == VMPI_SERVICE_TO_UI_PATCHING ) + { + LogString( "Got a VMPI_SERVICE_TO_UI_PATCHING packet.\n" ); + + int bExitAfter = pData[offset]; + ++offset; + + char workingDir[MAX_PATH], commandLine[4096]; + V_strncpy( workingDir, &pData[offset], sizeof( workingDir ) ); + offset += V_strlen( workingDir ) + 1; + + V_strncpy( commandLine, &pData[offset], sizeof( commandLine ) ); + offset += V_strlen( commandLine ) + 1; + + // Run whatever they said to run. + STARTUPINFO si; + memset( &si, 0, sizeof( si ) ); + si.cb = sizeof( si ); + + PROCESS_INFORMATION pi; + memset( &pi, 0, sizeof( pi ) ); + if ( CreateProcess( NULL, commandLine, NULL, NULL, false, CREATE_NO_WINDOW, NULL, workingDir, &si, &pi ) ) + { + LogString( "CreateProcess succeeded:\n%s\n", commandLine ); + + CloseHandle( pi.hProcess ); + CloseHandle( pi.hThread ); + + if ( bExitAfter ) + PostQuitMessage( 0 ); + } + else + { + LogString( "CreateProcess failed: %s", GetLastErrorString() ); + } + } + else if ( packetID == VMPI_SERVICE_TO_UI_EXIT ) + { + // Exit. + PostQuitMessage( 0 ); + } +} + + +// ------------------------------------------------------------------------------------------ // +// Helpers. +// ------------------------------------------------------------------------------------------ // + +void InternalSpew( const char *pMsg ) +{ + if ( g_pConsoleWnd ) + { + g_pConsoleWnd->PrintToConsole( pMsg ); + } + + OutputDebugString( pMsg ); +} + + +SpewRetval_t MySpewOutputFunc( SpewType_t spewType, const char *pMsg ) +{ + // Prepend the time. + time_t aclock; + time( &aclock ); + struct tm *newtime = localtime( &aclock ); + + // Get rid of the \n. + char timeString[512]; + Q_strncpy( timeString, asctime( newtime ), sizeof( timeString ) ); + char *pEnd = strstr( timeString, "\n" ); + if ( pEnd ) + *pEnd = 0; + InternalSpew( timeString ); + + InternalSpew( " - " ); + InternalSpew( pMsg ); + + if ( spewType == SPEW_ASSERT ) + return SPEW_DEBUGGER; + else if( spewType == SPEW_ERROR ) + return SPEW_ABORT; + else + return SPEW_CONTINUE; +} + + + +CUIConnMgr g_ConnMgr; + +void InitConsoleWindow() +{ + // Only initialize it once. + if ( g_pConsoleWnd ) + return; + + g_pConsoleWnd = CreateConsoleWnd( + g_hInstance, + IDD_VMPI_SERVICE, + IDC_DEBUG_OUTPUT, + false ); +} + + +// ------------------------------------------------------------------------------------------ // +// Implementation of IShellIconMgrHelper. +// ------------------------------------------------------------------------------------------ // + +HMENU g_hMenu = NULL; +HMENU g_hPopupMenu = NULL; // This is just a submenu of g_hMenu. + + +bool LoadPopupMenu() +{ + g_hMenu = LoadMenu( g_hInstance, MAKEINTRESOURCE( IDR_POPUP_MENU ) ); + if ( !g_hMenu ) + { + Assert( false ); + Warning( "LoadMenu failed.\n" ); + return false; + } + + g_hPopupMenu = GetSubMenu( g_hMenu, 0 ); + return true; +} + + +void TermPopupMenu() +{ + if ( g_hMenu ) + { + DestroyMenu( g_hMenu ); + g_hMenu = NULL; + } + g_hPopupMenu = NULL; +} + + +void UpdatePopupMenuState() +{ + bool bEnabled = (g_iCurState == VMPI_SERVICE_STATE_IDLE || g_iCurState == VMPI_SERVICE_STATE_BUSY); + EnableMenuItem( g_hPopupMenu, ID_ENABLE_WORKER, bEnabled ? MF_GRAYED : MF_ENABLED ); + EnableMenuItem( g_hPopupMenu, ID_DISABLE_WORKER, !bEnabled ? MF_GRAYED : MF_ENABLED ); + + // Enable or disable console items. + EnableMenuItem( g_hPopupMenu, ID_SHOW_CONSOLE_WINDOW, g_pConsoleWnd->IsVisible() ? MF_GRAYED : MF_ENABLED ); + EnableMenuItem( g_hPopupMenu, ID_HIDE_CONSOLE_WINDOW, !g_pConsoleWnd->IsVisible() ? MF_GRAYED : MF_ENABLED ); + + CheckMenuItem( g_hPopupMenu, ID_SCREENSAVER_MODE, g_bScreensaverMode ? MF_CHECKED : MF_UNCHECKED ); + CheckMenuItem( g_hPopupMenu, ID_HIGHLIGHT_ICON_WHEN_BUSY, g_bHighlightIconWhenBusy ? MF_CHECKED : MF_UNCHECKED ); +} + + +int CALLBACK SetPasswordDlgProc( + HWND hwndDlg, // handle to dialog box + UINT uMsg, // message + WPARAM wParam, // first message parameter + LPARAM lParam // second message parameter +) +{ + switch( uMsg ) + { + case WM_INITDIALOG: + { + if ( g_pPassword ) + { + HWND hWnd = GetDlgItem( hwndDlg, IDC_PASSWORD ); + SetWindowText( hWnd, g_pPassword ); + } + } + break; + + case WM_COMMAND: + { + switch( wParam ) + { + case IDOK: + { + // Set our new password. + HWND hWnd = GetDlgItem( hwndDlg, IDC_PASSWORD ); + if ( hWnd ) + { + char tempBuf[512]; + GetWindowText( hWnd, tempBuf, sizeof( tempBuf ) ); + + // Send it to the service. + CUtlVector<char> data; + data.AddToTail( VMPI_SERVICE_UPDATE_PASSWORD ); + data.AddMultipleToTail( strlen( tempBuf ) + 1, tempBuf ); + g_ConnMgr.SendPacket( -1, data.Base(), data.Count() ); + } + EndDialog( hwndDlg, 0 ); + } + break; + + case IDCANCEL: + { + EndDialog( hwndDlg, 0 ); + } + break; + } + } + break; + } + + return FALSE; +} + + +class CShellIconMgrHelper : public IShellIconMgrHelper +{ +public: + virtual HINSTANCE GetHInstance() + { + return g_hInstance; + } + + virtual int WindowProc( void *pWnd, int uMsg, long wParam, long lParam ) + { + HWND hWnd = (HWND)pWnd; + + switch( uMsg ) + { + // Right button brings up the popup menu. + case MYWM_NOTIFYICON: + { + if ( lParam == WM_RBUTTONDOWN ) + { + POINT cursorPos; + GetCursorPos( &cursorPos ); + + UpdatePopupMenuState(); + + // Make a popup menu. + SetForegroundWindow( hWnd ); + TrackPopupMenu( g_hPopupMenu, TPM_RIGHTALIGN | TPM_BOTTOMALIGN, cursorPos.x, cursorPos.y, 0, hWnd, NULL ); + return 0; + } + else if ( lParam == WM_LBUTTONDOWN ) + { + // Left button brings up the console. + g_pConsoleWnd->SetVisible( true ); + UpdatePopupMenuState(); + return 0; + } + } + break; + + case WM_COMMAND: + { + switch( wParam ) + { + case ID_ENABLE_WORKER: + { + char cPacket = VMPI_SERVICE_ENABLE; + g_ConnMgr.SendPacket( -1, &cPacket, 1 ); + } + break; + + case ID_DISABLE_WORKER: + { + char cPacket = VMPI_SERVICE_DISABLE; + g_ConnMgr.SendPacket( -1, &cPacket, 1 ); + } + break; + + case ID_KILLCURRENTJOB: + { + char cPacket = VMPI_KILL_PROCESS; + g_ConnMgr.SendPacket( -1, &cPacket, 1 ); + } + break; + + case ID_HIGHLIGHT_ICON_WHEN_BUSY: + { + g_bHighlightIconWhenBusy = !g_bHighlightIconWhenBusy; + SaveStateToRegistry(); + UpdateAppIcon(); + UpdatePopupMenuState(); + } + break; + + case ID_SCREENSAVER_MODE: + { + g_bScreensaverMode = !g_bScreensaverMode; + char cPacket[2] = { VMPI_SERVICE_SCREENSAVER_MODE, g_bScreensaverMode }; + g_ConnMgr.SendPacket( -1, cPacket, sizeof( cPacket ) ); + } + break; + + + case ID_SHOW_CONSOLE_WINDOW: + { + g_pConsoleWnd->SetVisible( true ); + UpdatePopupMenuState(); + } + break; + + case ID_HIDE_CONSOLE_WINDOW: + { + g_pConsoleWnd->SetVisible( false ); + UpdatePopupMenuState(); + } + break; + + case ID_SET_PASSWORD: + { + DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_SET_PASSWORD ), NULL, SetPasswordDlgProc ); + } + break; + + case ID_EXIT_SERVICE: + { + // Quit the service app.. + char cPacket = VMPI_SERVICE_EXIT; + g_ConnMgr.SendPacket( -1, &cPacket, 1 ); + + // Stop showing the icon. + g_ShellIconMgr.Term(); + + // Wait for a bit for the connection to go away. + DWORD startTime = GetTickCount(); + while ( GetTickCount()-startTime < 2000 ) + { + g_ConnMgr.Update(); + if ( !g_ConnMgr.IsConnected() ) + break; + else + Sleep( 10 ); + } + + // Quit the UI app. + PostQuitMessage( 0 ); + return 1; + } + break; + } + } + break; + } + + return DefWindowProc( (HWND)hWnd, uMsg, wParam, lParam ); + } +}; + +CShellIconMgrHelper g_ShellIconMgrHelper; + + + +int APIENTRY WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + g_hInstance = hInstance; + + + LogString( "vmpi_service_ui startup.\n" ); + + // Don't run multiple instances. + HANDLE hMutex = CreateMutex( NULL, FALSE, "vmpi_service_ui_mutex" ); + if ( hMutex && GetLastError() == ERROR_ALREADY_EXISTS ) + return 1; + + + // Hook spew output. + SpewOutputFunc( MySpewOutputFunc ); + InitConsoleWindow(); + LogString( "Setup console window.\n" ); + + LoadStateFromRegistry(); + + // Setup the popup menu. + if( !LoadPopupMenu() ) + { + return false; + } + UpdatePopupMenuState(); + + + // Setup the tray icon. + Msg( "Waiting for jobs...\n" ); + if ( !g_ShellIconMgr.Init( &g_ShellIconMgrHelper, g_pIconTooltip, MYWM_NOTIFYICON, IDI_WAITING_ICON ) ) + { + return false; + } + + + // Connect to the VMPI service. + g_ConnMgr.InitClient(); + + LogString( "Entering main loop.\n" ); + + while ( 1 ) + { + MSG msg; + msg.message = !WM_QUIT; // So it doesn't accidentally exit. + while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) + { + if ( msg.message == WM_QUIT ) + break; + + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + if ( msg.message == WM_QUIT ) + break; + + g_ConnMgr.Update(); + if ( !g_ConnMgr.IsConnected() ) + { + g_ShellIconMgr.ChangeIcon( IDI_UNCONNECTED ); + } + + Sleep( 30 ); + } + + // Important that we call this instead of letting the destructor do it because it deletes its + // socket and it needs to cleanup some threads. + g_ConnMgr.Term(); + + g_ShellIconMgr.Term(); + + return 0; +} + + + diff --git a/utils/vmpi/vmpi_service_ui/vmpi_service_ui.rc b/utils/vmpi/vmpi_service_ui/vmpi_service_ui.rc new file mode 100644 index 0000000..c3a6c62 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/vmpi_service_ui.rc @@ -0,0 +1,171 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS +#include "resource.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_DISABLED_ICON ICON "idi_disabled_icon.ico" +IDI_VMPI_SERVICE ICON "vmpi_service.ICO" +IDI_BUSY_ICON ICON "idi_busy_icon.ico" +IDI_WAITING_ICON ICON "idi_waiting_icon.ico" +IDI_UNCONNECTED ICON "unconnec.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_POPUP_MENU MENU +BEGIN + POPUP "item1" + BEGIN + MENUITEM "&Enable", ID_ENABLE_WORKER + MENUITEM "&Disable", ID_DISABLE_WORKER + MENUITEM "&Kill Current Job", ID_KILLCURRENTJOB + MENUITEM SEPARATOR + MENUITEM "&Show Console Window", ID_SHOW_CONSOLE_WINDOW + MENUITEM "&Hide Console Window", ID_HIDE_CONSOLE_WINDOW + MENUITEM SEPARATOR + MENUITEM "Set &Password", ID_SET_PASSWORD + MENUITEM "Highlight Icon When Busy", ID_HIGHLIGHT_ICON_WHEN_BUSY + MENUITEM "Screensaver Mode", ID_SCREENSAVER_MODE + MENUITEM SEPARATOR + MENUITEM "&Exit Service", ID_EXIT_SERVICE + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""resource.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_VMPI_SERVICE DIALOG 0, 0, 454, 225 +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +CAPTION "Valve MPI Service" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_DEBUG_OUTPUT,7,7,440,211,ES_MULTILINE | ES_READONLY | WS_VSCROLL | WS_HSCROLL +END + +IDD_SET_PASSWORD DIALOG 0, 0, 134, 50 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Set Password (-mpi_pw)" +FONT 8, "MS Sans Serif" +BEGIN + EDITTEXT IDC_PASSWORD,7,7,120,14,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDOK,7,29,50,14 + PUSHBUTTON "Cancel",IDCANCEL,77,29,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_VMPI_SERVICE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 447 + TOPMARGIN, 7 + BOTTOMMARGIN, 218 + END + + IDD_SET_PASSWORD, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 127 + TOPMARGIN, 7 + BOTTOMMARGIN, 43 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_APP_TITLE "vmpi_service" + IDS_HELLO "Hello World!" + IDC_VMPI_SERVICE "VMPI_SERVICE" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/utils/vmpi/vmpi_service_ui/vmpi_service_ui.vpc b/utils/vmpi/vmpi_service_ui/vmpi_service_ui.vpc new file mode 100644 index 0000000..0f33d66 --- /dev/null +++ b/utils/vmpi/vmpi_service_ui/vmpi_service_ui.vpc @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// VMPI_SERVICE.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\..\.." +$Macro OUTBINDIR "$SRCDIR\..\game\bin" + +$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\..\common,..\,..\vmpi_service" + $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE" + } + + $Linker + { + $AdditionalDependencies "$BASE ws2_32.lib odbc32.lib odbccp32.lib" + } +} + +$Project "Vmpi_service_ui" +{ + $Folder "Source Files" + { + $File "..\iphelpers.cpp" + $File "shell_icon_mgr.cpp" + $File "vmpi_service_ui.cpp" + $File "vmpi_service_ui.rc" + $File "StdAfx.cpp" + $File "..\tcpsocket_helpers.cpp" + $File "..\ThreadedTCPSocket.cpp" + $File "..\..\common\consolewnd.cpp" + $File "..\vmpi_service\service_conn_mgr.cpp" + $File "..\ThreadedTCPSocketEmu.cpp" + $File "..\threadhelpers.cpp" + } + + $Folder "Header Files" + { + $File "shell_icon_mgr.h" + $File "resource.h" + $File "StdAfx.h" + } + + $Folder "Resource Files" + { + $File "idi_busy_icon.ico" + $File "idi_disabled_icon.ico" + $File "idi_waiting_icon.ico" + $File "unconnec.ico" + $File "vmpi_service.ico" + } +} |