mirror of
https://github.com/rehlds/rechecker.git
synced 2024-12-27 12:55:28 +03:00
212 lines
5.6 KiB
C++
212 lines
5.6 KiB
C++
|
/*
|
||
|
*
|
||
|
* This program is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published by the
|
||
|
* Free Software Foundation; either version 2 of the License, or (at
|
||
|
* your option) any later version.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but
|
||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
* General Public License for more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License
|
||
|
* along with this program; if not, write to the Free Software Foundation,
|
||
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||
|
*
|
||
|
* In addition, as a special exception, the author gives permission to
|
||
|
* link the code of this program with the Half-Life Game Engine ("HL
|
||
|
* Engine") and Modified Game Libraries ("MODs") developed by Valve,
|
||
|
* L.L.C ("Valve"). You must obey the GNU General Public License in all
|
||
|
* respects for all of the code used other than the HL Engine and MODs
|
||
|
* from Valve. If you modify this file, you may extend this exception
|
||
|
* to your version of the file, but you are not obligated to do so. If
|
||
|
* you do not wish to do so, delete this exception statement from your
|
||
|
* version.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include "precompiled.h"
|
||
|
|
||
|
#ifdef _WIN32
|
||
|
#include "SteamAppStartup.h"
|
||
|
|
||
|
#define WIN32_LEAN_AND_MEAN
|
||
|
#include <assert.h>
|
||
|
#include <windows.h>
|
||
|
#include <process.h>
|
||
|
#include <direct.h>
|
||
|
#include <stdio.h>
|
||
|
#include <sys/stat.h>
|
||
|
|
||
|
#define STEAM_PARM "-steam"
|
||
|
|
||
|
bool FileExists(const char *fileName)
|
||
|
{
|
||
|
struct _stat statbuf;
|
||
|
return (_stat(fileName, &statbuf) == 0);
|
||
|
}
|
||
|
|
||
|
// Handles launching the game indirectly via steam
|
||
|
void LaunchSelfViaSteam(const char *params)
|
||
|
{
|
||
|
// calculate the details of our launch
|
||
|
char appPath[MAX_PATH];
|
||
|
::GetModuleFileName((HINSTANCE)GetModuleHandle(NULL), appPath, sizeof(appPath));
|
||
|
|
||
|
// strip out the exe name
|
||
|
char *slash = strrchr(appPath, '\\');
|
||
|
if (slash)
|
||
|
{
|
||
|
*slash = '\0';
|
||
|
}
|
||
|
|
||
|
// save out our details to the registry
|
||
|
HKEY hKey;
|
||
|
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
|
||
|
{
|
||
|
DWORD dwType = REG_SZ;
|
||
|
DWORD dwSize = static_cast<DWORD>( strlen(appPath) + 1 );
|
||
|
RegSetValueEx(hKey, "TempAppPath", NULL, dwType, (LPBYTE)appPath, dwSize);
|
||
|
dwSize = static_cast<DWORD>( strlen(params) + 1 );
|
||
|
RegSetValueEx(hKey, "TempAppCmdLine", NULL, dwType, (LPBYTE)params, dwSize);
|
||
|
// clear out the appID (since we don't know it yet)
|
||
|
dwType = REG_DWORD;
|
||
|
int appID = -1;
|
||
|
RegSetValueEx(hKey, "TempAppID", NULL, dwType, (LPBYTE)&appID, sizeof(appID));
|
||
|
RegCloseKey(hKey);
|
||
|
}
|
||
|
|
||
|
// search for an active steam instance
|
||
|
HWND hwnd = ::FindWindow("Valve_SteamIPC_Class", "Hidden Window");
|
||
|
if (hwnd)
|
||
|
{
|
||
|
::PostMessage(hwnd, WM_USER + 3, 0, 0);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// couldn't find steam, find and launch it
|
||
|
|
||
|
// first, search backwards through our current set of directories
|
||
|
char steamExe[MAX_PATH] = "";
|
||
|
char dir[MAX_PATH];
|
||
|
|
||
|
if (::GetCurrentDirectoryA(sizeof(dir), dir))
|
||
|
{
|
||
|
char *slash = strrchr(dir, '\\');
|
||
|
while (slash)
|
||
|
{
|
||
|
// see if steam_dev.exe is in the directory first
|
||
|
slash[1] = 0;
|
||
|
strcat(slash, "steam_dev.exe");
|
||
|
FILE *f = fopen(dir, "rb");
|
||
|
if (f)
|
||
|
{
|
||
|
// found it
|
||
|
fclose(f);
|
||
|
strcpy(steamExe, dir);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// see if steam.exe is in the directory
|
||
|
slash[1] = 0;
|
||
|
strcat(slash, "steam.exe");
|
||
|
f = fopen(dir, "rb");
|
||
|
if (f)
|
||
|
{
|
||
|
// found it
|
||
|
fclose(f);
|
||
|
strcpy(steamExe, dir);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// kill the string at the slash
|
||
|
slash[0] = 0;
|
||
|
|
||
|
// move to the previous slash
|
||
|
slash = strrchr(dir, '\\');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!steamExe[0])
|
||
|
{
|
||
|
// still not found, use the one in the registry
|
||
|
HKEY hKey;
|
||
|
if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
|
||
|
{
|
||
|
DWORD dwType;
|
||
|
DWORD dwSize = sizeof(steamExe);
|
||
|
RegQueryValueEx(hKey, "SteamExe", NULL, &dwType, (LPBYTE)steamExe, &dwSize);
|
||
|
RegCloseKey(hKey);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!steamExe[0])
|
||
|
{
|
||
|
// still no path, error
|
||
|
::MessageBox(NULL, "Error running game: could not find steam.exe to launch", "Fatal Error", MB_OK | MB_ICONERROR);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// fix any slashes
|
||
|
for (char *slash = steamExe; *slash; slash++)
|
||
|
{
|
||
|
if (*slash == '/')
|
||
|
{
|
||
|
*slash = '\\';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// change to the steam directory
|
||
|
strcpy(dir, steamExe);
|
||
|
char *delimiter = strrchr(dir, '\\');
|
||
|
if (delimiter)
|
||
|
{
|
||
|
*delimiter = 0;
|
||
|
_chdir(dir);
|
||
|
}
|
||
|
|
||
|
// exec steam.exe, in silent mode, with the launch app param
|
||
|
char *args[4] = { steamExe, "-silent", "-applaunch", '\0' };
|
||
|
_spawnv(_P_NOWAIT, steamExe, args);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Launches steam if necessary
|
||
|
bool ShouldLaunchAppViaSteam(const char *lpCmdLine, const char *steamFilesystemDllName, const char *stdioFilesystemDllName)
|
||
|
{
|
||
|
// see if steam is on the command line
|
||
|
const char *steamStr = strstr(lpCmdLine, STEAM_PARM);
|
||
|
|
||
|
// check the character following it is a whitespace or null
|
||
|
if (steamStr)
|
||
|
{
|
||
|
const char *postChar = steamStr + strlen(STEAM_PARM);
|
||
|
if (*postChar == 0 || isspace(*postChar))
|
||
|
{
|
||
|
// we're running under steam already, let the app continue
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// we're not running under steam, see which filesystems are available
|
||
|
if (FileExists(stdioFilesystemDllName))
|
||
|
{
|
||
|
// we're being run with a stdio filesystem, so we can continue without steam
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// make sure we have a steam filesystem available
|
||
|
if (!FileExists(steamFilesystemDllName))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// we have the steam filesystem, and no stdio filesystem, so we must need to be run under steam
|
||
|
// launch steam
|
||
|
LaunchSelfViaSteam(lpCmdLine);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
#endif // _WIN32
|