You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
7.3 KiB
265 lines
7.3 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Stuff which interacts with system libraries |
|
// |
|
//============================================================================= |
|
|
|
|
|
// Windows includes |
|
#include <windows.h> |
|
#include <direct.h> |
|
|
|
|
|
// Valve includes |
|
#include "itemtest/itemtest.h" |
|
#include "tier1/fmtstr.h" |
|
|
|
|
|
// Last include |
|
#include "tier0/memdbgon.h" |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Globals |
|
//----------------------------------------------------------------------------- |
|
HANDLE g_hChildStd_OUT_Rd = NULL; |
|
HANDLE g_hChildStd_OUT_Wr = NULL; |
|
|
|
HANDLE g_hInputFile = NULL; |
|
|
|
#define BUFSIZE 4096 |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
bool CItemUpload::CreateDirectory( const char *pszDirectory ) |
|
{ |
|
char szBuf[ BUFSIZE ]; |
|
V_strncpy( szBuf, pszDirectory, 1024 ); |
|
|
|
for ( int i = 0; i < V_strlen( szBuf ); ++i ) |
|
{ |
|
if ( szBuf[i] == '/' || szBuf[i] == '\\' ) |
|
{ |
|
szBuf[i] = '\0'; |
|
mkdir( szBuf ); |
|
szBuf[i] = CORRECT_PATH_SEPARATOR; |
|
} |
|
} |
|
|
|
mkdir( szBuf ); |
|
|
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Read output from the child process's pipe for STDOUT |
|
// and write to the parent process's pipe for STDOUT. |
|
// Stop when there is no more data. |
|
//----------------------------------------------------------------------------- |
|
static void ReadFromPipe( CItemLog *pLog ) |
|
{ |
|
DWORD dwRead; |
|
char chBuf[BUFSIZE + 1]; |
|
BOOL bSuccess = FALSE; |
|
|
|
// Close the write end of the pipe before reading from the |
|
// read end of the pipe, to control child process execution. |
|
// The pipe is assumed to have enough buffer space to hold the |
|
// data the child process has already written to it. |
|
|
|
if ( !CloseHandle( g_hChildStd_OUT_Wr ) ) |
|
return; |
|
|
|
// TODO: Prefix each line, print in color? |
|
|
|
for (;;) |
|
{ |
|
// This can hang if the process is waiting for input, for example... |
|
bSuccess = ReadFile( g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL ); |
|
|
|
if ( !bSuccess || dwRead == 0 ) |
|
break; |
|
|
|
chBuf[dwRead] = '\0'; |
|
|
|
pLog->Warning( chBuf ); |
|
} |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// |
|
//----------------------------------------------------------------------------- |
|
bool CItemUpload::RunCommandLine( const char *pszCmdLine, const char *pszWorkingDir, CItemLog *pLog ) |
|
{ |
|
bool bOk = false; |
|
|
|
Msg( "Launching: %s\n", pszCmdLine ); |
|
Msg( "Directory: %s\n", pszWorkingDir ); |
|
|
|
if ( pLog ) |
|
{ |
|
SECURITY_ATTRIBUTES saAttr; |
|
|
|
// Set the bInheritHandle flag so pipe handles are inherited. |
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); |
|
saAttr.bInheritHandle = TRUE; |
|
saAttr.lpSecurityDescriptor = NULL; |
|
|
|
// Create a pipe for the child process's STDOUT. |
|
if ( !CreatePipe( &g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0 ) ) |
|
return false; |
|
|
|
// Ensure the read handle to the pipe for STDOUT is not inherited. |
|
if ( !SetHandleInformation( g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0 ) ) |
|
return false; |
|
} |
|
|
|
// Create the child process. |
|
PROCESS_INFORMATION piProcInfo; |
|
STARTUPINFO siStartInfo; |
|
|
|
// Set up members of the PROCESS_INFORMATION structure. |
|
V_memset( &piProcInfo, 0, sizeof( PROCESS_INFORMATION ) ); |
|
|
|
// Set up members of the STARTUPINFO structure. |
|
// This structure specifies the STDIN and STDOUT handles for redirection. |
|
V_memset( &siStartInfo, 0, sizeof( STARTUPINFO ) ); |
|
siStartInfo.cb = sizeof( STARTUPINFO ); |
|
|
|
if ( pLog ) |
|
{ |
|
siStartInfo.hStdError = g_hChildStd_OUT_Wr; |
|
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr; |
|
siStartInfo.dwFlags |= STARTF_USESTDHANDLES; |
|
} |
|
|
|
// Create the child process. |
|
const BOOL bSuccess = CreateProcess(NULL, |
|
const_cast< char * >( pszCmdLine ), // command line |
|
NULL, // process security attributes |
|
NULL, // primary thread security attributes |
|
TRUE, // handles are inherited |
|
CREATE_NO_WINDOW, // creation flags |
|
NULL, // use parent's environment |
|
pszWorkingDir, // use parent's current directory |
|
&siStartInfo, // STARTUPINFO pointer |
|
&piProcInfo ); // receives PROCESS_INFORMATION |
|
|
|
// If an error occurs, return |
|
if ( !bSuccess ) |
|
return false; |
|
|
|
if ( pLog ) |
|
{ |
|
ReadFromPipe( pLog ); |
|
|
|
WaitForSingleObject( piProcInfo.hProcess, INFINITE ); |
|
|
|
bOk = false; |
|
|
|
DWORD nExitCode = 0; |
|
if ( GetExitCodeProcess( piProcInfo.hProcess, &nExitCode ) ) |
|
{ |
|
bOk = ( nExitCode == 0 ); |
|
} |
|
|
|
CloseHandle( piProcInfo.hProcess ); |
|
CloseHandle( piProcInfo.hThread ); |
|
} |
|
else |
|
{ |
|
bOk = true; |
|
} |
|
|
|
return bOk; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Determine if 2 paths point ot the same file... |
|
// Note: This only works if the file exists |
|
//----------------------------------------------------------------------------- |
|
bool CItemUpload::IsSameFile( const char *szPath1, const char *szPath2 ) |
|
{ |
|
if ( !szPath1 || !szPath2 ) |
|
return false; |
|
|
|
HANDLE handle1 = ::CreateFile( szPath1, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); |
|
HANDLE handle2 = ::CreateFile( szPath2, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); |
|
|
|
bool bResult = false; |
|
|
|
if ( handle1 != NULL && handle2 != NULL ) |
|
{ |
|
BY_HANDLE_FILE_INFORMATION fileInfo1; |
|
BY_HANDLE_FILE_INFORMATION fileInfo2; |
|
if ( ::GetFileInformationByHandle( handle1, &fileInfo1 ) && ::GetFileInformationByHandle( handle2, &fileInfo2 ) ) |
|
{ |
|
bResult = fileInfo1.dwVolumeSerialNumber == fileInfo2.dwVolumeSerialNumber && |
|
fileInfo1.nFileIndexHigh == fileInfo2.nFileIndexHigh && |
|
fileInfo1.nFileIndexLow == fileInfo2.nFileIndexLow; |
|
} |
|
} |
|
|
|
if ( handle1 != NULL ) |
|
{ |
|
::CloseHandle(handle1); |
|
} |
|
|
|
if ( handle2 != NULL ) |
|
{ |
|
::CloseHandle( handle2 ); |
|
} |
|
|
|
return bResult; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Gets the filename to the current executable |
|
//----------------------------------------------------------------------------- |
|
bool CItemUpload::GetCurrentExecutableFileName( CUtlString &sCurrentExecutableFileName ) |
|
{ |
|
char szModuleFileName[MAX_PATH]; |
|
szModuleFileName[0] = '\0'; |
|
|
|
if ( !::GetModuleFileName( (HMODULE)NULL, szModuleFileName, ARRAYSIZE( szModuleFileName ) ) ) |
|
return false; |
|
|
|
sCurrentExecutableFileName = szModuleFileName; |
|
|
|
return true; |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Get the install location of the app from the registry via |
|
// |
|
// HKEY_LOCAL_MACHINE : |
|
// "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App %d" |
|
// |
|
//----------------------------------------------------------------------------- |
|
bool CItemUpload::GetSteamAppInstallLocation( CUtlString &sSteamAppInstallLocation, int nAppId ) |
|
{ |
|
HKEY hKey; |
|
char szSteamAppInstallLocation[ 65536 ] = ""; |
|
|
|
const CFmtStr sRegKey( "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Steam App %d", nAppId ); |
|
|
|
if ( ERROR_SUCCESS == RegOpenKey( HKEY_LOCAL_MACHINE, sRegKey.String(), &hKey ) ) |
|
{ |
|
DWORD dwSize = sizeof( szSteamAppInstallLocation ); |
|
RegQueryValueEx( hKey, "InstallLocation", NULL, NULL, (LPBYTE)szSteamAppInstallLocation, &dwSize ); |
|
RegCloseKey( hKey ); |
|
|
|
sSteamAppInstallLocation = szSteamAppInstallLocation; |
|
|
|
return true; |
|
} |
|
|
|
return false; |
|
} |