Counter Strike : Global Offensive Source Code
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.

198 lines
5.2 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #ifdef _WIN32
  7. #include "SteamAppStartup.h"
  8. #define WIN32_LEAN_AND_MEAN
  9. #include <assert.h>
  10. #include <windows.h>
  11. #include <process.h>
  12. #include <direct.h>
  13. #include <stdio.h>
  14. #include <sys/stat.h>
  15. #define STEAM_PARM "-steam"
  16. void LaunchSelfViaSteam(const char *params);
  17. bool FileExists(const char *fileName)
  18. {
  19. struct _stat statbuf;
  20. return (_stat(fileName, &statbuf) == 0);
  21. }
  22. inline bool V_isspace(int c)
  23. {
  24. // The standard white-space characters are the following: space, tab, carriage-return, newline, vertical tab, and form-feed. In the C locale, V_isspace() returns true only for the standard white-space characters.
  25. return c == ' ' || c == 9 /*horizontal tab*/ || c == '\r' || c == '\n' || c == 11 /*vertical tab*/ || c == '\f';
  26. }
  27. //-----------------------------------------------------------------------------
  28. // Purpose: Launches steam if necessary
  29. //-----------------------------------------------------------------------------
  30. bool ShouldLaunchAppViaSteam(const char *lpCmdLine, const char *steamFilesystemDllName, const char *stdioFilesystemDllName)
  31. {
  32. // see if steam is on the command line
  33. const char *steamStr = strstr(lpCmdLine, STEAM_PARM);
  34. // check the character following it is a whitespace or null
  35. if (steamStr)
  36. {
  37. const char *postChar = steamStr + strlen(STEAM_PARM);
  38. if (*postChar == 0 || V_isspace(*postChar))
  39. {
  40. // we're running under steam already, let the app continue
  41. return false;
  42. }
  43. }
  44. // we're not running under steam, see which filesystems are available
  45. if (FileExists(stdioFilesystemDllName))
  46. {
  47. // we're being run with a stdio filesystem, so we can continue without steam
  48. return false;
  49. }
  50. // make sure we have a steam filesystem available
  51. if (!FileExists(steamFilesystemDllName))
  52. {
  53. return false;
  54. }
  55. // we have the steam filesystem, and no stdio filesystem, so we must need to be run under steam
  56. // launch steam
  57. LaunchSelfViaSteam(lpCmdLine);
  58. return true;
  59. }
  60. //-----------------------------------------------------------------------------
  61. // Purpose: Handles launching the game indirectly via steam
  62. //-----------------------------------------------------------------------------
  63. void LaunchSelfViaSteam(const char *params)
  64. {
  65. // calculate the details of our launch
  66. char appPath[MAX_PATH];
  67. ::GetModuleFileName((HINSTANCE)GetModuleHandle(NULL), appPath, sizeof(appPath));
  68. // strip out the exe name
  69. char *slash = strrchr(appPath, '\\');
  70. if (slash)
  71. {
  72. *slash = 0;
  73. }
  74. // save out our details to the registry
  75. HKEY hKey;
  76. if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
  77. {
  78. DWORD dwType = REG_SZ;
  79. DWORD dwSize = static_cast<DWORD>( strlen(appPath) + 1 );
  80. RegSetValueEx(hKey, "TempAppPath", NULL, dwType, (LPBYTE)appPath, dwSize);
  81. dwSize = static_cast<DWORD>( strlen(params) + 1 );
  82. RegSetValueEx(hKey, "TempAppCmdLine", NULL, dwType, (LPBYTE)params, dwSize);
  83. // clear out the appID (since we don't know it yet)
  84. dwType = REG_DWORD;
  85. int appID = -1;
  86. RegSetValueEx(hKey, "TempAppID", NULL, dwType, (LPBYTE)&appID, sizeof(appID));
  87. RegCloseKey(hKey);
  88. }
  89. // search for an active steam instance
  90. HWND hwnd = ::FindWindow("Valve_SteamIPC_Class", "Hidden Window");
  91. if (hwnd)
  92. {
  93. ::PostMessage(hwnd, WM_USER + 3, 0, 0);
  94. }
  95. else
  96. {
  97. // couldn't find steam, find and launch it
  98. // first, search backwards through our current set of directories
  99. char steamExe[MAX_PATH];
  100. steamExe[0] = 0;
  101. char dir[MAX_PATH];
  102. if (::GetCurrentDirectoryA(sizeof(dir), dir))
  103. {
  104. char *slash = strrchr(dir, '\\');
  105. while (slash)
  106. {
  107. // see if steam_dev.exe is in the directory first
  108. slash[1] = 0;
  109. strcat(slash, "steam_dev.exe");
  110. FILE *f = fopen(dir, "rb");
  111. if (f)
  112. {
  113. // found it
  114. fclose(f);
  115. strcpy(steamExe, dir);
  116. break;
  117. }
  118. // see if steam.exe is in the directory
  119. slash[1] = 0;
  120. strcat(slash, "steam.exe");
  121. f = fopen(dir, "rb");
  122. if (f)
  123. {
  124. // found it
  125. fclose(f);
  126. strcpy(steamExe, dir);
  127. break;
  128. }
  129. // kill the string at the slash
  130. slash[0] = 0;
  131. // move to the previous slash
  132. slash = strrchr(dir, '\\');
  133. }
  134. }
  135. if (!steamExe[0])
  136. {
  137. // still not found, use the one in the registry
  138. HKEY hKey;
  139. if (ERROR_SUCCESS == RegOpenKey(HKEY_CURRENT_USER, "Software\\Valve\\Steam", &hKey))
  140. {
  141. DWORD dwType;
  142. DWORD dwSize = sizeof(steamExe);
  143. RegQueryValueEx( hKey, "SteamExe", NULL, &dwType, (LPBYTE)steamExe, &dwSize);
  144. RegCloseKey( hKey );
  145. }
  146. }
  147. if (!steamExe[0])
  148. {
  149. // still no path, error
  150. ::MessageBox(NULL, "Error running game: could not find steam.exe to launch", "Fatal Error", MB_OK | MB_ICONERROR);
  151. return;
  152. }
  153. // fix any slashes
  154. for (char *slash = steamExe; *slash; slash++)
  155. {
  156. if (*slash == '/')
  157. {
  158. *slash = '\\';
  159. }
  160. }
  161. // change to the steam directory
  162. strcpy(dir, steamExe);
  163. char *delimiter = strrchr(dir, '\\');
  164. if (delimiter)
  165. {
  166. *delimiter = 0;
  167. _chdir(dir);
  168. }
  169. // exec steam.exe, in silent mode, with the launch app param
  170. char *args[4] = { steamExe, "-silent", "-applaunch", NULL };
  171. _spawnv(_P_NOWAIT, steamExe, args);
  172. }
  173. }
  174. #endif // _WIN32