source-engine/utils/vcrtrace/vcrtrace.cpp

662 lines
14 KiB
C++
Raw Normal View History

2020-04-22 16:56:21 +00:00
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// vcrtrace.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <time.h>
#include "tier0/vcrmode.h"
#include "tier1/utlvector.h"
IVCRTrace *g_pTrace = 0;
class CVCRHelpers : public IVCRHelpers
{
public:
virtual void ErrorMessage( const char *pMsg )
{
Msg("ERROR: %s\n", pMsg);
}
virtual void* GetMainWindow()
{
return 0;
}
};
static CVCRHelpers g_VCRHelpers;
void ErrFunction( char const *pMsg )
{
Msg( "%s", pMsg );
}
typedef struct
{
int m_Message;
char const *m_pName;
} WMessage;
#define DEFINE_WMESSAGE(x) x, #x
// Message table for windows messages.
WMessage g_WMessages[] =
{
DEFINE_WMESSAGE(WM_NOTIFY),
DEFINE_WMESSAGE(WM_INPUTLANGCHANGEREQUEST),
DEFINE_WMESSAGE(WM_INPUTLANGCHANGE),
DEFINE_WMESSAGE(WM_TCARD),
DEFINE_WMESSAGE(WM_HELP),
DEFINE_WMESSAGE(WM_USERCHANGED),
DEFINE_WMESSAGE(WM_NOTIFYFORMAT),
DEFINE_WMESSAGE(NFR_ANSI),
DEFINE_WMESSAGE(NFR_UNICODE),
DEFINE_WMESSAGE(NF_QUERY),
DEFINE_WMESSAGE(NF_REQUERY),
DEFINE_WMESSAGE(WM_CONTEXTMENU),
DEFINE_WMESSAGE(WM_STYLECHANGING),
DEFINE_WMESSAGE(WM_STYLECHANGED),
DEFINE_WMESSAGE(WM_DISPLAYCHANGE),
DEFINE_WMESSAGE(WM_GETICON),
DEFINE_WMESSAGE(WM_SETICON),
DEFINE_WMESSAGE(WM_NCCREATE),
DEFINE_WMESSAGE(WM_NCDESTROY),
DEFINE_WMESSAGE(WM_NCCALCSIZE),
DEFINE_WMESSAGE(WM_NCHITTEST),
DEFINE_WMESSAGE(WM_NCPAINT),
DEFINE_WMESSAGE(WM_NCACTIVATE),
DEFINE_WMESSAGE(WM_GETDLGCODE),
DEFINE_WMESSAGE(WM_SYNCPAINT),
DEFINE_WMESSAGE(WM_NCMOUSEMOVE),
DEFINE_WMESSAGE(WM_NCLBUTTONDOWN),
DEFINE_WMESSAGE(WM_NCLBUTTONUP),
DEFINE_WMESSAGE(WM_NCLBUTTONDBLCLK),
DEFINE_WMESSAGE(WM_NCRBUTTONDOWN),
DEFINE_WMESSAGE(WM_NCRBUTTONUP),
DEFINE_WMESSAGE(WM_NCRBUTTONDBLCLK),
DEFINE_WMESSAGE(WM_NCMBUTTONDOWN),
DEFINE_WMESSAGE(WM_NCMBUTTONUP),
DEFINE_WMESSAGE(WM_NCMBUTTONDBLCLK),
DEFINE_WMESSAGE(WM_KEYFIRST),
DEFINE_WMESSAGE(WM_KEYDOWN),
DEFINE_WMESSAGE(WM_KEYUP),
DEFINE_WMESSAGE(WM_CHAR),
DEFINE_WMESSAGE(WM_DEADCHAR),
DEFINE_WMESSAGE(WM_SYSKEYDOWN),
DEFINE_WMESSAGE(WM_SYSKEYUP),
DEFINE_WMESSAGE(WM_SYSCHAR),
DEFINE_WMESSAGE(WM_SYSDEADCHAR),
DEFINE_WMESSAGE(WM_KEYLAST),
DEFINE_WMESSAGE(WM_IME_STARTCOMPOSITION),
DEFINE_WMESSAGE(WM_IME_ENDCOMPOSITION),
DEFINE_WMESSAGE(WM_IME_COMPOSITION),
DEFINE_WMESSAGE(WM_IME_KEYLAST),
DEFINE_WMESSAGE(WM_INITDIALOG),
DEFINE_WMESSAGE(WM_COMMAND),
DEFINE_WMESSAGE(WM_SYSCOMMAND),
DEFINE_WMESSAGE(WM_TIMER),
DEFINE_WMESSAGE(WM_HSCROLL),
DEFINE_WMESSAGE(WM_VSCROLL),
DEFINE_WMESSAGE(WM_INITMENU),
DEFINE_WMESSAGE(WM_INITMENUPOPUP),
DEFINE_WMESSAGE(WM_MENUSELECT),
DEFINE_WMESSAGE(WM_MENUCHAR),
DEFINE_WMESSAGE(WM_ENTERIDLE),
DEFINE_WMESSAGE(WM_CTLCOLORMSGBOX),
DEFINE_WMESSAGE(WM_CTLCOLOREDIT),
DEFINE_WMESSAGE(WM_CTLCOLORLISTBOX),
DEFINE_WMESSAGE(WM_CTLCOLORBTN),
DEFINE_WMESSAGE(WM_CTLCOLORDLG),
DEFINE_WMESSAGE(WM_CTLCOLORSCROLLBAR),
DEFINE_WMESSAGE(WM_CTLCOLORSTATIC),
DEFINE_WMESSAGE(WM_MOUSEMOVE),
DEFINE_WMESSAGE(WM_LBUTTONDOWN),
DEFINE_WMESSAGE(WM_LBUTTONUP),
DEFINE_WMESSAGE(WM_LBUTTONDBLCLK),
DEFINE_WMESSAGE(WM_RBUTTONDOWN),
DEFINE_WMESSAGE(WM_RBUTTONUP),
DEFINE_WMESSAGE(WM_RBUTTONDBLCLK),
DEFINE_WMESSAGE(WM_MBUTTONDOWN),
DEFINE_WMESSAGE(WM_MBUTTONUP),
DEFINE_WMESSAGE(WM_MBUTTONDBLCLK),
DEFINE_WMESSAGE(WM_MOUSELAST),
DEFINE_WMESSAGE(WM_PARENTNOTIFY),
DEFINE_WMESSAGE(WM_ENTERMENULOOP),
DEFINE_WMESSAGE(WM_EXITMENULOOP )
};
// Message table for winsock messages.
WMessage g_WinsockMessages[] =
{
DEFINE_WMESSAGE(WSAEWOULDBLOCK),
DEFINE_WMESSAGE(WSAEINPROGRESS),
DEFINE_WMESSAGE(WSAEALREADY),
DEFINE_WMESSAGE(WSAENOTSOCK),
DEFINE_WMESSAGE(WSAEDESTADDRREQ),
DEFINE_WMESSAGE(WSAEMSGSIZE),
DEFINE_WMESSAGE(WSAEPROTOTYPE),
DEFINE_WMESSAGE(WSAENOPROTOOPT),
DEFINE_WMESSAGE(WSAEPROTONOSUPPORT),
DEFINE_WMESSAGE(WSAESOCKTNOSUPPORT),
DEFINE_WMESSAGE(WSAEOPNOTSUPP),
DEFINE_WMESSAGE(WSAEPFNOSUPPORT),
DEFINE_WMESSAGE(WSAEAFNOSUPPORT),
DEFINE_WMESSAGE(WSAEADDRINUSE),
DEFINE_WMESSAGE(WSAEADDRNOTAVAIL),
DEFINE_WMESSAGE(WSAENETDOWN),
DEFINE_WMESSAGE(WSAENETUNREACH),
DEFINE_WMESSAGE(WSAENETRESET),
DEFINE_WMESSAGE(WSAECONNABORTED),
DEFINE_WMESSAGE(WSAECONNRESET),
DEFINE_WMESSAGE(WSAENOBUFS),
DEFINE_WMESSAGE(WSAEISCONN),
DEFINE_WMESSAGE(WSAENOTCONN),
DEFINE_WMESSAGE(WSAESHUTDOWN),
DEFINE_WMESSAGE(WSAETOOMANYREFS),
DEFINE_WMESSAGE(WSAETIMEDOUT),
DEFINE_WMESSAGE(WSAECONNREFUSED),
DEFINE_WMESSAGE(WSAELOOP),
DEFINE_WMESSAGE(WSAENAMETOOLONG),
DEFINE_WMESSAGE(WSAEHOSTDOWN),
DEFINE_WMESSAGE(WSAEHOSTUNREACH),
DEFINE_WMESSAGE(WSAENOTEMPTY),
DEFINE_WMESSAGE(WSAEPROCLIM),
DEFINE_WMESSAGE(WSAEUSERS),
DEFINE_WMESSAGE(WSAEDQUOT),
DEFINE_WMESSAGE(WSAESTALE),
DEFINE_WMESSAGE(WSAEREMOTE),
DEFINE_WMESSAGE(WSAEDISCON),
DEFINE_WMESSAGE(WSASYSNOTREADY),
DEFINE_WMESSAGE(WSAVERNOTSUPPORTED),
DEFINE_WMESSAGE(WSANOTINITIALISED)
};
static char const* GetWMessageName(WMessage *pMessages, int nMessages, int msg)
{
static char str[128];
int i;
for(i=0; i < nMessages; i++)
{
if(pMessages[i].m_Message == msg)
return pMessages[i].m_pName;
}
sprintf(str, "%d", msg);
return str;
}
FILE *g_fpTrace = NULL;
bool g_bEndOfFile = false;
template<class T>
static void VCRTrace_ReadVal(T &val)
{
if ( fread( &val, 1, sizeof( val ), g_fpTrace ) != sizeof( val ) )
g_bEndOfFile = true;
}
static void VCRTrace_Read( void *pOut, int size )
{
if ( fread( pOut, 1, size, g_fpTrace ) != (size_t)size )
g_bEndOfFile = true;
}
void ReadAndPrintShortString( const char *pFormat )
{
unsigned short len;
VCRTrace_ReadVal( len );
static CUtlVector<char> tempData;
if ( tempData.Count() < len )
tempData.SetSize( len );
VCRTrace_Read( tempData.Base(), len );
if ( len > 0 && ( tempData[len-2] == '\n' || tempData[len-2] == '\r' ) )
tempData[len-2] = 0;
Msg( pFormat, tempData.Base() );
}
static void VCR_TraceEvents()
{
int iEvent = 0;
g_pTrace = g_pVCR->GetVCRTraceInterface();
while ( !g_bEndOfFile )
{
++iEvent;
unsigned char eventCode;
VCRTrace_Read( &eventCode, sizeof( eventCode ) );
unsigned short iThread = 0;
if ( eventCode & 0x80 )
{
VCRTrace_Read( &iThread, sizeof( iThread ) );
eventCode &= ~0x80;
}
Msg( "%5d (thread %d): ", iEvent, iThread );
VCREvent event = (VCREvent)eventCode;
switch(event)
{
case VCREvent_Sys_FloatTime:
{
double ret;
VCRTrace_Read(&ret, sizeof(ret));
Msg("Sys_FloatTime: %f\n", ret);
}
break;
case VCREvent_recvfrom:
{
int ret;
char buf[8192];
VCRTrace_Read(&ret, sizeof(ret));
Assert(ret < (int)sizeof(buf));
if(ret == SOCKET_ERROR)
{
int err;
VCRTrace_ReadVal(err);
Msg("recvfrom: %d (error %s)\n", ret, GetWMessageName(g_WinsockMessages, sizeof(g_WinsockMessages)/sizeof(g_WinsockMessages[0]), err));
}
else
{
Msg("recvfrom: %d\n", ret);
VCRTrace_Read(buf, ret);
char bFrom;
VCRTrace_ReadVal( bFrom );
if ( bFrom )
{
sockaddr_in from;
VCRTrace_Read( &from, sizeof( from ) );
}
}
}
break;
case VCREvent_SyncToken:
{
char len;
char buf[256];
VCRTrace_Read(&len, 1);
VCRTrace_Read(buf, len);
buf[len] = 0;
Msg("SyncToken: %s\n", buf);
}
break;
case VCREvent_GetCursorPos:
{
POINT pt;
VCRTrace_ReadVal(pt);
Msg("GetCursorPos: (%d, %d)\n", pt.x, pt.y);
}
break;
case VCREvent_SetCursorPos:
{
int x, y;
VCRTrace_Read(&x, sizeof(x));
VCRTrace_Read(&y, sizeof(y));
Msg("SetCursorPos: (%d, %d)\n", x, y);
}
break;
case VCREvent_ScreenToClient:
{
POINT pt;
VCRTrace_ReadVal(pt);
Msg("ScreenToClient: (%d, %d)\n", pt.x, pt.y);
}
break;
case VCREvent_Cmd_Exec:
{
int len;
char *f;
VCRTrace_Read(&len, sizeof(len));
if(len != -1)
{
f = (char*)malloc(len);
VCRTrace_Read(f, len);
}
Msg("Cmd_Exec: %d\n", len);
}
break;
case VCREvent_CmdLine:
{
int len;
char str[8192];
VCRTrace_Read(&len, sizeof(len));
Assert(len < sizeof(str));
VCRTrace_Read(str, len);
Msg("CmdLine: %s\n", str);
}
break;
case VCREvent_RegOpenKeyEx:
{
long ret;
VCRTrace_ReadVal(ret);
Msg("RegOpenKeyEx: %d\n", ret);
}
break;
case VCREvent_RegSetValueEx:
{
long ret;
VCRTrace_ReadVal(ret);
Msg("RegSetValueEx: %d\n", ret);
}
break;
case VCREvent_RegQueryValueEx:
{
long ret;
unsigned long type, cbData;
char dummy;
VCRTrace_ReadVal(ret);
VCRTrace_ReadVal(type);
VCRTrace_ReadVal(cbData);
while(cbData)
{
VCRTrace_ReadVal(dummy);
cbData--;
}
Msg("RegQueryValueEx\n");
}
break;
case VCREvent_RegCreateKeyEx:
{
long ret;
VCRTrace_ReadVal(ret);
Msg("RegCreateKeyEx: %d\n", ret);
}
break;
case VCREvent_RegCloseKey:
{
Msg("VCREvent_RegCloseKey\n");
}
break;
case VCREvent_PeekMessage:
{
MSG msg;
int valid;
VCRTrace_Read(&valid, sizeof(valid));
if(valid)
{
VCRTrace_Read(&msg, sizeof(MSG));
}
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);
}
break;
case VCREvent_GameMsg:
{
char valid;
VCRTrace_Read( &valid, sizeof(valid) );
if ( valid )
{
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
VCRTrace_Read( &uMsg, sizeof(uMsg) );
VCRTrace_Read( &wParam, sizeof(wParam) );
VCRTrace_Read( &lParam, sizeof(lParam) );
Msg( "GameMsg - msg: %s, wParam: %x, lParam: %x\n", GetWMessageName(g_WMessages, sizeof(g_WMessages)/sizeof(g_WMessages[0]), uMsg), wParam, lParam );
}
else
{
Msg("GameMsg - <end>\n" );
}
}
break;
case VCREvent_GetNumberOfConsoleInputEvents:
{
char val;
unsigned long nEvents;
VCRTrace_ReadVal( val );
VCRTrace_ReadVal( nEvents );
Msg( "GetNumberOfConsoleInputEvents (returned %d, nEvents = %d)\n", val, nEvents );
}
break;
case VCREvent_ReadConsoleInput:
{
char val;
unsigned long nRead;
INPUT_RECORD recs[1024];
VCRTrace_ReadVal( val );
if ( val )
{
VCRTrace_ReadVal( nRead );
VCRTrace_Read( recs, nRead * sizeof( INPUT_RECORD ) );
}
else
{
nRead = 0;
}
Msg( "ReadConsoleInput (returned %d, nRead = %d)\n", val, nRead );
}
break;
case VCREvent_GetKeyState:
{
short ret;
VCRTrace_ReadVal( ret );
Msg( "VCREvent_GetKeyState: %d\n", ret );
}
break;
case VCREvent_recv:
{
int ret;
// Get the result from our file.
VCRTrace_ReadVal( ret );
if ( ret == SOCKET_ERROR )
{
int err;
VCRTrace_ReadVal( err );
Msg( "VCREvent_recv - SOCKET_ERROR - %d\n", err );
}
else
{
CUtlVector<char> dummyData;
dummyData.SetSize( ret );
VCRTrace_Read( dummyData.Base(), ret );
Msg( "VCREvent_recv - size %d", ret );
}
}
break;
case VCREvent_send:
{
int ret;
// Get the result from our file.
VCRTrace_ReadVal( ret );
if ( ret == SOCKET_ERROR )
{
int err;
VCRTrace_ReadVal(err);
Msg( "VCREvent_send - SOCKET_ERROR - %d\n", err );
}
else
{
Msg( "VCREvent_send - %d\n", ret );
}
}
break;
case VCREvent_Generic:
{
unsigned char nameLen;
VCRTrace_ReadVal( nameLen );
char testName[512] = "(none)";
if ( nameLen != 255 )
{
VCRTrace_Read( testName, nameLen );
}
int dataLen;
VCRTrace_ReadVal( dataLen );
CUtlVector<char> tempData;
tempData.SetSize( dataLen );
VCRTrace_Read( tempData.Base(), dataLen );
Msg( "VCREvent_Generic (name: %s, len: %d)\n", testName, dataLen );
}
break;
case VCREvent_CreateThread:
{
Msg( "VCREvent_CreateThread\n" );
}
break;
case VCREvent_WaitForSingleObject:
{
char val;
VCRTrace_ReadVal( val );
Msg( "VCREvent_WaitForSingleObject " );
if ( val == 1 )
Msg( "(WAIT_OBJECT_0)\n" );
else if ( val == 2 )
Msg( "(WAIT_ABANDONED)\n" );
else
Msg( "(WAIT_TIMEOUT)\n" );
}
break;
case VCREvent_EnterCriticalSection:
{
Msg( "VCREvent_EnterCriticalSection\n" );
}
break;
case VCREvent_LocalTime:
{
tm today;
VCRTrace_ReadVal( today );
Msg( "VCREvent_LocalTime\n" );
}
break;
case VCREvent_Time:
{
long today;
VCRTrace_ReadVal( today );
Msg( "VCREvent_Time\n" );
}
break;
case VCREvent_GenericString:
{
Msg( "VCREvent_GenericString: " );
ReadAndPrintShortString( "[%s] " );
ReadAndPrintShortString( "%s" );
Msg( "\n" );
}
break;
default:
{
Msg( "***ERROR*** VCR_TraceEvent: invalid event" );
return;
}
}
}
}
SpewRetval_t MySpewOutput( SpewType_t spewType, tchar const *pMsg )
{
printf( "%s", pMsg );
OutputDebugString( pMsg );
if ( spewType == SPEW_ASSERT )
return SPEW_DEBUGGER;
else if ( spewType == SPEW_ERROR )
return SPEW_ABORT;
else
return SPEW_CONTINUE;
}
int main(int argc, char* argv[])
{
if(argc <= 1)
{
Msg("vcrtrace <vcr filename>\n");
return 1;
}
SpewOutputFunc( MySpewOutput );
g_fpTrace = fopen( argv[1], "rb" );
if ( !g_fpTrace )
{
Msg("Invalid or mission VCR file '%s'\n", argv[1]);
return 1;
}
unsigned long version;
VCRTrace_ReadVal( version );
if ( version != VCRFILE_VERSION )
{
Msg( "Invalid VCR file version (is %d, but we need %d).\n", version, VCRFILE_VERSION );
return 1;
}
VCR_TraceEvents();
return 0;
}