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.

661 lines
14 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // vcrtrace.cpp : Defines the entry point for the console application.
  9. //
  10. #include "stdafx.h"
  11. #include <time.h>
  12. #include "tier0/vcrmode.h"
  13. #include "tier1/utlvector.h"
  14. IVCRTrace *g_pTrace = 0;
  15. class CVCRHelpers : public IVCRHelpers
  16. {
  17. public:
  18. virtual void ErrorMessage( const char *pMsg )
  19. {
  20. Msg("ERROR: %s\n", pMsg);
  21. }
  22. virtual void* GetMainWindow()
  23. {
  24. return 0;
  25. }
  26. };
  27. static CVCRHelpers g_VCRHelpers;
  28. void ErrFunction( char const *pMsg )
  29. {
  30. Msg( "%s", pMsg );
  31. }
  32. typedef struct
  33. {
  34. int m_Message;
  35. char const *m_pName;
  36. } WMessage;
  37. #define DEFINE_WMESSAGE(x) x, #x
  38. // Message table for windows messages.
  39. WMessage g_WMessages[] =
  40. {
  41. DEFINE_WMESSAGE(WM_NOTIFY),
  42. DEFINE_WMESSAGE(WM_INPUTLANGCHANGEREQUEST),
  43. DEFINE_WMESSAGE(WM_INPUTLANGCHANGE),
  44. DEFINE_WMESSAGE(WM_TCARD),
  45. DEFINE_WMESSAGE(WM_HELP),
  46. DEFINE_WMESSAGE(WM_USERCHANGED),
  47. DEFINE_WMESSAGE(WM_NOTIFYFORMAT),
  48. DEFINE_WMESSAGE(NFR_ANSI),
  49. DEFINE_WMESSAGE(NFR_UNICODE),
  50. DEFINE_WMESSAGE(NF_QUERY),
  51. DEFINE_WMESSAGE(NF_REQUERY),
  52. DEFINE_WMESSAGE(WM_CONTEXTMENU),
  53. DEFINE_WMESSAGE(WM_STYLECHANGING),
  54. DEFINE_WMESSAGE(WM_STYLECHANGED),
  55. DEFINE_WMESSAGE(WM_DISPLAYCHANGE),
  56. DEFINE_WMESSAGE(WM_GETICON),
  57. DEFINE_WMESSAGE(WM_SETICON),
  58. DEFINE_WMESSAGE(WM_NCCREATE),
  59. DEFINE_WMESSAGE(WM_NCDESTROY),
  60. DEFINE_WMESSAGE(WM_NCCALCSIZE),
  61. DEFINE_WMESSAGE(WM_NCHITTEST),
  62. DEFINE_WMESSAGE(WM_NCPAINT),
  63. DEFINE_WMESSAGE(WM_NCACTIVATE),
  64. DEFINE_WMESSAGE(WM_GETDLGCODE),
  65. DEFINE_WMESSAGE(WM_SYNCPAINT),
  66. DEFINE_WMESSAGE(WM_NCMOUSEMOVE),
  67. DEFINE_WMESSAGE(WM_NCLBUTTONDOWN),
  68. DEFINE_WMESSAGE(WM_NCLBUTTONUP),
  69. DEFINE_WMESSAGE(WM_NCLBUTTONDBLCLK),
  70. DEFINE_WMESSAGE(WM_NCRBUTTONDOWN),
  71. DEFINE_WMESSAGE(WM_NCRBUTTONUP),
  72. DEFINE_WMESSAGE(WM_NCRBUTTONDBLCLK),
  73. DEFINE_WMESSAGE(WM_NCMBUTTONDOWN),
  74. DEFINE_WMESSAGE(WM_NCMBUTTONUP),
  75. DEFINE_WMESSAGE(WM_NCMBUTTONDBLCLK),
  76. DEFINE_WMESSAGE(WM_KEYFIRST),
  77. DEFINE_WMESSAGE(WM_KEYDOWN),
  78. DEFINE_WMESSAGE(WM_KEYUP),
  79. DEFINE_WMESSAGE(WM_CHAR),
  80. DEFINE_WMESSAGE(WM_DEADCHAR),
  81. DEFINE_WMESSAGE(WM_SYSKEYDOWN),
  82. DEFINE_WMESSAGE(WM_SYSKEYUP),
  83. DEFINE_WMESSAGE(WM_SYSCHAR),
  84. DEFINE_WMESSAGE(WM_SYSDEADCHAR),
  85. DEFINE_WMESSAGE(WM_KEYLAST),
  86. DEFINE_WMESSAGE(WM_IME_STARTCOMPOSITION),
  87. DEFINE_WMESSAGE(WM_IME_ENDCOMPOSITION),
  88. DEFINE_WMESSAGE(WM_IME_COMPOSITION),
  89. DEFINE_WMESSAGE(WM_IME_KEYLAST),
  90. DEFINE_WMESSAGE(WM_INITDIALOG),
  91. DEFINE_WMESSAGE(WM_COMMAND),
  92. DEFINE_WMESSAGE(WM_SYSCOMMAND),
  93. DEFINE_WMESSAGE(WM_TIMER),
  94. DEFINE_WMESSAGE(WM_HSCROLL),
  95. DEFINE_WMESSAGE(WM_VSCROLL),
  96. DEFINE_WMESSAGE(WM_INITMENU),
  97. DEFINE_WMESSAGE(WM_INITMENUPOPUP),
  98. DEFINE_WMESSAGE(WM_MENUSELECT),
  99. DEFINE_WMESSAGE(WM_MENUCHAR),
  100. DEFINE_WMESSAGE(WM_ENTERIDLE),
  101. DEFINE_WMESSAGE(WM_CTLCOLORMSGBOX),
  102. DEFINE_WMESSAGE(WM_CTLCOLOREDIT),
  103. DEFINE_WMESSAGE(WM_CTLCOLORLISTBOX),
  104. DEFINE_WMESSAGE(WM_CTLCOLORBTN),
  105. DEFINE_WMESSAGE(WM_CTLCOLORDLG),
  106. DEFINE_WMESSAGE(WM_CTLCOLORSCROLLBAR),
  107. DEFINE_WMESSAGE(WM_CTLCOLORSTATIC),
  108. DEFINE_WMESSAGE(WM_MOUSEMOVE),
  109. DEFINE_WMESSAGE(WM_LBUTTONDOWN),
  110. DEFINE_WMESSAGE(WM_LBUTTONUP),
  111. DEFINE_WMESSAGE(WM_LBUTTONDBLCLK),
  112. DEFINE_WMESSAGE(WM_RBUTTONDOWN),
  113. DEFINE_WMESSAGE(WM_RBUTTONUP),
  114. DEFINE_WMESSAGE(WM_RBUTTONDBLCLK),
  115. DEFINE_WMESSAGE(WM_MBUTTONDOWN),
  116. DEFINE_WMESSAGE(WM_MBUTTONUP),
  117. DEFINE_WMESSAGE(WM_MBUTTONDBLCLK),
  118. DEFINE_WMESSAGE(WM_MOUSELAST),
  119. DEFINE_WMESSAGE(WM_PARENTNOTIFY),
  120. DEFINE_WMESSAGE(WM_ENTERMENULOOP),
  121. DEFINE_WMESSAGE(WM_EXITMENULOOP )
  122. };
  123. // Message table for winsock messages.
  124. WMessage g_WinsockMessages[] =
  125. {
  126. DEFINE_WMESSAGE(WSAEWOULDBLOCK),
  127. DEFINE_WMESSAGE(WSAEINPROGRESS),
  128. DEFINE_WMESSAGE(WSAEALREADY),
  129. DEFINE_WMESSAGE(WSAENOTSOCK),
  130. DEFINE_WMESSAGE(WSAEDESTADDRREQ),
  131. DEFINE_WMESSAGE(WSAEMSGSIZE),
  132. DEFINE_WMESSAGE(WSAEPROTOTYPE),
  133. DEFINE_WMESSAGE(WSAENOPROTOOPT),
  134. DEFINE_WMESSAGE(WSAEPROTONOSUPPORT),
  135. DEFINE_WMESSAGE(WSAESOCKTNOSUPPORT),
  136. DEFINE_WMESSAGE(WSAEOPNOTSUPP),
  137. DEFINE_WMESSAGE(WSAEPFNOSUPPORT),
  138. DEFINE_WMESSAGE(WSAEAFNOSUPPORT),
  139. DEFINE_WMESSAGE(WSAEADDRINUSE),
  140. DEFINE_WMESSAGE(WSAEADDRNOTAVAIL),
  141. DEFINE_WMESSAGE(WSAENETDOWN),
  142. DEFINE_WMESSAGE(WSAENETUNREACH),
  143. DEFINE_WMESSAGE(WSAENETRESET),
  144. DEFINE_WMESSAGE(WSAECONNABORTED),
  145. DEFINE_WMESSAGE(WSAECONNRESET),
  146. DEFINE_WMESSAGE(WSAENOBUFS),
  147. DEFINE_WMESSAGE(WSAEISCONN),
  148. DEFINE_WMESSAGE(WSAENOTCONN),
  149. DEFINE_WMESSAGE(WSAESHUTDOWN),
  150. DEFINE_WMESSAGE(WSAETOOMANYREFS),
  151. DEFINE_WMESSAGE(WSAETIMEDOUT),
  152. DEFINE_WMESSAGE(WSAECONNREFUSED),
  153. DEFINE_WMESSAGE(WSAELOOP),
  154. DEFINE_WMESSAGE(WSAENAMETOOLONG),
  155. DEFINE_WMESSAGE(WSAEHOSTDOWN),
  156. DEFINE_WMESSAGE(WSAEHOSTUNREACH),
  157. DEFINE_WMESSAGE(WSAENOTEMPTY),
  158. DEFINE_WMESSAGE(WSAEPROCLIM),
  159. DEFINE_WMESSAGE(WSAEUSERS),
  160. DEFINE_WMESSAGE(WSAEDQUOT),
  161. DEFINE_WMESSAGE(WSAESTALE),
  162. DEFINE_WMESSAGE(WSAEREMOTE),
  163. DEFINE_WMESSAGE(WSAEDISCON),
  164. DEFINE_WMESSAGE(WSASYSNOTREADY),
  165. DEFINE_WMESSAGE(WSAVERNOTSUPPORTED),
  166. DEFINE_WMESSAGE(WSANOTINITIALISED)
  167. };
  168. static char const* GetWMessageName(WMessage *pMessages, int nMessages, int msg)
  169. {
  170. static char str[128];
  171. int i;
  172. for(i=0; i < nMessages; i++)
  173. {
  174. if(pMessages[i].m_Message == msg)
  175. return pMessages[i].m_pName;
  176. }
  177. sprintf(str, "%d", msg);
  178. return str;
  179. }
  180. FILE *g_fpTrace = NULL;
  181. bool g_bEndOfFile = false;
  182. template<class T>
  183. static void VCRTrace_ReadVal(T &val)
  184. {
  185. if ( fread( &val, 1, sizeof( val ), g_fpTrace ) != sizeof( val ) )
  186. g_bEndOfFile = true;
  187. }
  188. static void VCRTrace_Read( void *pOut, int size )
  189. {
  190. if ( fread( pOut, 1, size, g_fpTrace ) != (size_t)size )
  191. g_bEndOfFile = true;
  192. }
  193. void ReadAndPrintShortString( const char *pFormat )
  194. {
  195. unsigned short len;
  196. VCRTrace_ReadVal( len );
  197. static CUtlVector<char> tempData;
  198. if ( tempData.Count() < len )
  199. tempData.SetSize( len );
  200. VCRTrace_Read( tempData.Base(), len );
  201. if ( len > 0 && ( tempData[len-2] == '\n' || tempData[len-2] == '\r' ) )
  202. tempData[len-2] = 0;
  203. Msg( pFormat, tempData.Base() );
  204. }
  205. static void VCR_TraceEvents()
  206. {
  207. int iEvent = 0;
  208. g_pTrace = g_pVCR->GetVCRTraceInterface();
  209. while ( !g_bEndOfFile )
  210. {
  211. ++iEvent;
  212. unsigned char eventCode;
  213. VCRTrace_Read( &eventCode, sizeof( eventCode ) );
  214. unsigned short iThread = 0;
  215. if ( eventCode & 0x80 )
  216. {
  217. VCRTrace_Read( &iThread, sizeof( iThread ) );
  218. eventCode &= ~0x80;
  219. }
  220. Msg( "%5d (thread %d): ", iEvent, iThread );
  221. VCREvent event = (VCREvent)eventCode;
  222. switch(event)
  223. {
  224. case VCREvent_Sys_FloatTime:
  225. {
  226. double ret;
  227. VCRTrace_Read(&ret, sizeof(ret));
  228. Msg("Sys_FloatTime: %f\n", ret);
  229. }
  230. break;
  231. case VCREvent_recvfrom:
  232. {
  233. int ret;
  234. char buf[8192];
  235. VCRTrace_Read(&ret, sizeof(ret));
  236. Assert(ret < (int)sizeof(buf));
  237. if(ret == SOCKET_ERROR)
  238. {
  239. int err;
  240. VCRTrace_ReadVal(err);
  241. Msg("recvfrom: %d (error %s)\n", ret, GetWMessageName(g_WinsockMessages, sizeof(g_WinsockMessages)/sizeof(g_WinsockMessages[0]), err));
  242. }
  243. else
  244. {
  245. Msg("recvfrom: %d\n", ret);
  246. VCRTrace_Read(buf, ret);
  247. char bFrom;
  248. VCRTrace_ReadVal( bFrom );
  249. if ( bFrom )
  250. {
  251. sockaddr_in from;
  252. VCRTrace_Read( &from, sizeof( from ) );
  253. }
  254. }
  255. }
  256. break;
  257. case VCREvent_SyncToken:
  258. {
  259. char len;
  260. char buf[256];
  261. VCRTrace_Read(&len, 1);
  262. VCRTrace_Read(buf, len);
  263. buf[len] = 0;
  264. Msg("SyncToken: %s\n", buf);
  265. }
  266. break;
  267. case VCREvent_GetCursorPos:
  268. {
  269. POINT pt;
  270. VCRTrace_ReadVal(pt);
  271. Msg("GetCursorPos: (%d, %d)\n", pt.x, pt.y);
  272. }
  273. break;
  274. case VCREvent_SetCursorPos:
  275. {
  276. int x, y;
  277. VCRTrace_Read(&x, sizeof(x));
  278. VCRTrace_Read(&y, sizeof(y));
  279. Msg("SetCursorPos: (%d, %d)\n", x, y);
  280. }
  281. break;
  282. case VCREvent_ScreenToClient:
  283. {
  284. POINT pt;
  285. VCRTrace_ReadVal(pt);
  286. Msg("ScreenToClient: (%d, %d)\n", pt.x, pt.y);
  287. }
  288. break;
  289. case VCREvent_Cmd_Exec:
  290. {
  291. int len;
  292. char *f;
  293. VCRTrace_Read(&len, sizeof(len));
  294. if(len != -1)
  295. {
  296. f = (char*)malloc(len);
  297. VCRTrace_Read(f, len);
  298. }
  299. Msg("Cmd_Exec: %d\n", len);
  300. }
  301. break;
  302. case VCREvent_CmdLine:
  303. {
  304. int len;
  305. char str[8192];
  306. VCRTrace_Read(&len, sizeof(len));
  307. Assert(len < sizeof(str));
  308. VCRTrace_Read(str, len);
  309. Msg("CmdLine: %s\n", str);
  310. }
  311. break;
  312. case VCREvent_RegOpenKeyEx:
  313. {
  314. long ret;
  315. VCRTrace_ReadVal(ret);
  316. Msg("RegOpenKeyEx: %d\n", ret);
  317. }
  318. break;
  319. case VCREvent_RegSetValueEx:
  320. {
  321. long ret;
  322. VCRTrace_ReadVal(ret);
  323. Msg("RegSetValueEx: %d\n", ret);
  324. }
  325. break;
  326. case VCREvent_RegQueryValueEx:
  327. {
  328. long ret;
  329. unsigned long type, cbData;
  330. char dummy;
  331. VCRTrace_ReadVal(ret);
  332. VCRTrace_ReadVal(type);
  333. VCRTrace_ReadVal(cbData);
  334. while(cbData)
  335. {
  336. VCRTrace_ReadVal(dummy);
  337. cbData--;
  338. }
  339. Msg("RegQueryValueEx\n");
  340. }
  341. break;
  342. case VCREvent_RegCreateKeyEx:
  343. {
  344. long ret;
  345. VCRTrace_ReadVal(ret);
  346. Msg("RegCreateKeyEx: %d\n", ret);
  347. }
  348. break;
  349. case VCREvent_RegCloseKey:
  350. {
  351. Msg("VCREvent_RegCloseKey\n");
  352. }
  353. break;
  354. case VCREvent_PeekMessage:
  355. {
  356. MSG msg;
  357. int valid;
  358. VCRTrace_Read(&valid, sizeof(valid));
  359. if(valid)
  360. {
  361. VCRTrace_Read(&msg, sizeof(MSG));
  362. }
  363. Msg("PeekMessage - msg: %s, wParam: %x, lParam: %x\n", GetWMessageName(g_WMessages, sizeof(g_WMessages)/sizeof(g_WMessages[0]), msg.message), msg.wParam, msg.lParam);
  364. }
  365. break;
  366. case VCREvent_GameMsg:
  367. {
  368. char valid;
  369. VCRTrace_Read( &valid, sizeof(valid) );
  370. if ( valid )
  371. {
  372. UINT uMsg;
  373. WPARAM wParam;
  374. LPARAM lParam;
  375. VCRTrace_Read( &uMsg, sizeof(uMsg) );
  376. VCRTrace_Read( &wParam, sizeof(wParam) );
  377. VCRTrace_Read( &lParam, sizeof(lParam) );
  378. Msg( "GameMsg - msg: %s, wParam: %x, lParam: %x\n", GetWMessageName(g_WMessages, sizeof(g_WMessages)/sizeof(g_WMessages[0]), uMsg), wParam, lParam );
  379. }
  380. else
  381. {
  382. Msg("GameMsg - <end>\n" );
  383. }
  384. }
  385. break;
  386. case VCREvent_GetNumberOfConsoleInputEvents:
  387. {
  388. char val;
  389. unsigned long nEvents;
  390. VCRTrace_ReadVal( val );
  391. VCRTrace_ReadVal( nEvents );
  392. Msg( "GetNumberOfConsoleInputEvents (returned %d, nEvents = %d)\n", val, nEvents );
  393. }
  394. break;
  395. case VCREvent_ReadConsoleInput:
  396. {
  397. char val;
  398. unsigned long nRead;
  399. INPUT_RECORD recs[1024];
  400. VCRTrace_ReadVal( val );
  401. if ( val )
  402. {
  403. VCRTrace_ReadVal( nRead );
  404. VCRTrace_Read( recs, nRead * sizeof( INPUT_RECORD ) );
  405. }
  406. else
  407. {
  408. nRead = 0;
  409. }
  410. Msg( "ReadConsoleInput (returned %d, nRead = %d)\n", val, nRead );
  411. }
  412. break;
  413. case VCREvent_GetKeyState:
  414. {
  415. short ret;
  416. VCRTrace_ReadVal( ret );
  417. Msg( "VCREvent_GetKeyState: %d\n", ret );
  418. }
  419. break;
  420. case VCREvent_recv:
  421. {
  422. int ret;
  423. // Get the result from our file.
  424. VCRTrace_ReadVal( ret );
  425. if ( ret == SOCKET_ERROR )
  426. {
  427. int err;
  428. VCRTrace_ReadVal( err );
  429. Msg( "VCREvent_recv - SOCKET_ERROR - %d\n", err );
  430. }
  431. else
  432. {
  433. CUtlVector<char> dummyData;
  434. dummyData.SetSize( ret );
  435. VCRTrace_Read( dummyData.Base(), ret );
  436. Msg( "VCREvent_recv - size %d", ret );
  437. }
  438. }
  439. break;
  440. case VCREvent_send:
  441. {
  442. int ret;
  443. // Get the result from our file.
  444. VCRTrace_ReadVal( ret );
  445. if ( ret == SOCKET_ERROR )
  446. {
  447. int err;
  448. VCRTrace_ReadVal(err);
  449. Msg( "VCREvent_send - SOCKET_ERROR - %d\n", err );
  450. }
  451. else
  452. {
  453. Msg( "VCREvent_send - %d\n", ret );
  454. }
  455. }
  456. break;
  457. case VCREvent_Generic:
  458. {
  459. unsigned char nameLen;
  460. VCRTrace_ReadVal( nameLen );
  461. char testName[512] = "(none)";
  462. if ( nameLen != 255 )
  463. {
  464. VCRTrace_Read( testName, nameLen );
  465. }
  466. int dataLen;
  467. VCRTrace_ReadVal( dataLen );
  468. CUtlVector<char> tempData;
  469. tempData.SetSize( dataLen );
  470. VCRTrace_Read( tempData.Base(), dataLen );
  471. Msg( "VCREvent_Generic (name: %s, len: %d)\n", testName, dataLen );
  472. }
  473. break;
  474. case VCREvent_CreateThread:
  475. {
  476. Msg( "VCREvent_CreateThread\n" );
  477. }
  478. break;
  479. case VCREvent_WaitForSingleObject:
  480. {
  481. char val;
  482. VCRTrace_ReadVal( val );
  483. Msg( "VCREvent_WaitForSingleObject " );
  484. if ( val == 1 )
  485. Msg( "(WAIT_OBJECT_0)\n" );
  486. else if ( val == 2 )
  487. Msg( "(WAIT_ABANDONED)\n" );
  488. else
  489. Msg( "(WAIT_TIMEOUT)\n" );
  490. }
  491. break;
  492. case VCREvent_EnterCriticalSection:
  493. {
  494. Msg( "VCREvent_EnterCriticalSection\n" );
  495. }
  496. break;
  497. case VCREvent_LocalTime:
  498. {
  499. tm today;
  500. VCRTrace_ReadVal( today );
  501. Msg( "VCREvent_LocalTime\n" );
  502. }
  503. break;
  504. case VCREvent_Time:
  505. {
  506. long today;
  507. VCRTrace_ReadVal( today );
  508. Msg( "VCREvent_Time\n" );
  509. }
  510. break;
  511. case VCREvent_GenericString:
  512. {
  513. Msg( "VCREvent_GenericString: " );
  514. ReadAndPrintShortString( "[%s] " );
  515. ReadAndPrintShortString( "%s" );
  516. Msg( "\n" );
  517. }
  518. break;
  519. default:
  520. {
  521. Msg( "***ERROR*** VCR_TraceEvent: invalid event" );
  522. return;
  523. }
  524. }
  525. }
  526. }
  527. SpewRetval_t MySpewOutput( SpewType_t spewType, tchar const *pMsg )
  528. {
  529. printf( "%s", pMsg );
  530. OutputDebugString( pMsg );
  531. if ( spewType == SPEW_ASSERT )
  532. return SPEW_DEBUGGER;
  533. else if ( spewType == SPEW_ERROR )
  534. return SPEW_ABORT;
  535. else
  536. return SPEW_CONTINUE;
  537. }
  538. int main(int argc, char* argv[])
  539. {
  540. if(argc <= 1)
  541. {
  542. Msg("vcrtrace <vcr filename>\n");
  543. return 1;
  544. }
  545. SpewOutputFunc( MySpewOutput );
  546. g_fpTrace = fopen( argv[1], "rb" );
  547. if ( !g_fpTrace )
  548. {
  549. Msg("Invalid or mission VCR file '%s'\n", argv[1]);
  550. return 1;
  551. }
  552. unsigned long version;
  553. VCRTrace_ReadVal( version );
  554. if ( version != VCRFILE_VERSION )
  555. {
  556. Msg( "Invalid VCR file version (is %d, but we need %d).\n", version, VCRFILE_VERSION );
  557. return 1;
  558. }
  559. VCR_TraceEvents();
  560. return 0;
  561. }