diff options
Diffstat (limited to 'vgui2/src/System.cpp')
| -rw-r--r-- | vgui2/src/System.cpp | 1151 |
1 files changed, 1151 insertions, 0 deletions
diff --git a/vgui2/src/System.cpp b/vgui2/src/System.cpp new file mode 100644 index 0000000..381396f --- /dev/null +++ b/vgui2/src/System.cpp @@ -0,0 +1,1151 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +//=============================================================================// + + +#if !defined( _X360 ) +#define WIN32_LEAN_AND_MEAN +#define OEMRESOURCE +#include <windows.h> +#include <shellapi.h> +#include <shlwapi.h> +#include <shlobj.h> +#endif +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <sys/stat.h> + + +#ifdef ShellExecute +#undef ShellExecute +#endif + +#ifdef GetCurrentTime +#undef GetCurrentTime +#endif + +#ifdef GetTickCount +#undef GetTickCount +#endif + +#include <vgui/VGUI.h> +#include <vgui/ISystem.h> +#include <KeyValues.h> +#include <vgui/IInputInternal.h> +#include <vgui/ISurface.h> +#include "tier0/vcrmode.h" +#include "filesystem.h" + +#include "vgui_internal.h" +#include "filesystem_helpers.h" +#include "vgui_key_translation.h" +#include "filesystem.h" + +#if defined( _X360 ) +#include "xbox/xbox_win32stubs.h" +#endif + +#define PROTECTED_THINGS_DISABLE +// memdbgon must be the last include file in a .cpp file!!! +#include <tier0/memdbgon.h> + + + + +#ifndef _X360 + + +////////////////////////////////////////////////////////////////////////// +// +// Service Windows routines +// +////////////////////////////////////////////////////////////////////////// + +static BOOL CALLBACK GetMainApplicationWindowHWND_EnumProc( HWND hWnd, LPARAM lParam ) +{ + // Return TRUE to continue enumeration or FALSE to stop + + // Given window thread/process id + DWORD dwProcessId, dwThreadId; + dwThreadId = GetWindowThreadProcessId( hWnd, &dwProcessId ); + + // Our thread/process id + DWORD dwOurProcessId; + dwOurProcessId = GetCurrentProcessId(); + + // Foreign process + if ( dwOurProcessId != dwProcessId ) + return TRUE; + // Service window + if ( !IsWindowVisible( hWnd ) || !IsWindowEnabled( hWnd ) ) + return TRUE; + + // Assume that we found it + *( HWND * )lParam = hWnd; + return FALSE; // stop enumeration +} + +static HWND GetMainApplicationWindowHWND() +{ + HWND hWnd = NULL; + + // + // Pass 1: calling on a GUI thread + // + DWORD dwThreadId = GetCurrentThreadId(); + + GUITHREADINFO gti; + memset( >i, 0, sizeof( gti ) ); + gti.cbSize = sizeof( gti ); + GetGUIThreadInfo( dwThreadId, >i ); + + hWnd = gti.hwndActive; + for ( HWND hParent = hWnd ? GetParent( hWnd ) : hWnd; + hParent; hWnd = hParent, hParent = GetParent( hWnd ) ) + continue; + + if ( hWnd ) + return hWnd; + + // + // Pass 2: non-GUI thread requiring the main winow + // + EnumWindows( GetMainApplicationWindowHWND_EnumProc, ( LPARAM ) &hWnd ); + if ( hWnd ) + return hWnd; + + // Failed to find the window by all means... + return NULL; +} + + +#endif // #ifndef _X360 + + + +////////////////////////////////////////////////////////////////////////// +// +// ISystem implementation +// +////////////////////////////////////////////////////////////////////////// + + +using namespace vgui; + +SHORT System_GetKeyState( int virtualKeyCode ) +{ +#ifndef _X360 + return VCRHook_GetKeyState(virtualKeyCode); +#else + return 0; +#endif +} + +class CSystem : public ISystem +{ +public: + CSystem(); + ~CSystem(); + + virtual void Shutdown(); + virtual void RunFrame(); + + virtual long GetTimeMillis(); + + // returns the time at the start of the frame + virtual double GetFrameTime(); + + // returns the current time + virtual double GetCurrentTime(); + + virtual void ShellExecute(const char *command, const char *file); + + virtual int GetClipboardTextCount(); + virtual void SetClipboardText(const char *text, int textLen); + virtual void SetClipboardText(const wchar_t *text, int textLen); + virtual int GetClipboardText(int offset, char *buf, int bufLen); + virtual int GetClipboardText(int offset, wchar_t *buf, int bufLen); + + virtual void SetClipboardImage( void *pWnd, int x1, int y1, int x2, int y2 ); + + virtual bool SetRegistryString(const char *key, const char *value); + virtual bool GetRegistryString(const char *key, char *value, int valueLen); + virtual bool SetRegistryInteger(const char *key, int value); + virtual bool GetRegistryInteger(const char *key, int &value); + virtual bool DeleteRegistryKey(const char *keyName); + + virtual bool SetWatchForComputerUse(bool state); + virtual double GetTimeSinceLastUse(); + virtual int GetAvailableDrives(char *buf, int bufLen); + virtual double GetFreeDiskSpace(const char *path); + + virtual KeyValues *GetUserConfigFileData(const char *dialogName, int dialogID); + virtual void SetUserConfigFile(const char *fileName, const char *pathName); + virtual void SaveUserConfigFile(); + + virtual bool CommandLineParamExists(const char *commandName); + virtual bool GetCommandLineParamValue(const char *paramName, char *value, int valueBufferSize); + virtual const char *GetFullCommandLine(); + virtual bool GetCurrentTimeAndDate(int *year, int *month, int *dayOfWeek, int *day, int *hour, int *minute, int *second); + + // shortcut (.lnk) modification functions + virtual bool CreateShortcut(const char *linkFileName, const char *targetPath, const char *arguments, const char *workingDirectory, const char *iconFile); + virtual bool GetShortcutTarget(const char *linkFileName, char *targetPath, char *arguments, int destBufferSizes); + virtual bool ModifyShortcutTarget(const char *linkFileName, const char *targetPath, const char *arguments, const char *workingDirectory); + + virtual KeyCode KeyCode_VirtualKeyToVGUI( int keyCode ); + virtual const char *GetDesktopFolderPath(); + virtual void ShellExecuteEx( const char *command, const char *file, const char *pParams ); +private: + // auto-away data + bool m_bStaticWatchForComputerUse; + HHOOK m_hStaticKeyboardHook; + HHOOK m_hStaticMouseHook; + double m_StaticLastComputerUseTime; + int m_iStaticMouseOldX, m_iStaticMouseOldY; + + // timer data + double m_flFrameTime; + KeyValues *m_pUserConfigData; + char m_szFileName[MAX_PATH]; + char m_szPathID[MAX_PATH]; + +}; + + +CSystem g_System; +EXPOSE_SINGLE_INTERFACE_GLOBALVAR(CSystem, ISystem, VGUI_SYSTEM_INTERFACE_VERSION, g_System); + +namespace vgui +{ +vgui::ISystem *g_pSystem = &g_System; +} +//----------------------------------------------------------------------------- +// Purpose: Constructor +//----------------------------------------------------------------------------- +CSystem::CSystem() +{ + m_bStaticWatchForComputerUse = false; + m_hStaticKeyboardHook = NULL; + m_hStaticMouseHook = NULL; + m_StaticLastComputerUseTime = 0.0; + m_iStaticMouseOldX = m_iStaticMouseOldY = -1; + m_flFrameTime = 0.0; + m_pUserConfigData = NULL; +} + +//----------------------------------------------------------------------------- +// Purpose: Destructor +//----------------------------------------------------------------------------- +CSystem::~CSystem() +{ +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CSystem::Shutdown() +{ + if (m_pUserConfigData) + { + m_pUserConfigData->deleteThis(); + m_pUserConfigData = NULL; + } +} + +//----------------------------------------------------------------------------- +// Purpose: Handles all the per frame actions +//----------------------------------------------------------------------------- +void CSystem::RunFrame() +{ + // record the current frame time + m_flFrameTime = GetCurrentTime(); + + if (m_bStaticWatchForComputerUse) + { + // check for mouse movement + int x, y; + g_pInput->GetCursorPos(x, y); + // allow a little slack for jittery mice, don't reset until it's moved more than fifty pixels + if (abs((x + y) - (m_iStaticMouseOldX + m_iStaticMouseOldY)) > 50) + { + m_StaticLastComputerUseTime = GetTimeMillis() / 1000.0; + m_iStaticMouseOldX = x; + m_iStaticMouseOldY = y; + } + } +} + +//----------------------------------------------------------------------------- +// Purpose: returns the time at the start of the frame +//----------------------------------------------------------------------------- +double CSystem::GetFrameTime() +{ + return m_flFrameTime; +} + +//----------------------------------------------------------------------------- +// Purpose: returns the current time +//----------------------------------------------------------------------------- +double CSystem::GetCurrentTime() +{ + return Plat_FloatTime(); +} + + +//----------------------------------------------------------------------------- +// Purpose: returns the current time in milliseconds +//----------------------------------------------------------------------------- +long CSystem::GetTimeMillis() +{ + return (long)(GetCurrentTime() * 1000); +} + +void CSystem::ShellExecute( const char *command, const char *file ) +{ +#ifndef _X360 + ::ShellExecuteA(NULL, command, file, NULL, NULL, SW_SHOWNORMAL); +#endif +} + +void CSystem::ShellExecuteEx( const char *command, const char *file, const char *pParams ) +{ +#ifndef _X360 + ::ShellExecuteA(NULL, command, file, pParams, NULL, SW_SHOWNORMAL); +#endif +} + + +void CSystem::SetClipboardImage( void *pWnd, int x1, int y1, int x2, int y2 ) +{ +#ifndef _X360 + if ( x2 <= x1 || y2 <= y1 ) + return; + + // Main app window + HWND hWnd = ( HWND ) ( pWnd ); + if ( !hWnd ) + hWnd = GetMainApplicationWindowHWND(); + if ( !hWnd ) + return; + + // Prepare the blit + HBITMAP hBmMem = NULL; + { + // Device contexts + HDC hDc = GetDC( hWnd ); + HDC hDcMem = CreateCompatibleDC( hDc ); + hBmMem = CreateCompatibleBitmap( hDc, x2 - x1, y2 - y1 ); + HBITMAP hBmOld = ( HBITMAP ) SelectObject( hDcMem, hBmMem ); + BitBlt( hDcMem, 0, 0, x2 - x1, y2 - y1, hDc, x1, y1, SRCCOPY ); + SelectObject( hDcMem, hBmOld ); + DeleteDC( hDcMem ); + ReleaseDC( hWnd, hDc ); + // hBmMem now holds the image. + } + + if ( !OpenClipboard( GetDesktopWindow() ) ) + return; + + EmptyClipboard(); + + if (hBmMem) + { + SetClipboardData(CF_BITMAP, hBmMem); + } + + CloseClipboard(); +#endif +} + +void CSystem::SetClipboardText(const char *text, int textLen) +{ +#ifndef _X360 + if (!text) + return; + + if (textLen <= 0) + return; + + if (!OpenClipboard(GetDesktopWindow() )) + return; + + EmptyClipboard(); + + HANDLE hmem = GlobalAlloc(GMEM_MOVEABLE, textLen + 1); + if (hmem) + { + void *ptr = GlobalLock(hmem); + if (ptr != null) + { + memset(ptr, 0, textLen + 1); + memcpy(ptr, text, textLen); + GlobalUnlock(hmem); + + SetClipboardData(CF_TEXT, hmem); + } + } + + CloseClipboard(); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Puts unicode text into the clipboard +//----------------------------------------------------------------------------- +void CSystem::SetClipboardText(const wchar_t *text, int textLen) +{ +#ifndef _X360 + if (!text) + return; + + if (textLen <= 0) + return; + + BOOL cb = OpenClipboard(GetDesktopWindow() ); + if (!cb) + return; + + EmptyClipboard(); + + HANDLE hmem = GlobalAlloc(GMEM_MOVEABLE, (textLen + 1) * sizeof(wchar_t)); + if (hmem) + { + void *ptr = GlobalLock(hmem); + if (ptr != null) + { + memset(ptr, 0, (textLen + 1) * sizeof(wchar_t)); + memcpy(ptr, text, textLen * sizeof(wchar_t)); + GlobalUnlock(hmem); + + SetClipboardData( CF_UNICODETEXT, hmem ); + } + } + + CloseClipboard(); +#endif +} + +int CSystem::GetClipboardTextCount() +{ +#ifndef _X360 + int count = 0; + + if ( VCRGetMode() != VCR_Playback ) + { + if (OpenClipboard(GetDesktopWindow() )) + { + HANDLE hmem = GetClipboardData(CF_TEXT); + if (hmem) + { + count = GlobalSize(hmem); + } + + CloseClipboard(); + } + } + VCRGenericValue( "clipboard", &count, sizeof( count ) ); + + return count; +#else + return 0; +#endif +} + +int CSystem::GetClipboardText(int offset, char *buf, int bufLen) +{ +#ifndef _X360 + int count = 0; + if ( buf && bufLen > 0 && VCRGetMode() != VCR_Playback ) + { + if (OpenClipboard(GetDesktopWindow())) + { + HANDLE hmem = GetClipboardData(CF_UNICODETEXT); + if (hmem) + { + int len = GlobalSize(hmem); + count = len - offset; + if (count <= 0) + { + count = 0; + } + else + { + if (bufLen < count) + { + count = bufLen; + } + void *ptr = GlobalLock(hmem); + if (ptr) + { + memcpy(buf, ((char *)ptr) + offset, count); + GlobalUnlock(hmem); + } + } + } + + CloseClipboard(); + } + } + VCRGenericValue( "cb", &count, sizeof( count ) ); + VCRGenericValue( "cb", buf, count ); + + return count; +#else + return 0; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: Retrieves unicode text from the clipboard +//----------------------------------------------------------------------------- +int CSystem::GetClipboardText(int offset, wchar_t *buf, int bufLen) +{ +#ifndef _X360 + int retVal = 0; + if ( buf && bufLen > 0 && VCRGetMode() != VCR_Playback ) + { + if (OpenClipboard( GetDesktopWindow() ) ) + { + HANDLE hmem = GetClipboardData(CF_UNICODETEXT); + if (hmem) + { + int len = GlobalSize(hmem); + int count = len - offset; + if (count > 0) + { + if (bufLen < count) + { + count = bufLen; + } + void *ptr = GlobalLock(hmem); + if (ptr) + { + memcpy(buf, ((wchar_t *)ptr) + offset, count); + retVal = count / sizeof(wchar_t); + GlobalUnlock(hmem); + } + } + } + } + + CloseClipboard(); + } + + VCRGenericValue( "cb", &retVal, sizeof( retVal ) ); + VCRGenericValue( "cb", buf, retVal*sizeof(wchar_t) ); + + return retVal; +#else + return 0; +#endif +} + +static bool staticSplitRegistryKey(const char *key, char *key0, int key0Len, char *key1, int key1Len) +{ + if(key==null) + { + return false; + } + + int len=strlen(key); + if(len<=0) + { + 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; + } + + vgui_strcpy(key0,Start+1,key); + vgui_strcpy(key1,(len-Start)+1,key+Start); + + return true; +} + +bool CSystem::SetRegistryString(const char *key, const char *value) +{ +#ifndef _X360 + HKEY hKey; + + 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; + } + + char key0[256], key1[256]; + if (!staticSplitRegistryKey(key, key0, sizeof(key0), key1, sizeof(key1))) + { + return false; + } + + if(VCRHook_RegCreateKeyEx(hSlot,key0,null,null,REG_OPTION_NON_VOLATILE, value ? KEY_WRITE : KEY_ALL_ACCESS,null,&hKey,null)!=ERROR_SUCCESS) + { + return false; + } + + if (VCRHook_RegSetValueEx(hKey, key1, NULL, REG_SZ, (uchar*)value, strlen(value) + 1) == ERROR_SUCCESS) + { + VCRHook_RegCloseKey(hKey); + return true; + } + + VCRHook_RegCloseKey(hKey); +#endif + + return false; +} + +bool CSystem::GetRegistryString(const char *key, char *value, int valueLen) +{ +#ifndef _X360 + if (!value) + return false; + value[0] = 0; + + HKEY hKey; + + 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; + } + + char key0[256],key1[256]; + if(!staticSplitRegistryKey(key,key0,256,key1,256)) + { + return false; + } + + if(VCRHook_RegOpenKeyEx(hSlot,key0,null,KEY_READ,&hKey)!=ERROR_SUCCESS) + { + return false; + } + + ulong len=valueLen; + if(VCRHook_RegQueryValueEx(hKey,key1,null,null,(uchar*)value,&len)==ERROR_SUCCESS) + { + VCRHook_RegCloseKey(hKey); + return true; + } + + VCRHook_RegCloseKey(hKey); +#endif + + return false; +} + +bool CSystem::SetRegistryInteger(const char *key, int value) +{ +#ifndef _X360 + HKEY hKey; + 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; + } + + char key0[256],key1[256]; + if(!staticSplitRegistryKey(key,key0,256,key1,256)) + { + return false; + } + + if(VCRHook_RegCreateKeyEx(hSlot,key0,null,null,REG_OPTION_NON_VOLATILE,KEY_WRITE,null,&hKey,null)!=ERROR_SUCCESS) + { + return false; + } + + if(VCRHook_RegSetValueEx(hKey,key1,null,REG_DWORD,(uchar*)&value,4)==ERROR_SUCCESS) + { + VCRHook_RegCloseKey(hKey); + return true; + } + + VCRHook_RegCloseKey(hKey); +#endif + return false; +} + +bool CSystem::GetRegistryInteger(const char *key, int &value) +{ +#ifndef _X360 + HKEY hKey; + 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; + } + + char key0[256],key1[256]; + if(!staticSplitRegistryKey(key,key0,256,key1,256)) + { + return false; + } + + if(VCRHook_RegOpenKeyEx(hSlot,key0,null,KEY_READ,&hKey)!=ERROR_SUCCESS) + { + return false; + } + + ulong len=4; + if(VCRHook_RegQueryValueEx(hKey,key1,null,null,(uchar*)&value,&len)==ERROR_SUCCESS) + { + VCRHook_RegCloseKey(hKey); + return true; + } + + VCRHook_RegCloseKey(hKey); +#endif + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: recursively deletes a registry key and all it's subkeys +//----------------------------------------------------------------------------- +bool CSystem::DeleteRegistryKey(const char *key) +{ +#ifndef _X360 + 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 (SHDeleteKey(hSlot, key) == ERROR_SUCCESS) + { + return true; + } +#endif + return false; +} + +//----------------------------------------------------------------------------- +// Purpose: sets whether or not the app watches for global computer use +//----------------------------------------------------------------------------- +bool CSystem::SetWatchForComputerUse(bool state) +{ + if (state == m_bStaticWatchForComputerUse) + return true; + + m_bStaticWatchForComputerUse = state; + + if (m_bStaticWatchForComputerUse) + { + // enable watching + } + else + { + // disable watching + } + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: returns the time, in seconds, since the last computer use. +//----------------------------------------------------------------------------- +double CSystem::GetTimeSinceLastUse() +{ + if (m_bStaticWatchForComputerUse) + { + return (GetTimeMillis() / 1000.0) - m_StaticLastComputerUseTime; + } + + return 0.0f; +} + +//----------------------------------------------------------------------------- +// Purpose: Get the drives a user has available on their system +//----------------------------------------------------------------------------- +int CSystem::GetAvailableDrives(char *buf, int bufLen) +{ +#if defined( _X360 ) || defined ( OSX ) + return 0; +#else // Windows + return GetLogicalDriveStrings( bufLen, buf ); +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: returns the amount of available disk space, in bytes, on the specified path +//----------------------------------------------------------------------------- +double CSystem::GetFreeDiskSpace(const char *path) +{ + char buf[_MAX_PATH]; + strcpy(buf, path); + // strip of to first slash (to make it look like 'x:\') + char *slash = strstr(buf, "\\"); + if (slash) + { + slash[1] = 0; + } + + ULARGE_INTEGER userFreeBytes, totalBytes, totalFreeBytes; + if (::GetDiskFreeSpaceEx(buf, &userFreeBytes, &totalBytes, &totalFreeBytes)) + { + return (double)userFreeBytes.QuadPart; + } + return 0.0; +} + +//----------------------------------------------------------------------------- +// Purpose: user config +//----------------------------------------------------------------------------- +KeyValues *CSystem::GetUserConfigFileData(const char *dialogName, int dialogID) +{ + if (!m_pUserConfigData) + return NULL; + + Assert(dialogName && *dialogName); + + if (dialogID) + { + char buf[256]; + Q_snprintf(buf, sizeof(buf), "%s_%d", dialogName, dialogID); + dialogName = buf; + } + + return m_pUserConfigData->FindKey(dialogName, true); +} + +//----------------------------------------------------------------------------- +// Purpose: sets the name of the config file to save/restore from. Settings are loaded immediately. +//----------------------------------------------------------------------------- +void CSystem::SetUserConfigFile(const char *fileName, const char *pathName) +{ + if (!m_pUserConfigData) + { + m_pUserConfigData = new KeyValues("UserConfigData"); + } + + strncpy(m_szFileName, fileName, sizeof(m_szFileName) - 1); + strncpy(m_szPathID, pathName, sizeof(m_szPathID) - 1); + + // open + m_pUserConfigData->UsesEscapeSequences( true ); // VGUI may use this + m_pUserConfigData->LoadFromFile(g_pFullFileSystem, m_szFileName, m_szPathID); +} + +//----------------------------------------------------------------------------- +// Purpose: saves all the current settings to the user config file +//----------------------------------------------------------------------------- +void CSystem::SaveUserConfigFile() +{ + if (m_pUserConfigData) + { + m_pUserConfigData->SaveToFile(g_pFullFileSystem, m_szFileName, m_szPathID); + } +} + +//----------------------------------------------------------------------------- +// Purpose: returns whether or not the parameter was on the command line +//----------------------------------------------------------------------------- +bool CSystem::CommandLineParamExists(const char *paramName) +{ + const char *cmdLine = GetFullCommandLine(); + const char *loc = strstr(cmdLine, paramName); + return (loc != NULL); +} + +//----------------------------------------------------------------------------- +// Purpose: gets the string following a command line param +//----------------------------------------------------------------------------- +bool CSystem::GetCommandLineParamValue(const char *paramName, char *value, int valueBufferSize) +{ + const char *cmdLine = GetFullCommandLine(); + const char *loc = strstr(cmdLine, paramName); + if (!loc) + return false; + + loc += strlen(paramName); + + char token[512]; + ParseFile(loc, token, NULL); + + strncpy(value, token, valueBufferSize - 1); + value[valueBufferSize - 1] = 0; + + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: returns the name of the currently running exe +//----------------------------------------------------------------------------- +const char *CSystem::GetFullCommandLine() +{ + return VCRHook_GetCommandLine(); +} + + +KeyCode CSystem::KeyCode_VirtualKeyToVGUI( int keyCode ) +{ + return ::KeyCode_VirtualKeyToVGUI( keyCode ); +} + +//----------------------------------------------------------------------------- +// Purpose: returns the current local time and date +//----------------------------------------------------------------------------- +bool CSystem::GetCurrentTimeAndDate(int *year, int *month, int *dayOfWeek, int *day, int *hour, int *minute, int *second) +{ + SYSTEMTIME time; + GetLocalTime(&time); + if (year) + { + *year = time.wYear; + } + if (month) + { + *month = time.wMonth; + } + if (dayOfWeek) + { + *dayOfWeek = time.wDayOfWeek; + } + if (day) + { + *day = time.wDay; + } + if (hour) + { + *hour = time.wHour; + } + if (minute) + { + *minute = time.wMinute; + } + if (second) + { + *second = time.wSecond; + } + return true; +} + +//----------------------------------------------------------------------------- +// Purpose: Creates a shortcut file +//----------------------------------------------------------------------------- +bool CSystem::CreateShortcut(const char *linkFileName, const char *targetPath, const char *arguments, const char *workingDirectory, const char *iconFile) +{ +#ifndef _X360 + bool bSuccess = false; + char temp[MAX_PATH]; + strcpy(temp, linkFileName); + + // make sure it doesn't already exist + struct _stat statBuf; + if (_stat(linkFileName, &statBuf) != -1) + return false; + + // Create the ShellLink object + IShellLink *psl; + HRESULT hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*) &psl); + if (SUCCEEDED(hres)) + { + // Set the target information from the link object + psl->SetPath(targetPath); + psl->SetArguments(arguments); + if (workingDirectory && *workingDirectory) + { + psl->SetWorkingDirectory(workingDirectory); + } + if (iconFile && *iconFile) + { + psl->SetIconLocation(iconFile, 0); + } + + // Bind the ShellLink object to the Persistent File + IPersistFile *ppf; + hres = psl->QueryInterface( IID_IPersistFile, (LPVOID *) &ppf); + if (SUCCEEDED(hres)) + { + wchar_t wsz[MAX_PATH]; + // Get a UNICODE wide string wsz from the link path + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, temp, -1, wsz, MAX_PATH); + hres = ppf->Save(wsz, TRUE); + if (SUCCEEDED(hres)) + { + bSuccess = true; + } + ppf->Release(); + } + psl->Release(); + } + return bSuccess; +#else + return false; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: retrieves shortcut (.lnk) information +//----------------------------------------------------------------------------- +bool CSystem::GetShortcutTarget(const char *linkFileName, char *targetPath, char *arguments, int destBufferSizes) +{ +#ifndef _X360 + char temp[MAX_PATH]; + strcpy(temp, linkFileName); + strlwr(temp); + + targetPath[0] = 0; + arguments[0] = 0; + + // Create the ShellLink object + IShellLink *psl; + HRESULT hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*) &psl); + if (SUCCEEDED(hres)) + { + IPersistFile *ppf; + // Bind the ShellLink object to the Persistent File + hres = psl->QueryInterface( IID_IPersistFile, (LPVOID *) &ppf); + if (SUCCEEDED(hres)) + { + wchar_t wsz[MAX_PATH]; + // Get a UNICODE wide string wsz from the link path + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, temp, -1, wsz, MAX_PATH); + + // Read the link into the persistent file + hres = ppf->Load(wsz, 0); + + if (SUCCEEDED(hres)) + { + //Read the target information from the link object + //UNC paths are supported (SLGP_UNCPRIORITY) + psl->GetPath(targetPath, destBufferSizes, NULL, SLGP_UNCPRIORITY); + + //Read the arguments from the link object + psl->GetArguments(arguments, destBufferSizes); + } + ppf->Release(); + } + psl->Release(); + } + return (targetPath[0] != 0); +#else + return false; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: sets shortcut (.lnk) information +//----------------------------------------------------------------------------- +bool CSystem::ModifyShortcutTarget(const char *linkFileName, const char *targetPath, const char *arguments, const char *workingDirectory) +{ +#ifndef _X360 + bool bSuccess = false; + char temp[MAX_PATH]; + strcpy(temp, linkFileName); + strlwr(temp); + + // Create the ShellLink object + IShellLink *psl; + HRESULT hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*) &psl); + if (SUCCEEDED(hres)) + { + IPersistFile *ppf; + // Bind the ShellLink object to the Persistent File + hres = psl->QueryInterface( IID_IPersistFile, (LPVOID *) &ppf); + if (SUCCEEDED(hres)) + { + wchar_t wsz[MAX_PATH]; + // Get a UNICODE wide string wsz from the link path + MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, temp, -1, wsz, MAX_PATH); + + // Read the link into the persistent file + hres = ppf->Load(wsz, 0); + + if (SUCCEEDED(hres)) + { + // Set the target information from the link object + psl->SetPath(targetPath); + psl->SetArguments(arguments); + psl->SetWorkingDirectory(workingDirectory); + bSuccess = true; + ppf->Save(wsz, TRUE); + } + ppf->Release(); + } + psl->Release(); + } + return bSuccess; +#else + return false; +#endif +} + +//----------------------------------------------------------------------------- +// Purpose: returns the full path of the current user's desktop folder +//----------------------------------------------------------------------------- +const char *CSystem::GetDesktopFolderPath() +{ +#ifndef _X360 + static char folderPath[MAX_PATH]; + folderPath[0] = 0; + + // try the custom regkey + if ( GetRegistryString( "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Desktop", folderPath, sizeof(folderPath) ) + && strlen(folderPath) > 6 ) + { + return folderPath; + } + + + // try the default + if ( ::SHGetSpecialFolderPath( NULL, folderPath, CSIDL_DESKTOP, false ) + && strlen(folderPath) > 6 ) + { + return folderPath; + } +#endif + return NULL; +} |