summaryrefslogtreecommitdiff
path: root/utils/vproject
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/vproject
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/vproject')
-rw-r--r--utils/vproject/sys_utils.cpp436
-rw-r--r--utils/vproject/sys_utils.h35
-rw-r--r--utils/vproject/vproject.cpp648
-rw-r--r--utils/vproject/vproject.h33
-rw-r--r--utils/vproject/vproject.icobin0 -> 318 bytes
-rw-r--r--utils/vproject/vproject.rc116
-rw-r--r--utils/vproject/vproject.vpc39
7 files changed, 1307 insertions, 0 deletions
diff --git a/utils/vproject/sys_utils.cpp b/utils/vproject/sys_utils.cpp
new file mode 100644
index 0000000..4e8de68
--- /dev/null
+++ b/utils/vproject/sys_utils.cpp
@@ -0,0 +1,436 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// SYS_UTILS.C
+//
+//=====================================================================================//
+#include "sys_utils.h"
+
+//-----------------------------------------------------------------------------
+// Sys_SplitRegistryKey
+//
+//-----------------------------------------------------------------------------
+static BOOL Sys_SplitRegistryKey( const CHAR *key, CHAR *key0, int key0Len, CHAR *key1, int key1Len )
+{
+ if ( !key )
+ return false;
+
+ int len = (int)strlen( key );
+ if ( !len )
+ return false;
+
+ int Start = -1;
+ for ( int i = len-1; i >= 0; i-- )
+ {
+ if ( key[i] == '\\' )
+ break;
+ else
+ Start=i;
+ }
+
+ if ( Start == -1 )
+ return false;
+
+ _snprintf( key0, Start, key );
+ key0[Start] = '\0';
+
+ _snprintf( key1, ( len-Start )+1, key+Start );
+ key1[( len-Start )+1] = '\0';
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Sys_SetRegistryString
+//
+//-----------------------------------------------------------------------------
+BOOL Sys_SetRegistryString( const CHAR *key, const CHAR *value )
+{
+ HKEY hKey;
+ CHAR key0[256];
+ CHAR key1[256];
+
+ HKEY hSlot = HKEY_CURRENT_USER;
+ if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
+ {
+ hSlot = HKEY_LOCAL_MACHINE;
+ key += 19;
+ }
+ else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
+ {
+ hSlot = HKEY_CURRENT_USER;
+ key += 18;
+ }
+
+ if ( !Sys_SplitRegistryKey( key, key0, sizeof( key0 ), key1, sizeof( key1 ) ) )
+ return false;
+
+ if ( RegCreateKeyEx( hSlot,key0,NULL,NULL,REG_OPTION_NON_VOLATILE, value ? KEY_WRITE : KEY_ALL_ACCESS,NULL,&hKey,NULL )!=ERROR_SUCCESS )
+ return false;
+
+ if ( RegSetValueEx( hKey, key1, NULL, REG_SZ, ( UCHAR* )value, (int)strlen( value ) + 1 ) != ERROR_SUCCESS )
+ {
+ RegCloseKey( hKey );
+ return false;
+ }
+
+ // success
+ RegCloseKey( hKey );
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Sys_GetRegistryString
+//
+//-----------------------------------------------------------------------------
+BOOL Sys_GetRegistryString( const CHAR *key, CHAR *value, const CHAR* defValue, int valueLen )
+{
+ HKEY hKey;
+ CHAR key0[256];
+ CHAR key1[256];
+
+ if ( defValue )
+ _snprintf( value, valueLen, defValue );
+
+ HKEY hSlot = HKEY_CURRENT_USER;
+ if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
+ {
+ hSlot = HKEY_LOCAL_MACHINE;
+ key += 19;
+ }
+ else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
+ {
+ hSlot = HKEY_CURRENT_USER;
+ key += 18;
+ }
+
+ if ( !Sys_SplitRegistryKey( key,key0,256,key1,256 ) )
+ return false;
+
+ if ( RegOpenKeyEx( hSlot,key0,NULL,KEY_READ,&hKey )!=ERROR_SUCCESS )
+ return false;
+
+ unsigned long len=valueLen;
+ if ( RegQueryValueEx( hKey,key1,NULL,NULL,( UCHAR* )value,&len )!=ERROR_SUCCESS )
+ {
+ RegCloseKey( hKey );
+ return false;
+ }
+
+ // success
+ RegCloseKey( hKey );
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Sys_SetRegistryInteger
+//
+//-----------------------------------------------------------------------------
+BOOL Sys_SetRegistryInteger( const CHAR *key, int value )
+{
+ HKEY hKey;
+ CHAR key0[256];
+ CHAR key1[256];
+
+ HKEY hSlot = HKEY_CURRENT_USER;
+ if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
+ {
+ hSlot = HKEY_LOCAL_MACHINE;
+ key += 19;
+ }
+ else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
+ {
+ hSlot = HKEY_CURRENT_USER;
+ key += 18;
+ }
+
+ if ( !Sys_SplitRegistryKey( key,key0,256,key1,256 ) )
+ return false;
+
+ if ( RegCreateKeyEx( hSlot, key0, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL )!=ERROR_SUCCESS )
+ return false;
+
+ if ( RegSetValueEx( hKey, key1, NULL, REG_DWORD, ( UCHAR* )&value, 4 )!=ERROR_SUCCESS )
+ {
+ RegCloseKey( hKey );
+ return false;
+ }
+
+ // success
+ RegCloseKey( hKey );
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Sys_GetRegistryInteger
+//
+//-----------------------------------------------------------------------------
+BOOL Sys_GetRegistryInteger( const CHAR *key, int defValue, int &value )
+{
+ HKEY hKey;
+ CHAR key0[256];
+ CHAR key1[256];
+
+ value = defValue;
+
+ HKEY hSlot = HKEY_CURRENT_USER;
+ if ( !strncmp( key, "HKEY_LOCAL_MACHINE", 18 ) )
+ {
+ hSlot = HKEY_LOCAL_MACHINE;
+ key += 19;
+ }
+ else if ( !strncmp( key, "HKEY_CURRENT_USER", 17 ) )
+ {
+ hSlot = HKEY_CURRENT_USER;
+ key += 18;
+ }
+
+ if ( !Sys_SplitRegistryKey( key, key0, 256, key1, 256 ) )
+ return false;
+
+ if ( RegOpenKeyEx( hSlot, key0, NULL, KEY_READ, &hKey ) != ERROR_SUCCESS )
+ return false;
+
+ unsigned long len=4;
+ if ( RegQueryValueEx( hKey, key1, NULL, NULL, ( UCHAR* )&value, &len ) != ERROR_SUCCESS )
+ {
+ RegCloseKey( hKey );
+ return false;
+ }
+
+ // success
+ RegCloseKey( hKey );
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Sys_NormalizePath
+//
+//-----------------------------------------------------------------------------
+void Sys_NormalizePath( CHAR* path, bool forceToLower )
+{
+ int srcLen = (int)strlen( path );
+ for ( int i=0; i<srcLen; i++ )
+ {
+ if ( path[i] == '/' )
+ path[i] = '\\';
+ else if ( forceToLower && ( path[i] >= 'A' && path[i] <= 'Z' ) )
+ path[i] = path[i] - 'A' + 'a';
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Sys_SkipWhitespace
+//
+//-----------------------------------------------------------------------------
+CHAR* Sys_SkipWhitespace( CHAR *data, BOOL *hasNewLines, int* pNumLines )
+{
+ int c;
+
+ while( ( c = *data ) <= ' ' )
+ {
+ if ( c == '\n' )
+ {
+ if ( pNumLines )
+ (*pNumLines)++;
+
+ if ( hasNewLines )
+ *hasNewLines = true;
+ }
+ else if ( !c )
+ return ( NULL );
+
+ data++;
+ }
+
+ return ( data );
+}
+
+//-----------------------------------------------------------------------------
+// Sys_PeekToken
+//
+//-----------------------------------------------------------------------------
+CHAR* Sys_PeekToken( CHAR *dataptr, BOOL bAllowLineBreaks )
+{
+ CHAR *saved;
+ CHAR *pToken;
+
+ saved = dataptr;
+ pToken = Sys_GetToken( &saved, bAllowLineBreaks, NULL );
+
+ return pToken;
+}
+
+//-----------------------------------------------------------------------------
+// Sys_GetToken
+//
+//-----------------------------------------------------------------------------
+CHAR* Sys_GetToken( CHAR** dataptr, BOOL allowLineBreaks, int* pNumLines )
+{
+ CHAR c;
+ int len;
+ BOOL hasNewLines;
+ CHAR* data;
+ static CHAR token[MAX_SYSTOKENCHARS];
+
+ c = 0;
+ data = *dataptr;
+ len = 0;
+ token[0] = 0;
+ hasNewLines = false;
+
+ // make sure incoming data is valid
+ if ( !data )
+ {
+ *dataptr = NULL;
+ return ( token );
+ }
+
+ for ( ;; )
+ {
+ // skip whitespace
+ data = Sys_SkipWhitespace( data, &hasNewLines, pNumLines );
+ if ( !data )
+ {
+ *dataptr = NULL;
+ return ( token );
+ }
+
+ if ( hasNewLines && !allowLineBreaks )
+ {
+ *dataptr = data;
+ return ( token );
+ }
+
+ c = *data;
+
+ if ( c == '/' && data[1] == '/' )
+ {
+ // skip double slash comments
+ data += 2;
+ while ( *data && *data != '\n' )
+ data++;
+ if ( *data && *data == '\n' )
+ {
+ data++;
+ if ( pNumLines )
+ (*pNumLines)++;
+ }
+ }
+ else if ( c =='/' && data[1] == '*' )
+ {
+ // skip /* */ comments
+ data += 2;
+ while ( *data && ( *data != '*' || data[1] != '/' ) )
+ {
+ if ( *data == '\n' && pNumLines )
+ (*pNumLines)++;
+ data++;
+ }
+
+ if ( *data )
+ data += 2;
+ }
+ else
+ break;
+ }
+
+ // handle quoted strings
+ if ( c == '\"' || c == '<' )
+ {
+ data++;
+ for ( ;; )
+ {
+ c = *data++;
+ if ( c == '\"' || c == '>' || !c )
+ {
+ token[len] = 0;
+ *dataptr = ( CHAR* )data;
+ return ( token );
+ }
+ if ( len < MAX_SYSTOKENCHARS )
+ token[len++] = c;
+ }
+ }
+
+ // parse a regular word
+ do
+ {
+ if ( len < MAX_SYSTOKENCHARS )
+ token[len++] = c;
+
+ data++;
+ c = *data;
+ }
+ while ( c > ' ' );
+
+ if ( len >= MAX_SYSTOKENCHARS )
+ len = 0;
+
+ token[len] = '\0';
+ *dataptr = (CHAR*)data;
+
+ return token;
+}
+
+//-----------------------------------------------------------------------------
+// Sys_SkipBracedSection
+//
+// The next token should be an open brace.
+// Skips until a matching close brace is found.
+// Internal brace depths are properly skipped.
+//-----------------------------------------------------------------------------
+void Sys_SkipBracedSection( CHAR** dataptr, int* numlines )
+{
+ CHAR* token;
+ int depth;
+
+ depth = 0;
+ do
+ {
+ token = Sys_GetToken( dataptr, true, numlines );
+ if ( token[1] == '\0' )
+ {
+ if ( token[0] == '{' )
+ depth++;
+ else if ( token[0] == '}' )
+ depth--;
+ }
+ }
+ while( depth && *dataptr );
+}
+
+//-----------------------------------------------------------------------------
+// Sys_SkipRestOfLine
+//
+//-----------------------------------------------------------------------------
+void Sys_SkipRestOfLine( CHAR** dataptr, int* numlines )
+{
+ CHAR* p;
+ int c;
+
+ p = *dataptr;
+ while ( ( c = *p++ ) != '\0' )
+ {
+ if ( c == '\n' )
+ {
+ if ( numlines )
+ ( *numlines )++;
+ break;
+ }
+ }
+ *dataptr = p;
+}
+
+void Sys_StripQuotesFromToken( CHAR *pToken )
+{
+ int len;
+
+ len = (int)strlen( pToken );
+ if ( len >= 2 && pToken[0] == '\"' )
+ {
+ memcpy( pToken, pToken+1, len-1 );
+ pToken[len-2] = '\0';
+ }
+}
+
+
diff --git a/utils/vproject/sys_utils.h b/utils/vproject/sys_utils.h
new file mode 100644
index 0000000..595ba1d
--- /dev/null
+++ b/utils/vproject/sys_utils.h
@@ -0,0 +1,35 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// SYS_UTILS.H
+//
+// System Utilities.
+//=====================================================================================//
+#pragma once
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define MAX_SYSTOKENCHARS 1024
+
+extern void Sys_NormalizePath( CHAR *path, bool forceToLower );
+extern CHAR* Sys_PeekToken( CHAR *dataptr, BOOL bAllowLineBreaks );
+extern CHAR *Sys_GetToken( CHAR **dataptr, BOOL crossline, int *numlines );
+extern CHAR *Sys_SkipWhitespace( CHAR *data, BOOL *hasNewLines, int *numlines );
+extern void Sys_SkipBracedSection( CHAR **dataptr, int *numlines );
+extern void Sys_SkipRestOfLine( CHAR **dataptr, int *numlines );
+extern void Sys_StripQuotesFromToken( CHAR *pToken );
+extern BOOL Sys_SetRegistryString( const CHAR *key, const CHAR *value );
+extern BOOL Sys_GetRegistryString( const CHAR *key, CHAR *value, const CHAR *defValue, int valueLen );
+extern BOOL Sys_SetRegistryInteger( const CHAR *key, int value );
+extern BOOL Sys_GetRegistryInteger( const CHAR *key, int defValue, int &value );
+
+
+
+
+
+
+
+
+
diff --git a/utils/vproject/vproject.cpp b/utils/vproject/vproject.cpp
new file mode 100644
index 0000000..36be00c
--- /dev/null
+++ b/utils/vproject/vproject.cpp
@@ -0,0 +1,648 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// VPROJECT.CPP
+//
+//=====================================================================================//
+#include "vproject.h"
+
+#define MAX_PROJECTS 50
+
+#define ID_PROJECTS_LISTVIEW 100
+
+// column id
+#define ID_PROJECT_NAME 0
+#define ID_PROJECT_DIRECTORY 1
+
+#define WM_TRAY (WM_APP + 1)
+#define ID_TRAY 5000
+#define ID_TRAY_ADDVPROJECT 6000
+#define ID_TRAY_MODIFYVPROJECT 6001
+#define ID_TRAY_MOVEUP 6002
+#define ID_TRAY_MOVEDOWN 6003
+#define ID_TRAY_EXIT 6004
+
+typedef struct
+{
+ char *pName;
+ char *pGamedir;
+} project_t;
+
+HWND g_hWnd;
+char g_project_name[256];
+char g_project_gamedir[256];
+HINSTANCE g_hInstance;
+project_t g_projects[MAX_PROJECTS];
+int g_numProjects;
+NOTIFYICONDATA g_iconData;
+HMENU g_hMenu;
+int g_nActiveVProject;
+POINT g_cursorPoint;
+
+void TrayMessageHandler( HWND hWnd, UINT uMessageID );
+
+//-----------------------------------------------------------------------------
+// SetVProject
+//
+//-----------------------------------------------------------------------------
+void SetVProject( const char *pProjectName )
+{
+ char *pGamedir;
+ char project[256];
+ int i;
+
+ if ( pProjectName )
+ {
+ strcpy( project, pProjectName );
+ Sys_StripQuotesFromToken( project );
+
+ for ( i=0; i<g_numProjects; i++ )
+ {
+ if ( !stricmp( g_projects[i].pName, project ) )
+ {
+ // found
+ break;
+ }
+ }
+
+ if ( i >= g_numProjects )
+ {
+ // not found
+ return;
+ }
+
+ pGamedir = g_projects[i].pGamedir;
+ }
+ else
+ {
+ pGamedir = "";
+ }
+
+ // Changed to CURRENT_USER to solve security issues in vista!
+ Sys_SetRegistryString(
+ //"HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment\\VProject",
+ "HKEY_CURRENT_USER\\Environment\\VProject"
+ pGamedir );
+
+ DWORD result;
+ SendMessageTimeout(
+ HWND_BROADCAST,
+ WM_SETTINGCHANGE,
+ 0,
+ (LPARAM)"Environment",
+ SMTO_ABORTIFHUNG,
+ 0,
+ &result );
+}
+
+//-----------------------------------------------------------------------------
+// ModifyVProject
+//
+//-----------------------------------------------------------------------------
+void ModifyVProject( int index, const char *pName, const char *pGamedir )
+{
+ free( g_projects[index].pName );
+ free( g_projects[index].pGamedir );
+
+ if ( !pName || !pName[0] )
+ {
+ // delete
+ if ( g_numProjects-index-1 > 0 )
+ {
+ // shift remaining elements
+ memcpy( &g_projects[index], &g_projects[index+1], (g_numProjects-index-1)*sizeof( project_t ) );
+ }
+
+ g_projects[g_numProjects-1].pName = NULL;
+ g_projects[g_numProjects-1].pGamedir = NULL;
+
+ g_numProjects--;
+
+ if ( g_nActiveVProject == index+1 )
+ {
+ // deleted current vproject
+ if ( !g_numProjects )
+ {
+ // no more projects
+ g_nActiveVProject = 0;
+ SetVProject( NULL );
+ }
+ else
+ {
+ // set to top
+ g_nActiveVProject = 1;
+ SetVProject( g_projects[0].pName );
+ }
+ }
+ }
+ else
+ {
+ g_projects[index].pName = strdup( pName );
+ g_projects[index].pGamedir = strdup( pGamedir );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// AddVProject
+//
+//-----------------------------------------------------------------------------
+void AddVProject( const char *pName, const char *pGamedir )
+{
+ if ( !pName || !pName[0] )
+ {
+ // do not add empty projects
+ return;
+ }
+
+ ModifyVProject( g_numProjects, pName, pGamedir );
+ g_numProjects++;
+}
+
+//-----------------------------------------------------------------------------
+// LoadRegistryValues
+//
+//-----------------------------------------------------------------------------
+void LoadRegistryValues()
+{
+ char keyBuff[32];
+ char valueBuff[256];
+ char projectName[256];
+ char gamedirString[256];
+ char *ptr;
+ char *token;
+ int i;
+
+ for ( i=0; i<MAX_PROJECTS; i++ )
+ {
+ projectName[0] = '\0';
+ gamedirString[0] = '\0';
+
+ sprintf( keyBuff, "project%d", i );
+ Sys_GetRegistryString( keyBuff, valueBuff, "", sizeof( valueBuff ) );
+
+ // parse and populate valid values
+ ptr = valueBuff;
+ token = Sys_GetToken( &ptr, false, NULL );
+ if ( token[0] )
+ {
+ strcpy( projectName, token );
+ }
+ else
+ {
+ continue;
+ }
+
+ token = Sys_GetToken( &ptr, false, NULL );
+ if ( token[0] )
+ {
+ strcpy( gamedirString, token );
+ }
+
+ AddVProject( projectName, gamedirString );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// SaveRegistryValues
+//
+//-----------------------------------------------------------------------------
+void SaveRegistryValues()
+{
+ char valueBuff[256];
+ char keyBuff[32];
+ char *pProjectName;
+ char *pGamedir;
+ int len;
+ int i;
+
+ for ( i=0; i<MAX_PROJECTS; i++ )
+ {
+ sprintf( keyBuff, "project%d", i );
+
+ pProjectName = g_projects[i].pName;
+ if ( !pProjectName )
+ {
+ pProjectName = "";
+ }
+
+ pGamedir = g_projects[i].pGamedir;
+ if ( !pGamedir )
+ {
+ pGamedir = "";
+ }
+
+ len = _snprintf( valueBuff, sizeof( valueBuff ), "\"%s\" \"%s\"", pProjectName, pGamedir );
+ if ( len == -1 )
+ {
+ // kill it
+ valueBuff[0] = '\0';
+ }
+
+ Sys_SetRegistryString( keyBuff, valueBuff );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// ShiftActiveProjectUp
+//
+//-----------------------------------------------------------------------------
+void ShiftActiveProjectUp()
+{
+ if ( g_numProjects <= 1 || !g_nActiveVProject )
+ {
+ // nothing to do
+ return;
+ }
+
+ int active = g_nActiveVProject-1;
+ int previous = (active + g_numProjects - 1) % g_numProjects;
+
+ project_t tempProject;
+ tempProject = g_projects[previous];
+ g_projects[previous] = g_projects[active];
+ g_projects[active] = tempProject;
+
+ g_nActiveVProject = previous + 1;
+}
+
+//-----------------------------------------------------------------------------
+// ShiftActiveProjectDown
+//
+//-----------------------------------------------------------------------------
+void ShiftActiveProjectDown()
+{
+ if ( g_numProjects <= 1 || !g_nActiveVProject )
+ {
+ // nothing to do
+ return;
+ }
+
+ int active = g_nActiveVProject-1;
+ int next = (active + g_numProjects + 1) % g_numProjects;
+
+ project_t tempProject;
+ tempProject = g_projects[next];
+ g_projects[next] = g_projects[active];
+ g_projects[active] = tempProject;
+
+ g_nActiveVProject = next + 1;
+}
+
+//-----------------------------------------------------------------------------
+// ModifyDlg_Proc
+//
+//-----------------------------------------------------------------------------
+BOOL CALLBACK ModifyDlg_Proc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ size_t len;
+ int width;
+ int height;
+ RECT rect;
+
+ switch ( message )
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText( hWnd, IDC_MODIFY_PROJECT, g_project_name );
+ SetDlgItemText( hWnd, IDC_MODIFY_GAMEDIR, g_project_gamedir );
+
+ // center dialog
+ GetWindowRect( hWnd, &rect );
+ width = GetSystemMetrics( SM_CXSCREEN );
+ height = GetSystemMetrics( SM_CYSCREEN );
+ SetWindowPos( hWnd, NULL, ( width - ( rect.right - rect.left ) )/2, ( height - ( rect.bottom - rect.top ) )/2, 0, 0, SWP_NOSIZE | SWP_NOZORDER );
+ return ( TRUE );
+
+ case WM_COMMAND:
+ switch ( LOWORD( wParam ) )
+ {
+ case IDC_OK:
+ GetDlgItemText( hWnd, IDC_MODIFY_PROJECT, g_project_name, sizeof( g_project_name ) );
+ GetDlgItemText( hWnd, IDC_MODIFY_GAMEDIR, g_project_gamedir, sizeof( g_project_gamedir ) );
+
+ // remove trailing seperator
+ Sys_NormalizePath( g_project_gamedir, false );
+ len = strlen( g_project_gamedir );
+ if ( len > 2 && g_project_gamedir[len-1] == '\\' )
+ {
+ g_project_gamedir[len-1] = '\0';
+ }
+ // fall through
+
+ case IDCANCEL:
+ case IDC_CANCEL:
+ EndDialog( hWnd, wParam );
+ return ( TRUE );
+ }
+ break;
+ }
+ return ( FALSE );
+}
+
+//-----------------------------------------------------------------------------
+// ModifyDlg_Open
+//
+//-----------------------------------------------------------------------------
+BOOL ModifyDlg_Open()
+{
+ int result;
+
+ result = DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_VPROJECT ), g_hWnd, ( DLGPROC )ModifyDlg_Proc );
+ if ( LOWORD( result ) != IDC_OK )
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// ShowPopupMenu
+//
+//-----------------------------------------------------------------------------
+void ShowPopupMenu( HWND hWnd, bool bUseCachedMenuPos )
+{
+ BOOL bDelete = true;
+
+ // delete existing entries
+ for ( int nIndex = 1; nIndex < ID_TRAY_ADDVPROJECT && bDelete; nIndex++ )
+ {
+ bDelete = DeleteMenu( g_hMenu, nIndex, MF_BYCOMMAND );
+ }
+
+ // Insert projects
+ char szMenuItem[MAX_PATH];
+ for ( int nIndex = 0; nIndex < g_numProjects; nIndex++ )
+ {
+ strcpy( szMenuItem, g_projects[nIndex].pName );
+ strcat( szMenuItem, "\t" );
+ strcat( szMenuItem, g_projects[nIndex].pGamedir );
+ strcat( szMenuItem, " " );
+
+ InsertMenu( g_hMenu, nIndex, MF_BYPOSITION | MF_STRING, nIndex + 1, szMenuItem );
+ }
+
+ if ( g_nActiveVProject )
+ {
+ CheckMenuItem( g_hMenu, g_nActiveVProject, MF_BYCOMMAND|MF_CHECKED );
+ SetMenuDefaultItem( g_hMenu, g_nActiveVProject, FALSE );
+ }
+
+ // Display the popup menu at the current cursor location
+ // Use the cached cursor position if set
+ if ( !bUseCachedMenuPos || ( !g_cursorPoint.x && !g_cursorPoint.y ) )
+ {
+ GetCursorPos( &g_cursorPoint );
+ }
+ SetForegroundWindow( hWnd );
+ TrackPopupMenu( g_hMenu, 0, g_cursorPoint.x, g_cursorPoint.y, 0, hWnd, 0 );
+ PostMessage( hWnd, WM_NULL, 0, 0 );
+}
+
+//-----------------------------------------------------------------------------
+// TrayMessageHandler
+//
+//-----------------------------------------------------------------------------
+void TrayMessageHandler( HWND hWnd, UINT uMessageID )
+{
+ switch ( uMessageID )
+ {
+ case 0:
+ break;
+
+ case ID_TRAY_EXIT:
+ DestroyWindow( hWnd );
+ break;
+
+ case ID_TRAY_ADDVPROJECT:
+ SetForegroundWindow( hWnd );
+ g_project_name[0] = '\0';
+ g_project_gamedir[0] = '\0';
+ if ( ModifyDlg_Open() )
+ {
+ AddVProject( g_project_name, g_project_gamedir );
+ SaveRegistryValues();
+ }
+ ShowPopupMenu( hWnd, true );
+ break;
+
+ case ID_TRAY_MODIFYVPROJECT:
+ SetForegroundWindow( hWnd );
+ if ( g_nActiveVProject )
+ {
+ strcpy( g_project_name, g_projects[g_nActiveVProject-1].pName );
+ strcpy( g_project_gamedir, g_projects[g_nActiveVProject-1].pGamedir );
+ if ( ModifyDlg_Open() )
+ {
+ ModifyVProject( g_nActiveVProject-1, g_project_name, g_project_gamedir );
+ SaveRegistryValues();
+ }
+ ShowPopupMenu( hWnd, true );
+ }
+ break;
+
+ case ID_TRAY_MOVEUP:
+ SetForegroundWindow( hWnd );
+ if ( g_nActiveVProject )
+ {
+ ShiftActiveProjectUp();
+ SaveRegistryValues();
+ ShowPopupMenu( hWnd, true );
+ }
+ break;
+
+ case ID_TRAY_MOVEDOWN:
+ SetForegroundWindow( hWnd );
+ if ( g_nActiveVProject )
+ {
+ ShiftActiveProjectDown();
+ SaveRegistryValues();
+ ShowPopupMenu( hWnd, true );
+ }
+ break;
+
+ default:
+ if ( uMessageID >= 1 && uMessageID <= MAX_PROJECTS )
+ {
+ // set current vproject
+ g_nActiveVProject = uMessageID;
+ SetVProject( g_projects[uMessageID-1].pName );
+ }
+ break;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Main_WndProc
+//
+//-----------------------------------------------------------------------------
+LRESULT CALLBACK Main_WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
+{
+ switch ( message )
+ {
+ case WM_DESTROY:
+ PostQuitMessage( 0 );
+ return 0L;
+
+ case WM_TRAY:
+ if ( lParam == WM_LBUTTONDOWN || lParam == WM_RBUTTONDOWN )
+ {
+ ShowPopupMenu( hWnd, false );
+ return 0L;
+ }
+ break;
+
+ case WM_COMMAND:
+ TrayMessageHandler( hWnd, LOWORD( wParam ) );
+ break;
+ }
+
+ return ( DefWindowProc( hWnd, message, wParam, lParam ) );
+}
+
+//-----------------------------------------------------------------------------
+// Startup
+//
+//-----------------------------------------------------------------------------
+bool Startup()
+{
+ int i;
+
+ // set up our window class
+ WNDCLASS wndclass;
+ memset( &wndclass, 0, sizeof( wndclass ) );
+ wndclass.style = 0;
+ wndclass.lpfnWndProc = Main_WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = g_hInstance;
+ wndclass.hIcon = LoadIcon( g_hInstance, (LPCTSTR)IDI_VPROJECT );
+ wndclass.hCursor = LoadCursor( NULL, IDC_ARROW );
+ wndclass.hbrBackground = NULL;
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = VPROJECT_CLASSNAME;
+ if ( !RegisterClass( &wndclass ) )
+ {
+ return false;
+ }
+
+ // create the hidden window
+ g_hWnd = CreateWindow(
+ VPROJECT_CLASSNAME,
+ 0,
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ 0,
+ CW_USEDEFAULT,
+ 0,
+ NULL,
+ NULL,
+ g_hInstance,
+ NULL );
+
+ // Create tray icon
+ g_iconData.cbSize = sizeof( NOTIFYICONDATA );
+ g_iconData.hIcon = LoadIcon( g_hInstance, (LPCTSTR)IDI_VPROJECT );
+ g_iconData.hWnd = g_hWnd;
+ g_iconData.uCallbackMessage = WM_TRAY;
+ g_iconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
+ g_iconData.uID = ID_TRAY;
+ strcpy(g_iconData.szTip, "VPROJECT");
+ Shell_NotifyIcon( NIM_ADD, &g_iconData );
+
+ // Create popup menu and add initial items
+ g_hMenu = CreatePopupMenu();
+ AppendMenu( g_hMenu, MF_SEPARATOR, 0, 0);
+ AppendMenu( g_hMenu, MF_STRING, ID_TRAY_ADDVPROJECT, "Add VProject" );
+ AppendMenu( g_hMenu, MF_STRING, ID_TRAY_MODIFYVPROJECT, "Modify VProject" );
+ AppendMenu( g_hMenu, MF_STRING, ID_TRAY_MOVEUP, "Move Up" );
+ AppendMenu( g_hMenu, MF_STRING, ID_TRAY_MOVEDOWN, "Move Down" );
+ AppendMenu( g_hMenu, MF_SEPARATOR, 0, 0);
+ AppendMenu( g_hMenu, MF_STRING, ID_TRAY_EXIT, "Remove From Tray" );
+
+ // find the current vproject
+ char* vproject = getenv( "vproject" );
+ if ( vproject && vproject[0] )
+ {
+ char temp[MAX_PATH];
+ strcpy( temp, vproject );
+ Sys_NormalizePath( temp, false );
+ for ( i=0; i<g_numProjects; i++ )
+ {
+ if ( !stricmp( g_projects[i].pGamedir, temp ) )
+ {
+ // found
+ g_nActiveVProject = i+1;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Shutdown
+//
+// Free all resources
+//-----------------------------------------------------------------------------
+void Shutdown()
+{
+}
+
+//-----------------------------------------------------------------------------
+// WinMain
+//
+// Entry point for program
+//-----------------------------------------------------------------------------
+int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow )
+{
+ bool error = true;
+ MSG msg = {0};
+
+ g_hInstance = hInstance;
+
+ // get the project list
+ LoadRegistryValues();
+
+ if ( pCmdLine && pCmdLine[0] )
+ {
+ // set directly
+ SetVProject( pCmdLine );
+ return 0;
+ }
+
+ HWND hwnd = FindWindow( VPROJECT_CLASSNAME, NULL );
+ if ( hwnd )
+ {
+ // single instance only
+ return ( FALSE );
+ }
+
+ if ( !Startup() )
+ {
+ goto cleanUp;
+ }
+
+ // message pump
+ while ( GetMessage( &msg, NULL, 0, 0 ) )
+ {
+ TranslateMessage( &msg );
+ DispatchMessage( &msg );
+ }
+
+ // no-error, end of app
+ error = false;
+
+cleanUp:
+ if ( error )
+ {
+ char str[255];
+ FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, str, 255, NULL );
+ MessageBox( NULL, str, NULL, MB_OK );
+ }
+
+ Shutdown();
+
+ return ( (int)msg.wParam );
+}
+
+
diff --git a/utils/vproject/vproject.h b/utils/vproject/vproject.h
new file mode 100644
index 0000000..85cf00e
--- /dev/null
+++ b/utils/vproject/vproject.h
@@ -0,0 +1,33 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// VPROJECT.H
+//
+// Master Header.
+//=====================================================================================//
+#pragma once
+
+#include <winsock2.h>
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <richedit.h>
+#include <assert.h>
+#include <time.h>
+#include "resource.h"
+#include <sys/stat.h>
+#include "sys_utils.h"
+
+#define VPROJECT_VERSION "1.0"
+#define VPROJECT_CLASSNAME "VPROJECTCLASS"
+#define VPROJECT_TITLE "VProject"
+#define VPROJECT_MAGIC "2\\"
+#define VPROJECT_REGISTRY "HKEY_CURRENT_USER\\Software\\VProject\\" VPROJECT_MAGIC
+#ifdef _DEBUG
+#define VPROJECT_BUILDTYPE "Debug"
+#else
+#define VPROJECT_BUILDTYPE "Release"
+#endif
+
+
diff --git a/utils/vproject/vproject.ico b/utils/vproject/vproject.ico
new file mode 100644
index 0000000..d7aaa83
--- /dev/null
+++ b/utils/vproject/vproject.ico
Binary files differ
diff --git a/utils/vproject/vproject.rc b/utils/vproject/vproject.rc
new file mode 100644
index 0000000..7d6f5ad
--- /dev/null
+++ b/utils/vproject/vproject.rc
@@ -0,0 +1,116 @@
+// 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
+
+/////////////////////////////////////////////////////////////////////////////
+#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_VPROJECT ICON "vproject.ico"
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "#include ""windows.h""\r\n"
+ "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_VPROJECT DIALOGEX 0, 0, 254, 101
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION |
+ WS_SYSMENU
+CAPTION "VProject"
+FONT 8, "MS Shell Dlg", 400, 0, 0x1
+BEGIN
+ LTEXT "Project Name: (Clear To Delete)",IDC_STATIC,7,7,237,8
+ EDITTEXT IDC_MODIFY_PROJECT,7,18,237,14,ES_AUTOHSCROLL
+ LTEXT "Game Directory: (example: u:\\dev\\game\\hl2)",
+ IDC_STATIC,7,39,237,8
+ EDITTEXT IDC_MODIFY_GAMEDIR,7,50,237,14,ES_AUTOHSCROLL
+ PUSHBUTTON "Cancel",IDC_CANCEL,138,80,50,14
+ DEFPUSHBUTTON "OK",IDC_OK,194,80,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_VPROJECT, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 244
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 94
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/utils/vproject/vproject.vpc b/utils/vproject/vproject.vpc
new file mode 100644
index 0000000..6b4eb60
--- /dev/null
+++ b/utils/vproject/vproject.vpc
@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// VPROJECT.VPC
+//
+// Project Script
+//-----------------------------------------------------------------------------
+
+$Macro SRCDIR "..\.."
+$Macro OUTBINDIR "$SRCDIR\devtools\bin"
+
+$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
+
+$Project "VProject"
+{
+ $Folder "Source Files"
+ {
+ $File "vproject.cpp"
+ $File "sys_utils.cpp"
+ -$File "memoverride.cpp"
+ }
+
+ $Folder "Header Files"
+ {
+ $File "sys_utils.h"
+ $File "vproject.h"
+ }
+
+ $Folder "Resources"
+ {
+ $File "vproject.rc"
+ $File "vproject.ico"
+ }
+
+ $Folder "Link Libraries"
+ {
+ -$File "tier0"
+ -$File "tier1"
+ -$File "vstdlib"
+ }
+}