2013-11-22 17:01:13 +01:00
///////////////////////////////////////////////////////////////////////////////
// Simple x264 Launcher
2018-02-26 15:56:51 +01:00
// Copyright (C) 2004-2018 LoRd_MuldeR <MuldeR2@GMX.de>
2013-11-22 17:01:13 +01:00
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// http://www.gnu.org/licenses/gpl-2.0.txt
///////////////////////////////////////////////////////////////////////////////
# include "win_updater.h"
2015-02-01 16:33:31 +01:00
# include "UIC_win_updater.h"
2013-11-22 17:01:13 +01:00
2015-02-01 21:05:17 +01:00
//Internal
2013-11-22 17:01:13 +01:00
# include "global.h"
2014-02-12 19:34:14 +01:00
# include "model_sysinfo.h"
2015-02-01 21:05:17 +01:00
//MUtils
# include <MUtils/UpdateChecker.h>
2016-12-26 02:24:43 +01:00
# include <MUtils/Hash.h>
2015-02-02 22:11:06 +01:00
# include <MUtils/GUI.h>
# include <MUtils/OSSupport.h>
# include <MUtils/Exception.h>
2013-11-23 15:20:07 +01:00
2015-02-02 22:11:06 +01:00
//Qt
2013-11-23 15:20:07 +01:00
# include <QMovie>
# include <QCloseEvent>
# include <QTimer>
2013-11-29 18:10:11 +01:00
# include <QMessageBox>
2013-12-11 15:50:26 +01:00
# include <QDesktopServices>
# include <QUrl>
# include <QProcess>
# include <QFileInfo>
# include <QDir>
# include <QMap>
2017-03-29 23:42:39 +02:00
# include <QElapsedTimer>
2013-11-23 15:20:07 +01:00
///////////////////////////////////////////////////////////////////////////////
2016-12-26 02:24:43 +01:00
static const char * const DIGEST_KEY = " ~Dv/bW3/7t>6?RXVwkaZk-hmS0#O4JS/5YQAO> \\ 8hvr0B~7[n!X~KMYruemu:MDq " ;
2014-04-21 16:39:54 +02:00
const UpdaterDialog : : binary_t UpdaterDialog : : BINARIES [ ] =
{
2016-12-26 02:24:43 +01:00
{ " wget.exe " , " 35d70bf8a1799956b5de3975ff99088a4444a2d17202059afb63949b297e2cc81e5e49e2b95df1c4e26b49ab7430399c293bf805a0b250d686c6f4dd994a0764 " , 1 } ,
2017-04-08 14:15:05 +02:00
{ " mcat.exe " , " 8328dbdc505e8816a5d17929678cdcbb573eca0ab107a7da66dca9a94044b404619e2fcc15f8d66950bf0c1fc3af94c31661035cbb5133a4ec721f4c4825a7c9 " , 1 } ,
2018-05-11 11:39:48 +02:00
{ " gpgv.exe " , " 21219d89c1b5e0755264adb2484035309f486be05a15cb1b33d326badfafa3c84879cf15fa0dcc3fef1f02d5f3e581842117ea348b37a89e25674f683fcea5e7 " , 1 } ,
2016-12-26 02:24:43 +01:00
{ " gpgv.gpg " , " 1a2f528e551b9abfb064f08674fdd421d3abe403469ddfee2beafd007775a6c684212a6274dc2b41a0b20dd5c2200021c91320e737f7a90b2ac5a40a6221d93f " , 0 } ,
2018-05-11 11:39:48 +02:00
{ " wupd.exe " , " 018a8d0d848407fb0cb530b4540c6f025fd4c280885becd37f83feed8aeb3af6f8e8e0d45066a36549efac7e64706ac1ef09aaa5c75ab8d12c4a70f41518a894 " , 1 } ,
2014-04-21 16:39:54 +02:00
{ NULL , NULL , 0 }
} ;
2013-11-23 15:20:07 +01:00
# define UPDATE_TEXT(N, TEXT) ui->label_phase##N->setText((TEXT))
# define UPDATE_ICON(N, ICON) ui->icon_phase##N->setPixmap(QIcon(": / buttons / " ICON ".png").pixmap(16, 16))
# define SHOW_ANIMATION(FLAG) do \
{ \
2013-12-16 22:58:21 +01:00
ui - > frameAnimation - > setVisible ( ( FLAG ) ) ; \
2013-11-23 15:20:07 +01:00
ui - > labelInfo - > setVisible ( ! ( FLAG ) ) ; \
ui - > labelUrl - > setVisible ( ! ( FLAG ) ) ; \
2013-12-16 22:58:21 +01:00
ui - > labelBuildNo - > setVisible ( ! ( FLAG ) ) ; \
2013-12-13 15:25:36 +01:00
if ( ( FLAG ) ) m_animator - > start ( ) ; else m_animator - > stop ( ) ; \
2013-11-23 15:20:07 +01:00
} \
while ( 0 )
2017-04-02 17:42:59 +02:00
static inline QString getBin ( const QMap < QString , QSharedPointer < QFile > > & binaries , const QString & nameName )
2017-03-30 23:10:12 +02:00
{
2017-04-02 17:42:59 +02:00
const QSharedPointer < QFile > file = binaries . value ( nameName ) ;
return file . isNull ( ) ? QString ( ) : file - > fileName ( ) ;
}
static void qFileDeleter ( QFile * const file )
{
if ( file )
{
file - > close ( ) ;
delete file ;
}
2017-03-30 23:10:12 +02:00
}
2013-11-22 17:01:13 +01:00
///////////////////////////////////////////////////////////////////////////////
// Constructor & Destructor
///////////////////////////////////////////////////////////////////////////////
2014-04-20 19:40:59 +02:00
UpdaterDialog : : UpdaterDialog ( QWidget * parent , const SysinfoModel * sysinfo , const char * const updateUrl )
2013-11-22 17:01:13 +01:00
:
QDialog ( parent ) ,
2013-11-23 15:20:07 +01:00
ui ( new Ui : : UpdaterDialog ( ) ) ,
2014-02-12 19:34:14 +01:00
m_sysinfo ( sysinfo ) ,
2014-04-20 19:40:59 +02:00
m_updateUrl ( updateUrl ) ,
2015-02-01 21:05:17 +01:00
m_status ( MUtils : : UpdateChecker : : UpdateStatus_NotStartedYet ) ,
2013-12-09 22:19:32 +01:00
m_thread ( NULL ) ,
2013-12-13 15:25:36 +01:00
m_updaterProcess ( NULL ) ,
2013-12-14 22:30:19 +01:00
m_success ( false ) ,
2013-11-23 15:20:07 +01:00
m_firstShow ( true )
2013-11-22 17:01:13 +01:00
{
//Init the dialog, from the .ui file
ui - > setupUi ( this ) ;
setWindowFlags ( windowFlags ( ) & ( ~ Qt : : WindowContextHelpButtonHint ) ) ;
2018-10-12 20:31:30 +02:00
//Scale and fix size
MUtils : : GUI : : scale_widget ( this ) ;
2013-11-23 15:20:07 +01:00
setFixedSize ( size ( ) ) ;
2013-12-11 15:50:26 +01:00
//Enable buttons
connect ( ui - > buttonCancel , SIGNAL ( clicked ( ) ) , this , SLOT ( close ( ) ) ) ;
connect ( ui - > buttonDownload , SIGNAL ( clicked ( ) ) , this , SLOT ( installUpdate ( ) ) ) ;
connect ( ui - > buttonRetry , SIGNAL ( clicked ( ) ) , this , SLOT ( checkForUpdates ( ) ) ) ;
//Enable info label
connect ( ui - > labelUrl , SIGNAL ( linkActivated ( QString ) ) , this , SLOT ( openUrl ( QString ) ) ) ;
2013-11-23 15:20:07 +01:00
//Init animation
2015-02-01 21:05:17 +01:00
m_animator . reset ( new QMovie ( " :/images/loading.gif " ) ) ;
ui - > labelLoadingCenter - > setMovie ( m_animator . data ( ) ) ;
2013-11-23 15:20:07 +01:00
//Init buttons
ui - > buttonCancel - > setEnabled ( false ) ;
ui - > buttonRetry - > hide ( ) ;
ui - > buttonDownload - > hide ( ) ;
2017-03-29 21:43:01 +02:00
ui - > labelCancel - > hide ( ) ;
2013-11-23 15:20:07 +01:00
2013-12-16 22:58:21 +01:00
//Start animation
SHOW_ANIMATION ( true ) ;
2013-11-22 17:01:13 +01:00
}
UpdaterDialog : : ~ UpdaterDialog ( void )
{
2015-02-01 21:05:17 +01:00
if ( ! m_thread . isNull ( ) )
2013-12-09 22:19:32 +01:00
{
2015-02-01 21:05:17 +01:00
if ( ! m_thread - > wait ( 5000 ) )
2013-12-09 22:19:32 +01:00
{
m_thread - > terminate ( ) ;
m_thread - > wait ( ) ;
}
}
2013-11-22 17:01:13 +01:00
delete ui ;
}
///////////////////////////////////////////////////////////////////////////////
// Events
///////////////////////////////////////////////////////////////////////////////
2013-12-13 15:25:36 +01:00
bool UpdaterDialog : : event ( QEvent * e )
{
if ( ( e - > type ( ) = = QEvent : : ActivationChange ) & & ( m_updaterProcess ! = NULL ) )
{
2015-02-02 22:11:06 +01:00
MUtils : : GUI : : bring_to_front ( m_updaterProcess ) ;
2013-12-13 15:25:36 +01:00
}
return QDialog : : event ( e ) ;
}
2013-11-23 15:20:07 +01:00
void UpdaterDialog : : showEvent ( QShowEvent * event )
{
if ( m_firstShow )
{
m_firstShow = false ;
2013-12-14 22:30:19 +01:00
QTimer : : singleShot ( 16 , this , SLOT ( initUpdate ( ) ) ) ;
2013-11-23 15:20:07 +01:00
}
}
void UpdaterDialog : : closeEvent ( QCloseEvent * e )
{
if ( ! ui - > buttonCancel - > isEnabled ( ) )
{
e - > ignore ( ) ;
}
}
2013-11-22 17:01:13 +01:00
2013-12-11 15:50:26 +01:00
void UpdaterDialog : : keyPressEvent ( QKeyEvent * event )
{
2017-03-29 21:43:01 +02:00
switch ( event - > key ( ) )
2013-12-11 15:50:26 +01:00
{
2017-03-29 21:43:01 +02:00
case Qt : : Key_Escape :
if ( ( ! m_thread . isNull ( ) ) & & m_thread - > isRunning ( ) )
2013-12-11 15:50:26 +01:00
{
2017-03-29 21:43:01 +02:00
if ( m_status > = MUtils : : UpdateChecker : : UpdateStatus_FetchingUpdates )
2013-12-11 15:50:26 +01:00
{
2017-03-29 21:43:01 +02:00
UPDATE_TEXT ( 2 , tr ( " Cancellation requested... " ) ) ;
}
else
{
UPDATE_TEXT ( 1 , tr ( " Cancellation requested... " ) ) ;
}
m_thread - > cancel ( ) ;
}
break ;
case Qt : : Key_F11 :
{
2017-03-29 23:42:39 +02:00
const QString logFilePath = MUtils : : make_temp_file ( MUtils : : temp_folder ( ) , " txt " , true ) ;
2017-03-29 21:43:01 +02:00
if ( ! logFilePath . isEmpty ( ) )
{
2017-03-29 23:42:39 +02:00
qWarning ( " Write log to: '%s' " , MUTILS_UTF8 ( logFilePath ) ) ;
2017-03-29 21:43:01 +02:00
QFile logFile ( logFilePath ) ;
if ( logFile . open ( QIODevice : : WriteOnly | QIODevice : : Truncate ) )
2016-12-16 20:54:01 +01:00
{
2017-03-29 21:43:01 +02:00
logFile . write ( " \xEF \xBB \xBF " ) ;
for ( QStringList : : ConstIterator iter = m_logFile . constBegin ( ) ; iter ! = m_logFile . constEnd ( ) ; iter + + )
{
logFile . write ( iter - > toUtf8 ( ) ) ;
logFile . write ( " \r \n " ) ;
}
logFile . close ( ) ;
QDesktopServices : : openUrl ( QUrl : : fromLocalFile ( logFile . fileName ( ) ) ) ;
2016-12-16 20:54:01 +01:00
}
2013-12-11 15:50:26 +01:00
}
}
2017-03-29 21:43:01 +02:00
break ;
default :
QDialog : : keyPressEvent ( event ) ;
2013-12-11 15:50:26 +01:00
}
}
2013-11-22 17:01:13 +01:00
///////////////////////////////////////////////////////////////////////////////
// Slots
///////////////////////////////////////////////////////////////////////////////
2013-11-23 15:20:07 +01:00
void UpdaterDialog : : initUpdate ( void )
{
2013-12-09 20:42:02 +01:00
//Check binary files
2016-04-23 15:09:13 +02:00
if ( ! checkBinaries ( ) )
2013-12-09 20:42:02 +01:00
{
ui - > buttonCancel - > setEnabled ( true ) ;
2014-04-20 19:40:59 +02:00
const QString message = QString ( " %1<br><br><nobr><a href= \" %2 \" >%3</a></nobr><br> " ) . arg ( tr ( " At least one file required by the web-update tool is missing or corrupted.<br>Please re-install this application and then try again! " ) , QString : : fromLatin1 ( m_updateUrl ) , QString : : fromLatin1 ( m_updateUrl ) . replace ( " - " , " − " ) ) ;
if ( QMessageBox : : critical ( this , tr ( " File Error " ) , message , tr ( " Download Latest Version " ) , tr ( " Discard " ) ) = = 0 )
{
QDesktopServices : : openUrl ( QUrl ( QString : : fromLatin1 ( m_updateUrl ) ) ) ;
}
2017-03-30 23:10:12 +02:00
close ( ) ;
return ;
2013-12-16 22:58:21 +01:00
}
//Make sure user does have admin access
2015-02-02 22:11:06 +01:00
if ( ! MUtils : : OS : : user_is_admin ( ) )
2013-12-16 22:58:21 +01:00
{
qWarning ( " User is not in the \" admin \" group, cannot update! " ) ;
QString message ;
message + = QString ( " <nobr>%1</nobr><br> " ) . arg ( tr ( " Sorry, but only users in the \" Administrators \" group can install updates. " ) ) ;
message + = QString ( " <nobr>%1</nobr> " ) . arg ( tr ( " Please start application from an administrator account and try again! " ) ) ;
if ( QMessageBox : : critical ( this , this - > windowTitle ( ) , message , tr ( " Discard " ) , tr ( " Ignore " ) ) ! = 1 )
{
ui - > buttonCancel - > setEnabled ( true ) ;
2017-03-30 23:10:12 +02:00
close ( ) ;
return ;
2013-12-16 22:58:21 +01:00
}
2013-12-09 20:42:02 +01:00
}
2013-12-09 22:19:32 +01:00
//Create and setup thread
if ( ! m_thread )
{
2017-04-08 14:15:05 +02:00
m_thread . reset ( new MUtils : : UpdateChecker ( getBin ( m_binaries , " wget.exe " ) , getBin ( m_binaries , " mcat.exe " ) , getBin ( m_binaries , " gpgv.exe " ) , getBin ( m_binaries , " gpgv.gpg " ) , " Simple x264 Launcher " , x264_version_build ( ) , false ) ) ;
2015-02-01 21:05:17 +01:00
connect ( m_thread . data ( ) , SIGNAL ( statusChanged ( int ) ) , this , SLOT ( threadStatusChanged ( int ) ) ) ;
connect ( m_thread . data ( ) , SIGNAL ( finished ( ) ) , this , SLOT ( threadFinished ( ) ) ) ;
connect ( m_thread . data ( ) , SIGNAL ( terminated ( ) ) , this , SLOT ( threadFinished ( ) ) ) ;
connect ( m_thread . data ( ) , SIGNAL ( messageLogged ( QString ) ) , this , SLOT ( threadMessageLogged ( QString ) ) ) ;
2013-12-09 22:19:32 +01:00
}
2013-12-09 20:42:02 +01:00
2013-12-11 15:50:26 +01:00
//Begin updater run
2013-12-14 22:30:19 +01:00
QTimer : : singleShot ( 16 , this , SLOT ( checkForUpdates ( ) ) ) ;
2013-12-09 22:19:32 +01:00
}
void UpdaterDialog : : checkForUpdates ( void )
{
if ( ( ! m_thread ) | | m_thread - > isRunning ( ) )
{
qWarning ( " Update in progress, cannot check for updates now! " ) ;
}
2013-12-11 15:50:26 +01:00
//Clear texts
ui - > retranslateUi ( this ) ;
2013-12-14 22:30:19 +01:00
ui - > labelBuildNo - > setText ( tr ( " Installed build is #%1 | Latest build is #%2 " ) . arg ( QString : : number ( x264_version_build ( ) ) , tr ( " N/A " ) ) ) ;
2013-12-11 15:50:26 +01:00
2013-12-09 22:19:32 +01:00
//Init buttons
ui - > buttonCancel - > setEnabled ( false ) ;
ui - > buttonRetry - > hide ( ) ;
ui - > buttonDownload - > hide ( ) ;
//Hide labels
ui - > labelInfo - > hide ( ) ;
ui - > labelUrl - > hide ( ) ;
2017-03-29 21:43:01 +02:00
ui - > labelCancel - > show ( ) ;
2013-12-11 15:50:26 +01:00
2013-12-09 22:19:32 +01:00
//Update status
2015-02-01 21:05:17 +01:00
threadStatusChanged ( MUtils : : UpdateChecker : : UpdateStatus_NotStartedYet ) ;
2013-12-09 22:19:32 +01:00
2013-12-11 15:50:26 +01:00
//Start animation
SHOW_ANIMATION ( true ) ;
2013-12-09 22:19:32 +01:00
//Update cursor
QApplication : : processEvents ( QEventLoop : : ExcludeUserInputEvents ) ;
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
2013-12-11 15:50:26 +01:00
//Clear log
m_logFile . clear ( ) ;
2017-03-29 23:42:39 +02:00
//Init timer
m_elapsed . reset ( new QElapsedTimer ( ) ) ;
m_elapsed - > start ( ) ;
2013-12-09 22:19:32 +01:00
//Start the updater thread
2017-03-29 23:42:39 +02:00
QTimer : : singleShot ( 125 , m_thread . data ( ) , SLOT ( start ( ) ) ) ;
2013-11-23 15:20:07 +01:00
}
2013-12-09 22:19:32 +01:00
void UpdaterDialog : : threadStatusChanged ( int status )
2013-11-23 15:20:07 +01:00
{
2017-03-29 21:43:01 +02:00
const int prevStatus = m_status ;
2013-12-11 15:50:26 +01:00
switch ( m_status = status )
2013-11-23 15:20:07 +01:00
{
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_NotStartedYet :
2013-12-09 22:19:32 +01:00
UPDATE_ICON ( 1 , " clock " ) ;
UPDATE_ICON ( 2 , " clock " ) ;
UPDATE_ICON ( 3 , " clock " ) ;
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_CheckingConnection :
2013-11-23 15:20:07 +01:00
UPDATE_ICON ( 1 , " play " ) ;
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_FetchingUpdates :
2013-11-23 15:20:07 +01:00
UPDATE_ICON ( 1 , " shield_green " ) ;
UPDATE_TEXT ( 1 , tr ( " Internet connection is working. " ) ) ;
UPDATE_ICON ( 2 , " play " ) ;
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_ErrorNoConnection :
2013-12-11 15:50:26 +01:00
UPDATE_ICON ( 1 , " shield_error " ) ;
UPDATE_TEXT ( 1 , tr ( " Computer is currently offline! " ) ) ;
UPDATE_ICON ( 2 , " shield_grey " ) ;
UPDATE_ICON ( 3 , " shield_grey " ) ;
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_ErrorConnectionTestFailed :
2013-12-11 15:50:26 +01:00
UPDATE_ICON ( 1 , " shield_error " ) ;
UPDATE_TEXT ( 1 , tr ( " Internet connectivity test failed! " ) ) ;
UPDATE_ICON ( 2 , " shield_grey " ) ;
UPDATE_ICON ( 3 , " shield_grey " ) ;
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_ErrorFetchUpdateInfo :
2013-12-11 15:50:26 +01:00
UPDATE_ICON ( 2 , " shield_error " ) ;
UPDATE_TEXT ( 2 , tr ( " Failed to download the update information! " ) ) ;
UPDATE_ICON ( 3 , " shield_grey " ) ;
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_CompletedUpdateAvailable :
case MUtils : : UpdateChecker : : UpdateStatus_CompletedNoUpdates :
case MUtils : : UpdateChecker : : UpdateStatus_CompletedNewVersionOlder :
2013-12-11 15:50:26 +01:00
UPDATE_ICON ( 2 , " shield_green " ) ;
UPDATE_TEXT ( 2 , tr ( " Update information received successfully. " ) ) ;
UPDATE_ICON ( 3 , " play " ) ;
2013-12-09 22:19:32 +01:00
break ;
2017-03-29 21:43:01 +02:00
case MUtils : : UpdateChecker : : UpdateStatus_CancelledByUser :
if ( prevStatus > = MUtils : : UpdateChecker : : UpdateStatus_FetchingUpdates )
{
UPDATE_ICON ( 2 , " shield_error " ) ;
UPDATE_TEXT ( 2 , tr ( " Operation was cancelled by the user! " ) ) ;
UPDATE_ICON ( 3 , " shield_grey " ) ;
}
else
{
UPDATE_ICON ( 1 , " shield_error " ) ;
UPDATE_TEXT ( 1 , tr ( " Operation was cancelled by the user! " ) ) ;
UPDATE_ICON ( 2 , " shield_grey " ) ;
UPDATE_ICON ( 3 , " shield_grey " ) ;
}
break ;
2013-12-09 22:19:32 +01:00
default :
2015-02-02 22:11:06 +01:00
MUTILS_THROW ( " Unknown status code! " ) ;
2013-12-09 22:19:32 +01:00
}
2013-12-11 15:50:26 +01:00
}
void UpdaterDialog : : threadFinished ( void )
2013-12-14 22:30:19 +01:00
{
m_success = m_thread - > getSuccess ( ) ;
2017-03-29 21:43:01 +02:00
ui - > labelCancel - > hide ( ) ;
2017-03-29 23:42:39 +02:00
QTimer : : singleShot ( ( m_success ? 500 : 0 ) , this , SLOT ( updateFinished ( ) ) ) ;
2013-12-14 22:30:19 +01:00
}
void UpdaterDialog : : updateFinished ( void )
2013-12-11 15:50:26 +01:00
{
2017-03-29 23:42:39 +02:00
//Query the timer, if available
if ( ! m_elapsed . isNull ( ) )
{
const quint64 elapsed = m_elapsed - > restart ( ) ;
qDebug ( " Update check completed after %.2f seconds. " , double ( elapsed ) / 1000.0 ) ;
}
2013-12-11 15:50:26 +01:00
//Restore cursor
QApplication : : restoreOverrideCursor ( ) ;
2013-12-13 15:25:36 +01:00
//If update was successfull, process final updater state
if ( m_thread - > getSuccess ( ) )
2013-12-09 22:19:32 +01:00
{
2013-12-13 15:25:36 +01:00
switch ( m_status )
{
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_CompletedUpdateAvailable :
2013-12-13 15:25:36 +01:00
UPDATE_ICON ( 3 , " shield_exclamation " ) ;
UPDATE_TEXT ( 3 , tr ( " A newer version is available! " ) ) ;
ui - > buttonDownload - > show ( ) ;
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_CompletedNoUpdates :
2013-12-13 15:25:36 +01:00
UPDATE_ICON ( 3 , " shield_green " ) ;
UPDATE_TEXT ( 3 , tr ( " Your version is up-to-date. " ) ) ;
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_CompletedNewVersionOlder :
2013-12-14 22:30:19 +01:00
UPDATE_ICON ( 3 , " shield_blue " ) ;
2013-12-14 14:20:43 +01:00
UPDATE_TEXT ( 3 , tr ( " You are using a pre-release version! " ) ) ;
2013-12-13 15:25:36 +01:00
break ;
default :
qWarning ( " Update thread succeeded with unexpected status code: %d " , m_status ) ;
}
2013-12-11 15:50:26 +01:00
}
//Show update info or retry button
switch ( m_status )
{
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_CompletedUpdateAvailable :
case MUtils : : UpdateChecker : : UpdateStatus_CompletedNoUpdates :
case MUtils : : UpdateChecker : : UpdateStatus_CompletedNewVersionOlder :
2013-12-11 15:50:26 +01:00
SHOW_ANIMATION ( false ) ;
2015-02-01 21:05:17 +01:00
ui - > labelBuildNo - > setText ( tr ( " Installed build is #%1 | Latest build is #%2 " ) . arg ( QString : : number ( x264_version_build ( ) ) , QString : : number ( m_thread - > getUpdateInfo ( ) - > getBuildNo ( ) ) ) ) ;
ui - > labelUrl - > setText ( QString ( " <a href= \" %1 \" >%1</a> " ) . arg ( m_thread - > getUpdateInfo ( ) - > getDownloadSite ( ) ) ) ;
2013-12-11 15:50:26 +01:00
break ;
2015-02-01 21:05:17 +01:00
case MUtils : : UpdateChecker : : UpdateStatus_ErrorNoConnection :
case MUtils : : UpdateChecker : : UpdateStatus_ErrorConnectionTestFailed :
case MUtils : : UpdateChecker : : UpdateStatus_ErrorFetchUpdateInfo :
2017-03-29 21:43:01 +02:00
case MUtils : : UpdateChecker : : UpdateStatus_CancelledByUser :
2013-12-13 15:25:36 +01:00
m_animator - > stop ( ) ;
2013-12-11 15:50:26 +01:00
ui - > buttonRetry - > show ( ) ;
2013-11-23 15:20:07 +01:00
break ;
2013-12-13 15:25:36 +01:00
default :
qWarning ( " Update thread finished with unexpected status code: %d " , m_status ) ;
2013-11-23 15:20:07 +01:00
}
2013-12-11 15:50:26 +01:00
//Re-enbale cancel button
ui - > buttonCancel - > setEnabled ( true ) ;
}
void UpdaterDialog : : threadMessageLogged ( const QString & message )
{
m_logFile < < message ;
}
void UpdaterDialog : : openUrl ( const QString & url )
{
qDebug ( " Open URL: %s " , url . toLatin1 ( ) . constData ( ) ) ;
QDesktopServices : : openUrl ( QUrl ( url ) ) ;
}
void UpdaterDialog : : installUpdate ( void )
{
if ( ! ( ( m_thread ) & & m_thread - > getSuccess ( ) ) )
{
qWarning ( " Cannot download/install update at this point! " ) ;
return ;
}
2013-12-13 15:25:36 +01:00
QApplication : : setOverrideCursor ( Qt : : WaitCursor ) ;
ui - > buttonDownload - > hide ( ) ;
ui - > buttonCancel - > setEnabled ( false ) ;
SHOW_ANIMATION ( true ) ;
2015-02-01 21:05:17 +01:00
const MUtils : : UpdateCheckerInfo * updateInfo = m_thread - > getUpdateInfo ( ) ;
2013-12-11 15:50:26 +01:00
QProcess process ;
QStringList args ;
QEventLoop loop ;
2015-02-02 22:11:06 +01:00
MUtils : : init_process ( process , MUtils : : temp_folder ( ) , false ) ;
2013-12-11 15:50:26 +01:00
connect ( & process , SIGNAL ( error ( QProcess : : ProcessError ) ) , & loop , SLOT ( quit ( ) ) ) ;
connect ( & process , SIGNAL ( finished ( int , QProcess : : ExitStatus ) ) , & loop , SLOT ( quit ( ) ) ) ;
2015-02-01 21:05:17 +01:00
args < < QString ( " /Location=%1 " ) . arg ( updateInfo - > getDownloadAddress ( ) ) ;
args < < QString ( " /Filename=%1 " ) . arg ( updateInfo - > getDownloadFilename ( ) ) ;
args < < QString ( " /TicketID=%1 " ) . arg ( updateInfo - > getDownloadFilecode ( ) ) ;
2015-10-12 20:31:24 +02:00
args < < QString ( " /CheckSum=%1 " ) . arg ( updateInfo - > getDownloadChecksum ( ) ) ;
args < < QString ( " /ToFolder=%1 " ) . arg ( QDir : : toNativeSeparators ( QDir ( QApplication : : applicationDirPath ( ) ) . canonicalPath ( ) ) ) ;
2013-12-11 15:50:26 +01:00
args < < QString ( " /ToExFile=%1.exe " ) . arg ( QFileInfo ( QFileInfo ( QApplication : : applicationFilePath ( ) ) . canonicalFilePath ( ) ) . completeBaseName ( ) ) ;
2015-02-01 21:05:17 +01:00
args < < QString ( " /AppTitle=Simple x264 Launcher (Build #%1) " ) . arg ( QString : : number ( updateInfo - > getBuildNo ( ) ) ) ;
2013-12-11 15:50:26 +01:00
2017-04-02 17:42:59 +02:00
process . start ( getBin ( m_binaries , " wupd.exe " ) , args ) ;
2013-12-11 15:50:26 +01:00
if ( ! process . waitForStarted ( ) )
{
2013-12-13 15:25:36 +01:00
QApplication : : restoreOverrideCursor ( ) ;
SHOW_ANIMATION ( false ) ;
2013-12-11 15:50:26 +01:00
QMessageBox : : critical ( this , tr ( " Update Failed " ) , tr ( " Sorry, failed to launch web-update program! " ) ) ;
2013-12-13 15:25:36 +01:00
ui - > buttonDownload - > show ( ) ;
ui - > buttonCancel - > setEnabled ( true ) ;
2013-12-11 15:50:26 +01:00
return ;
}
2015-02-02 22:11:06 +01:00
m_updaterProcess = MUtils : : OS : : process_id ( & process ) ;
2013-12-11 15:50:26 +01:00
loop . exec ( QEventLoop : : ExcludeUserInputEvents ) ;
if ( ! process . waitForFinished ( ) )
{
process . kill ( ) ;
process . waitForFinished ( ) ;
}
2013-12-13 15:25:36 +01:00
m_updaterProcess = NULL ;
2013-12-11 15:50:26 +01:00
QApplication : : restoreOverrideCursor ( ) ;
ui - > buttonDownload - > show ( ) ;
ui - > buttonCancel - > setEnabled ( true ) ;
2013-12-13 15:25:36 +01:00
SHOW_ANIMATION ( false ) ;
2013-12-11 15:50:26 +01:00
if ( process . exitCode ( ) = = 0 )
{
2013-12-14 22:30:19 +01:00
done ( READY_TO_INSTALL_UPDATE ) ;
2013-12-11 15:50:26 +01:00
}
2013-11-23 15:20:07 +01:00
}
2013-12-09 20:42:02 +01:00
///////////////////////////////////////////////////////////////////////////////
// Private Functions
///////////////////////////////////////////////////////////////////////////////
2016-04-23 15:09:13 +02:00
bool UpdaterDialog : : checkBinaries ( void )
2013-12-09 20:42:02 +01:00
{
qDebug ( " [File Verification] " ) ;
2014-04-21 16:39:54 +02:00
for ( size_t i = 0 ; BINARIES [ i ] . name ; i + + )
2013-12-09 20:42:02 +01:00
{
2017-03-30 23:10:12 +02:00
const QString name = QString : : fromLatin1 ( BINARIES [ i ] . name ) ;
if ( ! m_binaries . contains ( name ) )
2013-12-11 15:50:26 +01:00
{
2017-03-30 23:10:12 +02:00
QScopedPointer < QFile > binary ( new QFile ( QString ( " %1/toolset/common/%2 " ) . arg ( m_sysinfo - > getAppPath ( ) , name ) ) ) ;
if ( binary - > open ( QIODevice : : ReadOnly ) )
{
if ( checkFileHash ( binary - > fileName ( ) , BINARIES [ i ] . hash ) )
{
QApplication : : processEvents ( QEventLoop : : ExcludeUserInputEvents ) ;
2017-04-02 17:42:59 +02:00
m_binaries . insert ( name , QSharedPointer < QFile > ( binary . take ( ) , qFileDeleter ) ) ;
2017-03-30 23:10:12 +02:00
}
else
{
qWarning ( " Verification of '%s' has failed! " , MUTILS_UTF8 ( name ) ) ;
2017-04-02 17:42:59 +02:00
binary - > close ( ) ;
2017-03-30 23:10:12 +02:00
return false ;
}
}
else
{
qWarning ( " File '%s' could not be opened! " , MUTILS_UTF8 ( name ) ) ;
return false ;
}
2013-12-11 15:50:26 +01:00
}
2013-12-09 20:42:02 +01:00
}
2017-03-30 23:10:12 +02:00
qDebug ( " File check completed. \n " ) ;
2015-02-01 21:05:17 +01:00
return true ;
2013-12-09 20:42:02 +01:00
}
bool UpdaterDialog : : checkFileHash ( const QString & filePath , const char * expectedHash )
{
2017-03-30 23:10:12 +02:00
qDebug ( " Checking file: %s " , MUTILS_UTF8 ( filePath ) ) ;
2016-12-26 02:24:43 +01:00
QScopedPointer < MUtils : : Hash : : Hash > checksum ( MUtils : : Hash : : create ( MUtils : : Hash : : HASH_BLAKE2_512 , DIGEST_KEY ) ) ;
2013-12-09 20:42:02 +01:00
QFile file ( filePath ) ;
if ( file . open ( QIODevice : : ReadOnly ) )
{
2016-12-26 02:24:43 +01:00
checksum - > update ( file ) ;
const QByteArray fileHash = checksum - > digest ( ) ;
2013-12-09 20:42:02 +01:00
if ( ( strlen ( expectedHash ) ! = fileHash . size ( ) ) | | ( memcmp ( fileHash . constData ( ) , expectedHash , fileHash . size ( ) ) ! = 0 ) )
{
qWarning ( " \n File appears to be corrupted: \n %s \n " , filePath . toUtf8 ( ) . constData ( ) ) ;
qWarning ( " Expected Hash: %s \n Detected Hash: %s \n " , expectedHash , fileHash . constData ( ) ) ;
return false ;
}
return true ;
}
else
{
qWarning ( " Failed to open file: \n %s \n " , filePath . toUtf8 ( ) . constData ( ) ) ;
return false ;
}
}