/////////////////////////////////////////////////////////////
//
// CProxyDirect3DIndexBuffer::Lock
//
// For stats
//
/////////////////////////////////////////////////////////////
HRESULT CProxyDirect3DIndexBuffer::Lock(UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags)
{
    m_stats.iLockedCount++;

    *ppbData = NULL;
    HRESULT hr = m_pOriginal->Lock(OffsetToLock, SizeToLock, ppbData, Flags);

    if (FAILED(hr))
    {
        SString strMessage("Lock IndexBuffer fail: hr:%x Length:%x Usage:%x Format:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x", hr, m_iMemUsed,
                           m_dwUsage, m_format, m_pool, OffsetToLock, SizeToLock, Flags);
        WriteDebugEvent(strMessage);
        AddReportLog(8625, strMessage);
        CCore::GetSingleton().LogEvent(625, "Lock IndexBuffer", "", strMessage);
    }
    else if (*ppbData == NULL)
    {
        SString strMessage("Lock IndexBuffer result NULL: hr:%x Length:%x Usage:%x Format:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x", hr, m_iMemUsed,
                           m_dwUsage, m_format, m_pool, OffsetToLock, SizeToLock, Flags);
        WriteDebugEvent(strMessage);
        AddReportLog(8626, strMessage);
        CCore::GetSingleton().LogEvent(626, "Lock IndexBuffer NULL", "", strMessage);
    }
    return hr;
}
/////////////////////////////////////////////////////////////
//
// CProxyDirect3DVertexBuffer::Lock
//
// If lock is writable, tell manager that range content will change
//
/////////////////////////////////////////////////////////////
HRESULT CProxyDirect3DVertexBuffer::Lock ( UINT OffsetToLock, UINT SizeToLock, void** ppbData, DWORD Flags )
{
    m_stats.iLockedCount++;

    if ( ( Flags & D3DLOCK_READONLY ) == 0 )
    {
        CAdditionalVertexStreamManager::GetSingleton ()->OnVertexBufferRangeInvalidated ( m_pOriginal, OffsetToLock, SizeToLock );
        CVertexStreamBoundingBoxManager::GetSingleton ()->OnVertexBufferRangeInvalidated ( m_pOriginal, OffsetToLock, SizeToLock );
    }

    *ppbData = NULL;
    HRESULT hr = m_pOriginal->Lock ( OffsetToLock, SizeToLock, ppbData, Flags );

    if( FAILED( hr ) )
    {
        SString strMessage( "Lock VertexBuffer fail: hr:%x Length:%x Usage:%x FVF:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x"
                                                        , hr, m_iMemUsed, m_dwUsage, m_dwFVF, m_pool, OffsetToLock, SizeToLock, Flags );
        WriteDebugEvent( strMessage );
        AddReportLog( 8620, strMessage );
        CCore::GetSingleton ().LogEvent ( 620, "Lock VertexBuffer", "", strMessage );
    }
    else
    if ( *ppbData == NULL )
    {
        SString strMessage( "Lock VertexBuffer result NULL: hr:%x Length:%x Usage:%x FVF:%x Pool:%x OffsetToLock:%x SizeToLock:%x Flags:%x"
                                                        , hr, m_iMemUsed, m_dwUsage, m_dwFVF, m_pool, OffsetToLock, SizeToLock, Flags );
        WriteDebugEvent( strMessage );
        AddReportLog( 8621, strMessage );
        CCore::GetSingleton ().LogEvent ( 621, "Lock VertexBuffer NULL", "", strMessage );
    }
    return hr;
}
Example #3
0
////////////////////////////////////////////////////
//
//  CNewsBrowser::LoadLayoutAndImages
//
//
//
////////////////////////////////////////////////////
CGUIWindow* CNewsBrowser::LoadLayoutAndImages(CGUIElement* pParent, const SNewsItem& newsItem)
{
    CGUI* pManager = g_pCore->GetGUI();

    // Make sure we have the layout filename
    if (newsItem.strLayoutFilename.empty())
    {
        AddReportLog(3302, SString("CNewsBrowser::LoadLayout: Problem loading %s", *newsItem.strContentFullDir));
        return NULL;
    }

    // Load any imagesets
    for (uint i = 0; i < newsItem.imagesetFilenameList.size(); i++)
    {
        if (!pManager->LoadImageset(newsItem.imagesetFilenameList[i]))
        {
            AddReportLog(
                3303, SString("CNewsBrowser::LoadLayout: Problem with LoadImageset [%s] %s", *newsItem.strContentFullDir, *newsItem.imagesetFilenameList[i]));
            return NULL;
        }
    }

    // Load layout
    CGUIWindow* pWindow = pManager->LoadLayout(pParent, newsItem.strLayoutFilename);
    if (!pWindow)
    {
        AddReportLog(3304, SString("CNewsBrowser::LoadLayout: Problem with LoadLayout [%s] %s", *newsItem.strContentFullDir, *newsItem.strLayoutFilename));
        return NULL;
    }
    return pWindow;
}
Example #4
0
//////////////////////////////////////////////////////////
//
// CInstallManager::_InstallNewsItems
//
//
//
//////////////////////////////////////////////////////////
SString CInstallManager::_InstallNewsItems ( void )
{
    // Get install news queue
    CArgMap queue;
    queue.SetFromString ( GetApplicationSetting ( "news-install" ) );
    SetApplicationSetting ( "news-install", "" );

    std::vector < SString > keyList;
    queue.GetKeys ( keyList );
    for ( uint i = 0 ; i < keyList.size () ; i++ )
    {
        // Install each file
        SString strDate = keyList[i];
        SString strFileLocation = queue.Get ( strDate );

        // Save cwd
        SString strSavedDir = GetSystemCurrentDirectory ();

        // Calc and make target dir
        SString strTargetDir = PathJoin ( GetMTADataPath (), "news", strDate );
        MkDir ( strTargetDir );

        // Extract into target dir
        SetCurrentDirectory ( strTargetDir );

        // Try to extract the files
        if ( !ExtractFiles ( strFileLocation ) )
        {
            // If extract failed and update file is an exe, try to run it
            if ( ExtractExtension ( strFileLocation ).CompareI ( "exe" ) )
                ShellExecuteBlocking ( "open", strFileLocation, "-s" );
        }

        // Restore cwd
        SetCurrentDirectory ( strSavedDir );

        // Check result
        if ( FileExists ( PathJoin ( strTargetDir, "files.xml" ) ) )
        {
            SetApplicationSettingInt ( "news-updated", 1 );
            AddReportLog ( 2051, SString ( "InstallNewsItems ok for '%s'", *strDate ) );
        }
        else
        {
            AddReportLog ( 4048, SString ( "InstallNewsItems failed with '%s' '%s' '%s'", *strDate, *strFileLocation, *strTargetDir ) );
        }
    }
    return "ok";
}
/////////////////////////////////////////////////////////////
//
// CDirect3DEvents9::CreateTexture
//
//
//
/////////////////////////////////////////////////////////////
HRESULT CDirect3DEvents9::CreateTexture ( IDirect3DDevice9 *pDevice, UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle )
{
    HRESULT hr;

    for ( uint i = 0 ; i < 2 ; i++ )
    {
        hr = pDevice->CreateTexture ( Width, Height, Levels, Usage, Format, Pool, ppTexture, pSharedHandle );
        if( SUCCEEDED( hr ) )
            break;

        if ( hr != D3DERR_OUTOFVIDEOMEMORY || i > 0 )
        {
            SString strMessage( "CreateTexture fail: hr:%x W:%x H:%x L:%x Usage:%x Format:%x Pool:%x", hr, Width, Height, Levels, Usage, Format, Pool );
            WriteDebugEvent( strMessage );
            AddReportLog( 8612, strMessage );
            CCore::GetSingleton ().LogEvent ( 612, "CreateTexture", "", strMessage );
            return hr;
        }

        pDevice->EvictManagedResources ();
    }

    // Create proxy so we can track when it's finished with
    *ppTexture = new CProxyDirect3DTexture ( pDevice, *ppTexture, Width, Height, Levels, Usage, Format, Pool );
    return hr;
}
/////////////////////////////////////////////////////////////
//
// CDirect3DEvents9::CreateIndexBuffer
//
//
//
/////////////////////////////////////////////////////////////
HRESULT CDirect3DEvents9::CreateIndexBuffer ( IDirect3DDevice9 *pDevice, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle )
{
    HRESULT hr;

    for ( uint i = 0 ; i < 2 ; i++ )
    {
        hr = pDevice->CreateIndexBuffer ( Length, Usage, Format, Pool, ppIndexBuffer, pSharedHandle );
        if( SUCCEEDED( hr ) )
            break;

        if ( hr != D3DERR_OUTOFVIDEOMEMORY || i > 0 )
        {
            SString strMessage( "CreateIndexBuffer fail: hr:%x Length:%x Usage:%x Format:%x Pool:%x", hr, Length, Usage, Format, Pool );
            WriteDebugEvent( strMessage );
            AddReportLog( 8611, strMessage );
            CCore::GetSingleton ().LogEvent ( 611, "CreateIndexBuffer", "", strMessage );
            return hr;
        }

        pDevice->EvictManagedResources ();
    }

    // Create proxy so we can track when it's finished with
    *ppIndexBuffer = new CProxyDirect3DIndexBuffer ( pDevice, *ppIndexBuffer, Length, Usage, Format, Pool );
    return hr;
}
/////////////////////////////////////////////////////////////
//
// CDirect3DEvents9::CreateVertexBuffer
//
// Creates a proxy object for the new vertex buffer
//
/////////////////////////////////////////////////////////////
HRESULT CDirect3DEvents9::CreateVertexBuffer ( IDirect3DDevice9 *pDevice, UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,HANDLE* pSharedHandle )
{
    HRESULT hr;

    // We may have to look at the contents to generate normals (Not needed for dynamic buffers)
    if ( ( Usage & D3DUSAGE_DYNAMIC ) == 0 )
        Usage &= -1 - D3DUSAGE_WRITEONLY;

    for ( uint i = 0 ; i < 2 ; i++ )
    {
        hr = pDevice->CreateVertexBuffer ( Length, Usage, FVF, Pool, ppVertexBuffer, pSharedHandle );
        if( SUCCEEDED( hr ) )
            break;

        if ( hr != D3DERR_OUTOFVIDEOMEMORY || i > 0 )
        {
            SString strMessage( "CreateVertexBuffer fail: hr:%x Length:%x Usage:%x FVF:%x Pool:%x", hr, Length, Usage, FVF, Pool );
            WriteDebugEvent( strMessage );
            AddReportLog( 8610, strMessage );
            CCore::GetSingleton ().LogEvent ( 610, "CreateVertexBuffer", "", strMessage );
            return hr;
        }

        pDevice->EvictManagedResources ();
    }

    // Create proxy
    *ppVertexBuffer = new CProxyDirect3DVertexBuffer ( pDevice, *ppVertexBuffer, Length, Usage, FVF, Pool );
    return hr;
}
    //////////////////////////////////////////////////////////////
    //
    // Check if any clumps have become unused outside of the cache
    //
    //////////////////////////////////////////////////////////////
    uint GetNumCached ( void )
    {
        uint uiNumCached = 0;
        for ( std::vector < SSavedClumpInfo >::iterator iter = savedClumpList.begin () ; iter != savedClumpList.end () ; ++iter )
        {
            SSavedClumpInfo& info = *iter;
            RpGeometry* pGeometry = ( ( RpAtomic* ) ( ( info.pClump->atomics.root.next ) - 0x8 ) )->geometry;
#ifdef CLOTHES_REF_TEST
            if ( pGeometry->refs < 21 )
            {
                AddReportLog( 7521, SString ( "Clothes geometry refs below expected value: %d", pGeometry->refs ) );
                pGeometry->refs = 21;
            }
            if ( pGeometry->refs == 21 )
#else
            if ( pGeometry->refs == 1 )
#endif
            {
                uiNumCached++;
                if ( !info.bUnused )
                {
                    info.timeUnused = CTickCount::Now ();
                    info.bUnused = true;
                }
            }
            else
                info.bUnused = false;
        }

        m_Stats.uiNumTotal = savedClumpList.size ();
        m_Stats.uiNumUnused = uiNumCached;
        return uiNumCached;
    }
