2010-11-06 23:04:47 +01:00
///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
2012-01-02 00:52:27 +01:00
// Copyright (C) 2004-2012 LoRd_MuldeR <MuldeR2@GMX.de>
2010-11-06 23:04:47 +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 "Global.h"
//Qt includes
# include <QApplication>
# include <QMessageBox>
# include <QDir>
# include <QUuid>
# include <QMap>
# include <QDate>
# include <QIcon>
# include <QPlastiqueStyle>
# include <QImageReader>
# include <QSharedMemory>
# include <QSysInfo>
# include <QStringList>
2010-11-08 19:29:36 +01:00
# include <QSystemSemaphore>
2010-11-19 13:31:45 +01:00
# include <QMutex>
2010-11-22 21:45:00 +01:00
# include <QTextCodec>
2010-11-25 16:56:32 +01:00
# include <QLibrary>
2010-12-07 22:58:28 +01:00
# include <QRegExp>
2010-12-28 21:26:16 +01:00
# include <QResource>
# include <QTranslator>
2011-05-03 20:17:33 +02:00
# include <QEventLoop>
# include <QTimer>
2011-12-17 15:56:24 +01:00
# include <QLibraryInfo>
2011-12-29 14:42:20 +01:00
# include <QEvent>
2010-11-06 23:04:47 +01:00
//LameXP includes
2010-11-07 23:06:30 +01:00
# include "Resource.h"
2010-11-06 23:04:47 +01:00
# include "LockedFile.h"
2010-11-07 23:06:30 +01:00
//CRT includes
2011-09-27 21:32:45 +02:00
# include <iostream>
# include <fstream>
2010-11-07 23:06:30 +01:00
# include <io.h>
# include <fcntl.h>
2010-11-15 04:42:06 +01:00
# include <intrin.h>
2011-06-21 22:07:22 +02:00
# include <math.h>
2011-12-27 20:10:19 +01:00
# include <time.h>
2012-03-26 04:40:49 +02:00
# include <process.h>
2010-11-07 23:06:30 +01:00
2011-04-11 21:55:34 +02:00
//COM includes
# include <Objbase.h>
2011-10-22 01:13:28 +02:00
# include <PowrProf.h>
2011-04-11 21:55:34 +02:00
2010-11-07 16:32:54 +01:00
//Debug only includes
2011-04-19 16:14:05 +02:00
# if LAMEXP_DEBUG
2010-11-07 16:32:54 +01:00
# include <Psapi.h>
2011-04-19 16:14:05 +02:00
# endif
2010-11-06 23:04:47 +01:00
2011-04-19 16:14:05 +02:00
//Initialize static Qt plugins
2010-11-11 19:37:16 +01:00
# ifdef QT_NODLL
2011-04-19 16:14:05 +02:00
Q_IMPORT_PLUGIN ( qico )
Q_IMPORT_PLUGIN ( qsvg )
2010-11-11 19:37:16 +01:00
# endif
2010-11-08 19:29:36 +01:00
///////////////////////////////////////////////////////////////////////////////
// TYPES
///////////////////////////////////////////////////////////////////////////////
2011-12-29 14:42:20 +01:00
static const size_t g_lamexp_ipc_slots = 128 ;
2010-11-08 19:29:36 +01:00
typedef struct
{
unsigned int command ;
unsigned int reserved_1 ;
unsigned int reserved_2 ;
char parameter [ 4096 ] ;
2011-12-29 14:42:20 +01:00
}
lamexp_ipc_data_t ;
typedef struct
{
unsigned int pos_write ;
unsigned int pos_read ;
lamexp_ipc_data_t data [ g_lamexp_ipc_slots ] ;
}
lamexp_ipc_t ;
2010-11-08 19:29:36 +01:00
2010-11-06 23:04:47 +01:00
///////////////////////////////////////////////////////////////////////////////
// GLOBAL VARS
///////////////////////////////////////////////////////////////////////////////
//Build version
2011-01-20 22:54:10 +01:00
static const struct
{
unsigned int ver_major ;
unsigned int ver_minor ;
unsigned int ver_build ;
char * ver_release_name ;
}
g_lamexp_version =
{
VER_LAMEXP_MAJOR ,
VER_LAMEXP_MINOR ,
VER_LAMEXP_BUILD ,
VER_LAMEXP_RNAME
} ;
2010-11-06 23:04:47 +01:00
//Build date
static QDate g_lamexp_version_date ;
static const char * g_lamexp_months [ ] = { " Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " , " Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec " } ;
static const char * g_lamexp_version_raw_date = __DATE__ ;
2011-07-26 22:17:14 +02:00
static const char * g_lamexp_version_raw_time = __TIME__ ;
2010-11-06 23:04:47 +01:00
2011-03-04 23:40:09 +01:00
//Console attached flag
static bool g_lamexp_console_attached = false ;
2011-04-07 22:40:47 +02:00
//Compiler detection
//The following code was borrowed from MPC-HC project: http://mpc-hc.sf.net/
# if defined(__INTEL_COMPILER)
# if (__INTEL_COMPILER >= 1200)
static const char * g_lamexp_version_compiler = " ICL 12.x " ;
# elif (__INTEL_COMPILER >= 1100)
2012-04-10 01:25:34 +02:00
static const char * g_lamexp_version_compiler = " ICL 11.x " ;
2011-04-07 22:40:47 +02:00
# elif (__INTEL_COMPILER >= 1000)
2012-04-10 01:25:34 +02:00
static const char * g_lamexp_version_compiler = " ICL 10.x " ;
2010-11-20 22:14:29 +01:00
# else
2011-04-07 22:40:47 +02:00
# error Compiler is not supported!
# endif
# elif defined(_MSC_VER)
# if (_MSC_VER == 1600)
# if (_MSC_FULL_VER >= 160040219)
static const char * g_lamexp_version_compiler = " MSVC 2010-SP1 " ;
2010-11-20 22:14:29 +01:00
# else
2011-04-07 22:40:47 +02:00
static const char * g_lamexp_version_compiler = " MSVC 2010 " ;
2010-11-20 22:14:29 +01:00
# endif
2011-04-07 22:40:47 +02:00
# elif (_MSC_VER == 1500)
# if (_MSC_FULL_VER >= 150030729)
static const char * g_lamexp_version_compiler = " MSVC 2008-SP1 " ;
# else
static const char * g_lamexp_version_compiler = " MSVC 2008 " ;
# endif
# else
# error Compiler is not supported!
2010-11-20 22:14:29 +01:00
# endif
2011-04-07 22:40:47 +02:00
// Note: /arch:SSE and /arch:SSE2 are only available for the x86 platform
# if !defined(_M_X64) && defined(_M_IX86_FP)
# if (_M_IX86_FP == 1)
LAMEXP_COMPILER_WARNING ( " SSE instruction set is enabled! " )
# elif (_M_IX86_FP == 2)
LAMEXP_COMPILER_WARNING ( " SSE2 instruction set is enabled! " )
# endif
# endif
# else
# error Compiler is not supported!
2010-11-20 22:14:29 +01:00
# endif
2011-07-26 22:17:14 +02:00
//Architecture detection
# if defined(_M_X64)
static const char * g_lamexp_version_arch = " x64 " ;
# elif defined(_M_IX86)
static const char * g_lamexp_version_arch = " x86 " ;
# else
# error Architecture is not supported!
# endif
2011-02-28 01:28:27 +01:00
//Official web-site URL
2011-07-06 23:30:43 +02:00
static const char * g_lamexp_website_url = " http://lamexp.sourceforge.net/ " ;
2011-03-20 14:28:27 +01:00
static const char * g_lamexp_support_url = " http://forum.doom9.org/showthread.php?t=157726 " ;
2011-02-28 01:28:27 +01:00
2011-08-21 14:43:18 +02:00
//Tool versions (expected versions!)
2010-11-12 15:58:53 +01:00
static const unsigned int g_lamexp_toolver_neroaac = VER_LAMEXP_TOOL_NEROAAC ;
2011-08-21 14:43:18 +02:00
static const unsigned int g_lamexp_toolver_fhgaacenc = VER_LAMEXP_TOOL_FHGAACENC ;
2011-11-21 01:22:41 +01:00
static const unsigned int g_lamexp_toolver_qaacenc = VER_LAMEXP_TOOL_QAAC ;
2011-11-21 14:40:32 +01:00
static const unsigned int g_lamexp_toolver_coreaudio = VER_LAMEXP_TOOL_COREAUDIO ;
2010-11-12 15:58:53 +01:00
2010-11-06 23:04:47 +01:00
//Special folders
static QString g_lamexp_temp_folder ;
//Tools
static QMap < QString , LockedFile * > g_lamexp_tool_registry ;
2010-11-12 15:58:53 +01:00
static QMap < QString , unsigned int > g_lamexp_tool_versions ;
2010-11-06 23:04:47 +01:00
2010-12-28 21:26:16 +01:00
//Languages
2011-01-21 00:10:51 +01:00
static struct
{
QMap < QString , QString > files ;
QMap < QString , QString > names ;
QMap < QString , unsigned int > sysid ;
2011-12-19 17:26:20 +01:00
QMap < QString , unsigned int > cntry ;
2011-01-21 00:10:51 +01:00
}
g_lamexp_translation ;
//Translator
2010-12-28 21:26:16 +01:00
static QTranslator * g_lamexp_currentTranslator = NULL ;
2010-11-06 23:04:47 +01:00
//Shared memory
2011-01-20 22:54:10 +01:00
static const struct
{
char * sharedmem ;
char * semaphore_read ;
2011-12-29 14:42:20 +01:00
char * semaphore_read_mutex ;
2011-01-20 22:54:10 +01:00
char * semaphore_write ;
2011-12-29 14:42:20 +01:00
char * semaphore_write_mutex ;
2011-01-20 22:54:10 +01:00
}
g_lamexp_ipc_uuid =
{
" {21A68A42-6923-43bb-9CF6-64BF151942EE} " ,
" {7A605549-F58C-4d78-B4E5-06EFC34F405B} " ,
2011-12-29 14:42:20 +01:00
" {60AA8D04-F6B8-497d-81EB-0F600F4A65B5} " ,
" {726061D5-1615-4B82-871C-75FD93458E46} " ,
" {1A616023-AA6A-4519-8AF3-F7736E899977} "
2011-01-20 22:54:10 +01:00
} ;
static struct
{
QSharedMemory * sharedmem ;
QSystemSemaphore * semaphore_read ;
2011-12-29 14:42:20 +01:00
QSystemSemaphore * semaphore_read_mutex ;
2011-01-20 22:54:10 +01:00
QSystemSemaphore * semaphore_write ;
2011-12-29 14:42:20 +01:00
QSystemSemaphore * semaphore_write_mutex ;
2011-01-20 22:54:10 +01:00
}
g_lamexp_ipc_ptr =
{
NULL , NULL , NULL
} ;
2010-11-06 23:04:47 +01:00
2010-11-11 19:37:16 +01:00
//Image formats
2011-03-21 02:16:18 +01:00
static const char * g_lamexp_imageformats [ ] = { " png " , " jpg " , " gif " , " ico " , " svg " , NULL } ;
2010-11-11 19:37:16 +01:00
2010-11-19 13:31:45 +01:00
//Global locks
static QMutex g_lamexp_message_mutex ;
2011-04-24 23:18:00 +02:00
//Main thread ID
static const DWORD g_main_thread_id = GetCurrentThreadId ( ) ;
2011-12-27 20:10:19 +01:00
//Log file
static FILE * g_lamexp_log_file = NULL ;
2010-11-06 23:04:47 +01:00
///////////////////////////////////////////////////////////////////////////////
// GLOBAL FUNCTIONS
///////////////////////////////////////////////////////////////////////////////
/*
* Version getters
*/
2011-01-20 22:54:10 +01:00
unsigned int lamexp_version_major ( void ) { return g_lamexp_version . ver_major ; }
unsigned int lamexp_version_minor ( void ) { return g_lamexp_version . ver_minor ; }
unsigned int lamexp_version_build ( void ) { return g_lamexp_version . ver_build ; }
const char * lamexp_version_release ( void ) { return g_lamexp_version . ver_release_name ; }
2011-07-26 22:17:14 +02:00
const char * lamexp_version_time ( void ) { return g_lamexp_version_raw_time ; }
const char * lamexp_version_compiler ( void ) { return g_lamexp_version_compiler ; }
const char * lamexp_version_arch ( void ) { return g_lamexp_version_arch ; }
2010-11-12 15:58:53 +01:00
unsigned int lamexp_toolver_neroaac ( void ) { return g_lamexp_toolver_neroaac ; }
2011-08-21 14:43:18 +02:00
unsigned int lamexp_toolver_fhgaacenc ( void ) { return g_lamexp_toolver_fhgaacenc ; }
2011-11-21 01:22:41 +01:00
unsigned int lamexp_toolver_qaacenc ( void ) { return g_lamexp_toolver_qaacenc ; }
2011-11-21 14:40:32 +01:00
unsigned int lamexp_toolver_coreaudio ( void ) { return g_lamexp_toolver_coreaudio ; }
2011-03-20 14:28:27 +01:00
/*
* URL getters
*/
2011-02-28 01:28:27 +01:00
const char * lamexp_website_url ( void ) { return g_lamexp_website_url ; }
2011-03-20 14:28:27 +01:00
const char * lamexp_support_url ( void ) { return g_lamexp_support_url ; }
2010-11-07 23:06:30 +01:00
2011-03-20 14:28:27 +01:00
/*
* Check for Demo ( pre - release ) version
*/
2010-11-07 23:06:30 +01:00
bool lamexp_version_demo ( void )
2011-02-12 22:17:42 +01:00
{
2011-04-16 21:21:08 +02:00
char buffer [ 128 ] ;
bool releaseVersion = false ;
2011-07-28 13:35:24 +02:00
if ( ! strncpy_s ( buffer , 128 , g_lamexp_version . ver_release_name , _TRUNCATE ) )
2011-04-16 21:21:08 +02:00
{
char * context , * prefix = strtok_s ( buffer , " -,; " , & context ) ;
if ( prefix )
{
releaseVersion = ( ! _stricmp ( prefix , " Final " ) ) | | ( ! _stricmp ( prefix , " Hotfix " ) ) ;
}
}
return LAMEXP_DEBUG | | ( ! releaseVersion ) ;
2010-11-07 23:06:30 +01:00
}
2010-11-06 23:04:47 +01:00
2011-03-20 14:28:27 +01:00
/*
* Calculate expiration date
*/
2011-01-20 22:06:59 +01:00
QDate lamexp_version_expires ( void )
{
2012-04-11 00:44:40 +02:00
return lamexp_version_date ( ) . addDays ( LAMEXP_DEBUG ? 7 : 30 ) ;
2011-01-20 22:06:59 +01:00
}
2010-11-06 23:04:47 +01:00
/*
* Get build date date
*/
const QDate & lamexp_version_date ( void )
{
if ( ! g_lamexp_version_date . isValid ( ) )
{
2012-01-02 00:52:27 +01:00
int date [ 3 ] = { 0 , 0 , 0 } ; char temp [ 12 ] = { ' \0 ' } ;
strncpy_s ( temp , 12 , g_lamexp_version_raw_date , _TRUNCATE ) ;
2010-11-06 23:04:47 +01:00
2012-01-02 00:52:27 +01:00
if ( strlen ( temp ) = = 11 )
2010-11-06 23:04:47 +01:00
{
2012-01-02 00:52:27 +01:00
temp [ 3 ] = temp [ 6 ] = ' \0 ' ;
date [ 2 ] = atoi ( & temp [ 4 ] ) ;
date [ 0 ] = atoi ( & temp [ 7 ] ) ;
for ( int j = 0 ; j < 12 ; j + + )
2010-11-06 23:04:47 +01:00
{
2012-01-02 00:52:27 +01:00
if ( ! _strcmpi ( & temp [ 0 ] , g_lamexp_months [ j ] ) )
2010-11-06 23:04:47 +01:00
{
2012-01-02 00:52:27 +01:00
date [ 1 ] = j + 1 ;
break ;
2010-11-06 23:04:47 +01:00
}
}
2012-01-02 00:52:27 +01:00
g_lamexp_version_date = QDate ( date [ 0 ] , date [ 1 ] , date [ 2 ] ) ;
2010-11-06 23:04:47 +01:00
}
2012-01-02 00:52:27 +01:00
if ( ! g_lamexp_version_date . isValid ( ) )
2010-11-06 23:04:47 +01:00
{
2012-01-02 00:52:27 +01:00
qFatal ( " Internal error: Date format could not be recognized! " ) ;
2010-11-06 23:04:47 +01:00
}
}
return g_lamexp_version_date ;
}
2011-10-14 18:02:37 +02:00
/*
* Get the native operating system version
*/
2011-10-21 16:17:22 +02:00
DWORD lamexp_get_os_version ( void )
2011-10-14 18:02:37 +02:00
{
2012-04-05 13:40:52 +02:00
static DWORD osVersion = 0 ;
2011-10-14 18:02:37 +02:00
2012-04-05 13:40:52 +02:00
if ( ! osVersion )
2011-10-14 18:02:37 +02:00
{
2012-04-05 13:40:52 +02:00
OSVERSIONINFO osVerInfo ;
memset ( & osVerInfo , 0 , sizeof ( OSVERSIONINFO ) ) ;
osVerInfo . dwOSVersionInfoSize = sizeof ( OSVERSIONINFO ) ;
if ( GetVersionEx ( & osVerInfo ) = = TRUE )
2011-10-14 18:02:37 +02:00
{
2012-04-05 13:40:52 +02:00
if ( osVerInfo . dwPlatformId ! = VER_PLATFORM_WIN32_NT )
{
throw " Ouuups: Not running under Windows NT. This is not supposed to happen! " ;
}
osVersion = ( DWORD ) ( ( osVerInfo . dwMajorVersion < < 16 ) | ( osVerInfo . dwMinorVersion & 0xffff ) ) ;
2011-10-14 18:02:37 +02:00
}
}
2012-04-05 13:40:52 +02:00
return osVersion ;
}
/*
* Check if we are running under wine
*/
bool lamexp_detect_wine ( void )
{
static bool isWine = false ;
static bool isWine_initialized = false ;
if ( ! isWine_initialized )
{
QLibrary ntdll ( " ntdll.dll " ) ;
if ( ntdll . load ( ) )
{
if ( ntdll . resolve ( " wine_nt_to_unix_file_name " ) ! = NULL ) isWine = true ;
if ( ntdll . resolve ( " wine_get_version " ) ! = NULL ) isWine = true ;
ntdll . unload ( ) ;
}
isWine_initialized = true ;
}
return isWine ;
2011-10-14 18:02:37 +02:00
}
2011-04-17 15:53:28 +02:00
/*
* Global exception handler
*/
LONG WINAPI lamexp_exception_handler ( __in struct _EXCEPTION_POINTERS * ExceptionInfo )
{
2011-04-24 23:18:00 +02:00
if ( GetCurrentThreadId ( ) ! = g_main_thread_id )
{
HANDLE mainThread = OpenThread ( THREAD_TERMINATE , FALSE , g_main_thread_id ) ;
if ( mainThread ) TerminateThread ( mainThread , ULONG_MAX ) ;
}
2011-08-25 03:44:46 +02:00
FatalAppExit ( 0 , L " Unhandeled exception handler invoked, application will exit! " ) ;
2011-04-17 15:53:28 +02:00
TerminateProcess ( GetCurrentProcess ( ) , - 1 ) ;
2011-04-24 23:18:00 +02:00
return LONG_MAX ;
2011-04-17 15:53:28 +02:00
}
2011-07-28 13:35:24 +02:00
/*
* Invalid parameters handler
*/
2011-07-26 22:17:14 +02:00
void lamexp_invalid_param_handler ( const wchar_t * , const wchar_t * , const wchar_t * , unsigned int , uintptr_t )
{
if ( GetCurrentThreadId ( ) ! = g_main_thread_id )
{
HANDLE mainThread = OpenThread ( THREAD_TERMINATE , FALSE , g_main_thread_id ) ;
if ( mainThread ) TerminateThread ( mainThread , ULONG_MAX ) ;
}
FatalAppExit ( 0 , L " Invalid parameter handler invoked, application will exit! " ) ;
TerminateProcess ( GetCurrentProcess ( ) , - 1 ) ;
}
2011-07-28 13:35:24 +02:00
/*
* Change console text color
*/
static void lamexp_console_color ( FILE * file , WORD attributes )
{
const HANDLE hConsole = ( HANDLE ) ( _get_osfhandle ( _fileno ( file ) ) ) ;
if ( ( hConsole ! = NULL ) & & ( hConsole ! = INVALID_HANDLE_VALUE ) )
{
SetConsoleTextAttribute ( hConsole , attributes ) ;
}
}
2010-11-19 13:31:45 +01:00
/*
* Qt message handler
*/
void lamexp_message_handler ( QtMsgType type , const char * msg )
{
2011-03-12 01:50:43 +01:00
static const char * GURU_MEDITATION = " \n \n GURU MEDITATION !!! \n \n " ;
QMutexLocker lock ( & g_lamexp_message_mutex ) ;
2011-03-10 02:07:51 +01:00
2011-12-27 20:10:19 +01:00
if ( g_lamexp_log_file )
{
static char prefix [ ] = " DWCF " ;
int index = qBound ( 0 , static_cast < int > ( type ) , 3 ) ;
2011-12-29 14:42:20 +01:00
unsigned int timestamp = static_cast < unsigned int > ( _time64 ( NULL ) % 3600 I64 ) ;
2011-12-27 20:10:19 +01:00
QString str = QString : : fromUtf8 ( msg ) . trimmed ( ) . replace ( ' \n ' , ' \t ' ) ;
2011-12-29 14:42:20 +01:00
fprintf ( g_lamexp_log_file , " [%c][%04u] %s \r \n " , prefix [ index ] , timestamp , str . toUtf8 ( ) . constData ( ) ) ;
2011-12-27 20:10:19 +01:00
fflush ( g_lamexp_log_file ) ;
}
2010-11-19 13:31:45 +01:00
2011-07-28 13:35:24 +02:00
if ( g_lamexp_console_attached )
2010-11-19 13:31:45 +01:00
{
2011-08-04 00:55:17 +02:00
UINT oldOutputCP = GetConsoleOutputCP ( ) ;
if ( oldOutputCP ! = CP_UTF8 ) SetConsoleOutputCP ( CP_UTF8 ) ;
2011-03-04 23:40:09 +01:00
switch ( type )
{
case QtCriticalMsg :
case QtFatalMsg :
fflush ( stdout ) ;
fflush ( stderr ) ;
2011-07-28 13:35:24 +02:00
lamexp_console_color ( stderr , FOREGROUND_RED | FOREGROUND_INTENSITY ) ;
fprintf ( stderr , GURU_MEDITATION ) ;
2011-09-29 20:06:09 +02:00
fprintf ( stderr , " %s \n " , msg ) ;
2011-07-28 13:35:24 +02:00
fflush ( stderr ) ;
2011-03-04 23:40:09 +01:00
break ;
case QtWarningMsg :
2011-07-28 13:35:24 +02:00
lamexp_console_color ( stderr , FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY ) ;
2011-09-29 20:06:09 +02:00
fprintf ( stderr , " %s \n " , msg ) ;
2011-07-28 13:35:24 +02:00
fflush ( stderr ) ;
2011-03-04 23:40:09 +01:00
break ;
default :
2011-07-28 13:35:24 +02:00
lamexp_console_color ( stderr , FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY ) ;
2011-09-29 20:06:09 +02:00
fprintf ( stderr , " %s \n " , msg ) ;
2011-07-28 13:35:24 +02:00
fflush ( stderr ) ;
2011-03-04 23:40:09 +01:00
break ;
}
2011-07-28 13:35:24 +02:00
lamexp_console_color ( stderr , FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ) ;
2011-08-04 00:55:17 +02:00
if ( oldOutputCP ! = CP_UTF8 ) SetConsoleOutputCP ( oldOutputCP ) ;
2010-11-19 13:31:45 +01:00
}
2011-03-04 23:40:09 +01:00
else
{
2011-09-29 20:06:09 +02:00
QString temp ( " [LameXP][%1] %2 " ) ;
2011-07-28 13:35:24 +02:00
2011-03-04 23:40:09 +01:00
switch ( type )
{
case QtCriticalMsg :
case QtFatalMsg :
2011-09-29 20:06:09 +02:00
temp = temp . arg ( " C " , QString : : fromUtf8 ( msg ) ) ;
2011-03-04 23:40:09 +01:00
break ;
case QtWarningMsg :
2011-09-29 20:06:09 +02:00
temp = temp . arg ( " W " , QString : : fromUtf8 ( msg ) ) ;
2011-03-04 23:40:09 +01:00
break ;
default :
2011-09-29 20:06:09 +02:00
temp = temp . arg ( " I " , QString : : fromUtf8 ( msg ) ) ;
2011-03-04 23:40:09 +01:00
break ;
}
2011-09-29 20:06:09 +02:00
temp . replace ( " \n " , " \t " ) . append ( " \n " ) ;
OutputDebugStringA ( temp . toLatin1 ( ) . constData ( ) ) ;
2011-03-04 23:40:09 +01:00
}
2010-11-19 13:31:45 +01:00
if ( type = = QtCriticalMsg | | type = = QtFatalMsg )
{
2010-11-20 03:11:12 +01:00
lock . unlock ( ) ;
2012-02-24 22:12:28 +01:00
if ( GetCurrentThreadId ( ) ! = g_main_thread_id )
{
HANDLE mainThread = OpenThread ( THREAD_TERMINATE , FALSE , g_main_thread_id ) ;
if ( mainThread ) TerminateThread ( mainThread , ULONG_MAX ) ;
}
2011-09-29 20:06:09 +02:00
MessageBoxW ( NULL , QWCHAR ( QString : : fromUtf8 ( msg ) ) , L " LameXP - GURU MEDITATION " , MB_ICONERROR | MB_TOPMOST | MB_TASKMODAL ) ;
2010-11-19 13:31:45 +01:00
FatalAppExit ( 0 , L " The application has encountered a critical error and will exit now! " ) ;
TerminateProcess ( GetCurrentProcess ( ) , - 1 ) ;
}
2011-03-10 02:07:51 +01:00
}
2010-11-19 13:31:45 +01:00
2010-11-07 23:06:30 +01:00
/*
* Initialize the console
*/
void lamexp_init_console ( int argc , char * argv [ ] )
{
2011-02-14 19:03:36 +01:00
bool enableConsole = lamexp_version_demo ( ) ;
2011-03-12 21:58:46 +01:00
2011-12-27 20:10:19 +01:00
if ( _environ )
{
wchar_t * logfile = NULL ;
size_t logfile_len = 0 ;
if ( ! _wdupenv_s ( & logfile , & logfile_len , L " LAMEXP_LOGFILE " ) )
{
2011-12-29 14:42:20 +01:00
if ( logfile & & ( logfile_len > 0 ) )
2011-12-27 20:10:19 +01:00
{
2011-12-29 14:42:20 +01:00
FILE * temp = NULL ;
if ( ! _wfopen_s ( & temp , logfile , L " wb " ) )
{
fprintf ( temp , " %c%c%c " , 0xEF , 0xBB , 0xBF ) ;
g_lamexp_log_file = temp ;
}
free ( logfile ) ;
2011-12-27 20:10:19 +01:00
}
}
}
2011-03-25 16:17:19 +01:00
if ( ! LAMEXP_DEBUG )
2010-11-07 23:06:30 +01:00
{
2011-03-25 16:17:19 +01:00
for ( int i = 0 ; i < argc ; i + + )
2010-11-07 23:06:30 +01:00
{
2011-03-25 16:17:19 +01:00
if ( ! _stricmp ( argv [ i ] , " --console " ) )
{
enableConsole = true ;
}
else if ( ! _stricmp ( argv [ i ] , " --no-console " ) )
{
enableConsole = false ;
}
2011-02-14 19:03:36 +01:00
}
}
2010-11-07 23:06:30 +01:00
2011-02-14 19:03:36 +01:00
if ( enableConsole )
{
2011-03-04 23:40:09 +01:00
if ( ! g_lamexp_console_attached )
{
2011-07-28 13:35:24 +02:00
if ( AllocConsole ( ) ! = FALSE )
{
2011-08-04 00:55:17 +02:00
SetConsoleCtrlHandler ( NULL , TRUE ) ;
SetConsoleTitle ( L " LameXP - Audio Encoder Front-End | Debug Console " ) ;
SetConsoleOutputCP ( CP_UTF8 ) ;
2011-07-28 13:35:24 +02:00
g_lamexp_console_attached = true ;
}
2011-03-04 23:40:09 +01:00
}
if ( g_lamexp_console_attached )
2011-02-14 19:03:36 +01:00
{
//-------------------------------------------------------------------
//See: http://support.microsoft.com/default.aspx?scid=kb;en-us;105305
//-------------------------------------------------------------------
2011-08-04 00:55:17 +02:00
const int flags = _O_WRONLY | _O_U8TEXT ;
int hCrtStdOut = _open_osfhandle ( ( intptr_t ) GetStdHandle ( STD_OUTPUT_HANDLE ) , flags ) ;
int hCrtStdErr = _open_osfhandle ( ( intptr_t ) GetStdHandle ( STD_ERROR_HANDLE ) , flags ) ;
2011-09-27 21:32:45 +02:00
FILE * hfStdOut = ( hCrtStdOut > = 0 ) ? _fdopen ( hCrtStdOut , " wb " ) : NULL ;
FILE * hfStdErr = ( hCrtStdErr > = 0 ) ? _fdopen ( hCrtStdErr , " wb " ) : NULL ;
if ( hfStdOut ) { * stdout = * hfStdOut ; std : : cout . rdbuf ( new std : : filebuf ( hfStdOut ) ) ; }
if ( hfStdErr ) { * stderr = * hfStdErr ; std : : cerr . rdbuf ( new std : : filebuf ( hfStdErr ) ) ; }
2010-11-07 23:06:30 +01:00
}
2011-02-14 19:03:36 +01:00
2011-07-28 13:35:24 +02:00
HWND hwndConsole = GetConsoleWindow ( ) ;
if ( ( hwndConsole ! = NULL ) & & ( hwndConsole ! = INVALID_HANDLE_VALUE ) )
2011-03-04 23:40:09 +01:00
{
HMENU hMenu = GetSystemMenu ( hwndConsole , 0 ) ;
EnableMenuItem ( hMenu , SC_CLOSE , MF_BYCOMMAND | MF_GRAYED ) ;
RemoveMenu ( hMenu , SC_CLOSE , MF_BYCOMMAND ) ;
2011-08-26 03:28:34 +02:00
SetWindowPos ( hwndConsole , HWND_TOP , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED ) ;
SetWindowLong ( hwndConsole , GWL_STYLE , GetWindowLong ( hwndConsole , GWL_STYLE ) & ( ~ WS_MAXIMIZEBOX ) & ( ~ WS_MINIMIZEBOX ) ) ;
SetWindowPos ( hwndConsole , HWND_TOP , 0 , 0 , 0 , 0 , SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED ) ;
2011-03-04 23:40:09 +01:00
}
2010-11-07 23:06:30 +01:00
}
}
2010-11-15 04:42:06 +01:00
/*
* Detect CPU features
*/
2011-09-20 00:03:51 +02:00
lamexp_cpu_t lamexp_detect_cpu_features ( int argc , char * * argv )
2010-11-15 04:42:06 +01:00
{
2010-11-25 16:56:32 +01:00
typedef BOOL ( WINAPI * IsWow64ProcessFun ) ( __in HANDLE hProcess , __out PBOOL Wow64Process ) ;
typedef VOID ( WINAPI * GetNativeSystemInfoFun ) ( __out LPSYSTEM_INFO lpSystemInfo ) ;
static IsWow64ProcessFun IsWow64ProcessPtr = NULL ;
static GetNativeSystemInfoFun GetNativeSystemInfoPtr = NULL ;
2010-11-15 04:42:06 +01:00
2010-11-25 16:56:32 +01:00
lamexp_cpu_t features ;
SYSTEM_INFO systemInfo ;
2010-11-15 04:42:06 +01:00
int CPUInfo [ 4 ] = { - 1 } ;
2010-11-26 00:29:53 +01:00
char CPUIdentificationString [ 0x40 ] ;
2010-11-25 16:56:32 +01:00
char CPUBrandString [ 0x40 ] ;
2011-02-07 22:01:06 +01:00
2010-11-25 16:56:32 +01:00
memset ( & features , 0 , sizeof ( lamexp_cpu_t ) ) ;
memset ( & systemInfo , 0 , sizeof ( SYSTEM_INFO ) ) ;
2010-11-26 00:29:53 +01:00
memset ( CPUIdentificationString , 0 , sizeof ( CPUIdentificationString ) ) ;
2010-11-25 16:56:32 +01:00
memset ( CPUBrandString , 0 , sizeof ( CPUBrandString ) ) ;
2010-11-15 04:42:06 +01:00
__cpuid ( CPUInfo , 0 ) ;
2010-11-26 00:29:53 +01:00
memcpy ( CPUIdentificationString , & CPUInfo [ 1 ] , sizeof ( int ) ) ;
memcpy ( CPUIdentificationString + 4 , & CPUInfo [ 3 ] , sizeof ( int ) ) ;
memcpy ( CPUIdentificationString + 8 , & CPUInfo [ 2 ] , sizeof ( int ) ) ;
features . intel = ( _stricmp ( CPUIdentificationString , " GenuineIntel " ) = = 0 ) ;
2011-07-28 13:35:24 +02:00
strncpy_s ( features . vendor , 0x40 , CPUIdentificationString , _TRUNCATE ) ;
2010-11-26 00:29:53 +01:00
2010-11-15 04:42:06 +01:00
if ( CPUInfo [ 0 ] > = 1 )
{
__cpuid ( CPUInfo , 1 ) ;
features . mmx = ( CPUInfo [ 3 ] & 0x800000 ) | | false ;
features . sse = ( CPUInfo [ 3 ] & 0x2000000 ) | | false ;
features . sse2 = ( CPUInfo [ 3 ] & 0x4000000 ) | | false ;
features . ssse3 = ( CPUInfo [ 2 ] & 0x200 ) | | false ;
features . sse3 = ( CPUInfo [ 2 ] & 0x1 ) | | false ;
features . ssse3 = ( CPUInfo [ 2 ] & 0x200 ) | | false ;
features . stepping = CPUInfo [ 0 ] & 0xf ;
features . model = ( ( CPUInfo [ 0 ] > > 4 ) & 0xf ) + ( ( ( CPUInfo [ 0 ] > > 16 ) & 0xf ) < < 4 ) ;
features . family = ( ( CPUInfo [ 0 ] > > 8 ) & 0xf ) + ( ( CPUInfo [ 0 ] > > 20 ) & 0xff ) ;
}
__cpuid ( CPUInfo , 0x80000000 ) ;
2011-11-08 15:12:31 +01:00
int nExIds = qMax < int > ( qMin < int > ( CPUInfo [ 0 ] , 0x80000004 ) , 0x80000000 ) ;
2010-11-15 04:42:06 +01:00
2011-02-07 22:01:06 +01:00
for ( int i = 0x80000002 ; i < = nExIds ; + + i )
2010-11-15 04:42:06 +01:00
{
__cpuid ( CPUInfo , i ) ;
2011-02-07 22:01:06 +01:00
switch ( i )
{
case 0x80000002 :
memcpy ( CPUBrandString , CPUInfo , sizeof ( CPUInfo ) ) ;
break ;
case 0x80000003 :
memcpy ( CPUBrandString + 16 , CPUInfo , sizeof ( CPUInfo ) ) ;
break ;
case 0x80000004 :
memcpy ( CPUBrandString + 32 , CPUInfo , sizeof ( CPUInfo ) ) ;
break ;
}
2010-11-15 04:42:06 +01:00
}
2011-07-28 13:35:24 +02:00
strncpy_s ( features . brand , 0x40 , CPUBrandString , _TRUNCATE ) ;
2010-11-15 14:02:58 +01:00
2011-07-28 13:35:24 +02:00
if ( strlen ( features . brand ) < 1 ) strncpy_s ( features . brand , 0x40 , " Unknown " , _TRUNCATE ) ;
if ( strlen ( features . vendor ) < 1 ) strncpy_s ( features . vendor , 0x40 , " Unknown " , _TRUNCATE ) ;
2011-02-07 22:01:06 +01:00
2010-11-25 16:56:32 +01:00
# if !defined(_M_X64 ) && !defined(_M_IA64)
if ( ! IsWow64ProcessPtr | | ! GetNativeSystemInfoPtr )
2010-11-15 14:02:58 +01:00
{
2010-11-25 16:56:32 +01:00
QLibrary Kernel32Lib ( " kernel32.dll " ) ;
IsWow64ProcessPtr = ( IsWow64ProcessFun ) Kernel32Lib . resolve ( " IsWow64Process " ) ;
GetNativeSystemInfoPtr = ( GetNativeSystemInfoFun ) Kernel32Lib . resolve ( " GetNativeSystemInfo " ) ;
2010-11-15 14:02:58 +01:00
}
2010-11-25 16:56:32 +01:00
if ( IsWow64ProcessPtr )
{
BOOL x64 = FALSE ;
if ( IsWow64ProcessPtr ( GetCurrentProcess ( ) , & x64 ) )
{
features . x64 = x64 ;
}
}
if ( GetNativeSystemInfoPtr )
{
GetNativeSystemInfoPtr ( & systemInfo ) ;
}
else
{
GetSystemInfo ( & systemInfo ) ;
}
2011-11-16 22:53:18 +01:00
features . count = qBound ( 1UL , systemInfo . dwNumberOfProcessors , 64UL ) ;
2010-11-25 16:56:32 +01:00
# else
2010-11-15 14:02:58 +01:00
GetNativeSystemInfo ( & systemInfo ) ;
features . count = systemInfo . dwNumberOfProcessors ;
2010-11-25 16:56:32 +01:00
features . x64 = true ;
# endif
2010-11-15 14:02:58 +01:00
2011-10-21 16:17:22 +02:00
if ( ( argv ! = NULL ) & & ( argc > 0 ) )
2011-09-20 00:03:51 +02:00
{
2011-09-30 20:17:42 +02:00
bool flag = false ;
2011-09-20 00:03:51 +02:00
for ( int i = 0 ; i < argc ; i + + )
{
2011-09-30 20:17:42 +02:00
if ( ! _stricmp ( " --force-cpu-no-64bit " , argv [ i ] ) ) { flag = true ; features . x64 = false ; }
if ( ! _stricmp ( " --force-cpu-no-sse " , argv [ i ] ) ) { flag = true ; features . sse = features . sse2 = features . sse3 = features . ssse3 = false ; }
if ( ! _stricmp ( " --force-cpu-no-intel " , argv [ i ] ) ) { flag = true ; features . intel = false ; }
2011-09-20 00:03:51 +02:00
}
2011-09-30 20:17:42 +02:00
if ( flag ) qWarning ( " CPU flags overwritten by user-defined parameters. Take care! \n " ) ;
2011-09-20 00:03:51 +02:00
}
2010-11-15 04:42:06 +01:00
return features ;
}
2011-06-22 01:10:53 +02:00
/*
* Check for debugger ( detect routine )
*/
2012-03-26 04:40:49 +02:00
static __forceinline bool lamexp_check_for_debugger ( void )
2011-06-22 01:10:53 +02:00
{
2012-03-26 04:40:49 +02:00
if ( IsDebuggerPresent ( ) )
{
return true ;
}
__try
{
CloseHandle ( ( HANDLE ) 0x7FFFFFFF ) ;
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
return true ;
}
2011-06-22 01:10:53 +02:00
__try
{
DebugBreak ( ) ;
}
2012-03-26 04:40:49 +02:00
__except ( EXCEPTION_EXECUTE_HANDLER )
2011-06-22 01:10:53 +02:00
{
return false ;
}
2012-03-26 04:40:49 +02:00
2011-06-22 01:10:53 +02:00
return true ;
}
2010-11-15 04:42:06 +01:00
/*
2011-04-19 16:14:05 +02:00
* Check for debugger ( thread proc )
2010-11-15 04:42:06 +01:00
*/
2012-03-26 04:40:49 +02:00
static unsigned int __stdcall lamexp_debug_thread_proc ( LPVOID lpParameter )
2010-11-15 04:42:06 +01:00
{
2012-03-26 04:40:49 +02:00
while ( ! lamexp_check_for_debugger ( ) )
{
Sleep ( 32 ) ;
}
if ( HANDLE thrd = OpenThread ( THREAD_TERMINATE , FALSE , g_main_thread_id ) )
2010-11-15 04:42:06 +01:00
{
2012-03-26 04:40:49 +02:00
if ( TerminateThread ( thrd , - 1 ) )
{
FatalAppExit ( 0 , L " Not a debug build. Please unload debugger and try again! " ) ;
}
CloseHandle ( thrd ) ;
2010-11-15 04:42:06 +01:00
}
TerminateProcess ( GetCurrentProcess ( ) , - 1 ) ;
2012-03-26 04:40:49 +02:00
return 666 ;
2010-11-15 04:42:06 +01:00
}
2011-04-19 16:14:05 +02:00
/*
* Check for debugger ( startup routine )
*/
static HANDLE lamexp_debug_thread_init ( void )
2011-02-18 00:53:36 +01:00
{
2012-03-26 04:40:49 +02:00
if ( lamexp_check_for_debugger ( ) )
2011-02-18 00:53:36 +01:00
{
FatalAppExit ( 0 , L " Not a debug build. Please unload debugger and try again! " ) ;
TerminateProcess ( GetCurrentProcess ( ) , - 1 ) ;
}
2011-06-22 01:10:53 +02:00
2012-03-26 04:40:49 +02:00
return ( HANDLE ) _beginthreadex ( NULL , 0 , lamexp_debug_thread_proc , NULL , 0 , NULL ) ;
2011-02-18 00:53:36 +01:00
}
2010-11-15 04:42:06 +01:00
2010-12-23 03:13:11 +01:00
/*
* Check for compatibility mode
*/
2011-03-08 01:12:40 +01:00
static bool lamexp_check_compatibility_mode ( const char * exportName , const char * executableName )
2010-12-23 03:13:11 +01:00
{
QLibrary kernel32 ( " kernel32.dll " ) ;
2010-12-27 01:50:22 +01:00
if ( exportName ! = NULL )
{
if ( kernel32 . resolve ( exportName ) ! = NULL )
{
2011-03-08 01:12:40 +01:00
qWarning ( " Function '%s' exported from 'kernel32.dll' -> Windows compatibility mode! " , exportName ) ;
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' doesn't support Windows compatibility mode. " ) . arg ( QString : : fromLatin1 ( executableName ) ) . toLatin1 ( ) . constData ( ) ) ;
2010-12-27 01:50:22 +01:00
return false ;
}
}
return true ;
}
2011-12-24 20:04:49 +01:00
/*
* Computus according to H . Lichtenberg
*/
static bool lamexp_computus ( const QDate & date )
{
int X = date . year ( ) ;
int A = X % 19 ;
int K = X / 100 ;
int M = 15 + ( 3 * K + 3 ) / 4 - ( 8 * K + 13 ) / 25 ;
int D = ( 19 * A + M ) % 30 ;
int S = 2 - ( 3 * K + 3 ) / 4 ;
int R = D / 29 + ( D / 28 - D / 29 ) * ( A / 11 ) ;
int OG = 21 + D - R ;
int SZ = 7 - ( X + X / 4 + S ) % 7 ;
int OE = 7 - ( OG - SZ ) % 7 ;
int OS = ( OG + OE ) ;
if ( OS > 31 )
{
return ( date . month ( ) = = 4 ) & & ( date . day ( ) = = ( OS - 31 ) ) ;
}
else
{
return ( date . month ( ) = = 3 ) & & ( date . day ( ) = = OS ) ;
}
}
2011-12-25 22:29:04 +01:00
/*
* Check for Thanksgiving
*/
static bool lamexp_thanksgiving ( const QDate & date )
{
int day = 0 ;
switch ( QDate ( date . year ( ) , 11 , 1 ) . dayOfWeek ( ) )
{
case 1 : day = 25 ; break ;
case 2 : day = 24 ; break ;
case 3 : day = 23 ; break ;
case 4 : day = 22 ; break ;
case 5 : day = 28 ; break ;
case 6 : day = 27 ; break ;
case 7 : day = 26 ; break ;
}
return ( date . month ( ) = = 11 ) & & ( date . day ( ) = = day ) ;
}
2011-12-24 20:04:49 +01:00
/*
* Initialize app icon
*/
2011-12-26 21:02:55 +01:00
QIcon lamexp_app_icon ( const QDate * date , const QTime * time )
2011-12-24 20:04:49 +01:00
{
2011-12-26 21:02:55 +01:00
QDate currentDate = ( date ) ? QDate ( * date ) : QDate : : currentDate ( ) ;
QTime currentTime = ( time ) ? QTime ( * time ) : QTime : : currentTime ( ) ;
if ( lamexp_thanksgiving ( currentDate ) )
2011-12-25 22:29:04 +01:00
{
return QIcon ( " :/MainIcon6.png " ) ;
}
2011-12-26 21:02:55 +01:00
else if ( ( ( currentDate . month ( ) = = 12 ) & & ( currentDate . day ( ) = = 31 ) & & ( currentTime . hour ( ) > = 20 ) ) | | ( ( currentDate . month ( ) = = 1 ) & & ( currentDate . day ( ) = = 1 ) & & ( currentTime . hour ( ) < = 19 ) ) )
2011-12-24 20:04:49 +01:00
{
return QIcon ( " :/MainIcon5.png " ) ;
}
2011-12-26 21:02:55 +01:00
else if ( ( ( currentDate . month ( ) = = 10 ) & & ( currentDate . day ( ) = = 31 ) & & ( currentTime . hour ( ) > = 12 ) ) | | ( ( currentDate . month ( ) = = 11 ) & & ( currentDate . day ( ) = = 1 ) & & ( currentTime . hour ( ) < = 11 ) ) )
2011-12-24 20:04:49 +01:00
{
return QIcon ( " :/MainIcon4.png " ) ;
}
2011-12-26 21:02:55 +01:00
else if ( ( currentDate . month ( ) = = 12 ) & & ( currentDate . day ( ) > = 24 ) & & ( currentDate . day ( ) < = 26 ) )
2011-12-24 20:04:49 +01:00
{
return QIcon ( " :/MainIcon3.png " ) ;
}
2011-12-26 21:02:55 +01:00
else if ( lamexp_computus ( currentDate ) )
2011-12-24 20:04:49 +01:00
{
return QIcon ( " :/MainIcon2.png " ) ;
}
else
{
return QIcon ( " :/MainIcon1.png " ) ;
}
}
2011-12-27 05:04:53 +01:00
/*
2011-12-29 14:42:20 +01:00
* Broadcast event to all windows
2011-12-27 05:04:53 +01:00
*/
2011-12-29 14:42:20 +01:00
static bool lamexp_broadcast ( int eventType , bool onlyToVisible )
2011-12-27 05:04:53 +01:00
{
2011-12-29 14:42:20 +01:00
if ( QApplication * app = dynamic_cast < QApplication * > ( QApplication : : instance ( ) ) )
2011-12-27 05:04:53 +01:00
{
2011-12-29 14:42:20 +01:00
qDebug ( " Broadcasting %d " , eventType ) ;
bool allOk = true ;
QEvent poEvent ( static_cast < QEvent : : Type > ( eventType ) ) ;
QWidgetList list = app - > topLevelWidgets ( ) ;
while ( ! list . isEmpty ( ) )
2011-12-27 05:04:53 +01:00
{
2011-12-29 14:42:20 +01:00
QWidget * widget = list . takeFirst ( ) ;
if ( ! onlyToVisible | | widget - > isVisible ( ) )
2011-12-27 05:04:53 +01:00
{
2011-12-29 14:42:20 +01:00
if ( ! app - > sendEvent ( widget , & poEvent ) )
2011-12-27 05:04:53 +01:00
{
2011-12-29 14:42:20 +01:00
allOk = false ;
2011-12-27 05:04:53 +01:00
}
}
}
2011-12-29 14:42:20 +01:00
qDebug ( " Broadcast %d done (%s) " , eventType , ( allOk ? " OK " : " Stopped " ) ) ;
return allOk ;
}
else
{
qWarning ( " Broadcast failed, could not get QApplication instance! " ) ;
return false ;
}
}
/*
* Qt event filter
*/
static bool lamexp_event_filter ( void * message , long * result )
{
2012-03-26 04:40:49 +02:00
if ( ( ! ( LAMEXP_DEBUG ) ) & & lamexp_check_for_debugger ( ) )
{
FatalAppExit ( 0 , L " Not a debug build. Please unload debugger and try again! " ) ;
TerminateProcess ( GetCurrentProcess ( ) , - 1 ) ;
}
2011-12-29 14:42:20 +01:00
switch ( reinterpret_cast < MSG * > ( message ) - > message )
{
case WM_QUERYENDSESSION :
qWarning ( " WM_QUERYENDSESSION message received! " ) ;
* result = lamexp_broadcast ( lamexp_event_queryendsession , false ) ? TRUE : FALSE ;
2011-12-27 05:04:53 +01:00
return true ;
case WM_ENDSESSION :
qWarning ( " WM_ENDSESSION message received! " ) ;
if ( reinterpret_cast < MSG * > ( message ) - > wParam = = TRUE )
{
2011-12-29 14:42:20 +01:00
lamexp_broadcast ( lamexp_event_endsession , false ) ;
2011-12-27 05:04:53 +01:00
if ( QApplication * app = reinterpret_cast < QApplication * > ( QApplication : : instance ( ) ) )
{
2011-12-29 14:42:20 +01:00
app - > closeAllWindows ( ) ;
2011-12-27 05:04:53 +01:00
app - > quit ( ) ;
}
2011-12-29 14:42:20 +01:00
lamexp_finalization ( ) ;
exit ( 1 ) ;
2011-12-27 05:04:53 +01:00
}
* result = 0 ;
return true ;
default :
/*ignore this message and let Qt handle it*/
return false ;
}
}
2010-12-27 01:50:22 +01:00
/*
* Check for process elevation
*/
static bool lamexp_check_elevation ( void )
{
2011-01-03 22:24:58 +01:00
typedef enum { lamexp_token_elevationType_class = 18 , lamexp_token_elevation_class = 20 } LAMEXP_TOKEN_INFORMATION_CLASS ;
typedef enum { lamexp_elevationType_default = 1 , lamexp_elevationType_full , lamexp_elevationType_limited } LAMEXP_TOKEN_ELEVATION_TYPE ;
2010-12-27 01:50:22 +01:00
HANDLE hToken = NULL ;
bool bIsProcessElevated = false ;
2010-12-23 03:13:11 +01:00
2010-12-27 01:50:22 +01:00
if ( OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_QUERY , & hToken ) )
2010-12-23 03:13:11 +01:00
{
2011-01-03 22:24:58 +01:00
LAMEXP_TOKEN_ELEVATION_TYPE tokenElevationType ;
2010-12-27 01:50:22 +01:00
DWORD returnLength ;
2011-01-03 22:24:58 +01:00
if ( GetTokenInformation ( hToken , ( TOKEN_INFORMATION_CLASS ) lamexp_token_elevationType_class , & tokenElevationType , sizeof ( LAMEXP_TOKEN_ELEVATION_TYPE ) , & returnLength ) )
2010-12-23 03:13:11 +01:00
{
2011-01-03 22:24:58 +01:00
if ( returnLength = = sizeof ( LAMEXP_TOKEN_ELEVATION_TYPE ) )
2010-12-23 03:13:11 +01:00
{
2011-01-03 22:24:58 +01:00
switch ( tokenElevationType )
{
case lamexp_elevationType_default :
qDebug ( " Process token elevation type: Default -> UAC is disabled. \n " ) ;
break ;
case lamexp_elevationType_full :
qWarning ( " Process token elevation type: Full -> potential security risk! \n " ) ;
bIsProcessElevated = true ;
break ;
case lamexp_elevationType_limited :
qDebug ( " Process token elevation type: Limited -> not elevated. \n " ) ;
break ;
}
2010-12-23 03:13:11 +01:00
}
}
2010-12-27 01:50:22 +01:00
CloseHandle ( hToken ) ;
}
else
{
qWarning ( " Failed to open process token! " ) ;
2010-12-23 03:13:11 +01:00
}
2010-12-27 01:50:22 +01:00
return ! bIsProcessElevated ;
2010-12-23 03:13:11 +01:00
}
2010-11-15 04:42:06 +01:00
2010-11-06 23:04:47 +01:00
/*
* Initialize Qt framework
*/
bool lamexp_init_qt ( int argc , char * argv [ ] )
{
static bool qt_initialized = false ;
2011-07-26 22:17:14 +02:00
typedef BOOL ( WINAPI * SetDllDirectoryProc ) ( WCHAR * lpPathName ) ;
2010-11-06 23:04:47 +01:00
//Don't initialized again, if done already
if ( qt_initialized )
{
return true ;
}
2011-07-26 22:17:14 +02:00
//Secure DLL loading
QLibrary kernel32 ( " kernel32.dll " ) ;
2011-07-27 22:17:43 +02:00
if ( kernel32 . load ( ) )
{
SetDllDirectoryProc pSetDllDirectory = ( SetDllDirectoryProc ) kernel32 . resolve ( " SetDllDirectoryW " ) ;
if ( pSetDllDirectory ! = NULL ) pSetDllDirectory ( L " " ) ;
kernel32 . unload ( ) ;
}
2011-07-26 22:17:14 +02:00
2011-03-08 01:12:40 +01:00
//Extract executable name from argv[] array
char * executableName = argv [ 0 ] ;
while ( char * temp = strpbrk ( executableName , " \\ /:? " ) )
{
executableName = temp + 1 ;
}
2010-11-06 23:04:47 +01:00
//Check Qt version
2012-04-11 00:44:40 +02:00
# ifdef QT_BUILD_KEY
2011-12-17 22:01:42 +01:00
qDebug ( " Using Qt v%s [%s], %s, %s " , qVersion ( ) , QLibraryInfo : : buildDate ( ) . toString ( Qt : : ISODate ) . toLatin1 ( ) . constData ( ) , ( qSharedBuild ( ) ? " DLL " : " Static " ) , QLibraryInfo : : buildKey ( ) . toLatin1 ( ) . constData ( ) ) ;
2011-12-17 15:56:24 +01:00
qDebug ( " Compiled with Qt v%s [%s], %s \n " , QT_VERSION_STR , QT_PACKAGEDATE_STR , QT_BUILD_KEY ) ;
2011-03-08 01:12:40 +01:00
if ( _stricmp ( qVersion ( ) , QT_VERSION_STR ) )
{
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' requires Qt v%2, but found Qt v%3. " ) . arg ( QString : : fromLatin1 ( executableName ) , QString : : fromLatin1 ( QT_VERSION_STR ) , QString : : fromLatin1 ( qVersion ( ) ) ) . toLatin1 ( ) . constData ( ) ) ;
return false ;
}
2011-12-17 15:56:24 +01:00
if ( QLibraryInfo : : buildKey ( ) . compare ( QString : : fromLatin1 ( QT_BUILD_KEY ) , Qt : : CaseInsensitive ) )
{
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' was built for Qt '%2', but found Qt '%3'. " ) . arg ( QString : : fromLatin1 ( executableName ) , QString : : fromLatin1 ( QT_BUILD_KEY ) , QLibraryInfo : : buildKey ( ) ) . toLatin1 ( ) . constData ( ) ) ;
return false ;
}
2012-04-11 00:44:40 +02:00
# else
qDebug ( " Using Qt v%s [%s], %s " , qVersion ( ) , QLibraryInfo : : buildDate ( ) . toString ( Qt : : ISODate ) . toLatin1 ( ) . constData ( ) , ( qSharedBuild ( ) ? " DLL " : " Static " ) ) ;
qDebug ( " Compiled with Qt v%s [%s] \n " , QT_VERSION_STR , QT_PACKAGEDATE_STR ) ;
# endif
2011-03-08 01:12:40 +01:00
2010-11-06 23:04:47 +01:00
//Check the Windows version
2010-11-11 19:37:16 +01:00
switch ( QSysInfo : : windowsVersion ( ) & QSysInfo : : WV_NT_based )
2010-11-06 23:04:47 +01:00
{
2011-08-26 16:32:25 +02:00
case 0 :
case QSysInfo : : WV_NT :
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' requires Windows 2000 or later. " ) . arg ( QString : : fromLatin1 ( executableName ) ) . toLatin1 ( ) . constData ( ) ) ;
break ;
2011-08-15 15:27:56 +02:00
case QSysInfo : : WV_2000 :
qDebug ( " Running on Windows 2000 (not officially supported!). \n " ) ;
lamexp_check_compatibility_mode ( " GetNativeSystemInfo " , executableName ) ;
break ;
2010-11-06 23:04:47 +01:00
case QSysInfo : : WV_XP :
2010-12-27 01:50:22 +01:00
qDebug ( " Running on Windows XP. \n " ) ;
2011-03-08 01:12:40 +01:00
lamexp_check_compatibility_mode ( " GetLargePageMinimum " , executableName ) ;
2010-11-06 23:04:47 +01:00
break ;
case QSysInfo : : WV_2003 :
2010-12-27 01:50:22 +01:00
qDebug ( " Running on Windows Server 2003 or Windows XP x64-Edition. \n " ) ;
2011-03-08 01:12:40 +01:00
lamexp_check_compatibility_mode ( " GetLocaleInfoEx " , executableName ) ;
2010-11-06 23:04:47 +01:00
break ;
case QSysInfo : : WV_VISTA :
2010-12-27 01:50:22 +01:00
qDebug ( " Running on Windows Vista or Windows Server 2008. \n " ) ;
2011-03-08 01:12:40 +01:00
lamexp_check_compatibility_mode ( " CreateRemoteThreadEx " , executableName ) ;
2010-11-06 23:04:47 +01:00
break ;
case QSysInfo : : WV_WINDOWS7 :
qDebug ( " Running on Windows 7 or Windows Server 2008 R2. \n " ) ;
2011-03-08 01:12:40 +01:00
lamexp_check_compatibility_mode ( NULL , executableName ) ;
2010-11-06 23:04:47 +01:00
break ;
default :
2011-10-14 18:02:37 +02:00
{
DWORD osVersionNo = lamexp_get_os_version ( ) ;
qWarning ( " Running on an unknown/untested WinNT-based OS (v%u.%u). \n " , HIWORD ( osVersionNo ) , LOWORD ( osVersionNo ) ) ;
}
2010-11-06 23:04:47 +01:00
break ;
}
2010-12-23 03:13:11 +01:00
2011-04-17 00:17:43 +02:00
//Check for Wine
2012-04-05 13:40:52 +02:00
if ( lamexp_detect_wine ( ) )
2011-07-27 22:17:43 +02:00
{
2012-04-05 13:40:52 +02:00
qWarning ( " It appears we are running under Wine, unexpected things might happen! \n " ) ;
2011-07-27 22:17:43 +02:00
}
2011-04-17 00:17:43 +02:00
2012-04-11 00:44:40 +02:00
//Set text Codec for locale
QTextCodec : : setCodecForLocale ( QTextCodec : : codecForName ( " UTF-8 " ) ) ;
2012-04-05 13:40:52 +02:00
2012-04-11 00:44:40 +02:00
//Create Qt application instance
2010-11-06 23:04:47 +01:00
QApplication * application = new QApplication ( argc , argv ) ;
2012-04-11 00:44:40 +02:00
//Load plugins from application directory
QCoreApplication : : setLibraryPaths ( QStringList ( ) < < QApplication : : applicationDirPath ( ) ) ;
qDebug ( " Library Path: \n %s \n " , QApplication : : libraryPaths ( ) . first ( ) . toUtf8 ( ) . constData ( ) ) ;
//Set application properties
2010-11-06 23:04:47 +01:00
application - > setApplicationName ( " LameXP - Audio Encoder Front-End " ) ;
application - > setApplicationVersion ( QString ( ) . sprintf ( " %d.%02d.%04d " , lamexp_version_major ( ) , lamexp_version_minor ( ) , lamexp_version_build ( ) ) ) ;
application - > setOrganizationName ( " LoRd_MuldeR " ) ;
2011-08-26 16:32:25 +02:00
application - > setOrganizationDomain ( " mulder.at.gg " ) ;
2011-12-26 21:02:55 +01:00
application - > setWindowIcon ( lamexp_app_icon ( ) ) ;
2011-12-27 05:04:53 +01:00
application - > setEventFilter ( lamexp_event_filter ) ;
2011-09-29 20:06:09 +02:00
//Set text Codec for locale
2012-04-11 00:44:40 +02:00
// QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
2011-09-29 20:06:09 +02:00
2010-11-06 23:04:47 +01:00
//Load plugins from application directory
2012-04-11 00:44:40 +02:00
// QCoreApplication::setLibraryPaths(QStringList() << QApplication::applicationDirPath());
// qDebug("Library Path:\n%s\n", QApplication::libraryPaths().first().toUtf8().constData());
2010-11-07 23:06:30 +01:00
2010-11-06 23:04:47 +01:00
//Check for supported image formats
QList < QByteArray > supportedFormats = QImageReader : : supportedImageFormats ( ) ;
2010-11-11 19:37:16 +01:00
for ( int i = 0 ; g_lamexp_imageformats [ i ] ; i + + )
2010-11-06 23:04:47 +01:00
{
2010-11-11 19:37:16 +01:00
if ( ! supportedFormats . contains ( g_lamexp_imageformats [ i ] ) )
{
2011-03-08 01:12:40 +01:00
qFatal ( " Qt initialization error: QImageIOHandler for '%s' missing! " , g_lamexp_imageformats [ i ] ) ;
2010-11-11 19:37:16 +01:00
return false ;
}
2010-11-06 23:04:47 +01:00
}
2010-12-30 16:12:21 +01:00
2011-01-04 19:58:18 +01:00
//Add default translations
2011-01-21 00:10:51 +01:00
g_lamexp_translation . files . insert ( LAMEXP_DEFAULT_LANGID , " " ) ;
g_lamexp_translation . names . insert ( LAMEXP_DEFAULT_LANGID , " English " ) ;
2011-01-04 19:58:18 +01:00
2010-12-27 01:50:22 +01:00
//Check for process elevation
2012-04-05 16:24:33 +02:00
if ( ( ! lamexp_check_elevation ( ) ) & & ( ! lamexp_detect_wine ( ) ) )
2010-12-27 01:50:22 +01:00
{
2012-04-10 03:51:04 +02:00
QMessageBox messageBox ( QMessageBox : : Warning , " LameXP " , " <nobr>LameXP was started with 'elevated' rights, altough LameXP does not need these rights.<br>Running an applications with unnecessary rights is a potential security risk!</nobr> " , QMessageBox : : NoButton , NULL , Qt : : Dialog | Qt : : MSWindowsFixedSizeDialogHint | Qt : : WindowStaysOnTopHint ) ;
messageBox . addButton ( " Quit Program (Recommended) " , QMessageBox : : NoRole ) ;
messageBox . addButton ( " Ignore " , QMessageBox : : NoRole ) ;
if ( messageBox . exec ( ) = = 0 )
2010-12-27 01:50:22 +01:00
{
return false ;
}
}
2011-03-18 01:12:17 +01:00
//Update console icon, if a console is attached
2012-04-11 00:44:40 +02:00
# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
2012-04-05 13:40:52 +02:00
if ( g_lamexp_console_attached & & ( ! lamexp_detect_wine ( ) ) )
2011-03-18 01:12:17 +01:00
{
typedef DWORD ( __stdcall * SetConsoleIconFun ) ( HICON ) ;
QLibrary kernel32 ( " kernel32.dll " ) ;
2011-07-27 22:17:43 +02:00
if ( kernel32 . load ( ) )
2011-03-18 01:12:17 +01:00
{
2011-07-27 22:17:43 +02:00
SetConsoleIconFun SetConsoleIconPtr = ( SetConsoleIconFun ) kernel32 . resolve ( " SetConsoleIcon " ) ;
if ( SetConsoleIconPtr ! = NULL ) SetConsoleIconPtr ( QIcon ( " :/icons/sound.png " ) . pixmap ( 16 , 16 ) . toWinHICON ( ) ) ;
kernel32 . unload ( ) ;
2011-03-18 01:12:17 +01:00
}
}
2012-04-11 00:44:40 +02:00
# endif
2011-03-18 01:12:17 +01:00
2010-11-06 23:04:47 +01:00
//Done
qt_initialized = true ;
return true ;
}
/*
2010-11-08 21:47:35 +01:00
* Initialize IPC
2010-11-06 23:04:47 +01:00
*/
2010-11-08 21:47:35 +01:00
int lamexp_init_ipc ( void )
2010-11-06 23:04:47 +01:00
{
2011-12-29 14:42:20 +01:00
if ( g_lamexp_ipc_ptr . sharedmem & & g_lamexp_ipc_ptr . semaphore_read & & g_lamexp_ipc_ptr . semaphore_write & & g_lamexp_ipc_ptr . semaphore_read_mutex & & g_lamexp_ipc_ptr . semaphore_write_mutex )
2010-11-06 23:04:47 +01:00
{
2010-11-08 21:47:35 +01:00
return 0 ;
2010-11-06 23:04:47 +01:00
}
2010-11-11 22:58:02 +01:00
2011-01-20 22:54:10 +01:00
g_lamexp_ipc_ptr . semaphore_read = new QSystemSemaphore ( QString ( g_lamexp_ipc_uuid . semaphore_read ) , 0 ) ;
g_lamexp_ipc_ptr . semaphore_write = new QSystemSemaphore ( QString ( g_lamexp_ipc_uuid . semaphore_write ) , 0 ) ;
2011-12-29 14:42:20 +01:00
g_lamexp_ipc_ptr . semaphore_read_mutex = new QSystemSemaphore ( QString ( g_lamexp_ipc_uuid . semaphore_read_mutex ) , 0 ) ;
g_lamexp_ipc_ptr . semaphore_write_mutex = new QSystemSemaphore ( QString ( g_lamexp_ipc_uuid . semaphore_write_mutex ) , 0 ) ;
2010-11-08 19:29:36 +01:00
2011-01-20 22:54:10 +01:00
if ( g_lamexp_ipc_ptr . semaphore_read - > error ( ) ! = QSystemSemaphore : : NoError )
2010-11-08 19:29:36 +01:00
{
2011-01-20 22:54:10 +01:00
QString errorMessage = g_lamexp_ipc_ptr . semaphore_read - > errorString ( ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write ) ;
2011-12-29 14:42:20 +01:00
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read_mutex ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write_mutex ) ;
2010-11-08 19:29:36 +01:00
qFatal ( " Failed to create system smaphore: %s " , errorMessage . toUtf8 ( ) . constData ( ) ) ;
2010-11-08 21:47:35 +01:00
return - 1 ;
2010-11-08 19:29:36 +01:00
}
2011-01-20 22:54:10 +01:00
if ( g_lamexp_ipc_ptr . semaphore_write - > error ( ) ! = QSystemSemaphore : : NoError )
2010-11-08 19:29:36 +01:00
{
2011-01-20 22:54:10 +01:00
QString errorMessage = g_lamexp_ipc_ptr . semaphore_write - > errorString ( ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write ) ;
2011-12-29 14:42:20 +01:00
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read_mutex ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write_mutex ) ;
qFatal ( " Failed to create system smaphore: %s " , errorMessage . toUtf8 ( ) . constData ( ) ) ;
return - 1 ;
}
if ( g_lamexp_ipc_ptr . semaphore_read_mutex - > error ( ) ! = QSystemSemaphore : : NoError )
{
QString errorMessage = g_lamexp_ipc_ptr . semaphore_read_mutex - > errorString ( ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read_mutex ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write_mutex ) ;
qFatal ( " Failed to create system smaphore: %s " , errorMessage . toUtf8 ( ) . constData ( ) ) ;
return - 1 ;
}
if ( g_lamexp_ipc_ptr . semaphore_write_mutex - > error ( ) ! = QSystemSemaphore : : NoError )
{
QString errorMessage = g_lamexp_ipc_ptr . semaphore_write_mutex - > errorString ( ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read_mutex ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write_mutex ) ;
2010-11-08 19:29:36 +01:00
qFatal ( " Failed to create system smaphore: %s " , errorMessage . toUtf8 ( ) . constData ( ) ) ;
2010-11-08 21:47:35 +01:00
return - 1 ;
2010-11-08 19:29:36 +01:00
}
2011-01-20 22:54:10 +01:00
g_lamexp_ipc_ptr . sharedmem = new QSharedMemory ( QString ( g_lamexp_ipc_uuid . sharedmem ) , NULL ) ;
2010-11-06 23:04:47 +01:00
2011-01-20 22:54:10 +01:00
if ( ! g_lamexp_ipc_ptr . sharedmem - > create ( sizeof ( lamexp_ipc_t ) ) )
2010-11-06 23:04:47 +01:00
{
2011-01-20 22:54:10 +01:00
if ( g_lamexp_ipc_ptr . sharedmem - > error ( ) = = QSharedMemory : : AlreadyExists )
2010-11-06 23:04:47 +01:00
{
2011-01-20 22:54:10 +01:00
g_lamexp_ipc_ptr . sharedmem - > attach ( ) ;
if ( g_lamexp_ipc_ptr . sharedmem - > error ( ) = = QSharedMemory : : NoError )
2010-11-08 19:29:36 +01:00
{
2010-11-08 21:47:35 +01:00
return 1 ;
2010-11-08 19:29:36 +01:00
}
else
{
2011-01-20 22:54:10 +01:00
QString errorMessage = g_lamexp_ipc_ptr . sharedmem - > errorString ( ) ;
2011-12-29 14:42:20 +01:00
LAMEXP_DELETE ( g_lamexp_ipc_ptr . sharedmem ) ;
2010-11-08 21:47:35 +01:00
qFatal ( " Failed to attach to shared memory: %s " , errorMessage . toUtf8 ( ) . constData ( ) ) ;
return - 1 ;
2010-11-08 19:29:36 +01:00
}
2010-11-06 23:04:47 +01:00
}
else
{
2011-01-20 22:54:10 +01:00
QString errorMessage = g_lamexp_ipc_ptr . sharedmem - > errorString ( ) ;
2011-12-29 14:42:20 +01:00
LAMEXP_DELETE ( g_lamexp_ipc_ptr . sharedmem ) ;
2010-11-07 23:06:30 +01:00
qFatal ( " Failed to create shared memory: %s " , errorMessage . toUtf8 ( ) . constData ( ) ) ;
2010-11-08 21:47:35 +01:00
return - 1 ;
2010-11-06 23:04:47 +01:00
}
}
2011-01-20 22:54:10 +01:00
memset ( g_lamexp_ipc_ptr . sharedmem - > data ( ) , 0 , sizeof ( lamexp_ipc_t ) ) ;
2011-12-29 14:42:20 +01:00
g_lamexp_ipc_ptr . semaphore_write - > release ( g_lamexp_ipc_slots ) ;
g_lamexp_ipc_ptr . semaphore_read_mutex - > release ( ) ;
g_lamexp_ipc_ptr . semaphore_write_mutex - > release ( ) ;
2010-11-08 19:29:36 +01:00
2010-11-08 21:47:35 +01:00
return 0 ;
2010-11-06 23:04:47 +01:00
}
2010-11-08 19:29:36 +01:00
/*
* IPC send message
*/
void lamexp_ipc_send ( unsigned int command , const char * message )
{
2011-12-29 14:42:20 +01:00
if ( ! g_lamexp_ipc_ptr . sharedmem | | ! g_lamexp_ipc_ptr . semaphore_read | | ! g_lamexp_ipc_ptr . semaphore_write | | ! g_lamexp_ipc_ptr . semaphore_read_mutex | | ! g_lamexp_ipc_ptr . semaphore_write_mutex )
2010-11-08 19:29:36 +01:00
{
throw " Shared memory for IPC not initialized yet. " ;
}
2011-12-29 14:42:20 +01:00
lamexp_ipc_data_t ipc_data ;
memset ( & ipc_data , 0 , sizeof ( lamexp_ipc_data_t ) ) ;
ipc_data . command = command ;
2010-11-09 22:06:11 +01:00
if ( message )
{
2011-12-29 14:42:20 +01:00
strncpy_s ( ipc_data . parameter , 4096 , message , _TRUNCATE ) ;
2010-11-09 22:06:11 +01:00
}
2010-11-08 19:29:36 +01:00
2011-01-20 22:54:10 +01:00
if ( g_lamexp_ipc_ptr . semaphore_write - > acquire ( ) )
2010-11-08 21:47:35 +01:00
{
2011-12-29 14:42:20 +01:00
if ( g_lamexp_ipc_ptr . semaphore_write_mutex - > acquire ( ) )
{
lamexp_ipc_t * ptr = reinterpret_cast < lamexp_ipc_t * > ( g_lamexp_ipc_ptr . sharedmem - > data ( ) ) ;
memcpy ( & ptr - > data [ ptr - > pos_write ] , & ipc_data , sizeof ( lamexp_ipc_data_t ) ) ;
ptr - > pos_write = ( ptr - > pos_write + 1 ) % g_lamexp_ipc_slots ;
g_lamexp_ipc_ptr . semaphore_read - > release ( ) ;
g_lamexp_ipc_ptr . semaphore_write_mutex - > release ( ) ;
}
2010-11-08 21:47:35 +01:00
}
2010-11-08 19:29:36 +01:00
}
/*
* IPC read message
*/
void lamexp_ipc_read ( unsigned int * command , char * message , size_t buffSize )
{
* command = 0 ;
message [ 0 ] = ' \0 ' ;
2011-12-29 14:42:20 +01:00
if ( ! g_lamexp_ipc_ptr . sharedmem | | ! g_lamexp_ipc_ptr . semaphore_read | | ! g_lamexp_ipc_ptr . semaphore_write | | ! g_lamexp_ipc_ptr . semaphore_read_mutex | | ! g_lamexp_ipc_ptr . semaphore_write_mutex )
2010-11-08 19:29:36 +01:00
{
throw " Shared memory for IPC not initialized yet. " ;
}
2011-12-29 14:42:20 +01:00
lamexp_ipc_data_t ipc_data ;
memset ( & ipc_data , 0 , sizeof ( lamexp_ipc_data_t ) ) ;
2010-11-08 19:29:36 +01:00
2011-01-20 22:54:10 +01:00
if ( g_lamexp_ipc_ptr . semaphore_read - > acquire ( ) )
2010-11-08 19:29:36 +01:00
{
2011-12-29 14:42:20 +01:00
if ( g_lamexp_ipc_ptr . semaphore_read_mutex - > acquire ( ) )
2010-11-08 21:47:35 +01:00
{
2011-12-29 14:42:20 +01:00
lamexp_ipc_t * ptr = reinterpret_cast < lamexp_ipc_t * > ( g_lamexp_ipc_ptr . sharedmem - > data ( ) ) ;
memcpy ( & ipc_data , & ptr - > data [ ptr - > pos_read ] , sizeof ( lamexp_ipc_data_t ) ) ;
ptr - > pos_read = ( ptr - > pos_read + 1 ) % g_lamexp_ipc_slots ;
g_lamexp_ipc_ptr . semaphore_write - > release ( ) ;
g_lamexp_ipc_ptr . semaphore_read_mutex - > release ( ) ;
if ( ! ( ipc_data . reserved_1 | | ipc_data . reserved_2 ) )
{
* command = ipc_data . command ;
strncpy_s ( message , buffSize , ipc_data . parameter , _TRUNCATE ) ;
}
else
{
qWarning ( " Malformed IPC message, will be ignored " ) ;
}
2010-11-08 21:47:35 +01:00
}
2010-11-08 19:29:36 +01:00
}
2010-11-08 21:47:35 +01:00
}
2011-01-24 00:04:07 +01:00
/*
* Check for LameXP " portable " mode
*/
bool lamexp_portable_mode ( void )
{
QString baseName = QFileInfo ( QApplication : : applicationFilePath ( ) ) . completeBaseName ( ) ;
2011-08-26 16:32:25 +02:00
int idx1 = baseName . indexOf ( " lamexp " , 0 , Qt : : CaseInsensitive ) ;
int idx2 = baseName . lastIndexOf ( " portable " , - 1 , Qt : : CaseInsensitive ) ;
return ( idx1 > = 0 ) & & ( idx2 > = 0 ) & & ( idx1 < idx2 ) ;
2011-01-24 00:04:07 +01:00
}
2010-12-07 22:58:28 +01:00
/*
* Get a random string
*/
QString lamexp_rand_str ( void )
{
QRegExp regExp ( " \\ {( \\ w+) - ( \ \ w + ) - ( \ \ w + ) - ( \ \ w + ) - ( \ \ w + ) \ \ } " ) ;
QString uuid = QUuid : : createUuid ( ) . toString ( ) ;
if ( regExp . indexIn ( uuid ) > = 0 )
{
return QString ( ) . append ( regExp . cap ( 1 ) ) . append ( regExp . cap ( 2 ) ) . append ( regExp . cap ( 3 ) ) . append ( regExp . cap ( 4 ) ) . append ( regExp . cap ( 5 ) ) ;
}
throw " The RegExp didn't match on the UUID string. This shouldn't happen ;-) " ;
}
2010-11-06 23:04:47 +01:00
/*
* Get LameXP temp folder
*/
2011-02-25 22:03:39 +01:00
const QString & lamexp_temp_folder2 ( void )
2010-11-06 23:04:47 +01:00
{
2010-12-12 13:44:11 +01:00
static const char * TEMP_STR = " Temp " ;
2011-03-08 01:12:40 +01:00
const QString WRITE_TEST_DATA = lamexp_rand_str ( ) ;
const QString SUB_FOLDER = lamexp_rand_str ( ) ;
2010-12-07 22:58:28 +01:00
2011-03-08 01:12:40 +01:00
//Already initialized?
if ( ! g_lamexp_temp_folder . isEmpty ( ) )
{
if ( QDir ( g_lamexp_temp_folder ) . exists ( ) )
{
return g_lamexp_temp_folder ;
}
else
{
g_lamexp_temp_folder . clear ( ) ;
}
}
//Try the %TMP% or %TEMP% directory first
QDir temp = QDir : : temp ( ) ;
if ( temp . exists ( ) )
{
temp . mkdir ( SUB_FOLDER ) ;
if ( temp . cd ( SUB_FOLDER ) & & temp . exists ( ) )
{
QFile testFile ( QString ( " %1/~%2.tmp " ) . arg ( temp . canonicalPath ( ) , lamexp_rand_str ( ) ) ) ;
if ( testFile . open ( QIODevice : : ReadWrite ) )
{
if ( testFile . write ( WRITE_TEST_DATA . toLatin1 ( ) . constData ( ) ) > = strlen ( WRITE_TEST_DATA . toLatin1 ( ) . constData ( ) ) )
{
g_lamexp_temp_folder = temp . canonicalPath ( ) ;
}
testFile . remove ( ) ;
}
}
if ( ! g_lamexp_temp_folder . isEmpty ( ) )
{
return g_lamexp_temp_folder ;
}
}
//Create TEMP folder in %LOCALAPPDATA%
QDir localAppData = QDir ( lamexp_known_folder ( lamexp_folder_localappdata ) ) ;
if ( ! localAppData . path ( ) . isEmpty ( ) )
{
if ( ! localAppData . exists ( ) )
{
localAppData . mkpath ( " . " ) ;
}
if ( localAppData . exists ( ) )
{
if ( ! localAppData . entryList ( QDir : : AllDirs ) . contains ( TEMP_STR , Qt : : CaseInsensitive ) )
{
localAppData . mkdir ( TEMP_STR ) ;
}
if ( localAppData . cd ( TEMP_STR ) & & localAppData . exists ( ) )
{
localAppData . mkdir ( SUB_FOLDER ) ;
if ( localAppData . cd ( SUB_FOLDER ) & & localAppData . exists ( ) )
{
QFile testFile ( QString ( " %1/~%2.tmp " ) . arg ( localAppData . canonicalPath ( ) , lamexp_rand_str ( ) ) ) ;
if ( testFile . open ( QIODevice : : ReadWrite ) )
{
if ( testFile . write ( WRITE_TEST_DATA . toLatin1 ( ) . constData ( ) ) > = strlen ( WRITE_TEST_DATA . toLatin1 ( ) . constData ( ) ) )
{
g_lamexp_temp_folder = localAppData . canonicalPath ( ) ;
}
testFile . remove ( ) ;
}
}
}
}
if ( ! g_lamexp_temp_folder . isEmpty ( ) )
{
return g_lamexp_temp_folder ;
}
}
//Failed to create TEMP folder!
2011-03-09 00:20:36 +01:00
qFatal ( " Temporary directory could not be initialized! \n \n First attempt: \n %s \n \n Second attempt: \n %s " , temp . canonicalPath ( ) . toUtf8 ( ) . constData ( ) , localAppData . canonicalPath ( ) . toUtf8 ( ) . constData ( ) ) ;
2011-03-08 01:12:40 +01:00
return g_lamexp_temp_folder ;
}
2010-11-06 23:04:47 +01:00
/*
* Clean folder
*/
2011-03-21 17:36:43 +01:00
bool lamexp_clean_folder ( const QString & folderPath )
2010-11-06 23:04:47 +01:00
{
QDir tempFolder ( folderPath ) ;
2010-12-21 01:09:25 +01:00
QFileInfoList entryList = tempFolder . entryInfoList ( QDir : : AllEntries | QDir : : NoDotAndDotDot ) ;
2010-11-06 23:04:47 +01:00
for ( int i = 0 ; i < entryList . count ( ) ; i + + )
{
if ( entryList . at ( i ) . isDir ( ) )
{
2010-11-15 22:07:46 +01:00
lamexp_clean_folder ( entryList . at ( i ) . canonicalFilePath ( ) ) ;
2010-11-06 23:04:47 +01:00
}
else
{
2010-12-21 01:09:25 +01:00
for ( int j = 0 ; j < 3 ; j + + )
{
if ( lamexp_remove_file ( entryList . at ( i ) . canonicalFilePath ( ) ) )
{
break ;
}
}
2010-11-06 23:04:47 +01:00
}
}
tempFolder . rmdir ( " . " ) ;
return ! tempFolder . exists ( ) ;
}
/*
* Register tool
*/
2010-11-12 15:58:53 +01:00
void lamexp_register_tool ( const QString & toolName , LockedFile * file , unsigned int version )
2010-11-06 23:04:47 +01:00
{
2010-11-11 22:58:02 +01:00
if ( g_lamexp_tool_registry . contains ( toolName . toLower ( ) ) )
2010-11-06 23:04:47 +01:00
{
throw " lamexp_register_tool: Tool is already registered! " ;
}
2010-11-11 22:58:02 +01:00
g_lamexp_tool_registry . insert ( toolName . toLower ( ) , file ) ;
2010-11-12 15:58:53 +01:00
g_lamexp_tool_versions . insert ( toolName . toLower ( ) , version ) ;
2010-11-06 23:04:47 +01:00
}
/*
2010-11-11 22:58:02 +01:00
* Check for tool
*/
bool lamexp_check_tool ( const QString & toolName )
{
return g_lamexp_tool_registry . contains ( toolName . toLower ( ) ) ;
}
/*
2010-12-15 22:39:18 +01:00
* Lookup tool path
2010-11-06 23:04:47 +01:00
*/
const QString lamexp_lookup_tool ( const QString & toolName )
{
2010-11-11 22:58:02 +01:00
if ( g_lamexp_tool_registry . contains ( toolName . toLower ( ) ) )
2010-11-06 23:04:47 +01:00
{
2010-11-12 15:58:53 +01:00
return g_lamexp_tool_registry . value ( toolName . toLower ( ) ) - > filePath ( ) ;
2010-11-06 23:04:47 +01:00
}
else
{
return QString ( ) ;
}
2010-11-07 16:32:54 +01:00
}
2010-11-12 15:58:53 +01:00
/*
2010-12-15 22:39:18 +01:00
* Lookup tool version
2010-11-12 15:58:53 +01:00
*/
unsigned int lamexp_tool_version ( const QString & toolName )
{
if ( g_lamexp_tool_versions . contains ( toolName . toLower ( ) ) )
{
return g_lamexp_tool_versions . value ( toolName . toLower ( ) ) ;
}
else
{
return UINT_MAX ;
}
}
/*
* Version number to human - readable string
*/
2011-01-14 23:34:31 +01:00
const QString lamexp_version2string ( const QString & pattern , unsigned int version , const QString & defaultText )
2010-11-12 15:58:53 +01:00
{
2010-12-15 22:39:18 +01:00
if ( version = = UINT_MAX )
{
2011-01-14 23:34:31 +01:00
return defaultText ;
2010-12-15 22:39:18 +01:00
}
2010-11-12 15:58:53 +01:00
QString result = pattern ;
int digits = result . count ( " ? " , Qt : : CaseInsensitive ) ;
if ( digits < 1 )
{
return result ;
}
int pos = 0 ;
QString versionStr = QString ( ) . sprintf ( QString ( ) . sprintf ( " %%0%du " , digits ) . toLatin1 ( ) . constData ( ) , version ) ;
int index = result . indexOf ( " ? " , Qt : : CaseInsensitive ) ;
while ( index > = 0 & & pos < versionStr . length ( ) )
{
result [ index ] = versionStr [ pos + + ] ;
index = result . indexOf ( " ? " , Qt : : CaseInsensitive ) ;
}
return result ;
}
2011-01-04 19:58:18 +01:00
/*
* Register a new translation
*/
2011-12-19 17:26:20 +01:00
bool lamexp_translation_register ( const QString & langId , const QString & qmFile , const QString & langName , unsigned int & systemId , unsigned int & country )
2011-01-04 19:58:18 +01:00
{
if ( qmFile . isEmpty ( ) | | langName . isEmpty ( ) | | systemId < 1 )
{
return false ;
}
2011-01-21 00:10:51 +01:00
g_lamexp_translation . files . insert ( langId , qmFile ) ;
g_lamexp_translation . names . insert ( langId , langName ) ;
g_lamexp_translation . sysid . insert ( langId , systemId ) ;
2011-12-19 17:26:20 +01:00
g_lamexp_translation . cntry . insert ( langId , country ) ;
2011-01-04 19:58:18 +01:00
return true ;
}
2010-12-28 21:26:16 +01:00
/*
2010-12-30 16:12:21 +01:00
* Get list of all translations
2010-12-28 21:26:16 +01:00
*/
QStringList lamexp_query_translations ( void )
{
2011-01-21 00:10:51 +01:00
return g_lamexp_translation . files . keys ( ) ;
2010-12-30 16:12:21 +01:00
}
/*
* Get translation name
*/
QString lamexp_translation_name ( const QString & langId )
{
2011-01-21 00:10:51 +01:00
return g_lamexp_translation . names . value ( langId . toLower ( ) , QString ( ) ) ;
2010-12-28 21:26:16 +01:00
}
2011-01-02 01:09:05 +01:00
/*
* Get translation system id
*/
2011-01-04 19:58:18 +01:00
unsigned int lamexp_translation_sysid ( const QString & langId )
2011-01-02 01:09:05 +01:00
{
2011-01-21 00:10:51 +01:00
return g_lamexp_translation . sysid . value ( langId . toLower ( ) , 0 ) ;
2011-01-02 01:09:05 +01:00
}
2011-12-19 15:48:50 +01:00
/*
* Get translation script id
*/
2011-12-19 17:26:20 +01:00
unsigned int lamexp_translation_country ( const QString & langId )
2011-12-19 15:48:50 +01:00
{
2011-12-19 17:26:20 +01:00
return g_lamexp_translation . cntry . value ( langId . toLower ( ) , 0 ) ;
2011-12-19 15:48:50 +01:00
}
2010-12-28 21:26:16 +01:00
/*
* Install a new translator
*/
2010-12-30 16:12:21 +01:00
bool lamexp_install_translator ( const QString & langId )
2010-12-28 21:26:16 +01:00
{
bool success = false ;
2010-12-30 16:12:21 +01:00
if ( langId . isEmpty ( ) | | langId . toLower ( ) . compare ( LAMEXP_DEFAULT_LANGID ) = = 0 )
2010-12-28 21:26:16 +01:00
{
2011-01-06 00:53:52 +01:00
success = lamexp_install_translator_from_file ( QString ( ) ) ;
2010-12-28 21:26:16 +01:00
}
else
{
2011-01-21 00:10:51 +01:00
QString qmFile = g_lamexp_translation . files . value ( langId . toLower ( ) , QString ( ) ) ;
2010-12-28 21:26:16 +01:00
if ( ! qmFile . isEmpty ( ) )
{
2011-01-06 00:53:52 +01:00
success = lamexp_install_translator_from_file ( QString ( " :/localization/%1 " ) . arg ( qmFile ) ) ;
2010-12-28 21:26:16 +01:00
}
else
{
2010-12-30 16:12:21 +01:00
qWarning ( " Translation '%s' not available! " , langId . toLatin1 ( ) . constData ( ) ) ;
2010-12-28 21:26:16 +01:00
}
}
return success ;
}
2011-01-06 00:53:52 +01:00
/*
* Install a new translator from file
*/
bool lamexp_install_translator_from_file ( const QString & qmFile )
{
bool success = false ;
if ( ! g_lamexp_currentTranslator )
{
g_lamexp_currentTranslator = new QTranslator ( ) ;
}
if ( ! qmFile . isEmpty ( ) )
{
QString qmPath = QFileInfo ( qmFile ) . canonicalFilePath ( ) ;
QApplication : : removeTranslator ( g_lamexp_currentTranslator ) ;
success = g_lamexp_currentTranslator - > load ( qmPath ) ;
QApplication : : installTranslator ( g_lamexp_currentTranslator ) ;
if ( ! success )
{
qWarning ( " Failed to load translation: \n \" %s \" " , qmPath . toLatin1 ( ) . constData ( ) ) ;
}
}
else
{
QApplication : : removeTranslator ( g_lamexp_currentTranslator ) ;
success = true ;
}
return success ;
}
2010-12-15 18:43:21 +01:00
/*
* Locate known folder on local system
*/
QString lamexp_known_folder ( lamexp_known_folder_t folder_id )
{
typedef HRESULT ( WINAPI * SHGetKnownFolderPathFun ) ( __in const GUID & rfid , __in DWORD dwFlags , __in HANDLE hToken , __out PWSTR * ppszPath ) ;
typedef HRESULT ( WINAPI * SHGetFolderPathFun ) ( __in HWND hwndOwner , __in int nFolder , __in HANDLE hToken , __in DWORD dwFlags , __out LPWSTR pszPath ) ;
static const int CSIDL_LOCAL_APPDATA = 0x001c ;
static const int CSIDL_PROGRAM_FILES = 0x0026 ;
2010-12-19 21:23:43 +01:00
static const int CSIDL_SYSTEM_FOLDER = 0x0025 ;
2010-12-15 18:43:21 +01:00
static const GUID GUID_LOCAL_APPDATA = { 0xF1B32785 , 0x6FBA , 0x4FCF , { 0x9D , 0x55 , 0x7B , 0x8E , 0x7F , 0x15 , 0x70 , 0x91 } } ;
static const GUID GUID_LOCAL_APPDATA_LOW = { 0xA520A1A4 , 0x1780 , 0x4FF6 , { 0xBD , 0x18 , 0x16 , 0x73 , 0x43 , 0xC5 , 0xAF , 0x16 } } ;
static const GUID GUID_PROGRAM_FILES = { 0x905e63b6 , 0xc1bf , 0x494e , { 0xb2 , 0x9c , 0x65 , 0xb7 , 0x32 , 0xd3 , 0xd2 , 0x1a } } ;
2010-12-19 21:23:43 +01:00
static const GUID GUID_SYSTEM_FOLDER = { 0x1AC14E77 , 0x02E7 , 0x4E5D , { 0xB7 , 0x44 , 0x2E , 0xB1 , 0xAE , 0x51 , 0x98 , 0xB7 } } ;
2010-12-15 18:43:21 +01:00
static SHGetKnownFolderPathFun SHGetKnownFolderPathPtr = NULL ;
static SHGetFolderPathFun SHGetFolderPathPtr = NULL ;
if ( ( ! SHGetKnownFolderPathPtr ) & & ( ! SHGetFolderPathPtr ) )
{
2012-04-06 23:15:58 +02:00
QLibrary kernel32Lib ( " shell32.dll " ) ;
if ( kernel32Lib . load ( ) )
{
SHGetKnownFolderPathPtr = ( SHGetKnownFolderPathFun ) kernel32Lib . resolve ( " SHGetKnownFolderPath " ) ;
SHGetFolderPathPtr = ( SHGetFolderPathFun ) kernel32Lib . resolve ( " SHGetFolderPathW " ) ;
}
2010-12-15 18:43:21 +01:00
}
int folderCSIDL = - 1 ;
GUID folderGUID = { 0x0000 , 0x0000 , 0x0000 , { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } } ;
switch ( folder_id )
{
case lamexp_folder_localappdata :
folderCSIDL = CSIDL_LOCAL_APPDATA ;
folderGUID = GUID_LOCAL_APPDATA ;
break ;
case lamexp_folder_programfiles :
folderCSIDL = CSIDL_PROGRAM_FILES ;
folderGUID = GUID_PROGRAM_FILES ;
break ;
2010-12-19 21:23:43 +01:00
case lamexp_folder_systemfolder :
folderCSIDL = CSIDL_SYSTEM_FOLDER ;
folderGUID = GUID_SYSTEM_FOLDER ;
break ;
2010-12-15 18:43:21 +01:00
default :
return QString ( ) ;
break ;
}
QString folder ;
if ( SHGetKnownFolderPathPtr )
{
WCHAR * path = NULL ;
if ( SHGetKnownFolderPathPtr ( folderGUID , 0x00008000 , NULL , & path ) = = S_OK )
{
2010-12-15 19:57:51 +01:00
//MessageBoxW(0, path, L"SHGetKnownFolderPath", MB_TOPMOST);
2010-12-15 18:43:21 +01:00
QDir folderTemp = QDir ( QDir : : fromNativeSeparators ( QString : : fromUtf16 ( reinterpret_cast < const unsigned short * > ( path ) ) ) ) ;
if ( ! folderTemp . exists ( ) )
{
folderTemp . mkpath ( " . " ) ;
}
if ( folderTemp . exists ( ) )
{
folder = folderTemp . canonicalPath ( ) ;
}
CoTaskMemFree ( path ) ;
}
}
else if ( SHGetFolderPathPtr )
{
WCHAR * path = new WCHAR [ 4096 ] ;
if ( SHGetFolderPathPtr ( NULL , folderCSIDL , NULL , NULL , path ) = = S_OK )
{
2010-12-15 19:57:51 +01:00
//MessageBoxW(0, path, L"SHGetFolderPathW", MB_TOPMOST);
2010-12-15 18:43:21 +01:00
QDir folderTemp = QDir ( QDir : : fromNativeSeparators ( QString : : fromUtf16 ( reinterpret_cast < const unsigned short * > ( path ) ) ) ) ;
if ( ! folderTemp . exists ( ) )
{
folderTemp . mkpath ( " . " ) ;
}
if ( folderTemp . exists ( ) )
{
folder = folderTemp . canonicalPath ( ) ;
}
}
delete [ ] path ;
}
return folder ;
}
2010-11-12 15:58:53 +01:00
2010-12-21 01:09:25 +01:00
/*
* Safely remove a file
*/
bool lamexp_remove_file ( const QString & filename )
{
if ( ! QFileInfo ( filename ) . exists ( ) | | ! QFileInfo ( filename ) . isFile ( ) )
{
return true ;
}
else
{
if ( ! QFile : : remove ( filename ) )
{
2011-02-25 22:03:39 +01:00
DWORD attributes = GetFileAttributesW ( QWCHAR ( filename ) ) ;
SetFileAttributesW ( QWCHAR ( filename ) , ( attributes & ( ~ FILE_ATTRIBUTE_READONLY ) ) ) ;
2010-12-21 01:09:25 +01:00
if ( ! QFile : : remove ( filename ) )
{
qWarning ( " Could not delete \" %s \" " , filename . toLatin1 ( ) . constData ( ) ) ;
return false ;
}
else
{
return true ;
}
}
else
{
return true ;
}
}
}
2010-12-19 00:50:22 +01:00
2011-01-02 20:47:26 +01:00
/*
* Check if visual themes are enabled ( WinXP and later )
*/
bool lamexp_themes_enabled ( void )
{
typedef int ( WINAPI * IsAppThemedFun ) ( void ) ;
2012-04-10 03:51:04 +02:00
static bool isAppThemed = false ;
static bool isAppThemed_initialized = false ;
2011-01-02 20:47:26 +01:00
2012-04-10 03:51:04 +02:00
if ( ! isAppThemed_initialized )
2011-01-02 20:47:26 +01:00
{
2012-04-10 03:51:04 +02:00
IsAppThemedFun IsAppThemedPtr = NULL ;
QLibrary uxTheme ( QString ( " %1/UxTheme.dll " ) . arg ( lamexp_known_folder ( lamexp_folder_systemfolder ) ) ) ;
if ( uxTheme . load ( ) )
2011-01-02 20:47:26 +01:00
{
2012-04-10 03:51:04 +02:00
IsAppThemedPtr = ( IsAppThemedFun ) uxTheme . resolve ( " IsAppThemed " ) ;
2011-01-02 20:47:26 +01:00
}
2012-04-10 03:51:04 +02:00
if ( IsAppThemedPtr )
{
isAppThemed = IsAppThemedPtr ( ) ;
if ( ! isAppThemed )
{
qWarning ( " Theme support is disabled for this process! " ) ;
}
}
isAppThemed_initialized = true ;
2011-01-02 20:47:26 +01:00
}
return isAppThemed ;
}
2010-12-19 00:50:22 +01:00
/*
2010-12-28 21:26:16 +01:00
* Get number of free bytes on disk
2010-12-19 00:50:22 +01:00
*/
2011-10-29 16:26:09 +02:00
unsigned __int64 lamexp_free_diskspace ( const QString & path , bool * ok )
2010-12-19 00:50:22 +01:00
{
ULARGE_INTEGER freeBytesAvailable , totalNumberOfBytes , totalNumberOfFreeBytes ;
if ( GetDiskFreeSpaceExW ( reinterpret_cast < const wchar_t * > ( QDir : : toNativeSeparators ( path ) . utf16 ( ) ) , & freeBytesAvailable , & totalNumberOfBytes , & totalNumberOfFreeBytes ) )
{
2011-10-29 16:26:09 +02:00
if ( ok ) * ok = true ;
2010-12-19 00:50:22 +01:00
return freeBytesAvailable . QuadPart ;
}
else
{
2011-10-29 16:26:09 +02:00
if ( ok ) * ok = false ;
2010-12-19 00:50:22 +01:00
return 0 ;
}
}
2011-10-22 01:34:24 +02:00
/*
* Check if computer does support hibernation
*/
bool lamexp_is_hibernation_supported ( void )
{
bool hibernationSupported = false ;
SYSTEM_POWER_CAPABILITIES pwrCaps ;
SecureZeroMemory ( & pwrCaps , sizeof ( SYSTEM_POWER_CAPABILITIES ) ) ;
if ( GetPwrCapabilities ( & pwrCaps ) )
{
hibernationSupported = pwrCaps . SystemS4 & & pwrCaps . HiberFilePresent ;
}
return hibernationSupported ;
}
2011-05-03 20:17:33 +02:00
/*
* Shutdown the computer
*/
2011-10-22 01:13:28 +02:00
bool lamexp_shutdown_computer ( const QString & message , const unsigned long timeout , const bool forceShutdown , const bool hibernate )
2011-03-18 01:12:17 +01:00
{
HANDLE hToken = NULL ;
if ( OpenProcessToken ( GetCurrentProcess ( ) , TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , & hToken ) )
{
TOKEN_PRIVILEGES privileges ;
memset ( & privileges , 0 , sizeof ( TOKEN_PRIVILEGES ) ) ;
privileges . PrivilegeCount = 1 ;
privileges . Privileges [ 0 ] . Attributes = SE_PRIVILEGE_ENABLED ;
if ( LookupPrivilegeValue ( NULL , SE_SHUTDOWN_NAME , & privileges . Privileges [ 0 ] . Luid ) )
{
if ( AdjustTokenPrivileges ( hToken , FALSE , & privileges , NULL , NULL , NULL ) )
{
2011-10-22 01:13:28 +02:00
if ( hibernate )
{
if ( SetSuspendState ( TRUE , TRUE , TRUE ) )
{
return true ;
}
}
2011-03-18 01:12:17 +01:00
const DWORD reason = SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_FLAG_PLANNED ;
2011-10-22 01:13:28 +02:00
return InitiateSystemShutdownEx ( NULL , const_cast < wchar_t * > ( QWCHAR ( message ) ) , timeout , forceShutdown ? TRUE : FALSE , FALSE , reason ) ;
2011-03-18 01:12:17 +01:00
}
}
}
return false ;
}
2011-05-03 20:17:33 +02:00
/*
* Make a window blink ( to draw user ' s attention )
*/
void lamexp_blink_window ( QWidget * poWindow , unsigned int count , unsigned int delay )
{
static QMutex blinkMutex ;
const double maxOpac = 1.0 ;
const double minOpac = 0.3 ;
const double delOpac = 0.1 ;
if ( ! blinkMutex . tryLock ( ) )
{
qWarning ( " Blinking is already in progress, skipping! " ) ;
return ;
}
try
{
const int steps = static_cast < int > ( ceil ( maxOpac - minOpac ) / delOpac ) ;
const int sleep = static_cast < int > ( floor ( static_cast < double > ( delay ) / static_cast < double > ( steps ) ) ) ;
const double opacity = poWindow - > windowOpacity ( ) ;
for ( unsigned int i = 0 ; i < count ; i + + )
{
for ( double x = maxOpac ; x > = minOpac ; x - = delOpac )
{
poWindow - > setWindowOpacity ( x ) ;
QApplication : : processEvents ( ) ;
Sleep ( sleep ) ;
}
for ( double x = minOpac ; x < = maxOpac ; x + = delOpac )
{
poWindow - > setWindowOpacity ( x ) ;
QApplication : : processEvents ( ) ;
Sleep ( sleep ) ;
}
}
poWindow - > setWindowOpacity ( opacity ) ;
QApplication : : processEvents ( ) ;
blinkMutex . unlock ( ) ;
}
catch ( . . . )
{
blinkMutex . unlock ( ) ;
qWarning ( " Exception error while blinking! " ) ;
}
}
2011-08-04 20:35:40 +02:00
/*
* Remove forbidden characters from a filename
*/
const QString lamexp_clean_filename ( const QString & str )
{
2011-08-04 23:26:38 +02:00
QString newStr ( str ) ;
2011-09-06 18:47:13 +02:00
2011-08-04 23:26:38 +02:00
newStr . replace ( " \\ " , " - " ) ;
newStr . replace ( " / " , " , " ) ;
newStr . replace ( " / " , " , " ) ;
newStr . replace ( " : " , " - " ) ;
newStr . replace ( " * " , " x " ) ;
newStr . replace ( " ? " , " " ) ;
newStr . replace ( " < " , " [ " ) ;
newStr . replace ( " > " , " ] " ) ;
newStr . replace ( " | " , " ! " ) ;
2011-09-06 18:47:13 +02:00
return newStr . simplified ( ) ;
2011-08-04 20:35:40 +02:00
}
/*
* Remove forbidden characters from a file path
*/
const QString lamexp_clean_filepath ( const QString & str )
{
QStringList parts = QString ( str ) . replace ( " \\ " , " / " ) . split ( " / " ) ;
for ( int i = 0 ; i < parts . count ( ) ; i + + )
{
parts [ i ] = lamexp_clean_filename ( parts [ i ] ) ;
}
return parts . join ( " / " ) ;
}
2011-12-10 23:12:47 +01:00
/*
* Get a list of all available Qt Text Codecs
*/
QStringList lamexp_available_codepages ( bool noAliases )
{
QStringList codecList ;
QList < QByteArray > availableCodecs = QTextCodec : : availableCodecs ( ) ;
while ( ! availableCodecs . isEmpty ( ) )
{
QByteArray current = availableCodecs . takeFirst ( ) ;
if ( ! ( current . startsWith ( " system " ) | | current . startsWith ( " System " ) ) )
{
codecList < < QString : : fromLatin1 ( current . constData ( ) , current . size ( ) ) ;
if ( noAliases )
{
if ( QTextCodec * currentCodec = QTextCodec : : codecForName ( current . constData ( ) ) )
{
QList < QByteArray > aliases = currentCodec - > aliases ( ) ;
while ( ! aliases . isEmpty ( ) ) availableCodecs . removeAll ( aliases . takeFirst ( ) ) ;
}
}
}
}
return codecList ;
}
2010-12-28 21:26:16 +01:00
/*
* Finalization function ( final clean - up )
*/
void lamexp_finalization ( void )
{
2011-12-29 14:42:20 +01:00
qDebug ( " lamexp_finalization() " ) ;
2010-12-28 21:26:16 +01:00
//Free all tools
if ( ! g_lamexp_tool_registry . isEmpty ( ) )
{
QStringList keys = g_lamexp_tool_registry . keys ( ) ;
for ( int i = 0 ; i < keys . count ( ) ; i + + )
{
LAMEXP_DELETE ( g_lamexp_tool_registry [ keys . at ( i ) ] ) ;
}
g_lamexp_tool_registry . clear ( ) ;
g_lamexp_tool_versions . clear ( ) ;
}
//Delete temporary files
if ( ! g_lamexp_temp_folder . isEmpty ( ) )
{
for ( int i = 0 ; i < 100 ; i + + )
{
if ( lamexp_clean_folder ( g_lamexp_temp_folder ) )
{
break ;
}
Sleep ( 125 ) ;
}
g_lamexp_temp_folder . clear ( ) ;
}
//Clear languages
2010-12-30 16:12:21 +01:00
if ( g_lamexp_currentTranslator )
{
QApplication : : removeTranslator ( g_lamexp_currentTranslator ) ;
LAMEXP_DELETE ( g_lamexp_currentTranslator ) ;
}
2011-01-21 00:10:51 +01:00
g_lamexp_translation . files . clear ( ) ;
g_lamexp_translation . names . clear ( ) ;
2010-12-28 21:26:16 +01:00
//Destroy Qt application object
QApplication * application = dynamic_cast < QApplication * > ( QApplication : : instance ( ) ) ;
LAMEXP_DELETE ( application ) ;
//Detach from shared memory
2011-01-20 22:54:10 +01:00
if ( g_lamexp_ipc_ptr . sharedmem ) g_lamexp_ipc_ptr . sharedmem - > detach ( ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . sharedmem ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write ) ;
2012-04-06 23:15:58 +02:00
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_read_mutex ) ;
LAMEXP_DELETE ( g_lamexp_ipc_ptr . semaphore_write_mutex ) ;
//Free STDOUT and STDERR buffers
if ( g_lamexp_console_attached )
{
if ( std : : filebuf * tmp = dynamic_cast < std : : filebuf * > ( std : : cout . rdbuf ( ) ) )
{
std : : cout . rdbuf ( NULL ) ;
LAMEXP_DELETE ( tmp ) ;
}
if ( std : : filebuf * tmp = dynamic_cast < std : : filebuf * > ( std : : cerr . rdbuf ( ) ) )
{
std : : cerr . rdbuf ( NULL ) ;
LAMEXP_DELETE ( tmp ) ;
}
}
2011-12-27 20:10:19 +01:00
//Close log file
if ( g_lamexp_log_file )
{
fclose ( g_lamexp_log_file ) ;
g_lamexp_log_file = NULL ;
}
2010-12-28 21:26:16 +01:00
}
2011-04-19 16:14:05 +02:00
/*
* Initialize debug thread
*/
static const HANDLE g_debug_thread = LAMEXP_DEBUG ? NULL : lamexp_debug_thread_init ( ) ;
2010-11-07 16:32:54 +01:00
/*
* Get number private bytes [ debug only ]
*/
SIZE_T lamexp_dbg_private_bytes ( void )
{
2011-04-19 16:14:05 +02:00
# if LAMEXP_DEBUG
2010-11-07 16:32:54 +01:00
PROCESS_MEMORY_COUNTERS_EX memoryCounters ;
memoryCounters . cb = sizeof ( PROCESS_MEMORY_COUNTERS_EX ) ;
GetProcessMemoryInfo ( GetCurrentProcess ( ) , ( PPROCESS_MEMORY_COUNTERS ) & memoryCounters , sizeof ( PROCESS_MEMORY_COUNTERS_EX ) ) ;
return memoryCounters . PrivateUsage ;
# else
throw " Cannot call this function in a non-debug build! " ;
2011-04-19 16:14:05 +02:00
# endif //LAMEXP_DEBUG
2010-11-07 16:32:54 +01:00
}