Replace useless code with more useful code.
--HG-- branch : trunk
This commit is contained in:
@@ -29,7 +29,7 @@ inline LPTSTR ErrorMessage(DWORD dw)
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR) &lpMsgBuf,
|
||||
0, NULL );
|
||||
0, NULL);
|
||||
return (LPTSTR)lpMsgBuf;
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ WheatyExceptionReport g_WheatyExceptionReport;
|
||||
|
||||
//============================== Class Methods =============================
|
||||
|
||||
WheatyExceptionReport::WheatyExceptionReport( ) // Constructor
|
||||
WheatyExceptionReport::WheatyExceptionReport() // Constructor
|
||||
{
|
||||
// Install the unhandled exception filter function
|
||||
m_previousFilter = SetUnhandledExceptionFilter(WheatyUnhandledExceptionFilter);
|
||||
@@ -58,67 +58,66 @@ WheatyExceptionReport::WheatyExceptionReport( ) // Constructor
|
||||
//============
|
||||
// Destructor
|
||||
//============
|
||||
WheatyExceptionReport::~WheatyExceptionReport( )
|
||||
WheatyExceptionReport::~WheatyExceptionReport()
|
||||
{
|
||||
if(m_previousFilter)
|
||||
SetUnhandledExceptionFilter( m_previousFilter );
|
||||
if (m_previousFilter)
|
||||
SetUnhandledExceptionFilter(m_previousFilter);
|
||||
}
|
||||
|
||||
//===========================================================
|
||||
// Entry point where control comes on an unhandled exception
|
||||
//===========================================================
|
||||
LONG WINAPI WheatyExceptionReport::WheatyUnhandledExceptionFilter(
|
||||
PEXCEPTION_POINTERS pExceptionInfo )
|
||||
PEXCEPTION_POINTERS pExceptionInfo)
|
||||
{
|
||||
TCHAR module_folder_name[MAX_PATH];
|
||||
GetModuleFileName( 0, module_folder_name, MAX_PATH );
|
||||
GetModuleFileName(0, module_folder_name, MAX_PATH);
|
||||
TCHAR* pos = _tcsrchr(module_folder_name, '\\');
|
||||
if(!pos)
|
||||
if (!pos)
|
||||
return 0;
|
||||
pos[0] = '\0';
|
||||
++pos;
|
||||
|
||||
TCHAR crash_folder_path[MAX_PATH];
|
||||
sprintf(crash_folder_path, "%s\\%s", module_folder_name, CrashFolder);
|
||||
if(!CreateDirectory(crash_folder_path, NULL))
|
||||
if (!CreateDirectory(crash_folder_path, NULL))
|
||||
{
|
||||
if(GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
SYSTEMTIME systime;
|
||||
GetLocalTime(&systime);
|
||||
sprintf(m_szLogFileName, "%s\\%s_[%u-%u_%u-%u-%u].txt",
|
||||
crash_folder_path, pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond
|
||||
);
|
||||
crash_folder_path, pos, systime.wDay, systime.wMonth, systime.wHour, systime.wMinute, systime.wSecond);
|
||||
|
||||
m_hReportFile = CreateFile( m_szLogFileName,
|
||||
m_hReportFile = CreateFile(m_szLogFileName,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
0,
|
||||
OPEN_ALWAYS,
|
||||
FILE_FLAG_WRITE_THROUGH,
|
||||
0 );
|
||||
0);
|
||||
|
||||
if ( m_hReportFile )
|
||||
if (m_hReportFile)
|
||||
{
|
||||
SetFilePointer( m_hReportFile, 0, 0, FILE_END );
|
||||
SetFilePointer(m_hReportFile, 0, 0, FILE_END);
|
||||
|
||||
GenerateExceptionReport( pExceptionInfo );
|
||||
GenerateExceptionReport(pExceptionInfo);
|
||||
|
||||
CloseHandle( m_hReportFile );
|
||||
CloseHandle(m_hReportFile);
|
||||
m_hReportFile = 0;
|
||||
}
|
||||
|
||||
if ( m_previousFilter )
|
||||
return m_previousFilter( pExceptionInfo );
|
||||
if (m_previousFilter)
|
||||
return m_previousFilter(pExceptionInfo);
|
||||
else
|
||||
return EXCEPTION_EXECUTE_HANDLER/*EXCEPTION_CONTINUE_SEARCH*/;
|
||||
}
|
||||
|
||||
BOOL WheatyExceptionReport::_GetProcessorName(TCHAR* sProcessorName, DWORD maxcount)
|
||||
{
|
||||
if(!sProcessorName)
|
||||
if (!sProcessorName)
|
||||
return FALSE;
|
||||
|
||||
HKEY hKey;
|
||||
@@ -172,7 +171,7 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax)
|
||||
_tcsncat(szVersion, _T("Microsoft Windows XP "), cntMax);
|
||||
if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0)
|
||||
_tcsncat(szVersion, _T("Microsoft Windows 2000 "), cntMax);
|
||||
if (osvi.dwMajorVersion <= 4 )
|
||||
if (osvi.dwMajorVersion <= 4)
|
||||
_tcsncat(szVersion, _T("Microsoft Windows NT "), cntMax);
|
||||
|
||||
// Test for specific product on Windows NT 4.0 SP6 and later.
|
||||
@@ -241,9 +240,9 @@ BOOL WheatyExceptionReport::_GetWindowsVersion(TCHAR* szVersion, DWORD cntMax)
|
||||
#endif // WINVER < 0x0500
|
||||
_tcsncat(szVersion, _T("Datacenter Server "), cntMax);
|
||||
#if WINVER < 0x0500
|
||||
else if (osvi.wReserved[0] & VER_SUITE_ENTERPRISE )
|
||||
else if (osvi.wReserved[0] & VER_SUITE_ENTERPRISE)
|
||||
#else
|
||||
else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
|
||||
else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
|
||||
#endif // WINVER < 0x0500
|
||||
_tcsncat(szVersion, _T("Advanced Server "), cntMax);
|
||||
else
|
||||
@@ -322,7 +321,7 @@ void WheatyExceptionReport::PrintSystemInfo()
|
||||
_tprintf(_T("*** Hardware ***\r\nProcessor: <unknown>\r\nNumber Of Processors: %d\r\nPhysical Memory: %d KB (Available: %d KB)\r\nCommit Charge Limit: %d KB\r\n"),
|
||||
SystemInfo.dwNumberOfProcessors, MemoryStatus.dwTotalPhys/0x400, MemoryStatus.dwAvailPhys/0x400, MemoryStatus.dwTotalPageFile/0x400);
|
||||
|
||||
if(_GetWindowsVersion(sString, countof(sString)))
|
||||
if (_GetWindowsVersion(sString, countof(sString)))
|
||||
_tprintf(_T("\r\n*** Operation System ***\r\n%s\r\n"), sString);
|
||||
else
|
||||
_tprintf(_T("\r\n*** Operation System:\r\n<unknown>\r\n"));
|
||||
@@ -337,18 +336,18 @@ void WheatyExceptionReport::printTracesForAllThreads()
|
||||
DWORD dwOwnerPID = GetCurrentProcessId();
|
||||
m_hProcess = GetCurrentProcess();
|
||||
// Take a snapshot of all running threads
|
||||
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
|
||||
if( hThreadSnap == INVALID_HANDLE_VALUE )
|
||||
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
if (hThreadSnap == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
// Fill in the size of the structure before using it.
|
||||
te32.dwSize = sizeof(THREADENTRY32 );
|
||||
te32.dwSize = sizeof(THREADENTRY32);
|
||||
|
||||
// Retrieve information about the first thread,
|
||||
// and exit if unsuccessful
|
||||
if( !Thread32First( hThreadSnap, &te32 ) )
|
||||
if (!Thread32First(hThreadSnap, &te32))
|
||||
{
|
||||
CloseHandle( hThreadSnap ); // Must clean up the
|
||||
CloseHandle(hThreadSnap); // Must clean up the
|
||||
// snapshot object!
|
||||
return;
|
||||
}
|
||||
@@ -358,21 +357,21 @@ void WheatyExceptionReport::printTracesForAllThreads()
|
||||
// associated with the specified process
|
||||
do
|
||||
{
|
||||
if( te32.th32OwnerProcessID == dwOwnerPID )
|
||||
if (te32.th32OwnerProcessID == dwOwnerPID)
|
||||
{
|
||||
CONTEXT context;
|
||||
context.ContextFlags = 0xffffffff;
|
||||
HANDLE threadHandle = OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION,false, te32.th32ThreadID);
|
||||
if(threadHandle && GetThreadContext(threadHandle, &context))
|
||||
if (threadHandle && GetThreadContext(threadHandle, &context))
|
||||
{
|
||||
WriteStackDetails( &context, false, threadHandle );
|
||||
WriteStackDetails(&context, false, threadHandle);
|
||||
}
|
||||
CloseHandle(threadHandle);
|
||||
}
|
||||
} while( Thread32Next(hThreadSnap, &te32 ) );
|
||||
} while(Thread32Next(hThreadSnap, &te32));
|
||||
|
||||
// Don't forget to clean up the snapshot object.
|
||||
CloseHandle( hThreadSnap );
|
||||
CloseHandle(hThreadSnap);
|
||||
}
|
||||
|
||||
|
||||
@@ -381,7 +380,7 @@ void WheatyExceptionReport::printTracesForAllThreads()
|
||||
// WheatyUnhandledExceptionFilter
|
||||
//===========================================================================
|
||||
void WheatyExceptionReport::GenerateExceptionReport(
|
||||
PEXCEPTION_POINTERS pExceptionInfo )
|
||||
PEXCEPTION_POINTERS pExceptionInfo)
|
||||
{
|
||||
SYSTEMTIME systime;
|
||||
GetLocalTime(&systime);
|
||||
@@ -394,66 +393,66 @@ PEXCEPTION_POINTERS pExceptionInfo )
|
||||
PrintSystemInfo();
|
||||
// First print information about the type of fault
|
||||
_tprintf(_T("\r\n//=====================================================\r\n"));
|
||||
_tprintf( _T("Exception code: %08X %s\r\n"),
|
||||
_tprintf(_T("Exception code: %08X %s\r\n"),
|
||||
pExceptionRecord->ExceptionCode,
|
||||
GetExceptionString(pExceptionRecord->ExceptionCode) );
|
||||
GetExceptionString(pExceptionRecord->ExceptionCode));
|
||||
|
||||
// Now print information about where the fault occured
|
||||
TCHAR szFaultingModule[MAX_PATH];
|
||||
DWORD section;
|
||||
DWORD_PTR offset;
|
||||
GetLogicalAddress( pExceptionRecord->ExceptionAddress,
|
||||
GetLogicalAddress(pExceptionRecord->ExceptionAddress,
|
||||
szFaultingModule,
|
||||
sizeof( szFaultingModule ),
|
||||
section, offset );
|
||||
sizeof(szFaultingModule),
|
||||
section, offset);
|
||||
|
||||
#ifdef _M_IX86
|
||||
_tprintf( _T("Fault address: %08X %02X:%08X %s\r\n"),
|
||||
_tprintf(_T("Fault address: %08X %02X:%08X %s\r\n"),
|
||||
pExceptionRecord->ExceptionAddress,
|
||||
section, offset, szFaultingModule );
|
||||
section, offset, szFaultingModule);
|
||||
#endif
|
||||
#ifdef _M_X64
|
||||
_tprintf( _T("Fault address: %016I64X %02X:%016I64X %s\r\n"),
|
||||
_tprintf(_T("Fault address: %016I64X %02X:%016I64X %s\r\n"),
|
||||
pExceptionRecord->ExceptionAddress,
|
||||
section, offset, szFaultingModule );
|
||||
section, offset, szFaultingModule);
|
||||
#endif
|
||||
|
||||
PCONTEXT pCtx = pExceptionInfo->ContextRecord;
|
||||
|
||||
// Show the registers
|
||||
#ifdef _M_IX86 // X86 Only!
|
||||
_tprintf( _T("\r\nRegisters:\r\n") );
|
||||
_tprintf(_T("\r\nRegisters:\r\n"));
|
||||
|
||||
_tprintf(_T("EAX:%08X\r\nEBX:%08X\r\nECX:%08X\r\nEDX:%08X\r\nESI:%08X\r\nEDI:%08X\r\n")
|
||||
,pCtx->Eax, pCtx->Ebx, pCtx->Ecx, pCtx->Edx,
|
||||
pCtx->Esi, pCtx->Edi );
|
||||
pCtx->Esi, pCtx->Edi);
|
||||
|
||||
_tprintf( _T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip );
|
||||
_tprintf( _T("SS:ESP:%04X:%08X EBP:%08X\r\n"),
|
||||
pCtx->SegSs, pCtx->Esp, pCtx->Ebp );
|
||||
_tprintf( _T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
|
||||
pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs );
|
||||
_tprintf( _T("Flags:%08X\r\n"), pCtx->EFlags );
|
||||
_tprintf(_T("CS:EIP:%04X:%08X\r\n"), pCtx->SegCs, pCtx->Eip);
|
||||
_tprintf(_T("SS:ESP:%04X:%08X EBP:%08X\r\n"),
|
||||
pCtx->SegSs, pCtx->Esp, pCtx->Ebp);
|
||||
_tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
|
||||
pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
|
||||
_tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags);
|
||||
#endif
|
||||
|
||||
#ifdef _M_X64
|
||||
_tprintf( _T("\r\nRegisters:\r\n") );
|
||||
_tprintf(_T("\r\nRegisters:\r\n"));
|
||||
_tprintf(_T("RAX:%016I64X\r\nRBX:%016I64X\r\nRCX:%016I64X\r\nRDX:%016I64X\r\nRSI:%016I64X\r\nRDI:%016I64X\r\n")
|
||||
_T("R8: %016I64X\r\nR9: %016I64X\r\nR10:%016I64X\r\nR11:%016I64X\r\nR12:%016I64X\r\nR13:%016I64X\r\nR14:%016I64X\r\nR15:%016I64X\r\n")
|
||||
,pCtx->Rax, pCtx->Rbx, pCtx->Rcx, pCtx->Rdx,
|
||||
pCtx->Rsi, pCtx->Rdi ,pCtx->R9,pCtx->R10,pCtx->R11,pCtx->R12,pCtx->R13,pCtx->R14,pCtx->R15);
|
||||
_tprintf( _T("CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip );
|
||||
_tprintf( _T("SS:RSP:%04X:%016X RBP:%08X\r\n"),
|
||||
pCtx->SegSs, pCtx->Rsp, pCtx->Rbp );
|
||||
_tprintf( _T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
|
||||
pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs );
|
||||
_tprintf( _T("Flags:%08X\r\n"), pCtx->EFlags );
|
||||
_tprintf(_T("CS:RIP:%04X:%016I64X\r\n"), pCtx->SegCs, pCtx->Rip);
|
||||
_tprintf(_T("SS:RSP:%04X:%016X RBP:%08X\r\n"),
|
||||
pCtx->SegSs, pCtx->Rsp, pCtx->Rbp);
|
||||
_tprintf(_T("DS:%04X ES:%04X FS:%04X GS:%04X\r\n"),
|
||||
pCtx->SegDs, pCtx->SegEs, pCtx->SegFs, pCtx->SegGs);
|
||||
_tprintf(_T("Flags:%08X\r\n"), pCtx->EFlags);
|
||||
#endif
|
||||
|
||||
SymSetOptions( SYMOPT_DEFERRED_LOADS );
|
||||
SymSetOptions(SYMOPT_DEFERRED_LOADS);
|
||||
|
||||
// Initialize DbgHelp
|
||||
if ( !SymInitialize( GetCurrentProcess(), 0, TRUE ) )
|
||||
if (!SymInitialize(GetCurrentProcess(), 0, TRUE))
|
||||
{
|
||||
_tprintf(_T("\n\rCRITICAL ERROR.\n\r Couldn't initialize the symbol handler for process.\n\rError [%s].\n\r\n\r"),
|
||||
ErrorMessage(GetLastError()));
|
||||
@@ -461,62 +460,62 @@ PEXCEPTION_POINTERS pExceptionInfo )
|
||||
|
||||
CONTEXT trashableContext = *pCtx;
|
||||
|
||||
WriteStackDetails( &trashableContext, false, NULL );
|
||||
WriteStackDetails(&trashableContext, false, NULL);
|
||||
printTracesForAllThreads();
|
||||
|
||||
// #ifdef _M_IX86 // X86 Only!
|
||||
|
||||
_tprintf( _T("========================\r\n") );
|
||||
_tprintf( _T("Local Variables And Parameters\r\n") );
|
||||
_tprintf(_T("========================\r\n"));
|
||||
_tprintf(_T("Local Variables And Parameters\r\n"));
|
||||
|
||||
trashableContext = *pCtx;
|
||||
WriteStackDetails( &trashableContext, true, NULL );
|
||||
WriteStackDetails(&trashableContext, true, NULL);
|
||||
|
||||
_tprintf( _T("========================\r\n") );
|
||||
_tprintf( _T("Global Variables\r\n") );
|
||||
_tprintf(_T("========================\r\n"));
|
||||
_tprintf(_T("Global Variables\r\n"));
|
||||
|
||||
SymEnumSymbols( GetCurrentProcess(),
|
||||
SymEnumSymbols(GetCurrentProcess(),
|
||||
(DWORD64)GetModuleHandle(szFaultingModule),
|
||||
0, EnumerateSymbolsCallback, 0 );
|
||||
0, EnumerateSymbolsCallback, 0);
|
||||
// #endif // X86 Only!
|
||||
|
||||
SymCleanup( GetCurrentProcess() );
|
||||
SymCleanup(GetCurrentProcess());
|
||||
|
||||
_tprintf( _T("\r\n") );
|
||||
_tprintf(_T("\r\n"));
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Given an exception code, returns a pointer to a static string with a
|
||||
// description of the exception
|
||||
//======================================================================
|
||||
LPTSTR WheatyExceptionReport::GetExceptionString( DWORD dwCode )
|
||||
LPTSTR WheatyExceptionReport::GetExceptionString(DWORD dwCode)
|
||||
{
|
||||
#define EXCEPTION( x ) case EXCEPTION_##x: return _T(#x);
|
||||
#define EXCEPTION(x) case EXCEPTION_##x: return _T(#x);
|
||||
|
||||
switch ( dwCode )
|
||||
switch (dwCode)
|
||||
{
|
||||
EXCEPTION( ACCESS_VIOLATION )
|
||||
EXCEPTION( DATATYPE_MISALIGNMENT )
|
||||
EXCEPTION( BREAKPOINT )
|
||||
EXCEPTION( SINGLE_STEP )
|
||||
EXCEPTION( ARRAY_BOUNDS_EXCEEDED )
|
||||
EXCEPTION( FLT_DENORMAL_OPERAND )
|
||||
EXCEPTION( FLT_DIVIDE_BY_ZERO )
|
||||
EXCEPTION( FLT_INEXACT_RESULT )
|
||||
EXCEPTION( FLT_INVALID_OPERATION )
|
||||
EXCEPTION( FLT_OVERFLOW )
|
||||
EXCEPTION( FLT_STACK_CHECK )
|
||||
EXCEPTION( FLT_UNDERFLOW )
|
||||
EXCEPTION( INT_DIVIDE_BY_ZERO )
|
||||
EXCEPTION( INT_OVERFLOW )
|
||||
EXCEPTION( PRIV_INSTRUCTION )
|
||||
EXCEPTION( IN_PAGE_ERROR )
|
||||
EXCEPTION( ILLEGAL_INSTRUCTION )
|
||||
EXCEPTION( NONCONTINUABLE_EXCEPTION )
|
||||
EXCEPTION( STACK_OVERFLOW )
|
||||
EXCEPTION( INVALID_DISPOSITION )
|
||||
EXCEPTION( GUARD_PAGE )
|
||||
EXCEPTION( INVALID_HANDLE )
|
||||
EXCEPTION(ACCESS_VIOLATION)
|
||||
EXCEPTION(DATATYPE_MISALIGNMENT)
|
||||
EXCEPTION(BREAKPOINT)
|
||||
EXCEPTION(SINGLE_STEP)
|
||||
EXCEPTION(ARRAY_BOUNDS_EXCEEDED)
|
||||
EXCEPTION(FLT_DENORMAL_OPERAND)
|
||||
EXCEPTION(FLT_DIVIDE_BY_ZERO)
|
||||
EXCEPTION(FLT_INEXACT_RESULT)
|
||||
EXCEPTION(FLT_INVALID_OPERATION)
|
||||
EXCEPTION(FLT_OVERFLOW)
|
||||
EXCEPTION(FLT_STACK_CHECK)
|
||||
EXCEPTION(FLT_UNDERFLOW)
|
||||
EXCEPTION(INT_DIVIDE_BY_ZERO)
|
||||
EXCEPTION(INT_OVERFLOW)
|
||||
EXCEPTION(PRIV_INSTRUCTION)
|
||||
EXCEPTION(IN_PAGE_ERROR)
|
||||
EXCEPTION(ILLEGAL_INSTRUCTION)
|
||||
EXCEPTION(NONCONTINUABLE_EXCEPTION)
|
||||
EXCEPTION(STACK_OVERFLOW)
|
||||
EXCEPTION(INVALID_DISPOSITION)
|
||||
EXCEPTION(GUARD_PAGE)
|
||||
EXCEPTION(INVALID_HANDLE)
|
||||
}
|
||||
|
||||
// If not one of the "known" exceptions, try to get the string
|
||||
@@ -524,9 +523,9 @@ LPTSTR WheatyExceptionReport::GetExceptionString( DWORD dwCode )
|
||||
|
||||
static TCHAR szBuffer[512] = { 0 };
|
||||
|
||||
FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
|
||||
GetModuleHandle( _T("NTDLL.DLL") ),
|
||||
dwCode, 0, szBuffer, sizeof( szBuffer ), 0 );
|
||||
FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
|
||||
GetModuleHandle(_T("NTDLL.DLL")),
|
||||
dwCode, 0, szBuffer, sizeof(szBuffer), 0);
|
||||
|
||||
return szBuffer;
|
||||
}
|
||||
@@ -539,16 +538,16 @@ LPTSTR WheatyExceptionReport::GetExceptionString( DWORD dwCode )
|
||||
// by the len parameter (in characters!)
|
||||
//=============================================================================
|
||||
BOOL WheatyExceptionReport::GetLogicalAddress(
|
||||
PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset )
|
||||
PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
if ( !VirtualQuery( addr, &mbi, sizeof(mbi) ) )
|
||||
if (!VirtualQuery(addr, &mbi, sizeof(mbi)))
|
||||
return FALSE;
|
||||
|
||||
DWORD_PTR hMod = (DWORD_PTR)mbi.AllocationBase;
|
||||
|
||||
if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) )
|
||||
if (!GetModuleFileName((HMODULE)hMod, szModule, len))
|
||||
return FALSE;
|
||||
|
||||
// Point to the DOS header in memory
|
||||
@@ -557,22 +556,22 @@ PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD_PTR& offset )
|
||||
// From the DOS header, find the NT (PE) header
|
||||
PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + DWORD_PTR(pDosHdr->e_lfanew));
|
||||
|
||||
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
|
||||
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHdr);
|
||||
|
||||
DWORD_PTR rva = (DWORD_PTR)addr - hMod; // RVA is offset from module load address
|
||||
|
||||
// Iterate through the section table, looking for the one that encompasses
|
||||
// the linear address.
|
||||
for ( unsigned i = 0;
|
||||
for (unsigned i = 0;
|
||||
i < pNtHdr->FileHeader.NumberOfSections;
|
||||
i++, pSection++ )
|
||||
i++, pSection++)
|
||||
{
|
||||
DWORD_PTR sectionStart = pSection->VirtualAddress;
|
||||
DWORD_PTR sectionEnd = sectionStart
|
||||
+ DWORD_PTR(max(pSection->SizeOfRawData, pSection->Misc.VirtualSize));
|
||||
|
||||
// Is the address in this section???
|
||||
if ( (rva >= sectionStart) && (rva <= sectionEnd) )
|
||||
if ((rva >= sectionStart) && (rva <= sectionEnd))
|
||||
{
|
||||
// Yes, address is in the section. Calculate section and offset,
|
||||
// and store in the "section" & "offset" params, which were
|
||||
@@ -604,15 +603,15 @@ void WheatyExceptionReport::WriteStackDetails(
|
||||
PCONTEXT pContext,
|
||||
bool bWriteVariables, HANDLE pThreadHandle) // true if local/params should be output
|
||||
{
|
||||
_tprintf( _T("\r\nCall stack:\r\n") );
|
||||
_tprintf(_T("\r\nCall stack:\r\n"));
|
||||
|
||||
_tprintf( _T("Address Frame Function SourceFile\r\n") );
|
||||
_tprintf(_T("Address Frame Function SourceFile\r\n"));
|
||||
|
||||
DWORD dwMachineType = 0;
|
||||
// Could use SymSetOptions here to add the SYMOPT_DEFERRED_LOADS flag
|
||||
|
||||
STACKFRAME64 sf;
|
||||
memset( &sf, 0, sizeof(sf) );
|
||||
memset(&sf, 0, sizeof(sf));
|
||||
|
||||
#ifdef _M_IX86
|
||||
// Initialize the STACKFRAME structure for the first call. This is only
|
||||
@@ -637,10 +636,10 @@ bool bWriteVariables, HANDLE pThreadHandle)
|
||||
dwMachineType = IMAGE_FILE_MACHINE_AMD64;
|
||||
#endif
|
||||
|
||||
while ( 1 )
|
||||
while (1)
|
||||
{
|
||||
// Get the next stack frame
|
||||
if ( ! StackWalk64( dwMachineType,
|
||||
if (! StackWalk64(dwMachineType,
|
||||
m_hProcess,
|
||||
pThreadHandle != NULL ? pThreadHandle : GetCurrentThread(),
|
||||
&sf,
|
||||
@@ -648,15 +647,15 @@ bool bWriteVariables, HANDLE pThreadHandle)
|
||||
0,
|
||||
SymFunctionTableAccess64,
|
||||
SymGetModuleBase64,
|
||||
0 ) )
|
||||
0))
|
||||
break;
|
||||
if ( 0 == sf.AddrFrame.Offset ) // Basic sanity check to make sure
|
||||
if (0 == sf.AddrFrame.Offset) // Basic sanity check to make sure
|
||||
break; // the frame is OK. Bail if not.
|
||||
#ifdef _M_IX86
|
||||
_tprintf( _T("%08X %08X "), sf.AddrPC.Offset, sf.AddrFrame.Offset );
|
||||
_tprintf(_T("%08X %08X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
|
||||
#endif
|
||||
#ifdef _M_X64
|
||||
_tprintf( _T("%016I64X %016I64X "), sf.AddrPC.Offset, sf.AddrFrame.Offset );
|
||||
_tprintf(_T("%016I64X %016I64X "), sf.AddrPC.Offset, sf.AddrFrame.Offset);
|
||||
#endif
|
||||
|
||||
DWORD64 symDisplacement = 0; // Displacement of the input address,
|
||||
@@ -664,14 +663,13 @@ bool bWriteVariables, HANDLE pThreadHandle)
|
||||
|
||||
// Get the name of the function for this stack frame entry
|
||||
CSymbolInfoPackage sip;
|
||||
if ( SymFromAddr(
|
||||
if (SymFromAddr(
|
||||
m_hProcess, // Process handle of the current process
|
||||
sf.AddrPC.Offset, // Symbol address
|
||||
&symDisplacement, // Address of the variable that will receive the displacement
|
||||
&sip.si // Address of the SYMBOL_INFO structure (inside "sip" object)
|
||||
))
|
||||
&sip.si)) // Address of the SYMBOL_INFO structure (inside "sip" object)
|
||||
{
|
||||
_tprintf( _T("%hs+%I64X"), sip.si.Name, symDisplacement );
|
||||
_tprintf(_T("%hs+%I64X"), sip.si.Name, symDisplacement);
|
||||
|
||||
}
|
||||
else // No symbol found. Print out the logical address instead.
|
||||
@@ -680,39 +678,39 @@ bool bWriteVariables, HANDLE pThreadHandle)
|
||||
DWORD section = 0;
|
||||
DWORD_PTR offset = 0;
|
||||
|
||||
GetLogicalAddress( (PVOID)sf.AddrPC.Offset,
|
||||
szModule, sizeof(szModule), section, offset );
|
||||
GetLogicalAddress((PVOID)sf.AddrPC.Offset,
|
||||
szModule, sizeof(szModule), section, offset);
|
||||
#ifdef _M_IX86
|
||||
_tprintf( _T("%04X:%08X %s"), section, offset, szModule );
|
||||
_tprintf(_T("%04X:%08X %s"), section, offset, szModule);
|
||||
#endif
|
||||
#ifdef _M_X64
|
||||
_tprintf( _T("%04X:%016I64X %s"), section, offset, szModule );
|
||||
_tprintf(_T("%04X:%016I64X %s"), section, offset, szModule);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Get the source line for this stack frame entry
|
||||
IMAGEHLP_LINE64 lineInfo = { sizeof(IMAGEHLP_LINE) };
|
||||
DWORD dwLineDisplacement;
|
||||
if ( SymGetLineFromAddr64( m_hProcess, sf.AddrPC.Offset,
|
||||
&dwLineDisplacement, &lineInfo ) )
|
||||
if (SymGetLineFromAddr64(m_hProcess, sf.AddrPC.Offset,
|
||||
&dwLineDisplacement, &lineInfo))
|
||||
{
|
||||
_tprintf(_T(" %s line %u"),lineInfo.FileName,lineInfo.LineNumber);
|
||||
}
|
||||
|
||||
_tprintf( _T("\r\n") );
|
||||
_tprintf(_T("\r\n"));
|
||||
|
||||
// Write out the variables, if desired
|
||||
if ( bWriteVariables )
|
||||
if (bWriteVariables)
|
||||
{
|
||||
// Use SymSetContext to get just the locals/params for this frame
|
||||
IMAGEHLP_STACK_FRAME imagehlpStackFrame;
|
||||
imagehlpStackFrame.InstructionOffset = sf.AddrPC.Offset;
|
||||
SymSetContext( m_hProcess, &imagehlpStackFrame, 0 );
|
||||
SymSetContext(m_hProcess, &imagehlpStackFrame, 0);
|
||||
|
||||
// Enumerate the locals/parameters
|
||||
SymEnumSymbols( m_hProcess, 0, 0, EnumerateSymbolsCallback, &sf );
|
||||
SymEnumSymbols(m_hProcess, 0, 0, EnumerateSymbolsCallback, &sf);
|
||||
|
||||
_tprintf( _T("\r\n") );
|
||||
_tprintf(_T("\r\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,20 +724,20 @@ BOOL CALLBACK
|
||||
WheatyExceptionReport::EnumerateSymbolsCallback(
|
||||
PSYMBOL_INFO pSymInfo,
|
||||
ULONG SymbolSize,
|
||||
PVOID UserContext )
|
||||
PVOID UserContext)
|
||||
{
|
||||
|
||||
char szBuffer[2048];
|
||||
|
||||
__try
|
||||
{
|
||||
if ( FormatSymbolValue( pSymInfo, (STACKFRAME*)UserContext,
|
||||
szBuffer, sizeof(szBuffer) ) )
|
||||
_tprintf( _T("\t%s\r\n"), szBuffer );
|
||||
if (FormatSymbolValue(pSymInfo, (STACKFRAME*)UserContext,
|
||||
szBuffer, sizeof(szBuffer)))
|
||||
_tprintf(_T("\t%s\r\n"), szBuffer);
|
||||
}
|
||||
__except( 1 )
|
||||
__except(1)
|
||||
{
|
||||
_tprintf( _T("punting on symbol %s\r\n"), pSymInfo->Name );
|
||||
_tprintf(_T("punting on symbol %s\r\n"), pSymInfo->Name);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -754,25 +752,25 @@ bool WheatyExceptionReport::FormatSymbolValue(
|
||||
PSYMBOL_INFO pSym,
|
||||
STACKFRAME * sf,
|
||||
char * pszBuffer,
|
||||
unsigned cbBuffer )
|
||||
unsigned cbBuffer)
|
||||
{
|
||||
char * pszCurrBuffer = pszBuffer;
|
||||
|
||||
// Indicate if the variable is a local or parameter
|
||||
if ( pSym->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER )
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, "Parameter " );
|
||||
else if ( pSym->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL )
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, "Local " );
|
||||
if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_PARAMETER)
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "Parameter ");
|
||||
else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_LOCAL)
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "Local ");
|
||||
|
||||
// If it's a function, don't do anything.
|
||||
if ( pSym->Tag == 5 ) // SymTagFunction from CVCONST.H from the DIA SDK
|
||||
if (pSym->Tag == 5) // SymTagFunction from CVCONST.H from the DIA SDK
|
||||
return false;
|
||||
|
||||
DWORD_PTR pVariable = 0; // Will point to the variable's data in memory
|
||||
|
||||
if ( pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE )
|
||||
if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGRELATIVE)
|
||||
{
|
||||
// if ( pSym->Register == 8 ) // EBP is the value 8 (in DBGHELP 5.1)
|
||||
// if (pSym->Register == 8) // EBP is the value 8 (in DBGHELP 5.1)
|
||||
{ // This may change!!!
|
||||
pVariable = sf->AddrFrame.Offset;
|
||||
pVariable += (DWORD_PTR)pSym->Address;
|
||||
@@ -780,7 +778,7 @@ unsigned cbBuffer )
|
||||
// else
|
||||
// return false;
|
||||
}
|
||||
else if ( pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER )
|
||||
else if (pSym->Flags & IMAGEHLP_SYMBOL_INFO_REGISTER)
|
||||
{
|
||||
return false; // Don't try to report register variable
|
||||
}
|
||||
@@ -793,21 +791,21 @@ unsigned cbBuffer )
|
||||
// will return true.
|
||||
bool bHandled;
|
||||
pszCurrBuffer = DumpTypeIndex(pszCurrBuffer,pSym->ModBase, pSym->TypeIndex,
|
||||
0, pVariable, bHandled, pSym->Name );
|
||||
0, pVariable, bHandled, pSym->Name);
|
||||
|
||||
if ( !bHandled )
|
||||
if (!bHandled)
|
||||
{
|
||||
// The symbol wasn't a UDT, so do basic, stupid formatting of the
|
||||
// variable. Based on the size, we're assuming it's a char, WORD, or
|
||||
// DWORD.
|
||||
BasicType basicType = GetBasicType( pSym->TypeIndex, pSym->ModBase );
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, rgBaseType[basicType]);
|
||||
BasicType basicType = GetBasicType(pSym->TypeIndex, pSym->ModBase);
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]);
|
||||
|
||||
// Emit the variable name
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, "\'%s\'", pSym->Name );
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "\'%s\'", pSym->Name);
|
||||
|
||||
pszCurrBuffer = FormatOutputValue(pszCurrBuffer, basicType, pSym->Size,
|
||||
(PVOID)pVariable );
|
||||
(PVOID)pVariable);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -832,19 +830,19 @@ char* Name)
|
||||
// Get the name of the symbol. This will either be a Type name (if a UDT),
|
||||
// or the structure member name.
|
||||
WCHAR * pwszTypeName;
|
||||
if ( SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME,
|
||||
&pwszTypeName ) )
|
||||
if (SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_SYMNAME,
|
||||
&pwszTypeName))
|
||||
{
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, " %ls", pwszTypeName );
|
||||
LocalFree( pwszTypeName );
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " %ls", pwszTypeName);
|
||||
LocalFree(pwszTypeName);
|
||||
}
|
||||
|
||||
// Determine how many children this type has.
|
||||
DWORD dwChildrenCount = 0;
|
||||
SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT,
|
||||
&dwChildrenCount );
|
||||
SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_GET_CHILDRENCOUNT,
|
||||
&dwChildrenCount);
|
||||
|
||||
if ( !dwChildrenCount ) // If no children, we're done
|
||||
if (!dwChildrenCount) // If no children, we're done
|
||||
return pszCurrBuffer;
|
||||
|
||||
// Prepare to get an array of "TypeIds", representing each of the children.
|
||||
@@ -860,44 +858,44 @@ char* Name)
|
||||
children.Start= 0;
|
||||
|
||||
// Get the array of TypeIds, one for each child type
|
||||
if ( !SymGetTypeInfo( m_hProcess, modBase, dwTypeIndex, TI_FINDCHILDREN,
|
||||
&children ) )
|
||||
if (!SymGetTypeInfo(m_hProcess, modBase, dwTypeIndex, TI_FINDCHILDREN,
|
||||
&children))
|
||||
{
|
||||
return pszCurrBuffer;
|
||||
}
|
||||
|
||||
// Append a line feed
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, "\r\n" );
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "\r\n");
|
||||
|
||||
// Iterate through each of the children
|
||||
for ( unsigned i = 0; i < dwChildrenCount; i++ )
|
||||
for (unsigned i = 0; i < dwChildrenCount; i++)
|
||||
{
|
||||
// Add appropriate indentation level (since this routine is recursive)
|
||||
for ( unsigned j = 0; j <= nestingLevel+1; j++ )
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, "\t" );
|
||||
for (unsigned j = 0; j <= nestingLevel+1; j++)
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "\t");
|
||||
|
||||
// Recurse for each of the child types
|
||||
bool bHandled2;
|
||||
BasicType basicType = GetBasicType(children.ChildId[i], modBase );
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, rgBaseType[basicType]);
|
||||
BasicType basicType = GetBasicType(children.ChildId[i], modBase);
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]);
|
||||
|
||||
pszCurrBuffer = DumpTypeIndex( pszCurrBuffer, modBase,
|
||||
pszCurrBuffer = DumpTypeIndex(pszCurrBuffer, modBase,
|
||||
children.ChildId[i], nestingLevel+1,
|
||||
offset, bHandled2, ""/*Name */);
|
||||
|
||||
// If the child wasn't a UDT, format it appropriately
|
||||
if ( !bHandled2 )
|
||||
if (!bHandled2)
|
||||
{
|
||||
// Get the offset of the child member, relative to its parent
|
||||
DWORD dwMemberOffset;
|
||||
SymGetTypeInfo( m_hProcess, modBase, children.ChildId[i],
|
||||
TI_GET_OFFSET, &dwMemberOffset );
|
||||
SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i],
|
||||
TI_GET_OFFSET, &dwMemberOffset);
|
||||
|
||||
// Get the real "TypeId" of the child. We need this for the
|
||||
// SymGetTypeInfo( TI_GET_TYPEID ) call below.
|
||||
// SymGetTypeInfo(TI_GET_TYPEID) call below.
|
||||
DWORD typeId;
|
||||
SymGetTypeInfo( m_hProcess, modBase, children.ChildId[i],
|
||||
TI_GET_TYPEID, &typeId );
|
||||
SymGetTypeInfo(m_hProcess, modBase, children.ChildId[i],
|
||||
TI_GET_TYPEID, &typeId);
|
||||
|
||||
// Get the size of the child member
|
||||
ULONG64 length;
|
||||
@@ -906,17 +904,17 @@ char* Name)
|
||||
// Calculate the address of the member
|
||||
DWORD_PTR dwFinalOffset = offset + dwMemberOffset;
|
||||
|
||||
// BasicType basicType = GetBasicType(children.ChildId[i], modBase );
|
||||
// BasicType basicType = GetBasicType(children.ChildId[i], modBase);
|
||||
//
|
||||
// pszCurrBuffer += sprintf( pszCurrBuffer, rgBaseType[basicType]);
|
||||
// pszCurrBuffer += sprintf(pszCurrBuffer, rgBaseType[basicType]);
|
||||
//
|
||||
// Emit the variable name
|
||||
// pszCurrBuffer += sprintf( pszCurrBuffer, "\'%s\'", Name );
|
||||
// pszCurrBuffer += sprintf(pszCurrBuffer, "\'%s\'", Name);
|
||||
|
||||
pszCurrBuffer = FormatOutputValue( pszCurrBuffer, basicType,
|
||||
length, (PVOID)dwFinalOffset );
|
||||
pszCurrBuffer = FormatOutputValue(pszCurrBuffer, basicType,
|
||||
length, (PVOID)dwFinalOffset);
|
||||
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, "\r\n" );
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,68 +922,68 @@ char* Name)
|
||||
return pszCurrBuffer;
|
||||
}
|
||||
|
||||
char * WheatyExceptionReport::FormatOutputValue( char * pszCurrBuffer,
|
||||
char * WheatyExceptionReport::FormatOutputValue(char * pszCurrBuffer,
|
||||
BasicType basicType,
|
||||
DWORD64 length,
|
||||
PVOID pAddress )
|
||||
PVOID pAddress)
|
||||
{
|
||||
// Format appropriately (assuming it's a 1, 2, or 4 bytes (!!!)
|
||||
if ( length == 1 )
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, " = %X", *(PBYTE)pAddress );
|
||||
else if ( length == 2 )
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, " = %X", *(PWORD)pAddress );
|
||||
else if ( length == 4 )
|
||||
if (length == 1)
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PBYTE)pAddress);
|
||||
else if (length == 2)
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = %X", *(PWORD)pAddress);
|
||||
else if (length == 4)
|
||||
{
|
||||
if ( basicType == btFloat )
|
||||
if (basicType == btFloat)
|
||||
{
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer," = %f", *(PFLOAT)pAddress);
|
||||
}
|
||||
else if ( basicType == btChar )
|
||||
else if (basicType == btChar)
|
||||
{
|
||||
if ( !IsBadStringPtr( *(PSTR*)pAddress, 32) )
|
||||
if (!IsBadStringPtr(*(PSTR*)pAddress, 32))
|
||||
{
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, " = \"%.31s\"",
|
||||
*(PDWORD)pAddress );
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = \"%.31s\"",
|
||||
*(PDWORD)pAddress);
|
||||
}
|
||||
else
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, " = %X",
|
||||
*(PDWORD)pAddress );
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = %X",
|
||||
*(PDWORD)pAddress);
|
||||
}
|
||||
else
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer," = %X", *(PDWORD)pAddress);
|
||||
}
|
||||
else if ( length == 8 )
|
||||
else if (length == 8)
|
||||
{
|
||||
if ( basicType == btFloat )
|
||||
if (basicType == btFloat)
|
||||
{
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, " = %lf",
|
||||
*(double *)pAddress );
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = %lf",
|
||||
*(double *)pAddress);
|
||||
}
|
||||
else
|
||||
pszCurrBuffer += sprintf( pszCurrBuffer, " = %I64X",
|
||||
*(DWORD64*)pAddress );
|
||||
pszCurrBuffer += sprintf(pszCurrBuffer, " = %I64X",
|
||||
*(DWORD64*)pAddress);
|
||||
}
|
||||
|
||||
return pszCurrBuffer;
|
||||
}
|
||||
|
||||
BasicType
|
||||
WheatyExceptionReport::GetBasicType( DWORD typeIndex, DWORD64 modBase )
|
||||
WheatyExceptionReport::GetBasicType(DWORD typeIndex, DWORD64 modBase)
|
||||
{
|
||||
BasicType basicType;
|
||||
if ( SymGetTypeInfo( m_hProcess, modBase, typeIndex,
|
||||
TI_GET_BASETYPE, &basicType ) )
|
||||
if (SymGetTypeInfo(m_hProcess, modBase, typeIndex,
|
||||
TI_GET_BASETYPE, &basicType))
|
||||
{
|
||||
return basicType;
|
||||
}
|
||||
|
||||
// Get the real "TypeId" of the child. We need this for the
|
||||
// SymGetTypeInfo( TI_GET_TYPEID ) call below.
|
||||
// SymGetTypeInfo(TI_GET_TYPEID) call below.
|
||||
DWORD typeId;
|
||||
if (SymGetTypeInfo(m_hProcess,modBase, typeIndex, TI_GET_TYPEID, &typeId))
|
||||
{
|
||||
if ( SymGetTypeInfo( m_hProcess, modBase, typeId, TI_GET_BASETYPE,
|
||||
&basicType ) )
|
||||
if (SymGetTypeInfo(m_hProcess, modBase, typeId, TI_GET_BASETYPE,
|
||||
&basicType))
|
||||
{
|
||||
return basicType;
|
||||
}
|
||||
@@ -1005,11 +1003,11 @@ int __cdecl WheatyExceptionReport::_tprintf(const TCHAR * format, ...)
|
||||
DWORD cbWritten;
|
||||
va_list argptr;
|
||||
|
||||
va_start( argptr, format );
|
||||
retValue = vsprintf( szBuff, format, argptr );
|
||||
va_end( argptr );
|
||||
va_start(argptr, format);
|
||||
retValue = vsprintf(szBuff, format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0 );
|
||||
WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0);
|
||||
|
||||
return retValue;
|
||||
}
|
||||
|
||||
@@ -72,37 +72,37 @@ class WheatyExceptionReport
|
||||
{
|
||||
public:
|
||||
|
||||
WheatyExceptionReport( );
|
||||
~WheatyExceptionReport( );
|
||||
WheatyExceptionReport();
|
||||
~WheatyExceptionReport();
|
||||
|
||||
// entry point where control comes on an unhandled exception
|
||||
static LONG WINAPI WheatyUnhandledExceptionFilter(
|
||||
PEXCEPTION_POINTERS pExceptionInfo );
|
||||
PEXCEPTION_POINTERS pExceptionInfo);
|
||||
|
||||
static void printTracesForAllThreads();
|
||||
private:
|
||||
// where report info is extracted and generated
|
||||
static void GenerateExceptionReport( PEXCEPTION_POINTERS pExceptionInfo );
|
||||
static void GenerateExceptionReport(PEXCEPTION_POINTERS pExceptionInfo);
|
||||
static void PrintSystemInfo();
|
||||
static BOOL _GetWindowsVersion(TCHAR* szVersion, DWORD cntMax);
|
||||
static BOOL _GetProcessorName(TCHAR* sProcessorName, DWORD maxcount);
|
||||
|
||||
// Helper functions
|
||||
static LPTSTR GetExceptionString( DWORD dwCode );
|
||||
static BOOL GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len,
|
||||
DWORD& section, DWORD_PTR& offset );
|
||||
static LPTSTR GetExceptionString(DWORD dwCode);
|
||||
static BOOL GetLogicalAddress(PVOID addr, PTSTR szModule, DWORD len,
|
||||
DWORD& section, DWORD_PTR& offset);
|
||||
|
||||
static void WriteStackDetails( PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
|
||||
static void WriteStackDetails(PCONTEXT pContext, bool bWriteVariables, HANDLE pThreadHandle);
|
||||
|
||||
static BOOL CALLBACK EnumerateSymbolsCallback(PSYMBOL_INFO,ULONG, PVOID);
|
||||
|
||||
static bool FormatSymbolValue( PSYMBOL_INFO, STACKFRAME *, char * pszBuffer, unsigned cbBuffer );
|
||||
static bool FormatSymbolValue(PSYMBOL_INFO, STACKFRAME *, char * pszBuffer, unsigned cbBuffer);
|
||||
|
||||
static char * DumpTypeIndex( char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool & , char*);
|
||||
static char * DumpTypeIndex(char *, DWORD64, DWORD, unsigned, DWORD_PTR, bool & , char*);
|
||||
|
||||
static char * FormatOutputValue( char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress );
|
||||
static char * FormatOutputValue(char * pszCurrBuffer, BasicType basicType, DWORD64 length, PVOID pAddress);
|
||||
|
||||
static BasicType GetBasicType( DWORD typeIndex, DWORD64 modBase );
|
||||
static BasicType GetBasicType(DWORD typeIndex, DWORD64 modBase);
|
||||
|
||||
static int __cdecl _tprintf(const TCHAR * format, ...);
|
||||
|
||||
|
||||
@@ -72,5 +72,7 @@ enum LoginResult
|
||||
//2.4.3 build 8606
|
||||
//3.1.3 build 9947
|
||||
//3.1.3 build 10146 Chinese build
|
||||
int accepted_versions[3][3];
|
||||
|
||||
#define EXPECTED_TRINITY_CLIENT_BUILD {10146, 9947, 8606, 5875, 6005, 0}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -539,24 +539,9 @@ bool AuthSocket::_HandleLogonChallenge()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool valid_pre_version = false;
|
||||
bool valid_tbc_version = false;
|
||||
bool valid_wlk_version = false;
|
||||
/// Logon Proof command handler
|
||||
bool AuthSocket::_HandleLogonProof()
|
||||
{
|
||||
for (int a = 0; a < 3; ++a)
|
||||
{
|
||||
accepted_versions[0][a] = 5875, 6005, 0;
|
||||
}
|
||||
for (int a = 0; a < 3; ++a)
|
||||
{
|
||||
accepted_versions[1][a] = 8606, 0, 0;
|
||||
}
|
||||
for (int a = 0; a < 3; ++a)
|
||||
{
|
||||
accepted_versions[2][a] = 10146, 9947, 0;
|
||||
}
|
||||
DEBUG_LOG("Entering _HandleLogonProof");
|
||||
///- Read the packet
|
||||
if (ibuf.GetLength() < sizeof(sAuthLogonProof_C))
|
||||
@@ -565,34 +550,19 @@ bool AuthSocket::_HandleLogonProof()
|
||||
ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));
|
||||
|
||||
///- Check if the client has one of the expected version numbers
|
||||
//int accepted_versions[] = EXPECTED_TRINITY_CLIENT_BUILD;
|
||||
for (int i = 0; accepted_versions[0][i]; ++i)
|
||||
bool valid_version = false;
|
||||
int accepted_versions[] = EXPECTED_TRINITY_CLIENT_BUILD;
|
||||
for (int i = 0; accepted_versions[i]; ++i)
|
||||
{
|
||||
if (_build == accepted_versions[0][i])
|
||||
if (_build == accepted_versions[i])
|
||||
{
|
||||
valid_pre_version = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; accepted_versions[1][i]; ++i)
|
||||
{
|
||||
if (_build == accepted_versions[1][i])
|
||||
{
|
||||
valid_tbc_version = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; accepted_versions[2][i]; ++i)
|
||||
{
|
||||
if (_build == accepted_versions[2][i])
|
||||
{
|
||||
valid_wlk_version = true;
|
||||
valid_version = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <ul><li> If the client has no valid version
|
||||
if (!valid_pre_version && !valid_tbc_version && !valid_wlk_version)
|
||||
if (!valid_version)
|
||||
{
|
||||
///- Check if we have the apropriate patch on the disk
|
||||
|
||||
@@ -736,7 +706,7 @@ bool AuthSocket::_HandleLogonProof()
|
||||
sha.UpdateBigNumbers(&A, &M, &K, NULL);
|
||||
sha.Finalize();
|
||||
|
||||
if (valid_tbc_version || valid_wlk_version)//2.4.3 and 3.1.3 cliens
|
||||
if (_build == 8606 || _build == 9947 || _build == 10146)//2.4.3 and 3.1.3 clients (10146 is Chinese build for 3.1.3)
|
||||
{
|
||||
sAuthLogonProof_S proof;
|
||||
memcpy(proof.M2, sha.GetDigest(), 20);
|
||||
@@ -746,9 +716,7 @@ bool AuthSocket::_HandleLogonProof()
|
||||
proof.unk2 = 0x00;
|
||||
proof.unk3 = 0x00;
|
||||
SendBuf((char *)&proof, sizeof(proof));
|
||||
}
|
||||
else if (valid_pre_version)
|
||||
{
|
||||
}else{
|
||||
sAuthLogonProof_S_Old proof;
|
||||
memcpy(proof.M2, sha.GetDigest(), 20);
|
||||
proof.cmd = AUTH_LOGON_PROOF;
|
||||
@@ -941,29 +909,15 @@ bool AuthSocket::_HandleRealmList()
|
||||
RealmList built_realmList;
|
||||
for (rlm = m_realmList.begin(); rlm != m_realmList.end(); ++rlm)
|
||||
{
|
||||
if (valid_pre_version)//1.12.1 and 1.12.2
|
||||
if (_build == 8606 || _build == 9947 || _build == 10146)//2.4.3 and 3.1.3 cliens
|
||||
{
|
||||
for (int i = 0; accepted_versions[1][i]; ++i)
|
||||
{
|
||||
if (rlm->second.gamebuild == accepted_versions[1][i])
|
||||
built_realmList.AddRealm(rlm->second);
|
||||
}
|
||||
if (rlm->second.gamebuild == _build)
|
||||
built_realmList.AddRealm(rlm->second);
|
||||
}
|
||||
else if (valid_tbc_version)//2.4.3
|
||||
else if (_build == 5875 || _build == 6005)//1.12.1 and 1.12.2 clients are compatible with eachother
|
||||
{
|
||||
for (int i = 0; accepted_versions[2][i]; ++i)
|
||||
{
|
||||
if (rlm->second.gamebuild == accepted_versions[2][i])
|
||||
built_realmList.AddRealm(rlm->second);
|
||||
}
|
||||
}
|
||||
else if (valid_wlk_version)//3.1.3
|
||||
{
|
||||
for (int i = 0; accepted_versions[3][i]; ++i)
|
||||
{
|
||||
if (rlm->second.gamebuild == accepted_versions[3][i])
|
||||
built_realmList.AddRealm(rlm->second);
|
||||
}
|
||||
if (rlm->second.gamebuild == 5875 || rlm->second.gamebuild == 6005)
|
||||
built_realmList.AddRealm(rlm->second);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -971,9 +925,9 @@ bool AuthSocket::_HandleRealmList()
|
||||
///- Circle through realms in the RealmList and construct the return packet (including # of user characters in each realm)
|
||||
ByteBuffer pkt;
|
||||
pkt << (uint32) 0;
|
||||
if (valid_tbc_version || valid_wlk_version)//only 2.4.3 and 3.1.3 cliens
|
||||
if (_build == 8606 || _build == 9947 || _build == 10146)//only 2.4.3 and 3.1.3 cliens
|
||||
pkt << (uint16) built_realmList.size();
|
||||
else if (valid_pre_version)
|
||||
else
|
||||
pkt << (uint32) built_realmList.size();
|
||||
RealmList::RealmMap::const_iterator i;
|
||||
for (i = built_realmList.begin(); i != built_realmList.end(); ++i)
|
||||
@@ -994,7 +948,7 @@ bool AuthSocket::_HandleRealmList()
|
||||
uint8 lock = (i->second.allowedSecurityLevel > _accountSecurityLevel) ? 1 : 0;
|
||||
|
||||
pkt << i->second.icon; // realm type
|
||||
if (valid_tbc_version || valid_wlk_version)// only 2.4.3 and 3.1.3
|
||||
if (i->second.gamebuild == 9947 || i->second.gamebuild == 10146 || i->second.gamebuild == 8606)//only 2.4.3 and 3.1.3 cliens
|
||||
pkt << lock; // if 1, then realm locked
|
||||
pkt << i->second.color; // if 2, then realm is offline
|
||||
pkt << i->first;
|
||||
@@ -1002,19 +956,17 @@ bool AuthSocket::_HandleRealmList()
|
||||
pkt << i->second.populationLevel;
|
||||
pkt << AmountOfCharacters;
|
||||
pkt << i->second.timezone; // realm category
|
||||
if (valid_tbc_version || valid_wlk_version)//2.4.3 and 3.1.3 clients
|
||||
if (i->second.gamebuild == 9947 || i->second.gamebuild == 10146 || i->second.gamebuild == 8606)//2.4.3 and 3.1.3 clients
|
||||
pkt << (uint8) 0x2C; // unk, may be realm number/id?
|
||||
else if (valid_tbc_version)
|
||||
else
|
||||
pkt << (uint8) 0x0; //1.12.1 and 1.12.2 clients
|
||||
}
|
||||
|
||||
if (valid_tbc_version || valid_wlk_version)//2.4.3 and 3.1.3 cliens
|
||||
if (_build == 9947 || _build == 10146 || _build == 8606)//2.4.3 and 3.1.3 cliens
|
||||
{
|
||||
pkt << (uint8) 0x10;
|
||||
pkt << (uint8) 0x00;
|
||||
}
|
||||
else if (valid_tbc_version)//1.12.1 and 1.12.2 clients
|
||||
{
|
||||
}else{//1.12.1 and 1.12.2 clients
|
||||
pkt << (uint8) 0x00;
|
||||
pkt << (uint8) 0x02;
|
||||
}
|
||||
|
||||
+32
-32
@@ -89,11 +89,11 @@ extern int main(int argc, char **argv)
|
||||
///- Command line parsing to get the configuration file name
|
||||
char const* cfg_file = _TRINITY_REALM_CONFIG;
|
||||
int c=1;
|
||||
while( c < argc )
|
||||
while(c < argc)
|
||||
{
|
||||
if( strcmp(argv[c],"-c") == 0)
|
||||
if (strcmp(argv[c],"-c") == 0)
|
||||
{
|
||||
if( ++c >= argc )
|
||||
if (++c >= argc)
|
||||
{
|
||||
sLog.outError("Runtime-Error: -c option requires an input argument");
|
||||
usage(argv[0]);
|
||||
@@ -107,23 +107,23 @@ extern int main(int argc, char **argv)
|
||||
////////////
|
||||
//Services//
|
||||
////////////
|
||||
if( strcmp(argv[c],"-s") == 0)
|
||||
if (strcmp(argv[c],"-s") == 0)
|
||||
{
|
||||
if( ++c >= argc )
|
||||
if (++c >= argc)
|
||||
{
|
||||
sLog.outError("Runtime-Error: -s option requires an input argument");
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if( strcmp(argv[c],"install") == 0)
|
||||
if (strcmp(argv[c],"install") == 0)
|
||||
{
|
||||
if (WinServiceInstall())
|
||||
sLog.outString("Installing service");
|
||||
return 1;
|
||||
}
|
||||
else if( strcmp(argv[c],"uninstall") == 0)
|
||||
else if (strcmp(argv[c],"uninstall") == 0)
|
||||
{
|
||||
if(WinServiceUninstall())
|
||||
if (WinServiceUninstall())
|
||||
sLog.outString("Uninstalling service");
|
||||
return 1;
|
||||
}
|
||||
@@ -134,7 +134,7 @@ extern int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if( strcmp(argv[c],"--service") == 0)
|
||||
if (strcmp(argv[c],"--service") == 0)
|
||||
{
|
||||
WinServiceRun();
|
||||
}
|
||||
@@ -150,8 +150,8 @@ extern int main(int argc, char **argv)
|
||||
}
|
||||
sLog.Initialize();
|
||||
|
||||
sLog.outString( "%s (realm-daemon)", _FULLVERSION );
|
||||
sLog.outString( "<Ctrl-C> to stop.\n" );
|
||||
sLog.outString("%s (realm-daemon)", _FULLVERSION);
|
||||
sLog.outString("<Ctrl-C> to stop.\n");
|
||||
sLog.outString("Using configuration file %s.", cfg_file);
|
||||
|
||||
///- Check the version of the configuration file
|
||||
@@ -169,7 +169,7 @@ extern int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION));
|
||||
if (SSLeay() < 0x009080bfL )
|
||||
if (SSLeay() < 0x009080bfL)
|
||||
{
|
||||
sLog.outError("Outdated version of OpenSSL lib. Logins to server impossible!");
|
||||
sLog.outError("Minimal required version [OpenSSL 0.9.8k]");
|
||||
@@ -180,24 +180,24 @@ extern int main(int argc, char **argv)
|
||||
|
||||
/// realmd PID file creation
|
||||
std::string pidfile = sConfig.GetStringDefault("PidFile", "");
|
||||
if(!pidfile.empty())
|
||||
if (!pidfile.empty())
|
||||
{
|
||||
uint32 pid = CreatePIDFile(pidfile);
|
||||
if( !pid )
|
||||
if (!pid)
|
||||
{
|
||||
sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() );
|
||||
sLog.outError("Cannot create PID file %s.\n", pidfile.c_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
sLog.outString( "Daemon PID: %u\n", pid );
|
||||
sLog.outString("Daemon PID: %u\n", pid);
|
||||
}
|
||||
|
||||
///- Initialize the database connection
|
||||
if(!StartDB())
|
||||
if (!StartDB())
|
||||
return 1;
|
||||
|
||||
///- Initialize the log database
|
||||
if(sConfig.GetBoolDefault("EnableLogDB", false))
|
||||
if (sConfig.GetBoolDefault("EnableLogDB", false))
|
||||
{
|
||||
// everything successful - set var to enable DB logging once startup finished.
|
||||
sLog.SetLogDBLater(true);
|
||||
@@ -221,14 +221,14 @@ extern int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
///- Launch the listening network socket
|
||||
port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT );
|
||||
port_t rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT);
|
||||
std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0");
|
||||
|
||||
SocketHandler h;
|
||||
ListenSocket<AuthSocket> authListenSocket(h);
|
||||
if ( authListenSocket.Bind(bind_ip.c_str(),rmport))
|
||||
if (authListenSocket.Bind(bind_ip.c_str(),rmport))
|
||||
{
|
||||
sLog.outError( "Trinity realm can not bind to %s:%d",bind_ip.c_str(), rmport );
|
||||
sLog.outError("Trinity realm can not bind to %s:%d",bind_ip.c_str(), rmport);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -243,22 +243,22 @@ extern int main(int argc, char **argv)
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
|
||||
uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0);
|
||||
if(Aff > 0)
|
||||
if (Aff > 0)
|
||||
{
|
||||
ULONG_PTR appAff;
|
||||
ULONG_PTR sysAff;
|
||||
|
||||
if(GetProcessAffinityMask(hProcess,&appAff,&sysAff))
|
||||
if (GetProcessAffinityMask(hProcess,&appAff,&sysAff))
|
||||
{
|
||||
ULONG_PTR curAff = Aff & appAff; // remove non accessible processors
|
||||
|
||||
if(!curAff )
|
||||
if (!curAff)
|
||||
{
|
||||
sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(SetProcessAffinityMask(hProcess,curAff))
|
||||
if (SetProcessAffinityMask(hProcess,curAff))
|
||||
sLog.outString("Using processors (bitmask, hex): %x", curAff);
|
||||
else
|
||||
sLog.outError("Can't set used processors (hex): %x", curAff);
|
||||
@@ -269,9 +269,9 @@ extern int main(int argc, char **argv)
|
||||
|
||||
bool Prio = sConfig.GetBoolDefault("ProcessPriority", false);
|
||||
|
||||
if(Prio)
|
||||
if (Prio)
|
||||
{
|
||||
if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
|
||||
if (SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS))
|
||||
sLog.outString("TrinityRealm process priority class set to HIGH");
|
||||
else
|
||||
sLog.outError("ERROR: Can't set realmd process priority class.");
|
||||
@@ -281,7 +281,7 @@ extern int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
// maximum counter for next ping
|
||||
uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000));
|
||||
uint32 numLoops = (sConfig.GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000));
|
||||
uint32 loopCounter = 0;
|
||||
|
||||
// possibly enable db logging; avoid massive startup spam by doing it here.
|
||||
@@ -304,7 +304,7 @@ extern int main(int argc, char **argv)
|
||||
|
||||
h.Select(0, 100000);
|
||||
|
||||
if( (++loopCounter) == numLoops )
|
||||
if ((++loopCounter) == numLoops)
|
||||
{
|
||||
loopCounter = 0;
|
||||
sLog.outDetail("Ping MySQL to keep connection alive");
|
||||
@@ -323,7 +323,7 @@ extern int main(int argc, char **argv)
|
||||
///- Remove signal handling before leaving
|
||||
UnhookSignals();
|
||||
|
||||
sLog.outString( "Halting process..." );
|
||||
sLog.outString("Halting process...");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -351,13 +351,13 @@ void OnSignal(int s)
|
||||
bool StartDB()
|
||||
{
|
||||
std::string dbstring = sConfig.GetStringDefault("loginDatabaseInfo", "");
|
||||
if(dbstring.empty())
|
||||
if (dbstring.empty())
|
||||
{
|
||||
sLog.outError("Database not specified");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!loginDatabase.Initialize(dbstring.c_str()))
|
||||
if (!loginDatabase.Initialize(dbstring.c_str()))
|
||||
{
|
||||
sLog.outError("Cannot connect to database");
|
||||
return false;
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
#include "Policies/SingletonImp.h"
|
||||
#include "Database/DatabaseEnv.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1( RealmList );
|
||||
INSTANTIATE_SINGLETON_1(RealmList);
|
||||
|
||||
extern DatabaseType loginDatabase;
|
||||
|
||||
RealmList::RealmList( ) : m_UpdateInterval(0), m_NextUpdateTime(time(NULL))
|
||||
RealmList::RealmList() : m_UpdateInterval(0), m_NextUpdateTime(time(NULL))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ void RealmList::Initialize(uint32 updateInterval)
|
||||
UpdateRealms(true);
|
||||
}
|
||||
|
||||
void RealmList::UpdateRealm( uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build)
|
||||
void RealmList::UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build)
|
||||
{
|
||||
///- Create new if not exist or update existed
|
||||
Realm& realm = m_realms[name];
|
||||
@@ -67,7 +67,7 @@ void RealmList::UpdateRealm( uint32 ID, const std::string& name, const std::stri
|
||||
void RealmList::UpdateIfNeed()
|
||||
{
|
||||
// maybe disabled or updated recently
|
||||
if(!m_UpdateInterval || m_NextUpdateTime > time(NULL))
|
||||
if (!m_UpdateInterval || m_NextUpdateTime > time(NULL))
|
||||
return;
|
||||
|
||||
m_NextUpdateTime = time(NULL) + m_UpdateInterval;
|
||||
@@ -83,10 +83,10 @@ void RealmList::UpdateRealms(bool init)
|
||||
{
|
||||
sLog.outDetail("Updating Realm List...");
|
||||
|
||||
QueryResult *result = loginDatabase.Query( "SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE color <> 3 ORDER BY name" );
|
||||
QueryResult *result = loginDatabase.Query("SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population, gamebuild FROM realmlist WHERE color <> 3 ORDER BY name");
|
||||
|
||||
///- Circle through results and add them to the realm map
|
||||
if(result)
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
@@ -94,10 +94,10 @@ void RealmList::UpdateRealms(bool init)
|
||||
|
||||
uint8 allowedSecurityLevel = fields[7].GetUInt8();
|
||||
|
||||
UpdateRealm(fields[0].GetUInt32(), fields[1].GetCppString(),fields[2].GetCppString(),fields[3].GetUInt32(),fields[4].GetUInt8(), fields[5].GetUInt8(), fields[6].GetUInt8(), (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), fields[8].GetFloat(), fields[9].GetUInt32() );
|
||||
if(init)
|
||||
UpdateRealm(fields[0].GetUInt32(), fields[1].GetCppString(),fields[2].GetCppString(),fields[3].GetUInt32(),fields[4].GetUInt8(), fields[5].GetUInt8(), fields[6].GetUInt8(), (allowedSecurityLevel <= SEC_ADMINISTRATOR ? AccountTypes(allowedSecurityLevel) : SEC_ADMINISTRATOR), fields[8].GetFloat(), fields[9].GetUInt32());
|
||||
if (init)
|
||||
sLog.outString("Added realm \"%s\".", fields[1].GetString());
|
||||
} while( result->NextRow() );
|
||||
} while(result->NextRow());
|
||||
delete result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class RealmList
|
||||
uint32 size() const { return m_realms.size(); }
|
||||
private:
|
||||
void UpdateRealms(bool init);
|
||||
void UpdateRealm( uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build);
|
||||
void UpdateRealm(uint32 ID, const std::string& name, const std::string& address, uint32 port, uint8 icon, uint8 color, uint8 timezone, AccountTypes allowedSecurityLevel, float popu, uint32 build);
|
||||
private:
|
||||
RealmMap m_realms; ///< Internal map of realms
|
||||
uint32 m_UpdateInterval;
|
||||
|
||||
Reference in New Issue
Block a user