Example #9
0
//////////////////////////////////////////////////////////
//
// CInstallManager::GetLauncherPathFilename
//
// Get path to launch exe
//
//////////////////////////////////////////////////////////
SString CInstallManager::GetLauncherPathFilename ( void )
{
    SString strLocation = m_pSequencer->GetVariable ( INSTALL_LOCATION );
    SString strResult = PathJoin ( strLocation == "far" ? GetSystemCurrentDirectory () : GetMTASAPath (), MTA_EXE_NAME );
    AddReportLog ( 1062, SString ( "GetLauncherPathFilename %s", *strResult ) );
    return strResult;
}
Example #10
0
//////////////////////////////////////////////////////////
//
// CInstallManager::RestoreSequencerFromSnapshot
//
// Set current sequencer position from a string
//
//////////////////////////////////////////////////////////
void CInstallManager::RestoreSequencerFromSnapshot ( const SString& strText )
{
    AddReportLog ( 1061, SString ( "CInstallManager::RestoreSequencerState %s", *strText ) );
    std::vector < SString > parts;
    strText.Split ( " ", parts );

    int iFirstArg = 0;
    if ( parts.size () > 0 && parts[0].Contains ( "=" ) )
    {
        // Upgrade variables
        if ( parts[0].Contains ( INSTALL_STAGE ) && !parts[0].Contains ( "_pc_label" ) )
            parts[0] = parts[0].Replace ( INSTALL_STAGE, "_pc_label" );

        m_pSequencer->RestoreStateFromString ( parts[0] );
        iFirstArg++;
    }

    // Add any extra command line args
    if ( m_pSequencer->GetVariableInt ( "_argc" ) == 0 )
    {
        m_pSequencer->SetVariable ( "_argc", parts.size () - iFirstArg );
        for ( uint i = iFirstArg ; i < parts.size () ; i++ )
        {
            m_pSequencer->SetVariable ( SString ( "_arg_%d", i - iFirstArg ), parts[i] );
        }
    }

    // Ignore LastResult
    m_pSequencer->SetVariable ( "LastResult", "ok" );
}
Example #11
0
////////////////////////////////////////////////
//
// CreateDeviceSecondCallCheck
//
// Check for, and handle subsequent calls to create device
// Know to occur with RTSSHooks.dll (EVGA Precision X on screen display)
//
////////////////////////////////////////////////
bool CreateDeviceSecondCallCheck(HRESULT& hOutResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
                                 D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface)
{
    static uint uiCreateCount = 0;

    // Also check for invalid size
    if (pPresentationParameters->BackBufferWidth == 0)
    {
        WriteDebugEvent(SString(" Passing through call #%d to CreateDevice because size is invalid", uiCreateCount));
        return true;
    }

    // Also check for calls from other threads
    if (!IsMainThread())
    {
        SString strMessage(" Passing through call #%d to CreateDevice because not main thread", uiCreateCount);
        WriteDebugEvent(strMessage);
        AddReportLog(8627, strMessage);
        return true;
    }

    if (++uiCreateCount == 1)
        return false;
    WriteDebugEvent(SString(" Passing through call #%d to CreateDevice", uiCreateCount));
    hOutResult = pDirect3D->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
    return true;
}
///////////////////////////////////////////////////////////////
//
// CCrashDumpWriter::UpdateCounters
//
// Static function. Called every so often, you know
//
///////////////////////////////////////////////////////////////
void CCrashDumpWriter::UpdateCounters( void )
{
    if ( ms_uiInvalidParameterCount > ms_uiInvalidParameterCountLogged && ms_uiInvalidParameterCountLogged < 10 )
    {
        AddReportLog( 9206, SString( "InvalidParameterCount changed from %d to %d", ms_uiInvalidParameterCountLogged, ms_uiInvalidParameterCount ) );
        ms_uiInvalidParameterCountLogged = ms_uiInvalidParameterCount;
    }
}
Example #13
0
//////////////////////////////////////////////////////////
//
// CheckOnRestartCommand
//
// Changes current directory if required
//
//////////////////////////////////////////////////////////
SString CheckOnRestartCommand ( void )
{
    const SString strMTASAPath = GetMTASAPath ();

    SetCurrentDirectory ( strMTASAPath );
    SetDllDirectory( strMTASAPath );

    SString strOperation, strFile, strParameters, strDirectory, strShowCmd;
    if ( GetOnRestartCommand ( strOperation, strFile, strParameters, strDirectory, strShowCmd ) )
    {
        if ( strOperation == "files" || strOperation == "silent" )
        {
            //
            // Update
            //

            // Make temp path name and go there
            SString strArchivePath, strArchiveName;
            strFile.Split ( "\\", &strArchivePath, &strArchiveName, -1 );

            SString strTempPath = MakeUniquePath ( strArchivePath + "\\_" + strArchiveName + "_tmp_" );

            if ( !MkDir ( strTempPath ) )
                return "FileError1";

            if ( !SetCurrentDirectory ( strTempPath ) )
                return "FileError2";

            // Start progress bar
            if ( !strParameters.Contains( "hideprogress" ) )
               StartPseudoProgress( g_hInstance, "MTA: San Andreas", _("Extracting files...") );

            // Try to extract the files
            if ( !ExtractFiles ( strFile ) )
            {
                // If extract failed and update file is an exe, try to run it
                if ( ExtractExtension ( strFile ).CompareI ( "exe" ) )
                    ShellExecuteBlocking ( "open", strFile, "-s" );
            }

            // Stop progress bar
            StopPseudoProgress();

            // If a new "Multi Theft Auto.exe" exists, let that complete the install
            if ( FileExists ( MTA_EXE_NAME_RELEASE ) )
                return "install from far " + strOperation + " " + strParameters;

            // Otherwise use the current exe to install
            return "install from near " + strOperation + " " + strParameters;
        }
        else
        {
            AddReportLog ( 5052, SString ( "CheckOnRestartCommand: Unknown restart command %s", strOperation.c_str () ) );
        }
    }
    return "no update";
}
///////////////////////////////////////////////////////////////
//
// CGameEntityXRefManagerImpl::OnGameEntityDestruct
//
// Called when GTA is destroying a game entity
//
///////////////////////////////////////////////////////////////
void CGameEntityXRefManagerImpl::OnGameEntityDestruct ( CEntitySAInterface* pEntitySAInterface )
{
    if ( MapContains ( m_InterfaceToClientMap, pEntitySAInterface ) )
    {
        BYTE* pInterface = (BYTE*)pEntitySAInterface;
        DWORD InterfaceVtbl = *(DWORD*)pInterface;
        ushort InterfaceModelId = *(ushort*)(pInterface + 34);
        CClientEntity* pClientEntity = MapFindRef ( m_InterfaceToClientMap, pEntitySAInterface );
        bool bClientEntityValid = MapContains ( m_ValidClientEntityMap, pClientEntity );

        SString strClientEntityInfo;
        if ( bClientEntityValid )
        {
            CEntity* pGameEntity = NULL;

            if ( CClientPed* pPed = DynamicCast < CClientPed > ( pClientEntity ) )
                pGameEntity = pPed->GetGameEntity ();

            if ( CClientVehicle* pVehicle = DynamicCast < CClientVehicle > ( pClientEntity ) )
                pGameEntity = pVehicle->GetGameEntity ();

            if ( CClientObject* pObject = DynamicCast < CClientObject > ( pClientEntity ) )
                pGameEntity = pObject->GetGameEntity ();

            if ( CClientProjectile* pProjectile = DynamicCast < CClientProjectile > ( pClientEntity ) )
                pGameEntity = pProjectile->GetGameEntity ();

            if ( CClientPickup* pPickup = DynamicCast < CClientPickup > ( pClientEntity ) )
                pGameEntity = pPickup->GetGameObject ();

            CEntity* pMappedGameEntity = MapFindRef ( m_ClientToGameMap, pClientEntity );
            CClientEntity* pMappedClientEntity = MapFindRef ( m_GameToClientMap, pGameEntity );


            strClientEntityInfo = SString ( "%s Id:%x GameEntity:%08x MappedGameEntity:%08x MappedClientEntity:%08x"
                                            , pClientEntity->GetClassName ()
                                            , pClientEntity->GetID ()
                                            , (int)pGameEntity
                                            , (int)pMappedGameEntity
                                            , (int)pMappedClientEntity
                                        );
        }

        SString strMessage ( "EntitySAInterface:%08x  Vtbl:%08x  ModelId:%d   ClientEntity:%08x  [%s]"
                                , (int)pEntitySAInterface
                                , InterfaceVtbl
                                , InterfaceModelId
                                , (int)pClientEntity
                                , *strClientEntityInfo
                                );

        g_pCore->LogEvent ( 8542, "XRefManager", "GameEntity Mismatch", strMessage );
        AddReportLog ( 8542, strMessage );
        dassert ( 0 );
    }
}
Example #15
0
//////////////////////////////////////////////////////////
//
// CInstallManager::_ChangeFromAdmin
//
// Save the state of the sequencer and exit back to the user process
//
//////////////////////////////////////////////////////////
SString CInstallManager::_ChangeFromAdmin ( void )
{
    if ( IsUserAdmin () && IsBlockingUserProcess () )
    {
        SendStringToUserProcess ( GetSequencerSnapshot () );
        AddReportLog ( 1003, SString ( "CInstallManager::_ChangeToAdmin - exit(0) %s", "" ) );
        ClearIsBlockingUserProcess ();
        ExitProcess ( 0 );
    }
    return "fail";
}
Example #16
0
//////////////////////////////////////////////////////////
//
// HandleResetSettings
//
//
//
//////////////////////////////////////////////////////////
void HandleResetSettings ( void )
{
    if ( CheckAndShowFileOpenFailureMessage () )
        return;

    CheckAndShowMissingFileMessage();

    SString strSaveFilePath = PathJoin ( GetSystemPersonalPath(), "GTA San Andreas User Files" );
    SString strSettingsFilename = PathJoin ( strSaveFilePath, "gta_sa.set" );
    SString strSettingsFilenameBak = PathJoin ( strSaveFilePath, "gta_sa_old.set" );

    if ( FileExists ( strSettingsFilename ) )
    {
        int iResponse = MessageBoxUTF8 ( NULL, _("There seems to be a problem launching MTA:SA.\nResetting GTA settings can sometimes fix this problem.\n\nDo you want to reset GTA settings now?"), "MTA: San Andreas"+_E("CL08"), MB_YESNO | MB_ICONQUESTION | MB_TOPMOST );
        if ( iResponse == IDYES )
        {
            FileDelete ( strSettingsFilenameBak );
            FileRename ( strSettingsFilename, strSettingsFilenameBak );
            FileDelete ( strSettingsFilename );
            if ( !FileExists ( strSettingsFilename ) )
            {
                AddReportLog ( 4053, "Deleted gta_sa.set" );
                MessageBoxUTF8 ( NULL, _("GTA settings have been reset.\n\nPress OK to continue."), "MTA: San Andreas", MB_OK | MB_ICONINFORMATION | MB_TOPMOST );
            }
            else
            {
                AddReportLog ( 5054, SString ( "Delete gta_sa.set failed with '%s'", *strSettingsFilename ) );
                MessageBoxUTF8 ( NULL, SString ( _("File could not be deleted: '%s'"), *strSettingsFilename ), "Error"+_E("CL09"), MB_OK | MB_ICONWARNING | MB_TOPMOST );
            }
        }
    }
    else
    {
        // No settings to delete, or can't find them
        int iResponse = MessageBoxUTF8 ( NULL, _("Are you having problems running MTA:SA?.\n\nDo you want to see some online help?"), "MTA: San Andreas", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST );
        if ( iResponse == IDYES )
        {
            BrowseToSolution ( "crashing-before-gtalaunch", TERMINATE_PROCESS );
        }
    }
}
Example #17
0
int WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, PVOID pvNothing)
{
    CFilePathTranslator     FileTranslator;
    std::string             WorkingDirectory;

    if ( dwReason == DLL_PROCESS_ATTACH )
    {
        WriteDebugEvent( SString( "DLL_PROCESS_ATTACH %08x", pvNothing ) );
        if ( IsGTAProcess() )
        {
            WriteDebugEvent( SString( "ModuleFileName: %s", *GetLaunchPathFilename() ) );

            AddUtf8FileHooks();

            // Set low frag heap for XP
            ULONG heapInfo = 2 ;
            HeapSetInformation( GetProcessHeap(), HeapCompatibilityInformation, &heapInfo, sizeof( heapInfo ) );

            FileTranslator.GetGTARootDirectory ( WorkingDirectory );
            SetCurrentDirectory ( WorkingDirectory.c_str ( ) );

            // For dll searches, this call replaces the current directory entry and turns off 'SafeDllSearchMode'
            // Meaning it will search the supplied path before the system and windows directory.
            // http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx
            SetDllDirectory( CalcMTASAPath ( "MTA" ) );

            g_pCore = new CCore;

            FileTranslator.GetGTARootDirectory ( WorkingDirectory );
            SetCurrentDirectory ( WorkingDirectory.c_str ( ) );
        }
    } 
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        WriteDebugEvent( SString( "DLL_PROCESS_DETACH %08x", pvNothing ) );
        if ( IsGTAProcess () )
        {
            RemoveUtf8FileHooks();

            AddReportLog( 7102, "Core - PROCESS_DETACH" );
            // For now, TerminateProcess if any destruction is attempted (or we'll crash)
            TerminateProcess ( GetCurrentProcess (), 0 );

            if ( g_pCore )
            {
                delete g_pCore;
                g_pCore = NULL;
            }
        }
    }

    return TRUE;
}
////////////////////////////////////////////////////////////////
//
// CRenderWareSA::OnDestroyTexInfo
//
//
//
////////////////////////////////////////////////////////////////
void CRenderWareSA::OnDestroyTexInfo ( STexInfo* pTexInfo )
{
    // Remove from lookup maps
    SString strUniqueKey ( "%d_%s", pTexInfo->usTxdId, *pTexInfo->strTextureName );
    if ( !MapContains ( m_UniqueTexInfoMap, strUniqueKey ) )
        AddReportLog ( 5133, SString ( "OnDestroyTexInfo missing %s", *strUniqueKey ) );
    MapRemove ( m_UniqueTexInfoMap, strUniqueKey );

	// This assert fails when using engine txd replace functions - TODO find out why
    //assert ( MapContains ( m_D3DDataTexInfoMap, pTexInfo->pD3DData ) );
    MapRemove ( m_D3DDataTexInfoMap, pTexInfo->pD3DData );
}
void CCrashDumpWriter::RunErrorTool ( CExceptionInformation* pExceptionInformation )
{
// MTA Error Reporter is now integrated into the launcher

    // Only do once
    static bool bDoneReport = false;
    if ( bDoneReport )
        return;
    bDoneReport = false;

    // Log the basic exception information
    SString strMessage ( "Crash 0x%08X 0x%08X %s"
                         " EAX=%08X EBX=%08X ECX=%08X EDX=%08X ESI=%08X"
                         " EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X"
                         " CS=%04X DS=%04X SS=%04X ES=%04X"
                         " FS=%04X GS=%04X",
                         pExceptionInformation->GetCode (),
                         pExceptionInformation->GetAddressModuleOffset (),
                         pExceptionInformation->GetModulePathName (),
                         pExceptionInformation->GetEAX (),
                         pExceptionInformation->GetEBX (),
                         pExceptionInformation->GetECX (),
                         pExceptionInformation->GetEDX (),
                         pExceptionInformation->GetESI (),
                         pExceptionInformation->GetEDI (),
                         pExceptionInformation->GetEBP (),
                         pExceptionInformation->GetESP (),
                         pExceptionInformation->GetEIP (),
                         pExceptionInformation->GetEFlags (),
                         pExceptionInformation->GetCS (),
                         pExceptionInformation->GetDS (),
                         pExceptionInformation->GetSS (),
                         pExceptionInformation->GetES (),
                         pExceptionInformation->GetFS (),
                         pExceptionInformation->GetGS ()
                        );

    AddReportLog ( 3120, strMessage );

    // Try relaunch with crashed flag
    SString strMTASAPath = GetMTASABaseDir ();
    SetCurrentDirectory ( strMTASAPath );
    SetDllDirectory( strMTASAPath );

#ifdef MTA_DEBUG
    #define MTA_EXE_NAME            "Multi Theft Auto_d.exe"
#else
    #define MTA_EXE_NAME            "Multi Theft Auto.exe"
#endif
    SString strFile = strMTASAPath + "\\" + MTA_EXE_NAME;
    ShellExecute( NULL, "open", strFile, "install_stage=crashed", NULL, SW_SHOWNORMAL );
}
Example #20
0
//////////////////////////////////////////////////////////
//
// CInstallManager::Continue
//
// Process next step
//
//////////////////////////////////////////////////////////
SString CInstallManager::Continue ( void )
{
    // Initial report line
    DWORD dwProcessId = GetCurrentProcessId();
    SString GotPathFrom = ( m_pSequencer->GetVariable ( INSTALL_LOCATION ) == "far" ) ? "registry" : "module location";
    AddReportLog ( 1041, SString ( "* Launch * pid:%d '%s' MTASAPath set from %s '%s'", dwProcessId, GetMTASAModuleFileName ().c_str (), GotPathFrom.c_str (), GetMTASAPath ().c_str () ) );

    // Run sequencer
    for ( int i = 0 ; !m_pSequencer->AtEnd () && i < 1000 ; i++ )
        m_pSequencer->ProcessNextLine ();

    // Remove unwanted files
    CleanDownloadCache ();

    // Extract command line launch args
    SString strCommandLineOut;
    for ( int i = 0 ; i < m_pSequencer->GetVariableInt ( "_argc" ) ; i++ )
        strCommandLineOut += m_pSequencer->GetVariable ( SString ( "_arg_%d", i ) ) + " ";

    AddReportLog ( 1060, SString ( "CInstallManager::Continue - return %s", *strCommandLineOut ) );
    return *strCommandLineOut.TrimEnd ( " " );
}
Example #21
0
//////////////////////////////////////////////////////////
//
// CInstallManager::_InstallFiles
//
//
//
//////////////////////////////////////////////////////////
SString CInstallManager::_InstallFiles ( void )
{
    WatchDogReset ();

    // Install new files
    if ( !InstallFiles ( m_pSequencer->GetVariable ( SILENT_OPT ) != "no" ) )
    {
        if ( !IsUserAdmin () )
            AddReportLog ( 3048, SString ( "_InstallFiles: Install - trying as admin %s", "" ) );
        else
            AddReportLog ( 5049, SString ( "_InstallFiles: Couldn't install files %s", "" ) );

        m_strAdminReason = _("Install updated MTA:SA files");
        return "fail";
    }
    else
    {
        UpdateMTAVersionApplicationSetting ();
        AddReportLog ( 2050, SString ( "_InstallFiles: ok %s", "" ) );
        return "ok";
    }
}
Example #22
0
//////////////////////////////////////////////////////////
//
// HandleNotUsedMainMenu
//
// Called when a problem occured before the main menu was used by user
// If fullscreen, then maybe change fullscreen mode
//
//////////////////////////////////////////////////////////
void HandleNotUsedMainMenu ( void )
{
    AddReportLog( 9310, "Loader - HandleNotUsedMainMenu" );
    {
        // Slighty hacky way of checking in-game settings
        SString strCoreConfigFilename = CalcMTASAPath( PathJoin( "mta", "config", "coreconfig.xml" ) );
        SString strCoreConfig;
        FileLoad( strCoreConfigFilename, strCoreConfig );
        SString strWindowed        = strCoreConfig.SplitRight( "<display_windowed>" ).Left( 1 );
        SString strFullscreenStyle = strCoreConfig.SplitRight( "<display_fullscreen_style>" ).Left( 1 );
        if ( strFullscreenStyle == "1" )
        {
            AddReportLog( 9315, "Loader - HandleNotUsedMainMenu - Already Borderless window" );
        }
        else
        if ( !strWindowed.empty() && !strFullscreenStyle.empty())
        {
            if ( strWindowed == "0" && strFullscreenStyle == "0" )   // 0=FULLSCREEN_STANDARD
            {
                // Inform user
                SString strMessage = _("Are you having problems running MTA:SA?.\n\nDo you want to change the following setting?");
                strMessage += "\n" + _("Fullscreen mode:") + " -> " + _("Borderless window");
                HideSplash();
                int iResponse = MessageBoxUTF8 ( NULL, strMessage, "MTA: San Andreas", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST );
                if ( iResponse == IDYES )
                {
                    // Very hacky way of changing in-game settings
                    strCoreConfig = strCoreConfig.Replace( "<display_fullscreen_style>0", "<display_fullscreen_style>1" );
                    FileSave( strCoreConfigFilename, strCoreConfig );
                    AddReportLog( 9311, "Loader - HandleNotUsedMainMenu - User change to Borderless window" );
                }
                else
                    AddReportLog( 9313, "Loader - HandleNotUsedMainMenu - User said no" );
            }
            else
                AddReportLog( 9314, "Loader - HandleNotUsedMainMenu - Mode not fullscreen standard" );
        }
        else
        {
            // If no valid settings file yet, do the change without asking
            strCoreConfig = "<mainconfig><settings><display_fullscreen_style>1</display_fullscreen_style></settings></mainconfig>";
            FileSave( strCoreConfigFilename, strCoreConfig );
            AddReportLog( 9312, "Loader - HandleNotUsedMainMenu - Set Borderless window" );
        }
    }

    // Check if Evolve is active
    for ( auto processId : MyEnumProcesses( true ) )
    {
        SString strFilename = ExtractFilename( GetProcessPathFilename( processId ) );
        if ( strFilename.BeginsWithI( "Evolve" ) )
        {
            SString strMessage = _("Are you having problems running MTA:SA?.\n\nTry disabling the following products for GTA and MTA:");
            strMessage += "\n\nEvolve";
            DisplayErrorMessageBox ( strMessage, _E("CL43"), "not-used-menu-evolve" );
            break;
        }
    }
}
///////////////////////////////////////////////////////////////
//
// CResourceFileDownloadManager::DoPulse
//
// Downloading initial resource files
//
///////////////////////////////////////////////////////////////
void CResourceFileDownloadManager::DoPulse()
{
    if (!g_pNet->IsConnected())
        return;

    if (!IsTransferringInitialFiles())
        return;

    // Pulse the http downloads
    uint uiDownloadSizeTotal = 0;
    for (auto serverInfo : m_HttpServerList)
    {
        CNetHTTPDownloadManagerInterface* pHTTP = g_pNet->GetHTTPDownloadManager(serverInfo.downloadChannel);
        pHTTP->ProcessQueuedFiles();
        uiDownloadSizeTotal += pHTTP->GetDownloadSizeNow();
    }

    // Handle fatal error
    if (!m_strLastHTTPError.empty())
    {
        // Throw the error and disconnect
        g_pCore->GetConsole()->Printf(_("Download error: %s"), *m_strLastHTTPError);
        AddReportLog(7106, SString("Game - HTTPError (%s)", *m_strLastHTTPError));

        g_pCore->GetModManager()->RequestUnload();
        g_pCore->ShowMessageBox(_("Error") + _E("CD20"), *m_strLastHTTPError, MB_BUTTON_OK | MB_ICON_ERROR);            // HTTP Error
        m_bIsTransferingFiles = false;
        return;
    }

    // Update progress box
    GetTransferBox()->SetInfo(uiDownloadSizeTotal);
    GetTransferBox()->DoPulse();

    // Check if completed downloading current group
    if (m_ActiveFileDownloadList.empty())
    {
        // Hide progress box if all groups done
        if (m_PendingFileDownloadList.empty())
        {
            m_bIsTransferingFiles = false;
            GetTransferBox()->Hide();
        }

        // Load our newly ready resources
        g_pClientGame->GetResourceManager()->OnDownloadGroupFinished();
        UpdatePendingDownloads();
    }
}
////////////////////////////////////////////////////////////////
//
// CRenderWareSA::CreateTexInfo
//
//
//
////////////////////////////////////////////////////////////////
STexInfo* CRenderWareSA::CreateTexInfo ( ushort usTxdId, const SString& strTextureName, CD3DDUMMY* pD3DData )
{
    // Create texinfo
    m_TexInfoList.push_back ( STexInfo ( usTxdId, strTextureName, pD3DData ) );
    STexInfo* pTexInfo = &m_TexInfoList.back ();

    // Add to lookup maps
    SString strUniqueKey ( "%d_%s", pTexInfo->usTxdId, *pTexInfo->strTextureName );
    if ( MapContains ( m_UniqueTexInfoMap, strUniqueKey ) )
        AddReportLog ( 5132, SString ( "CreateTexInfo duplicate %s", *strUniqueKey ) );
    MapSet ( m_UniqueTexInfoMap, strUniqueKey, pTexInfo );

	// This assert fails when using engine txd replace functions - TODO find out why
    //assert ( !MapContains ( m_D3DDataTexInfoMap, pTexInfo->pD3DData ) );
    MapSet ( m_D3DDataTexInfoMap, pTexInfo->pD3DData, pTexInfo );
    return pTexInfo;
}
Example #25
0
//
// Direct players to info about trouble
//
void SharedUtil::BrowseToSolution ( const SString& strType, bool bAskQuestion, bool bTerminateProcess, bool bDoOnExit, const SString& strMessageBoxMessage )
{
    AddReportLog ( 3200, SString ( "Trouble %s", *strType ) );

    // Put args into a string and save in the registry
    CArgMap argMap;
    argMap.Set ( "type", strType.SplitLeft ( ";" ) );
    argMap.Set ( "bAskQuestion", bAskQuestion );
    argMap.Set ( "message", strMessageBoxMessage );
    SetApplicationSetting ( "pending-browse-to-solution", argMap.ToString () );

    // Do it now if required
    if ( !bDoOnExit )
        ProcessPendingBrowseToSolution ();

    // Exit if required
    if ( bTerminateProcess )
        TerminateProcess ( GetCurrentProcess (), 1 );
}
Example #26
0
//////////////////////////////////////////////////////////
//
// CInstallManager::_CheckOnRestartCommand
//
//
//
//////////////////////////////////////////////////////////
SString CInstallManager::_CheckOnRestartCommand ( void )
{
    // Check for pending update
    const SString strResult = CheckOnRestartCommand ();

    if ( strResult.Contains ( "install" ) )
    {
        // New settings for install
        m_pSequencer->SetVariable ( INSTALL_LOCATION, strResult.Contains ( "far" )    ? "far" : "near" );
        m_pSequencer->SetVariable ( SILENT_OPT,       strResult.Contains ( "silent" ) ? "yes" : "no" );
        return "ok";
    }
    else
    if ( !strResult.Contains ( "no update" ) )
    {
        AddReportLog ( 4047, SString ( "_CheckOnRestartCommand: CheckOnRestartCommand returned %s", strResult.c_str () ) );
    }

    return "no_action";
}
Example #27
0
//
// What to do on next restart
//
bool SharedUtil::GetOnRestartCommand ( SString& strOperation, SString& strFile, SString& strParameters, SString& strDirectory, SString& strShowCmd )
{
    SString strOnRestartCommand = GetRegistryValue ( "", "OnRestartCommand" );
    SetOnRestartCommand ( "" );

    std::vector < SString > vecParts;
    strOnRestartCommand.Split ( "\t", vecParts );
    if ( vecParts.size () > 5 && vecParts[0].length () )
    {
        SString strVersion ( "%d.%d.%d-%d.%05d", MTASA_VERSION_MAJOR, MTASA_VERSION_MINOR, MTASA_VERSION_MAINTENANCE, MTASA_VERSION_TYPE, MTASA_VERSION_BUILD );
        if ( vecParts[5] == strVersion )
        {
            strOperation = vecParts[0];
            strFile = vecParts[1];
            strParameters = vecParts[2];
            strDirectory = vecParts[3];
            strShowCmd = vecParts[4];
            return true;
        }
        AddReportLog( 4000, SString ( "OnRestartCommand disregarded due to version change %s -> %s", vecParts[5].c_str (), strVersion.c_str () ) );
    }
    return false;
}
Example #28
0
///////////////////////////////////////////////////////////////
//
// WinMain
//
//
//
///////////////////////////////////////////////////////////////
int WINAPI WinMain ( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
    // Load the loader.dll and continue the load
#ifdef MTA_DEBUG
    SString strLoaderDllFilename = "loader_d.dll";
#else
    SString strLoaderDllFilename = "loader.dll";
#endif

    SString strMTASAPath = PathJoin ( GetLaunchPath (), "mta" );
    SString strLoaderDllPathFilename = PathJoin ( strMTASAPath, strLoaderDllFilename );

    // Load loader dll
    HMODULE hModule = LoadLibrary ( strLoaderDllPathFilename );

    int iReturnCode = 0;
    if ( hModule )
    {
        // Find and call DoWinMain
        typedef int (*PFNDOWINMAIN) ( HINSTANCE, HINSTANCE, LPSTR, int );
        PFNDOWINMAIN pfnDoWinMain = static_cast < PFNDOWINMAIN > ( static_cast < PVOID > ( GetProcAddress ( hModule, "DoWinMain" ) ) );
        if ( pfnDoWinMain )
            iReturnCode = pfnDoWinMain ( hInstance, hPrevInstance, lpCmdLine, nCmdShow );

        FreeLibrary ( hModule );
    }
    else
    {
        SString strError = GetSystemErrorMessage ( GetLastError () );
        SString strMessage ( "Failed to load: '%s'\n\n%s", *strLoaderDllPathFilename, *strError );
        AddReportLog ( 5711, strMessage );
        BrowseToSolution ( "loader-dll-missing", true, false, false, strMessage );
        iReturnCode = 1;
    }

    return iReturnCode;
}
/////////////////////////////////////////////////////////////
//
// CDirect3DEvents9::CreateVertexDeclaration
//
// Creates a proxy object for the new vertex declaration
//
/////////////////////////////////////////////////////////////
HRESULT CDirect3DEvents9::CreateVertexDeclaration ( IDirect3DDevice9 *pDevice, CONST D3DVERTEXELEMENT9* pVertexElements, IDirect3DVertexDeclaration9** ppDecl )
{
    HRESULT hr;

    hr = pDevice->CreateVertexDeclaration ( pVertexElements, ppDecl );
    if ( FAILED(hr) )
    {
        SString strStatus;
        // Make a string with decl info
        for ( uint i = 0 ; i < MAXD3DDECLLENGTH ; i++ )
        {
            const D3DVERTEXELEMENT9& element = pVertexElements[ i ];
            if ( element.Stream == 0xFF )
                break;

            strStatus += SString( "[%d,%d,%d,%d,%d,%d]"
                                    ,element.Stream
                                    ,element.Offset
                                    ,element.Type
                                    ,element.Method
                                    ,element.Usage
                                    ,element.UsageIndex
                                    );
        }

        SString strMessage( "CreateVertexDecl fail: hr:%x %s", hr, *strStatus );
        WriteDebugEvent( strMessage );
        AddReportLog( 8613, strMessage );
        CCore::GetSingleton ().LogEvent ( 613, "CreateVertexDecl", "", strMessage );
        return hr;
    }

    // Create proxy
	*ppDecl = new CProxyDirect3DVertexDeclaration ( pDevice, *ppDecl, pVertexElements );
    return hr;
}
void CCrashDumpWriter::DumpMiniDump ( _EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation )
{
    WriteDebugEvent ( "CCrashDumpWriter::DumpMiniDump" );

    // Try to load the DLL in our directory
    HMODULE hDll = NULL;
    char szDbgHelpPath [MAX_PATH];
    if ( GetModuleFileNameA ( NULL, szDbgHelpPath, MAX_PATH ) )
    {
        char* pSlash = _tcsrchr ( szDbgHelpPath, '\\' );
        if ( pSlash )
        {
            _tcscpy ( pSlash + 1, "DBGHELP.DLL" );
            hDll = LoadLibrary ( szDbgHelpPath );
        }
    }

    // If we couldn't load the one in our dir, load any version available
    if ( !hDll )
    {
        hDll = LoadLibrary( "DBGHELP.DLL" );
    }

    if ( !hDll )
        AddReportLog( 9201, "CCrashDumpWriter::DumpMiniDump - Could not load DBGHELP.DLL" );

    // We could load a dll?
    if ( hDll )
    {
        // Grab the MiniDumpWriteDump proc address
        MINIDUMPWRITEDUMP pDump = reinterpret_cast < MINIDUMPWRITEDUMP > ( GetProcAddress( hDll, "MiniDumpWriteDump" ) );
        if ( !pDump )
            AddReportLog( 9202, "CCrashDumpWriter::DumpMiniDump - Could not find MiniDumpWriteDump" );

        if ( pDump )
        {
            // Create the file
            HANDLE hFile = CreateFile ( CalcMTASAPath ( "mta\\core.dmp" ), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
            if ( hFile == INVALID_HANDLE_VALUE )
                AddReportLog( 9203, SString( "CCrashDumpWriter::DumpMiniDump - Could not create '%s'", *CalcMTASAPath ( "mta\\core.dmp" ) ) );

            if ( hFile != INVALID_HANDLE_VALUE )
            {
                // Create an exception information struct
                _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
                ExInfo.ThreadId = GetCurrentThreadId ();
                ExInfo.ExceptionPointers = pException;
                ExInfo.ClientPointers = FALSE;

                // Write the dump
                BOOL bResult = pDump ( GetCurrentProcess(), GetCurrentProcessId(), hFile, (MINIDUMP_TYPE)( MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory ), &ExInfo, NULL, NULL );

                if ( !bResult )
                    AddReportLog( 9204, SString( "CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump failed (%08x)", GetLastError() ) );
                else
                    WriteDebugEvent ( "CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump succeeded" );

                // Close the dumpfile
                CloseHandle ( hFile );

                // Grab the current time
                // Ask windows for the system time.
                SYSTEMTIME SystemTime;
                GetLocalTime ( &SystemTime );

                // Create the dump directory
                CreateDirectory ( CalcMTASAPath ( "mta\\dumps" ), 0 );
                CreateDirectory ( CalcMTASAPath ( "mta\\dumps\\private" ), 0 );

                SString strModuleName = pExceptionInformation->GetModuleBaseName ();
                strModuleName = strModuleName.ReplaceI ( ".dll", "" ).Replace ( ".exe", "" ).Replace ( "_", "" ).Replace ( ".", "" ).Replace ( "-", "" );
                if ( strModuleName.length () == 0 )
                    strModuleName = "unknown";

                SString strMTAVersionFull = SString ( "%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting ( "mta-version-ext" ).SplitRight ( ".", NULL, -2 ) );
                SString strSerialPart = GetApplicationSetting ( "serial" ).substr ( 0, 5 );
                uint uiServerIP = GetApplicationSettingInt ( "last-server-ip" );
                uint uiServerPort = GetApplicationSettingInt ( "last-server-port" );
                int uiServerTime = GetApplicationSettingInt ( "last-server-time" );
                int uiServerDuration = _time32 ( NULL ) - uiServerTime;
                uiServerDuration = Clamp ( 0, uiServerDuration + 1, 0xfff );

                // Get path to mta dir
                SString strPathCode;
                {
                    std::vector < SString > parts;
                    PathConform ( CalcMTASAPath ( "" ) ).Split ( PATH_SEPERATOR, parts );
                    for ( uint i = 0 ; i < parts.size () ; i++ )
                    {
                        if ( parts[i].CompareI ( "Program Files" ) )
                            strPathCode += "Pr";
                        else
                        if ( parts[i].CompareI ( "Program Files (x86)" ) )
                            strPathCode += "Px";
                        else
                        if ( parts[i].CompareI ( "MTA San Andreas" ) )
                            strPathCode += "Mt";
                        else
                        if ( parts[i].BeginsWithI ( "MTA San Andreas" ) )
                            strPathCode += "Mb";
                        else
                            strPathCode += parts[i].Left ( 1 ).ToUpper ();
                    }
                }

                // Ensure filename parts match up with EDumpFileNameParts
                SString strFilename ( "mta\\dumps\\private\\client_%s_%s_%08x_%x_%s_%08X_%04X_%03X_%s_%04d%02d%02d_%02d%02d.dmp",
                                             strMTAVersionFull.c_str (),
                                             strModuleName.c_str (),
                                             pExceptionInformation->GetAddressModuleOffset (),
                                             pExceptionInformation->GetCode () & 0xffff,
                                             strPathCode.c_str (),
                                             uiServerIP,
                                             uiServerPort,
                                             uiServerDuration,
                                             strSerialPart.c_str (),
                                             SystemTime.wYear,
                                             SystemTime.wMonth,
                                             SystemTime.wDay,
                                             SystemTime.wHour,
                                             SystemTime.wMinute
                                           );

                SString strPathFilename = CalcMTASAPath ( strFilename );

                // Copy the file
                CopyFile ( CalcMTASAPath ( "mta\\core.dmp" ), strPathFilename, false );

                // For the dump uploader
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "none" );
                SetApplicationSetting ( "diagnostics", "last-dump-save", strPathFilename );

                // Try to append pool sizes info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-pools" );
                CBuffer poolInfo;
                GetPoolInfo ( poolInfo );
                AppendToDumpFile ( strPathFilename, poolInfo, 'POLs', 'POLe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-pools" );

                // Try to append d3d state info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-d3d" );
                CBuffer d3dInfo;
                GetD3DInfo ( d3dInfo );
                AppendToDumpFile ( strPathFilename, d3dInfo, 'D3Ds', 'D3De' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-d3d" );

                // Try to append crash averted stats to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-crash-averted" );
                CBuffer crashAvertedStats;
                GetCrashAvertedStats ( crashAvertedStats );
                AppendToDumpFile ( strPathFilename, crashAvertedStats, 'CASs', 'CASe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-crash-averted" );

                // Try to append log info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-log" );
                CBuffer logInfo;
                GetLogInfo ( logInfo );
                AppendToDumpFile ( strPathFilename, logInfo, 'LOGs', 'LOGe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-log" );

                // Try to append dx info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-misc" );
                CBuffer dxInfo;
                GetDxInfo ( dxInfo );
                AppendToDumpFile ( strPathFilename, dxInfo, 'DXIs', 'DXIe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-misc" );

                // Try to append misc info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-misc" );
                CBuffer miscInfo;
                GetMiscInfo ( miscInfo );
                AppendToDumpFile ( strPathFilename, miscInfo, 'MSCs', 'MSCe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-misc" );

                // Try to append memory info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-mem" );
                CBuffer memInfo;
                GetMemoryInfo ( memInfo );
                AppendToDumpFile ( strPathFilename, memInfo, 'MEMs', 'MEMe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-mem" );

                // Try to logfile.txt to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-logfile" );
                CBuffer logfileContent;
                logfileContent.LoadFromFile( CalcMTASAPath( PathJoin( "mta", "logs", "logfile.txt" ) ) );
                AppendToDumpFile ( strPathFilename, logfileContent, 'LOGs', 'LOGe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-logfile" );

                // Try to report.log to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-report" );
                CBuffer reportLogContent;
                reportLogContent.LoadFromFile( PathJoin( GetMTADataPath(), "report.log" ) );
                AppendToDumpFile ( strPathFilename, reportLogContent, 'REPs', 'REPe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-report" );
            }
        }

        // Free the DLL again
        FreeLibrary ( hDll );
    }

    // Auto-fixes

    // Check if crash was in volumetric shadow code
    if ( ms_uiInCrashZone == 1 || ms_uiInCrashZone == 2 )
    {
        CVARS_SET( "volumetric_shadows", false );
        CCore::GetSingleton().SaveConfig();
        AddReportLog( 9205, "Disabled volumetric shadows" );
    }

    CNet* pNet = CCore::GetSingleton().GetNetwork();
    if ( pNet )
        pNet->PostCrash();    
}