Team Fortress 2 Source Code as on 22/4/2020
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.

295 lines
7.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Xbox Launch Routines.
  4. //
  5. //=====================================================================================//
  6. #ifndef _XBOX_LAUNCH_H_
  7. #define _XBOX_LAUNCH_H_
  8. #pragma once
  9. #ifndef _CERT
  10. #pragma comment( lib, "xbdm.lib" )
  11. #endif
  12. // id and version are used to tag the data blob, currently only need a singe hardcoded id
  13. // when the version and id don't match, the data blob is not ours
  14. #define VALVE_LAUNCH_ID (('V'<<24)|('A'<<16)|('L'<<8)|('V'<<0))
  15. #define VALVE_LAUNCH_VERSION 1
  16. // launch flags
  17. #define LF_ISDEBUGGING 0x80000000 // set if session was active prior to launch
  18. #define LF_INTERNALLAUNCH 0x00000001 // set if launch was internal (as opposed to dashboard)
  19. #define LF_EXITFROMINSTALLER 0x00000002 // set if exit was from an installer
  20. #define LF_EXITFROMGAME 0x00000004 // set if exit was from a game
  21. #define LF_EXITFROMCHOOSER 0x00000008 // set if exit was from the chooser
  22. #define LF_GAMERESTART 0x00000010 // set if game wants to restart self (skips appchooser)
  23. #define LF_INVITERESTART 0x00000020 // set if game was invited from another app (launches TF and fires off session connect)
  24. #pragma pack(1)
  25. struct launchHeader_t
  26. {
  27. unsigned int id;
  28. unsigned int version;
  29. unsigned int flags;
  30. int nStorageID;
  31. int nUserID;
  32. int bForceEnglish;
  33. XNKID nInviteSessionID;
  34. // for caller defined data, occurs after this header
  35. // limited to slightly less than MAX_LAUNCH_DATA_SIZE
  36. unsigned int nDataSize;
  37. };
  38. #pragma pack()
  39. // per docs, no larger than MAX_LAUNCH_DATA_SIZE
  40. union xboxLaunchData_t
  41. {
  42. launchHeader_t header;
  43. char data[MAX_LAUNCH_DATA_SIZE];
  44. };
  45. //--------------------------------------------------------------------------------------
  46. // Simple class to wrap the peristsent launch payload.
  47. //
  48. // Can be used by an application that does not use tier0 (i.e. the launcher).
  49. // Primarily designed to be anchored in tier0, so multiple systems can easily query and
  50. // set the persistent payload.
  51. //--------------------------------------------------------------------------------------
  52. class CXboxLaunch
  53. {
  54. public:
  55. CXboxLaunch()
  56. {
  57. ResetLaunchData();
  58. }
  59. void ResetLaunchData()
  60. {
  61. // invalid until established
  62. // nonzero identifies a valid payload
  63. m_LaunchDataSize = 0;
  64. m_Launch.header.id = 0;
  65. m_Launch.header.version = 0;
  66. m_Launch.header.flags = 0;
  67. m_Launch.header.nStorageID = XBX_INVALID_STORAGE_ID;
  68. m_Launch.header.nUserID = XBX_INVALID_USER_ID;
  69. m_Launch.header.bForceEnglish = false;
  70. memset( &m_Launch.header.nInviteSessionID, 0, sizeof( m_Launch.header.nInviteSessionID ) );
  71. m_Launch.header.nDataSize = 0;
  72. }
  73. // Returns how much space can be used by caller
  74. int MaxPayloadSize()
  75. {
  76. return sizeof( xboxLaunchData_t ) - sizeof( launchHeader_t );
  77. }
  78. bool SetLaunchData( void *pData, int dataSize, int flags = 0 )
  79. {
  80. if ( pData && dataSize && dataSize > MaxPayloadSize() )
  81. {
  82. // not enough room
  83. return false;
  84. }
  85. if ( pData && dataSize && dataSize <= MaxPayloadSize() )
  86. {
  87. memcpy( m_Launch.data + sizeof( launchHeader_t ), pData, dataSize );
  88. m_Launch.header.nDataSize = dataSize;
  89. }
  90. else
  91. {
  92. m_Launch.header.nDataSize = 0;
  93. }
  94. flags |= LF_INTERNALLAUNCH;
  95. #if !defined( _CERT )
  96. if ( DmIsDebuggerPresent() )
  97. {
  98. flags |= LF_ISDEBUGGING;
  99. }
  100. #endif
  101. m_Launch.header.id = VALVE_LAUNCH_ID;
  102. m_Launch.header.version = VALVE_LAUNCH_VERSION;
  103. m_Launch.header.flags = flags;
  104. XSetLaunchData( &m_Launch, MAX_LAUNCH_DATA_SIZE );
  105. // assume successful, mark as valid
  106. m_LaunchDataSize = MAX_LAUNCH_DATA_SIZE;
  107. return true;
  108. }
  109. //--------------------------------------------------------------------------------------
  110. // Returns TRUE if the launch data blob is available. FALSE otherwise.
  111. // Caller is expected to validate and interpret contents based on ID.
  112. //--------------------------------------------------------------------------------------
  113. bool GetLaunchData( unsigned int *pID, void **pData, int *pDataSize )
  114. {
  115. if ( !m_LaunchDataSize )
  116. {
  117. // purposely not doing this in the constructor (unstable as used by tier0), but on first fetch
  118. bool bValid = false;
  119. DWORD dwLaunchDataSize;
  120. DWORD dwStatus = XGetLaunchDataSize( &dwLaunchDataSize );
  121. if ( dwStatus == ERROR_SUCCESS && dwLaunchDataSize <= MAX_LAUNCH_DATA_SIZE )
  122. {
  123. dwStatus = XGetLaunchData( (void*)&m_Launch, dwLaunchDataSize );
  124. if ( dwStatus == ERROR_SUCCESS )
  125. {
  126. bValid = true;
  127. m_LaunchDataSize = dwLaunchDataSize;
  128. }
  129. }
  130. if ( !bValid )
  131. {
  132. ResetLaunchData();
  133. }
  134. }
  135. // a valid launch payload could be ours (re-launch) or from an alternate booter (demo launcher)
  136. if ( m_LaunchDataSize == MAX_LAUNCH_DATA_SIZE && m_Launch.header.id == VALVE_LAUNCH_ID && m_Launch.header.version == VALVE_LAUNCH_VERSION )
  137. {
  138. // internal recognized format
  139. if ( pID )
  140. {
  141. *pID = m_Launch.header.id;
  142. }
  143. if ( pData )
  144. {
  145. *pData = m_Launch.data + sizeof( launchHeader_t );
  146. }
  147. if ( pDataSize )
  148. {
  149. *pDataSize = m_Launch.header.nDataSize;
  150. }
  151. }
  152. else if ( m_LaunchDataSize )
  153. {
  154. // not ours, unknown format, caller interprets
  155. if ( pID )
  156. {
  157. // assume payload was packaged with an initial ID
  158. *pID = *(unsigned int *)m_Launch.data;
  159. }
  160. if ( pData )
  161. {
  162. *pData = m_Launch.data;
  163. }
  164. if ( pDataSize )
  165. {
  166. *pDataSize = m_LaunchDataSize;
  167. }
  168. }
  169. // valid when data is available (not necessarily valve's tag)
  170. return m_LaunchDataSize != 0;
  171. }
  172. //--------------------------------------------------------------------------------------
  173. // Returns TRUE if the launch data blob is available. FALSE otherwise.
  174. // Data blob could be ours or not.
  175. //--------------------------------------------------------------------------------------
  176. bool RestoreLaunchData()
  177. {
  178. return GetLaunchData( NULL, NULL, NULL );
  179. }
  180. //--------------------------------------------------------------------------------------
  181. // Restores the data blob. If the data blob is not ours, resets it.
  182. //--------------------------------------------------------------------------------------
  183. void RestoreOrResetLaunchData()
  184. {
  185. RestoreLaunchData();
  186. if ( m_Launch.header.id != VALVE_LAUNCH_ID || m_Launch.header.version != VALVE_LAUNCH_VERSION )
  187. {
  188. // not interested in somebody else's data
  189. ResetLaunchData();
  190. }
  191. }
  192. //--------------------------------------------------------------------------------------
  193. // Returns OUR internal launch flags.
  194. //--------------------------------------------------------------------------------------
  195. int GetLaunchFlags()
  196. {
  197. // establish the data
  198. RestoreOrResetLaunchData();
  199. return m_Launch.header.flags;
  200. }
  201. int GetStorageID( void )
  202. {
  203. RestoreOrResetLaunchData();
  204. return m_Launch.header.nStorageID;
  205. }
  206. void SetStorageID( int storageID )
  207. {
  208. RestoreOrResetLaunchData();
  209. m_Launch.header.nStorageID = storageID;
  210. }
  211. int GetUserID( void )
  212. {
  213. RestoreOrResetLaunchData();
  214. return m_Launch.header.nUserID;
  215. }
  216. void SetUserID( int userID )
  217. {
  218. RestoreOrResetLaunchData();
  219. m_Launch.header.nUserID = userID;
  220. }
  221. bool GetForceEnglish( void )
  222. {
  223. RestoreOrResetLaunchData();
  224. return m_Launch.header.bForceEnglish ? true : false;
  225. }
  226. void SetForceEnglish( bool bForceEnglish )
  227. {
  228. RestoreOrResetLaunchData();
  229. m_Launch.header.bForceEnglish = bForceEnglish;
  230. }
  231. void GetInviteSessionID( XNKID *pSessionID )
  232. {
  233. RestoreOrResetLaunchData();
  234. *pSessionID = m_Launch.header.nInviteSessionID;
  235. }
  236. void SetInviteSessionID( XNKID *pSessionID )
  237. {
  238. RestoreOrResetLaunchData();
  239. m_Launch.header.nInviteSessionID = *pSessionID;
  240. }
  241. void Launch( const char *pNewImageName = NULL )
  242. {
  243. if ( !pNewImageName )
  244. {
  245. pNewImageName = "default.xex";
  246. }
  247. XLaunchNewImage( pNewImageName, 0 );
  248. }
  249. private:
  250. xboxLaunchData_t m_Launch;
  251. DWORD m_LaunchDataSize;
  252. };
  253. #if defined( PLATFORM_H )
  254. // For applications that use tier0.dll
  255. PLATFORM_INTERFACE CXboxLaunch *XboxLaunch();
  256. #endif
  257. #endif