2010-11-06 23:04:47 +01:00
///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
2013-02-08 23:50:51 +01:00
// Copyright (C) 2004-2013 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
2013-10-23 20:56:57 +02:00
// (at your option) any later version, but always including the *additional*
// restrictions defined in the "License.txt" file.
2010-11-06 23:04:47 +01:00
//
// 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"
2013-11-03 23:43:21 +01:00
//Target version
# include "Targetver.h"
//Visual Leaks Detector
# include <vld.h>
2013-10-06 19:28:12 +02:00
//Windows includes
# define NOMINMAX
# define WIN32_LEAN_AND_MEAN
# include <Windows.h>
2013-10-07 00:01:15 +02:00
# include <MMSystem.h>
# include <ShellAPI.h>
2013-10-19 16:02:22 +02:00
# include <SensAPI.h>
2013-11-03 23:43:21 +01:00
# include <Objbase.h>
# include <PowrProf.h>
# include <Psapi.h>
2013-10-06 19:28:12 +02:00
2010-11-06 23:04:47 +01:00
//Qt includes
# include <QApplication>
# include <QDate>
2013-11-03 23:43:21 +01:00
# include <QDir>
# include <QEvent>
2010-11-06 23:04:47 +01:00
# include <QIcon>
# include <QImageReader>
2010-11-25 16:56:32 +01:00
# include <QLibrary>
2011-12-17 15:56:24 +01:00
# include <QLibraryInfo>
2013-11-03 23:43:21 +01:00
# include <QMap>
# include <QMessageBox>
# include <QMutex>
# include <QPlastiqueStyle>
2013-10-07 00:01:15 +02:00
# include <QProcess>
2013-11-03 23:43:21 +01:00
# include <QReadWriteLock>
# include <QRegExp>
# include <QSysInfo>
# include <QTextCodec>
# include <QTimer>
# include <QTranslator>
# include <QUuid>
2010-11-06 23:04:47 +01:00
//LameXP includes
2013-05-02 23:00:26 +02:00
# define LAMEXP_INC_CONFIG
2010-11-07 23:06:30 +01:00
# include "Resource.h"
2012-12-04 01:35:48 +01:00
# include "Config.h"
2010-11-06 23:04:47 +01:00
2010-11-07 23:06:30 +01:00
//CRT includes
2013-11-03 23:43:21 +01:00
# include <cstdio>
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>
2013-11-03 23:43:21 +01:00
# include <cmath>
# include <ctime>
2012-03-26 04:40:49 +02:00
# include <process.h>
2013-11-17 21:51:41 +01:00
# include <csignal>
2010-11-07 23:06:30 +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
2012-04-11 03:08:31 +02:00
# if QT_VERSION < QT_VERSION_CHECK(5,0,0)
2011-04-19 16:14:05 +02:00
Q_IMPORT_PLUGIN ( qico )
Q_IMPORT_PLUGIN ( qsvg )
2012-04-11 03:08:31 +02:00
# else
Q_IMPORT_PLUGIN ( QWindowsIntegrationPlugin )
Q_IMPORT_PLUGIN ( QICOPlugin )
# endif
2010-11-11 19:37:16 +01:00
# endif
2013-11-03 23:43:21 +01:00
///////////////////////////////////////////////////////////////////////////////
// HELPER MACROS
///////////////////////////////////////////////////////////////////////////////
2012-08-18 16:36:39 +02:00
2012-11-15 18:06:04 +01:00
# define _LAMEXP_MAKE_STR(STR) #STR
# define LAMEXP_MAKE_STR(STR) _LAMEXP_MAKE_STR(STR)
2013-10-25 15:12:27 +02:00
//String helper
# define CLEAN_OUTPUT_STRING(STR) do \
{ \
const char CTRL_CHARS [ 3 ] = { ' \r ' , ' \n ' , ' \t ' } ; \
for ( size_t i = 0 ; i < 3 ; i + + ) \
{ \
while ( char * pos = strchr ( ( STR ) , CTRL_CHARS [ i ] ) ) * pos = char ( 0x20 ) ; \
} \
} \
while ( 0 )
//String helper
# define TRIM_LEFT(STR) do \
{ \
const char WHITE_SPACE [ 4 ] = { char ( 0x20 ) , ' \r ' , ' \n ' , ' \t ' } ; \
for ( size_t i = 0 ; i < 4 ; i + + ) \
{ \
while ( * ( STR ) = = WHITE_SPACE [ i ] ) ( STR ) + + ; \
} \
} \
while ( 0 )
2010-11-06 23:04:47 +01:00
///////////////////////////////////////////////////////////////////////////////
// GLOBAL VARS
///////////////////////////////////////////////////////////////////////////////
2011-03-04 23:40:09 +01:00
//Console attached flag
static bool g_lamexp_console_attached = false ;
2010-11-06 23:04:47 +01:00
//Special folders
2012-08-13 23:12:19 +02:00
static struct
{
2012-08-18 16:36:39 +02:00
QMap < size_t , QString > * knownFolders ;
2012-08-13 23:12:19 +02:00
QReadWriteLock lock ;
}
2013-06-29 18:06:21 +02:00
g_lamexp_known_folder ;
2012-08-18 16:36:39 +02:00
//CLI Arguments
static struct
{
QStringList * list ;
QReadWriteLock lock ;
}
g_lamexp_argv ;
2013-02-25 23:12:14 +01:00
//OS Version
2012-09-09 23:05:00 +02:00
static struct
{
bool bInitialized ;
lamexp_os_version_t version ;
QReadWriteLock lock ;
}
g_lamexp_os_version ;
2013-11-03 23:43:21 +01:00
//Wine detection
2013-04-17 22:05:45 +02:00
static struct
{
bool bInitialized ;
2013-11-03 23:43:21 +01:00
bool bIsWine ;
2013-04-17 22:05:45 +02:00
QReadWriteLock lock ;
}
2013-11-03 23:43:21 +01:00
g_lamexp_wine ;
2013-04-17 22:05:45 +02:00
2013-02-25 23:12:14 +01:00
//Win32 Theme support
static struct
{
bool bInitialized ;
bool bThemesEnabled ;
QReadWriteLock lock ;
}
g_lamexp_themes_enabled ;
2010-11-11 19:37:16 +01:00
//Image formats
2012-04-12 03:18:48 +02:00
static const char * g_lamexp_imageformats [ ] = { " bmp " , " png " , " jpg " , " gif " , " ico " , " xpm " , NULL } ; //"svg"
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 ;
2013-01-23 23:25:31 +01:00
//Localization
const char * LAMEXP_DEFAULT_LANGID = " en " ;
const char * LAMEXP_DEFAULT_TRANSLATION = " LameXP_EN.qm " ;
2013-10-20 19:12:00 +02:00
//Known Windows versions - maps marketing names to the actual Windows NT versions
const lamexp_os_version_t lamexp_winver_win2k = { 5 , 0 } ;
const lamexp_os_version_t lamexp_winver_winxp = { 5 , 1 } ;
const lamexp_os_version_t lamexp_winver_xpx64 = { 5 , 2 } ;
const lamexp_os_version_t lamexp_winver_vista = { 6 , 0 } ;
const lamexp_os_version_t lamexp_winver_win70 = { 6 , 1 } ;
const lamexp_os_version_t lamexp_winver_win80 = { 6 , 2 } ;
const lamexp_os_version_t lamexp_winver_win81 = { 6 , 3 } ;
2013-10-25 15:12:27 +02:00
//GURU MEDITATION
static const char * GURU_MEDITATION = " \n \n GURU MEDITATION !!! \n \n " ;
2010-11-06 23:04:47 +01:00
///////////////////////////////////////////////////////////////////////////////
// GLOBAL FUNCTIONS
///////////////////////////////////////////////////////////////////////////////
/*
2013-11-03 23:43:21 +01:00
* Verify a specific Windows version
2010-11-06 23:04:47 +01:00
*/
2013-10-20 19:12:00 +02:00
static bool lamexp_verify_os_version ( const DWORD major , const DWORD minor )
2013-10-19 16:02:22 +02:00
{
2013-10-20 19:12:00 +02:00
OSVERSIONINFOEXW osvi ;
2013-10-19 16:02:22 +02:00
DWORDLONG dwlConditionMask = 0 ;
2013-10-20 19:12:00 +02:00
//Initialize the OSVERSIONINFOEX structure
memset ( & osvi , 0 , sizeof ( OSVERSIONINFOEXW ) ) ;
osvi . dwOSVersionInfoSize = sizeof ( OSVERSIONINFOEXW ) ;
2013-10-19 16:02:22 +02:00
osvi . dwMajorVersion = major ;
osvi . dwMinorVersion = minor ;
osvi . dwPlatformId = VER_PLATFORM_WIN32_NT ;
//Initialize the condition mask
2013-10-20 19:12:00 +02:00
VER_SET_CONDITION ( dwlConditionMask , VER_MAJORVERSION , VER_GREATER_EQUAL ) ;
VER_SET_CONDITION ( dwlConditionMask , VER_MINORVERSION , VER_GREATER_EQUAL ) ;
2013-10-19 16:02:22 +02:00
VER_SET_CONDITION ( dwlConditionMask , VER_PLATFORMID , VER_EQUAL ) ;
// Perform the test
2013-10-20 19:12:00 +02:00
const BOOL ret = VerifyVersionInfoW ( & osvi , VER_MAJORVERSION | VER_MINORVERSION | VER_PLATFORMID , dwlConditionMask ) ;
2013-10-19 16:02:22 +02:00
//Error checking
if ( ! ret )
{
if ( GetLastError ( ) ! = ERROR_OLD_WIN_VERSION )
{
qWarning ( " VerifyVersionInfo() system call has failed! " ) ;
}
}
return ( ret ! = FALSE ) ;
}
/*
* Determine the * real * Windows version
*/
2013-10-20 23:34:04 +02:00
static bool lamexp_get_real_os_version ( unsigned int * major , unsigned int * minor , bool * pbOverride )
2013-10-19 16:02:22 +02:00
{
2013-10-20 19:12:00 +02:00
* major = * minor = 0 ;
2013-10-20 23:34:04 +02:00
* pbOverride = false ;
2013-10-19 16:02:22 +02:00
2013-10-20 19:12:00 +02:00
//Initialize local variables
OSVERSIONINFOEXW osvi ;
memset ( & osvi , 0 , sizeof ( OSVERSIONINFOEXW ) ) ;
osvi . dwOSVersionInfoSize = sizeof ( OSVERSIONINFOEXW ) ;
//Try GetVersionEx() first
2013-10-20 23:34:04 +02:00
if ( GetVersionExW ( ( LPOSVERSIONINFOW ) & osvi ) = = FALSE )
2013-10-19 16:02:22 +02:00
{
2013-10-20 23:34:04 +02:00
qWarning ( " GetVersionEx() has failed, cannot detect Windows version! " ) ;
return false ;
}
//Make sure we are running on NT
if ( osvi . dwPlatformId = = VER_PLATFORM_WIN32_NT )
{
* major = osvi . dwMajorVersion ;
* minor = osvi . dwMinorVersion ;
}
else
{
qWarning ( " Not running on Windows NT, unsupported operating system! " ) ;
return false ;
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
//Determine the real *major* version first
forever
2013-10-19 16:02:22 +02:00
{
2013-10-20 19:12:00 +02:00
const DWORD nextMajor = ( * major ) + 1 ;
if ( lamexp_verify_os_version ( nextMajor , 0 ) )
2013-10-19 16:02:22 +02:00
{
2013-10-20 23:34:04 +02:00
* pbOverride = true ;
2013-10-20 19:12:00 +02:00
* major = nextMajor ;
* minor = 0 ;
continue ;
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
break ;
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
//Now also determine the real *minor* version
forever
2013-10-19 16:02:22 +02:00
{
2013-10-20 19:12:00 +02:00
const DWORD nextMinor = ( * minor ) + 1 ;
if ( lamexp_verify_os_version ( ( * major ) , nextMinor ) )
{
2013-10-20 23:34:04 +02:00
* pbOverride = true ;
2013-10-20 19:12:00 +02:00
* minor = nextMinor ;
continue ;
}
break ;
2013-10-19 16:02:22 +02:00
}
2013-10-20 23:34:04 +02:00
return true ;
2013-10-19 16:02:22 +02:00
}
2011-10-14 18:02:37 +02:00
/*
* Get the native operating system version
*/
2013-10-20 19:12:00 +02:00
const lamexp_os_version_t & lamexp_get_os_version ( void )
2011-10-14 18:02:37 +02:00
{
2012-09-09 23:05:00 +02:00
QReadLocker readLock ( & g_lamexp_os_version . lock ) ;
//Already initialized?
if ( g_lamexp_os_version . bInitialized )
{
2013-10-20 19:12:00 +02:00
return g_lamexp_os_version . version ;
2012-09-09 23:05:00 +02:00
}
2011-10-14 18:02:37 +02:00
2012-09-09 23:05:00 +02:00
readLock . unlock ( ) ;
QWriteLocker writeLock ( & g_lamexp_os_version . lock ) ;
//Detect OS version
if ( ! g_lamexp_os_version . bInitialized )
2011-10-14 18:02:37 +02:00
{
2013-10-20 23:34:04 +02:00
unsigned int major , minor ; bool oflag ;
if ( lamexp_get_real_os_version ( & major , & minor , & oflag ) )
2011-10-14 18:02:37 +02:00
{
2013-10-19 16:02:22 +02:00
g_lamexp_os_version . version . versionMajor = major ;
g_lamexp_os_version . version . versionMinor = minor ;
2013-10-20 23:34:04 +02:00
g_lamexp_os_version . version . overrideFlag = oflag ;
2013-10-19 16:02:22 +02:00
g_lamexp_os_version . bInitialized = true ;
2012-04-13 16:37:47 +02:00
}
else
{
2013-10-19 16:02:22 +02:00
qWarning ( " Failed to determin the operating system version! " ) ;
2011-10-14 18:02:37 +02:00
}
}
2013-10-20 19:12:00 +02:00
return g_lamexp_os_version . version ;
2012-04-05 13:40:52 +02:00
}
/*
* Check if we are running under wine
*/
bool lamexp_detect_wine ( void )
{
2013-11-03 23:43:21 +01:00
QReadLocker readLock ( & g_lamexp_wine . lock ) ;
//Already initialized?
if ( g_lamexp_wine . bInitialized )
{
return g_lamexp_wine . bIsWine ;
}
readLock . unlock ( ) ;
QWriteLocker writeLock ( & g_lamexp_wine . lock ) ;
2012-04-05 13:40:52 +02:00
2013-11-03 23:43:21 +01:00
if ( ! g_lamexp_wine . bInitialized )
2012-04-05 13:40:52 +02:00
{
2013-11-03 23:43:21 +01:00
g_lamexp_wine . bIsWine = false ;
2012-04-05 13:40:52 +02:00
QLibrary ntdll ( " ntdll.dll " ) ;
if ( ntdll . load ( ) )
{
2013-11-03 23:43:21 +01:00
if ( ntdll . resolve ( " wine_nt_to_unix_file_name " ) ! = NULL ) g_lamexp_wine . bIsWine = true ;
if ( ntdll . resolve ( " wine_get_version " ) ! = NULL ) g_lamexp_wine . bIsWine = true ;
2012-04-05 13:40:52 +02:00
ntdll . unload ( ) ;
}
2013-11-03 23:43:21 +01:00
g_lamexp_wine . bInitialized = true ;
2012-04-05 13:40:52 +02:00
}
2013-11-03 23:43:21 +01:00
return g_lamexp_wine . bIsWine ;
2011-04-17 15:53:28 +02:00
}
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
/*
2013-10-25 15:12:27 +02:00
* Output logging message to console
2010-11-19 13:31:45 +01:00
*/
2013-10-25 15:12:27 +02:00
static void lamexp_write_console ( const int type , const char * msg )
{
__try
{
if ( _isatty ( _fileno ( stderr ) ) )
{
UINT oldOutputCP = GetConsoleOutputCP ( ) ;
if ( oldOutputCP ! = CP_UTF8 ) SetConsoleOutputCP ( CP_UTF8 ) ;
2011-03-10 02:07:51 +01:00
2013-10-25 15:12:27 +02:00
switch ( type )
{
case QtCriticalMsg :
case QtFatalMsg :
lamexp_console_color ( stderr , FOREGROUND_RED | FOREGROUND_INTENSITY ) ;
fprintf ( stderr , GURU_MEDITATION ) ;
fprintf ( stderr , " %s \n " , msg ) ;
fflush ( stderr ) ;
break ;
case QtWarningMsg :
lamexp_console_color ( stderr , FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY ) ;
fprintf ( stderr , " %s \n " , msg ) ;
fflush ( stderr ) ;
break ;
default :
lamexp_console_color ( stderr , FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY ) ;
fprintf ( stderr , " %s \n " , msg ) ;
fflush ( stderr ) ;
break ;
}
lamexp_console_color ( stderr , FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED ) ;
if ( oldOutputCP ! = CP_UTF8 ) SetConsoleOutputCP ( oldOutputCP ) ;
}
}
__except ( 1 )
2011-12-27 20:10:19 +01:00
{
2013-10-25 15:12:27 +02:00
/*ignore any exception that might occur here!*/
2011-12-27 20:10:19 +01:00
}
2013-10-25 15:12:27 +02:00
}
2010-11-19 13:31:45 +01:00
2013-10-25 15:12:27 +02:00
/*
* Output logging message to debugger
*/
static void lamexp_write_dbg_out ( const int type , const char * msg )
{
const char * FORMAT = " [LameXP][%c] %s \n " ;
2011-03-04 23:40:09 +01:00
2013-10-25 15:12:27 +02:00
__try
{
char buffer [ 512 ] ;
const char * input = msg ;
TRIM_LEFT ( input ) ;
2011-03-04 23:40:09 +01:00
switch ( type )
{
case QtCriticalMsg :
case QtFatalMsg :
2013-10-25 15:12:27 +02:00
_snprintf_s ( buffer , 512 , _TRUNCATE , FORMAT , ' C ' , input ) ;
2011-03-04 23:40:09 +01:00
break ;
case QtWarningMsg :
2013-10-25 15:12:27 +02:00
_snprintf_s ( buffer , 512 , _TRUNCATE , FORMAT , ' W ' , input ) ;
2011-03-04 23:40:09 +01:00
break ;
default :
2013-10-25 15:12:27 +02:00
_snprintf_s ( buffer , 512 , _TRUNCATE , FORMAT , ' I ' , input ) ;
2011-03-04 23:40:09 +01:00
break ;
}
2013-10-25 15:12:27 +02:00
char * temp = & buffer [ 0 ] ;
CLEAN_OUTPUT_STRING ( temp ) ;
OutputDebugStringA ( temp ) ;
2010-11-19 13:31:45 +01:00
}
2013-10-25 15:12:27 +02:00
__except ( 1 )
2011-03-04 23:40:09 +01:00
{
2013-10-25 15:12:27 +02:00
/*ignore any exception that might occur here!*/
}
}
/*
* Output logging message to logfile
*/
static void lamexp_write_logfile ( const int type , const char * msg )
{
const char * FORMAT = " [%c][%04u] %s \r \n " ;
__try
{
if ( g_lamexp_log_file )
2011-03-04 23:40:09 +01:00
{
2013-10-25 15:12:27 +02:00
char buffer [ 512 ] ;
strncpy_s ( buffer , 512 , msg , _TRUNCATE ) ;
char * temp = & buffer [ 0 ] ;
TRIM_LEFT ( temp ) ;
CLEAN_OUTPUT_STRING ( temp ) ;
const unsigned int timestamp = static_cast < unsigned int > ( _time64 ( NULL ) % 3600 I64 ) ;
switch ( type )
{
case QtCriticalMsg :
case QtFatalMsg :
fprintf ( g_lamexp_log_file , FORMAT , ' C ' , timestamp , temp ) ;
break ;
case QtWarningMsg :
fprintf ( g_lamexp_log_file , FORMAT , ' W ' , timestamp , temp ) ;
break ;
default :
fprintf ( g_lamexp_log_file , FORMAT , ' I ' , timestamp , temp ) ;
break ;
}
fflush ( g_lamexp_log_file ) ;
2011-03-04 23:40:09 +01:00
}
2013-10-25 15:12:27 +02:00
}
__except ( 1 )
{
/*ignore any exception that might occur here!*/
}
}
/*
* Qt message handler
*/
void lamexp_message_handler ( QtMsgType type , const char * msg )
{
if ( ( ! msg ) | | ( ! ( msg [ 0 ] ) ) )
{
return ;
}
QMutexLocker lock ( & g_lamexp_message_mutex ) ;
2011-03-04 23:40:09 +01:00
2013-10-25 15:12:27 +02:00
if ( g_lamexp_log_file )
{
lamexp_write_logfile ( type , msg ) ;
}
if ( g_lamexp_console_attached )
{
lamexp_write_console ( type , msg ) ;
}
else
{
lamexp_write_dbg_out ( type , msg ) ;
2011-03-04 23:40:09 +01:00
}
2010-11-19 13:31:45 +01:00
2012-12-11 22:54:00 +01:00
if ( ( type = = QtCriticalMsg ) | | ( type = = QtFatalMsg ) )
2010-11-19 13:31:45 +01:00
{
2010-11-20 03:11:12 +01:00
lock . unlock ( ) ;
2012-12-11 22:54:00 +01:00
lamexp_fatal_exit ( L " The application has encountered a critical error and will exit now! " , QWCHAR ( QString : : fromUtf8 ( msg ) ) ) ;
2010-11-19 13:31:45 +01:00
}
2011-03-10 02:07:51 +01:00
}
2010-11-19 13:31:45 +01:00
2013-11-17 21:51:41 +01:00
/*
* Invalid parameters handler
*/
static void lamexp_invalid_param_handler ( const wchar_t * exp , const wchar_t * fun , const wchar_t * fil , unsigned int , uintptr_t )
{
lamexp_fatal_exit ( L " Invalid parameter handler invoked, application will exit! " ) ;
}
/*
* Signal handler
*/
static void lamexp_signal_handler ( int signal_num )
{
signal ( signal_num , lamexp_signal_handler ) ;
lamexp_fatal_exit ( L " Signal handler invoked, application will exit! " ) ;
}
2013-11-03 23:43:21 +01:00
/*
* Global exception handler
*/
2013-11-17 21:51:41 +01:00
static LONG WINAPI lamexp_exception_handler ( struct _EXCEPTION_POINTERS * ExceptionInfo )
2013-11-03 23:43:21 +01:00
{
lamexp_fatal_exit ( L " Unhandeled exception handler invoked, application will exit! " ) ;
return LONG_MAX ;
}
/*
* Initialize error handlers
*/
void lamexp_init_error_handlers ( void )
{
SetErrorMode ( SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX ) ;
SetUnhandledExceptionFilter ( lamexp_exception_handler ) ;
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_ABOVE_NORMAL ) ;
_set_invalid_parameter_handler ( lamexp_invalid_param_handler ) ;
2013-11-17 21:51:41 +01:00
static const int signal_num [ 6 ] = { SIGABRT , SIGFPE , SIGILL , SIGINT , SIGSEGV , SIGTERM } ;
for ( size_t i = 0 ; i < 6 ; i + + )
{
signal ( signal_num [ i ] , lamexp_signal_handler ) ;
}
2013-11-03 23:43:21 +01:00
}
2010-11-07 23:06:30 +01:00
/*
* Initialize the console
*/
2012-06-22 15:49:56 +02:00
void lamexp_init_console ( const QStringList & argv )
2010-11-07 23:06:30 +01:00
{
2013-06-16 22:07:28 +02:00
bool enableConsole = ( LAMEXP_DEBUG ) | | ( ( VER_LAMEXP_CONSOLE_ENABLED ) & & 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 " ) )
{
2013-10-25 15:12:27 +02:00
fprintf ( temp , " %c%c%c " , char ( 0xEF ) , char ( 0xBB ) , char ( 0xBF ) ) ;
2011-12-29 14:42:20 +01:00
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
{
2012-06-22 15:49:56 +02:00
for ( int i = 0 ; i < argv . count ( ) ; i + + )
2010-11-07 23:06:30 +01:00
{
2012-06-22 15:49:56 +02:00
if ( ! argv . at ( i ) . compare ( " --console " , Qt : : CaseInsensitive ) )
2011-03-25 16:17:19 +01:00
{
enableConsole = true ;
}
2012-06-22 15:49:56 +02:00
else if ( ! argv . at ( i ) . compare ( " --no-console " , Qt : : CaseInsensitive ) )
2011-03-25 16:17:19 +01:00
{
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 ) ;
2013-04-11 00:01:33 +02:00
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
*/
2012-06-23 18:18:57 +02:00
lamexp_cpu_t lamexp_detect_cpu_features ( const QStringList & 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 ) ;
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
2013-10-16 03:29:43 +02:00
# if (!(defined(_M_X64) || defined(_M_IA64)))
QLibrary Kernel32Lib ( " kernel32.dll " ) ;
if ( IsWow64ProcessFun IsWow64ProcessPtr = ( IsWow64ProcessFun ) Kernel32Lib . resolve ( " IsWow64Process " ) )
2010-11-25 16:56:32 +01:00
{
2013-10-16 03:29:43 +02:00
BOOL x64flag = FALSE ;
if ( IsWow64ProcessPtr ( GetCurrentProcess ( ) , & x64flag ) )
2010-11-25 16:56:32 +01:00
{
2013-10-16 03:29:43 +02:00
features . x64 = ( x64flag = = TRUE ) ;
2010-11-25 16:56:32 +01:00
}
}
# else
features . x64 = true ;
# endif
2010-11-15 14:02:58 +01:00
2013-10-18 01:59:08 +02:00
DWORD_PTR procAffinity , sysAffinity ;
if ( GetProcessAffinityMask ( GetCurrentProcess ( ) , & procAffinity , & sysAffinity ) )
{
for ( DWORD_PTR mask = 1 ; mask ; mask < < = 1 )
{
features . count + = ( ( sysAffinity & mask ) ? ( 1 ) : ( 0 ) ) ;
}
}
if ( features . count < 1 )
{
GetNativeSystemInfo ( & systemInfo ) ;
features . count = qBound ( 1UL , systemInfo . dwNumberOfProcessors , 64UL ) ;
}
2013-10-16 03:29:43 +02:00
2012-06-23 18:18:57 +02:00
if ( argv . count ( ) > 0 )
2011-09-20 00:03:51 +02:00
{
2011-09-30 20:17:42 +02:00
bool flag = false ;
2012-06-23 18:18:57 +02:00
for ( int i = 0 ; i < argv . count ( ) ; i + + )
2011-09-20 00:03:51 +02:00
{
2012-06-23 18:18:57 +02:00
if ( ! argv [ i ] . compare ( " --force-cpu-no-64bit " , Qt : : CaseInsensitive ) ) { flag = true ; features . x64 = false ; }
if ( ! argv [ i ] . compare ( " --force-cpu-no-sse " , Qt : : CaseInsensitive ) ) { flag = true ; features . sse = features . sse2 = features . sse3 = features . ssse3 = false ; }
if ( ! argv [ i ] . compare ( " --force-cpu-no-intel " , Qt : : CaseInsensitive ) ) { 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
__try
{
2013-10-26 15:49:16 +02:00
CloseHandle ( ( HANDLE ) ( ( DWORD_PTR ) - 3 ) ) ;
2012-03-26 04:40:49 +02:00
}
2013-10-26 15:49:16 +02:00
__except ( 1 )
2012-03-26 04:40:49 +02:00
{
return true ;
}
2011-06-22 01:10:53 +02:00
__try
{
2013-10-26 15:49:16 +02:00
__debugbreak ( ) ;
2011-06-22 01:10:53 +02:00
}
2013-10-26 15:49:16 +02:00
__except ( 1 )
2011-06-22 01:10:53 +02:00
{
2013-10-26 15:49:16 +02:00
return IsDebuggerPresent ( ) ;
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
{
2013-10-25 17:55:27 +02:00
SetThreadPriority ( GetCurrentThread ( ) , THREAD_PRIORITY_LOWEST ) ;
forever
2012-03-26 04:40:49 +02:00
{
2013-10-25 17:55:27 +02:00
if ( lamexp_check_for_debugger ( ) )
{
lamexp_fatal_exit ( L " Not a debug build. Please unload debugger and try again! " ) ;
return 666 ;
}
2013-10-26 15:49:16 +02:00
lamexp_sleep ( 100 ) ;
2012-03-26 04:40:49 +02:00
}
2010-11-15 04:42:06 +01:00
}
2011-04-19 16:14:05 +02:00
/*
* Check for debugger ( startup routine )
*/
2013-10-25 17:55:27 +02:00
static HANDLE lamexp_debug_thread_init ( )
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
{
2012-12-11 22:54:00 +01:00
lamexp_fatal_exit ( L " Not a debug build. Please unload debugger and try again! " ) ;
2011-02-18 00:53:36 +01:00
}
2013-10-26 15:49:16 +02:00
const uintptr_t h = _beginthreadex ( NULL , 0 , lamexp_debug_thread_proc , NULL , 0 , NULL ) ;
return ( HANDLE ) ( h ^ 0xdeadbeef ) ;
2011-02-18 00:53:36 +01:00
}
2010-11-15 04:42:06 +01:00
2011-12-29 14:42:20 +01:00
/*
* Qt event filter
*/
static bool lamexp_event_filter ( void * message , long * result )
2013-10-20 23:34:04 +02:00
{
2012-03-26 04:40:49 +02:00
if ( ( ! ( LAMEXP_DEBUG ) ) & & lamexp_check_for_debugger ( ) )
{
2012-12-11 22:54:00 +01:00
lamexp_fatal_exit ( L " Not a debug build. Please unload debugger and try again! " ) ;
2012-03-26 04:40:49 +02:00
}
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 ) ;
2012-06-23 18:18:57 +02:00
const QStringList & arguments = lamexp_arguments ( ) ;
2010-11-06 23:04:47 +01:00
//Don't initialized again, if done already
if ( qt_initialized )
{
return true ;
}
2012-08-13 23:12:19 +02:00
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 " " ) ;
}
2011-07-26 22:17:14 +02:00
2011-03-08 01:12:40 +01:00
//Extract executable name from argv[] array
2012-06-23 18:18:57 +02:00
QString executableName = QLatin1String ( " LameXP.exe " ) ;
if ( arguments . count ( ) > 0 )
2011-03-08 01:12:40 +01:00
{
2012-06-23 18:18:57 +02:00
static const char * delimiters = " \\ /:? " ;
executableName = arguments [ 0 ] . trimmed ( ) ;
for ( int i = 0 ; delimiters [ i ] ; i + + )
{
int temp = executableName . lastIndexOf ( QChar ( delimiters [ i ] ) ) ;
if ( temp > = 0 ) executableName = executableName . mid ( temp + 1 ) ;
}
executableName = executableName . trimmed ( ) ;
if ( executableName . isEmpty ( ) )
{
executableName = QLatin1String ( " LameXP.exe " ) ;
}
2011-03-08 01:12:40 +01:00
}
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 ) )
{
2012-06-23 18:18:57 +02:00
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' requires Qt v%2, but found Qt v%3. " ) . arg ( executableName , QString : : fromLatin1 ( QT_VERSION_STR ) , QString : : fromLatin1 ( qVersion ( ) ) ) . toLatin1 ( ) . constData ( ) ) ;
2011-03-08 01:12:40 +01:00
return false ;
}
2011-12-17 15:56:24 +01:00
if ( QLibraryInfo : : buildKey ( ) . compare ( QString : : fromLatin1 ( QT_BUILD_KEY ) , Qt : : CaseInsensitive ) )
{
2012-06-23 18:18:57 +02:00
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' was built for Qt '%2', but found Qt '%3'. " ) . arg ( executableName , QString : : fromLatin1 ( QT_BUILD_KEY ) , QLibraryInfo : : buildKey ( ) ) . toLatin1 ( ) . constData ( ) ) ;
2011-12-17 15:56:24 +01:00
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
2013-10-20 19:12:00 +02:00
const lamexp_os_version_t & osVersionNo = lamexp_get_os_version ( ) ;
if ( osVersionNo < lamexp_winver_winxp )
2010-11-06 23:04:47 +01:00
{
2013-10-16 18:23:53 +02:00
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' requires Windows XP or later. " ) . arg ( executableName ) . toLatin1 ( ) . constData ( ) ) ;
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
2013-10-20 23:34:04 +02:00
//Supported Windows version?
2013-10-20 19:12:00 +02:00
if ( osVersionNo = = lamexp_winver_winxp )
2013-10-19 16:02:22 +02:00
{
2013-10-21 15:00:03 +02:00
qDebug ( " Running on Windows XP or Windows XP Media Center Edition. \n " ) ; //lamexp_check_compatibility_mode("GetLargePageMinimum", executableName);
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
else if ( osVersionNo = = lamexp_winver_xpx64 )
2013-10-19 16:02:22 +02:00
{
2013-10-21 15:00:03 +02:00
qDebug ( " Running on Windows Server 2003, Windows Server 2003 R2 or Windows XP x64. \n " ) ; //lamexp_check_compatibility_mode("GetLocaleInfoEx", executableName);
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
else if ( osVersionNo = = lamexp_winver_vista )
2013-10-19 16:02:22 +02:00
{
2013-10-21 15:00:03 +02:00
qDebug ( " Running on Windows Vista or Windows Server 2008. \n " ) ; //lamexp_check_compatibility_mode("CreateRemoteThreadEx", executableName*/);
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
else if ( osVersionNo = = lamexp_winver_win70 )
2013-10-19 16:02:22 +02:00
{
2013-10-21 15:00:03 +02:00
qDebug ( " Running on Windows 7 or Windows Server 2008 R2. \n " ) ; //lamexp_check_compatibility_mode("CreateFile2", executableName);
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
else if ( osVersionNo = = lamexp_winver_win80 )
2013-10-19 16:02:22 +02:00
{
2013-10-21 15:00:03 +02:00
qDebug ( " Running on Windows 8 or Windows Server 2012. \n " ) ; //lamexp_check_compatibility_mode("FindPackagesByPackageFamily", executableName);
2013-10-19 16:02:22 +02:00
}
2013-10-20 19:12:00 +02:00
else if ( osVersionNo = = lamexp_winver_win81 )
2013-10-19 16:02:22 +02:00
{
2013-10-21 15:00:03 +02:00
qDebug ( " Running on Windows 8.1 or Windows Server 2012 R2. \n " ) ; //lamexp_check_compatibility_mode(NULL, executableName);
2013-10-19 16:02:22 +02:00
}
else
{
2013-10-20 19:12:00 +02:00
const QString message = QString ( ) . sprintf ( " Running on an unknown WindowsNT-based system (v%u.%u). " , osVersionNo . versionMajor , osVersionNo . versionMinor ) ;
2013-10-21 15:00:03 +02:00
qWarning ( " %s \n " , QUTF8 ( message ) ) ;
2013-10-20 19:12:00 +02:00
MessageBoxW ( NULL , QWCHAR ( message ) , L " LameXP " , MB_OK | MB_TOPMOST | MB_ICONWARNING ) ;
2010-11-06 23:04:47 +01:00
}
2010-12-23 03:13:11 +01:00
2013-10-20 23:34:04 +02:00
//Check for compat mode
2013-10-21 15:00:03 +02:00
if ( osVersionNo . overrideFlag & & ( osVersionNo < = lamexp_winver_win81 ) )
2013-10-20 23:34:04 +02:00
{
2013-10-21 16:51:01 +02:00
qWarning ( " Windows compatibility mode detected! " ) ;
if ( ! arguments . contains ( " --ignore-compat-mode " , Qt : : CaseInsensitive ) )
{
qFatal ( " %s " , QApplication : : tr ( " Executable '%1' doesn't support Windows compatibility mode. " ) . arg ( executableName ) . toLatin1 ( ) . constData ( ) ) ;
return false ;
}
2013-10-20 23:34:04 +02: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 ( ) ) ;
2013-10-21 15:00:03 +02:00
qDebug ( " Library Path: \n %s \n " , QUTF8 ( QApplication : : libraryPaths ( ) . first ( ) ) ) ;
2012-04-11 00:44:40 +02:00
//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 ) ;
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
}
2012-04-12 03:18:48 +02:00
2013-11-03 23:43:21 +01:00
//Add the default translations
lamexp_translation_init ( ) ;
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 " ) ;
2013-11-03 23:43:21 +01:00
QPixmap pixmap = QIcon ( " :/icons/sound.png " ) . pixmap ( 16 , 16 ) ;
if ( ( SetConsoleIconPtr ! = NULL ) & & ( ! pixmap . isNull ( ) ) ) SetConsoleIconPtr ( pixmap . toWinHICON ( ) ) ;
2011-07-27 22:17:43 +02:00
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 ;
}
2013-11-03 23:43:21 +01:00
const QStringList & lamexp_arguments ( void )
2010-11-06 23:04:47 +01:00
{
2013-11-03 23:43:21 +01:00
QReadLocker readLock ( & g_lamexp_argv . lock ) ;
if ( ! g_lamexp_argv . list )
2010-11-06 23:04:47 +01:00
{
2013-11-03 23:43:21 +01:00
readLock . unlock ( ) ;
QWriteLocker writeLock ( & g_lamexp_argv . lock ) ;
2010-11-11 22:58:02 +01:00
2013-11-03 23:43:21 +01:00
g_lamexp_argv . list = new QStringList ;
2010-11-08 19:29:36 +01:00
2013-11-03 23:43:21 +01:00
int nArgs = 0 ;
LPWSTR * szArglist = CommandLineToArgvW ( GetCommandLineW ( ) , & nArgs ) ;
2010-11-08 19:29:36 +01:00
2013-11-03 23:43:21 +01:00
if ( NULL ! = szArglist )
2010-11-06 23:04:47 +01:00
{
2013-11-03 23:43:21 +01:00
for ( int i = 0 ; i < nArgs ; i + + )
2010-11-08 19:29:36 +01:00
{
2013-11-03 23:43:21 +01:00
( * g_lamexp_argv . list ) < < WCHAR2QSTR ( szArglist [ i ] ) ;
2012-06-22 15:49:56 +02:00
}
LocalFree ( szArglist ) ;
}
else
{
2012-07-01 21:11:04 +02:00
qWarning ( " CommandLineToArgvW() has failed !!! " ) ;
2012-06-22 15:49:56 +02:00
}
}
2012-08-18 16:36:39 +02:00
return ( * g_lamexp_argv . list ) ;
2012-06-22 15:49:56 +02:00
}
2010-12-15 18:43:21 +01:00
/*
* Locate known folder on local system
*/
2012-08-18 22:37:10 +02:00
const QString & lamexp_known_folder ( lamexp_known_folder_t folder_id )
2010-12-15 18:43:21 +01:00
{
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
2013-06-29 18:06:21 +02:00
QReadLocker readLock ( & g_lamexp_known_folder . lock ) ;
2010-12-15 18:43:21 +01:00
int folderCSIDL = - 1 ;
GUID folderGUID = { 0x0000 , 0x0000 , 0x0000 , { 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 } } ;
2012-08-13 23:12:19 +02:00
size_t folderCacheId = size_t ( - 1 ) ;
2010-12-15 18:43:21 +01:00
switch ( folder_id )
{
case lamexp_folder_localappdata :
2012-08-13 23:12:19 +02:00
folderCacheId = 0 ;
2010-12-15 18:43:21 +01:00
folderCSIDL = CSIDL_LOCAL_APPDATA ;
folderGUID = GUID_LOCAL_APPDATA ;
break ;
case lamexp_folder_programfiles :
2012-08-13 23:12:19 +02:00
folderCacheId = 1 ;
2010-12-15 18:43:21 +01:00
folderCSIDL = CSIDL_PROGRAM_FILES ;
folderGUID = GUID_PROGRAM_FILES ;
break ;
2010-12-19 21:23:43 +01:00
case lamexp_folder_systemfolder :
2012-08-13 23:12:19 +02:00
folderCacheId = 2 ;
2010-12-19 21:23:43 +01:00
folderCSIDL = CSIDL_SYSTEM_FOLDER ;
folderGUID = GUID_SYSTEM_FOLDER ;
break ;
2010-12-15 18:43:21 +01:00
default :
2012-08-16 23:28:45 +02:00
qWarning ( " Invalid 'known' folder was requested! " ) ;
2012-08-18 22:37:10 +02:00
return * reinterpret_cast < QString * > ( NULL ) ;
2010-12-15 18:43:21 +01:00
break ;
}
2012-08-13 23:12:19 +02:00
//Already in cache?
2013-06-29 18:06:21 +02:00
if ( g_lamexp_known_folder . knownFolders )
2012-08-13 23:12:19 +02:00
{
2013-06-29 18:06:21 +02:00
if ( g_lamexp_known_folder . knownFolders - > contains ( folderCacheId ) )
2012-08-18 16:36:39 +02:00
{
2013-06-29 18:06:21 +02:00
return ( * g_lamexp_known_folder . knownFolders ) [ folderCacheId ] ;
2012-08-18 16:36:39 +02:00
}
2012-08-13 23:12:19 +02:00
}
2013-06-29 18:06:21 +02:00
//Obtain write lock to initialize
2012-08-13 23:12:19 +02:00
readLock . unlock ( ) ;
2013-06-29 18:06:21 +02:00
QWriteLocker writeLock ( & g_lamexp_known_folder . lock ) ;
//Still not in cache?
if ( g_lamexp_known_folder . knownFolders )
{
if ( g_lamexp_known_folder . knownFolders - > contains ( folderCacheId ) )
{
return ( * g_lamexp_known_folder . knownFolders ) [ folderCacheId ] ;
}
}
2012-08-13 23:12:19 +02:00
static SHGetKnownFolderPathFun SHGetKnownFolderPathPtr = NULL ;
static SHGetFolderPathFun SHGetFolderPathPtr = NULL ;
2013-06-29 18:06:21 +02:00
//Lookup functions
2012-08-13 23:12:19 +02:00
if ( ( ! SHGetKnownFolderPathPtr ) & & ( ! SHGetFolderPathPtr ) )
{
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
QString folder ;
2013-06-29 18:06:21 +02:00
//Now try to get the folder path!
2010-12-15 18:43:21 +01:00
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 ;
}
2012-08-18 22:37:10 +02:00
//Create cache
2013-06-29 18:06:21 +02:00
if ( ! g_lamexp_known_folder . knownFolders )
2012-08-13 23:12:19 +02:00
{
2013-06-29 18:06:21 +02:00
g_lamexp_known_folder . knownFolders = new QMap < size_t , QString > ( ) ;
2012-08-13 23:12:19 +02:00
}
2012-08-18 22:37:10 +02:00
//Update cache
2013-06-29 18:06:21 +02:00
g_lamexp_known_folder . knownFolders - > insert ( folderCacheId , folder ) ;
return ( * g_lamexp_known_folder . knownFolders ) [ folderCacheId ] ;
2010-12-15 18:43:21 +01:00
}
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 ) )
{
2013-11-17 21:51:41 +01:00
static const DWORD attrMask = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM ;
const DWORD attributes = GetFileAttributesW ( QWCHAR ( filename ) ) ;
if ( attributes & attrMask )
{
SetFileAttributesW ( QWCHAR ( filename ) , FILE_ATTRIBUTE_NORMAL ) ;
}
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 ) ;
2013-02-25 23:12:14 +01:00
QReadLocker readLock ( & g_lamexp_themes_enabled . lock ) ;
if ( g_lamexp_themes_enabled . bInitialized )
{
return g_lamexp_themes_enabled . bThemesEnabled ;
}
2011-01-02 20:47:26 +01:00
2013-02-25 23:12:14 +01:00
readLock . unlock ( ) ;
QWriteLocker writeLock ( & g_lamexp_themes_enabled . lock ) ;
if ( ! g_lamexp_themes_enabled . bInitialized )
2011-01-02 20:47:26 +01:00
{
2013-02-25 23:12:14 +01:00
g_lamexp_themes_enabled . bThemesEnabled = false ;
2013-10-20 19:12:00 +02:00
const lamexp_os_version_t & osVersion = lamexp_get_os_version ( ) ;
if ( osVersion > = lamexp_winver_winxp )
2012-04-10 03:51:04 +02:00
{
2013-02-25 23:12:14 +01:00
IsAppThemedFun IsAppThemedPtr = NULL ;
QLibrary uxTheme ( QString ( " %1/UxTheme.dll " ) . arg ( lamexp_known_folder ( lamexp_folder_systemfolder ) ) ) ;
if ( uxTheme . load ( ) )
2012-04-10 03:51:04 +02:00
{
2013-02-25 23:12:14 +01:00
IsAppThemedPtr = ( IsAppThemedFun ) uxTheme . resolve ( " IsAppThemed " ) ;
}
if ( IsAppThemedPtr )
{
g_lamexp_themes_enabled . bThemesEnabled = IsAppThemedPtr ( ) ;
if ( ! g_lamexp_themes_enabled . bThemesEnabled )
{
qWarning ( " Theme support is disabled for this process! " ) ;
}
2012-04-10 03:51:04 +02:00
}
}
2013-02-25 23:12:14 +01:00
g_lamexp_themes_enabled . bInitialized = true ;
2011-01-02 20:47:26 +01:00
}
2013-02-25 23:12:14 +01:00
return g_lamexp_themes_enabled . bThemesEnabled ;
2011-01-02 20:47:26 +01:00
}
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 ;
}
2013-01-12 01:53:43 +01:00
/*
* Determines the current date , resistant against certain manipulations
*/
QDate lamexp_current_date_safe ( void )
{
const DWORD MAX_PROC = 1024 ;
DWORD * processes = new DWORD [ MAX_PROC ] ;
DWORD bytesReturned = 0 ;
if ( ! EnumProcesses ( processes , sizeof ( DWORD ) * MAX_PROC , & bytesReturned ) )
{
LAMEXP_DELETE_ARRAY ( processes ) ;
return QDate : : currentDate ( ) ;
}
const DWORD procCount = bytesReturned / sizeof ( DWORD ) ;
ULARGE_INTEGER lastStartTime ;
memset ( & lastStartTime , 0 , sizeof ( ULARGE_INTEGER ) ) ;
for ( DWORD i = 0 ; i < procCount ; i + + )
{
HANDLE hProc = OpenProcess ( PROCESS_QUERY_INFORMATION , FALSE , processes [ i ] ) ;
if ( hProc )
{
FILETIME processTime [ 4 ] ;
if ( GetProcessTimes ( hProc , & processTime [ 0 ] , & processTime [ 1 ] , & processTime [ 2 ] , & processTime [ 3 ] ) )
{
ULARGE_INTEGER timeCreation ;
timeCreation . LowPart = processTime [ 0 ] . dwLowDateTime ;
timeCreation . HighPart = processTime [ 0 ] . dwHighDateTime ;
if ( timeCreation . QuadPart > lastStartTime . QuadPart )
{
lastStartTime . QuadPart = timeCreation . QuadPart ;
}
}
CloseHandle ( hProc ) ;
}
}
LAMEXP_DELETE_ARRAY ( processes ) ;
FILETIME lastStartTime_fileTime ;
lastStartTime_fileTime . dwHighDateTime = lastStartTime . HighPart ;
lastStartTime_fileTime . dwLowDateTime = lastStartTime . LowPart ;
FILETIME lastStartTime_localTime ;
if ( ! FileTimeToLocalFileTime ( & lastStartTime_fileTime , & lastStartTime_localTime ) )
{
memcpy ( & lastStartTime_localTime , & lastStartTime_fileTime , sizeof ( FILETIME ) ) ;
}
SYSTEMTIME lastStartTime_system ;
if ( ! FileTimeToSystemTime ( & lastStartTime_localTime , & lastStartTime_system ) )
{
memset ( & lastStartTime_system , 0 , sizeof ( SYSTEMTIME ) ) ;
lastStartTime_system . wYear = 1970 ; lastStartTime_system . wMonth = lastStartTime_system . wDay = 1 ;
}
const QDate currentDate = QDate : : currentDate ( ) ;
const QDate processDate = QDate ( lastStartTime_system . wYear , lastStartTime_system . wMonth , lastStartTime_system . wDay ) ;
return ( currentDate > = processDate ) ? currentDate : processDate ;
}
2013-10-07 00:01:15 +02:00
/*
* Suspend calling thread for N milliseconds
*/
2013-10-25 17:55:27 +02:00
inline void lamexp_sleep ( const unsigned int delay )
2013-10-07 00:01:15 +02:00
{
Sleep ( delay ) ;
}
bool lamexp_beep ( int beepType )
{
switch ( beepType )
{
case lamexp_beep_info : return MessageBeep ( MB_ICONASTERISK ) = = TRUE ; break ;
case lamexp_beep_warning : return MessageBeep ( MB_ICONEXCLAMATION ) = = TRUE ; break ;
case lamexp_beep_error : return MessageBeep ( MB_ICONHAND ) = = TRUE ; break ;
default : return false ;
}
}
/*
* Play a sound ( from resources )
*/
bool lamexp_play_sound ( const unsigned short uiSoundIdx , const bool bAsync , const wchar_t * alias )
{
if ( alias )
{
return PlaySound ( alias , GetModuleHandle ( NULL ) , ( SND_ALIAS | ( bAsync ? SND_ASYNC : SND_SYNC ) ) ) = = TRUE ;
}
else
{
return PlaySound ( MAKEINTRESOURCE ( uiSoundIdx ) , GetModuleHandle ( NULL ) , ( SND_RESOURCE | ( bAsync ? SND_ASYNC : SND_SYNC ) ) ) = = TRUE ;
}
}
/*
* Play a sound ( from resources )
*/
bool lamexp_play_sound_file ( const QString & library , const unsigned short uiSoundIdx , const bool bAsync )
{
bool result = false ;
HMODULE module = NULL ;
QFileInfo libraryFile ( library ) ;
if ( ! libraryFile . isAbsolute ( ) )
{
unsigned int buffSize = GetSystemDirectoryW ( NULL , NULL ) + 1 ;
wchar_t * buffer = ( wchar_t * ) _malloca ( buffSize * sizeof ( wchar_t ) ) ;
unsigned int result = GetSystemDirectory ( buffer , buffSize ) ;
if ( result > 0 & & result < buffSize )
{
libraryFile . setFile ( QString ( " %1/%2 " ) . arg ( QDir : : fromNativeSeparators ( QString : : fromUtf16 ( reinterpret_cast < const unsigned short * > ( buffer ) ) ) , library ) ) ;
}
_freea ( buffer ) ;
}
module = LoadLibraryW ( QWCHAR ( QDir : : toNativeSeparators ( libraryFile . absoluteFilePath ( ) ) ) ) ;
if ( module )
{
result = ( PlaySound ( MAKEINTRESOURCE ( uiSoundIdx ) , module , ( SND_RESOURCE | ( bAsync ? SND_ASYNC : SND_SYNC ) ) ) = = TRUE ) ;
FreeLibrary ( module ) ;
}
return result ;
}
/*
* Open file using the shell
*/
bool lamexp_exec_shell ( const QWidget * win , const QString & url , const bool explore )
{
return lamexp_exec_shell ( win , url , QString ( ) , QString ( ) , explore ) ;
}
/*
* Open file using the shell ( with parameters )
*/
bool lamexp_exec_shell ( const QWidget * win , const QString & url , const QString & parameters , const QString & directory , const bool explore )
{
return ( ( int ) ShellExecuteW ( ( ( win ) ? win - > winId ( ) : NULL ) , ( explore ? L " explore " : L " open " ) , QWCHAR ( url ) , ( ( ! parameters . isEmpty ( ) ) ? QWCHAR ( parameters ) : NULL ) , ( ( ! directory . isEmpty ( ) ) ? QWCHAR ( directory ) : NULL ) , SW_SHOW ) ) > 32 ;
}
/*
* Query value of the performance counter
*/
__int64 lamexp_perfcounter_value ( void )
{
LARGE_INTEGER counter ;
if ( QueryPerformanceCounter ( & counter ) = = TRUE )
{
return counter . QuadPart ;
}
return - 1 ;
}
/*
* Query frequency of the performance counter
*/
__int64 lamexp_perfcounter_frequ ( void )
{
LARGE_INTEGER frequency ;
if ( QueryPerformanceFrequency ( & frequency ) = = TRUE )
{
return frequency . QuadPart ;
}
return - 1 ;
}
/*
* Insert entry to the window ' s system menu
*/
bool lamexp_append_sysmenu ( const QWidget * win , const unsigned int identifier , const QString & text )
{
bool ok = false ;
if ( HMENU hMenu = GetSystemMenu ( win - > winId ( ) , FALSE ) )
{
ok = ( AppendMenuW ( hMenu , MF_SEPARATOR , 0 , 0 ) = = TRUE ) ;
ok = ( AppendMenuW ( hMenu , MF_STRING , identifier , QWCHAR ( text ) ) = = TRUE ) ;
}
return ok ;
}
/*
* Insert entry to the window ' s system menu
*/
bool lamexp_check_sysmenu_msg ( void * message , const unsigned int identifier )
{
return ( ( ( MSG * ) message ) - > message = = WM_SYSCOMMAND ) & & ( ( ( ( MSG * ) message ) - > wParam & 0xFFF0 ) = = identifier ) ;
}
/*
* Update system menu entry
*/
bool lamexp_update_sysmenu ( const QWidget * win , const unsigned int identifier , const QString & text )
{
bool ok = false ;
if ( HMENU hMenu = : : GetSystemMenu ( win - > winId ( ) , FALSE ) )
{
ok = ( ModifyMenu ( hMenu , identifier , MF_STRING | MF_BYCOMMAND , identifier , QWCHAR ( text ) ) = = TRUE ) ;
}
return ok ;
}
/*
* Display the window ' s close button
*/
bool lamexp_enable_close_button ( const QWidget * win , const bool bEnable )
{
bool ok = false ;
if ( HMENU hMenu = GetSystemMenu ( win - > winId ( ) , FALSE ) )
{
ok = ( EnableMenuItem ( hMenu , SC_CLOSE , MF_BYCOMMAND | ( bEnable ? MF_ENABLED : MF_GRAYED ) ) = = TRUE ) ;
}
return ok ;
}
/*
* Check whether ESC key has been pressed since the previous call to this function
*/
bool lamexp_check_escape_state ( void )
{
return ( GetAsyncKeyState ( VK_ESCAPE ) & 0x0001 ) ! = 0 ;
}
/*
* Set the process priority class for current process
*/
bool lamexp_change_process_priority ( const int priority )
{
return lamexp_change_process_priority ( GetCurrentProcess ( ) , priority ) ;
}
/*
* Set the process priority class for specified process
*/
bool lamexp_change_process_priority ( const QProcess * proc , const int priority )
{
2013-10-29 02:05:43 +01:00
if ( Q_PID qPid = proc - > pid ( ) )
{
return lamexp_change_process_priority ( qPid - > hProcess , priority ) ;
}
else
{
return false ;
}
2013-10-07 00:01:15 +02:00
}
/*
* Set the process priority class for specified process
*/
bool lamexp_change_process_priority ( void * hProcess , const int priority )
{
bool ok = false ;
switch ( qBound ( - 2 , priority , 2 ) )
{
case 2 :
ok = ( SetPriorityClass ( hProcess , HIGH_PRIORITY_CLASS ) = = TRUE ) ;
break ;
case 1 :
if ( ! ( ok = ( SetPriorityClass ( hProcess , ABOVE_NORMAL_PRIORITY_CLASS ) = = TRUE ) ) )
{
ok = ( SetPriorityClass ( hProcess , HIGH_PRIORITY_CLASS ) = = TRUE ) ;
}
break ;
case 0 :
ok = ( SetPriorityClass ( hProcess , NORMAL_PRIORITY_CLASS ) = = TRUE ) ;
break ;
case - 1 :
if ( ! ( ok = ( SetPriorityClass ( hProcess , BELOW_NORMAL_PRIORITY_CLASS ) = = TRUE ) ) )
{
ok = ( SetPriorityClass ( hProcess , IDLE_PRIORITY_CLASS ) = = TRUE ) ;
}
break ;
case - 2 :
ok = ( SetPriorityClass ( hProcess , IDLE_PRIORITY_CLASS ) = = TRUE ) ;
break ;
}
return ok ;
}
/*
* Returns the current file time
*/
unsigned __int64 lamexp_current_file_time ( void )
{
FILETIME fileTime ;
GetSystemTimeAsFileTime ( & fileTime ) ;
ULARGE_INTEGER temp ;
temp . HighPart = fileTime . dwHighDateTime ;
temp . LowPart = fileTime . dwLowDateTime ;
return temp . QuadPart ;
}
/*
* Bring the specifed window to the front
*/
bool lamexp_bring_to_front ( const QWidget * win )
{
const bool ret = ( SetForegroundWindow ( win - > winId ( ) ) = = TRUE ) ;
SwitchToThisWindow ( win - > winId ( ) , TRUE ) ;
return ret ;
}
/*
* Bring window of the specifed process to the front ( callback )
*/
static BOOL CALLBACK lamexp_bring_process_to_front_helper ( HWND hwnd , LPARAM lParam )
{
DWORD processId = * reinterpret_cast < WORD * > ( lParam ) ;
DWORD windowProcessId = NULL ;
GetWindowThreadProcessId ( hwnd , & windowProcessId ) ;
if ( windowProcessId = = processId )
{
SwitchToThisWindow ( hwnd , TRUE ) ;
SetForegroundWindow ( hwnd ) ;
return FALSE ;
}
return TRUE ;
}
/*
* Bring window of the specifed process to the front
*/
bool lamexp_bring_process_to_front ( const unsigned long pid )
{
return EnumWindows ( lamexp_bring_process_to_front_helper , reinterpret_cast < LPARAM > ( & pid ) ) = = TRUE ;
}
/*
2013-10-19 16:02:22 +02:00
* Check the network connection status
2013-10-07 00:01:15 +02:00
*/
2013-10-19 16:02:22 +02:00
int lamexp_network_status ( void )
2013-10-07 00:01:15 +02:00
{
2013-10-19 16:02:22 +02:00
DWORD dwFlags ;
const BOOL ret = ( IsNetworkAlive ( & dwFlags ) = = TRUE ) ;
if ( GetLastError ( ) = = 0 )
{
return ( ret = = TRUE ) ? lamexp_network_yes : lamexp_network_non ;
}
return lamexp_network_err ;
2013-10-07 00:01:15 +02:00
}
/*
* Retrun the process ID of the given QProcess
*/
unsigned long lamexp_process_id ( const QProcess * proc )
{
PROCESS_INFORMATION * procInf = proc - > pid ( ) ;
return ( procInf ) ? procInf - > dwProcessId : NULL ;
}
/*
* Convert long path to short path
*/
QString lamexp_path_to_short ( const QString & longPath )
{
QString shortPath ;
DWORD buffSize = GetShortPathNameW ( reinterpret_cast < const wchar_t * > ( longPath . utf16 ( ) ) , NULL , NULL ) ;
if ( buffSize > 0 )
{
wchar_t * buffer = new wchar_t [ buffSize ] ;
DWORD result = GetShortPathNameW ( reinterpret_cast < const wchar_t * > ( longPath . utf16 ( ) ) , buffer , buffSize ) ;
if ( result > 0 & & result < buffSize )
{
shortPath = QString : : fromUtf16 ( reinterpret_cast < const unsigned short * > ( buffer ) ) ;
}
delete [ ] buffer ;
}
return ( shortPath . isEmpty ( ) ? longPath : shortPath ) ;
}
/*
* Open media file in external player
*/
bool lamexp_open_media_file ( const QString & mediaFilePath )
{
const static wchar_t * registryPrefix [ 2 ] = { L " SOFTWARE \\ " , L " SOFTWARE \\ Wow6432Node \\ " } ;
const static wchar_t * registryKeys [ 3 ] =
{
L " Microsoft \\ Windows \\ CurrentVersion \\ Uninstall \\ {97D341C8-B0D1-4E4A-A49A-C30B52F168E9} " ,
L " Microsoft \\ Windows \\ CurrentVersion \\ Uninstall \\ {DB9E4EAB-2717-499F-8D56-4CC8A644AB60} " ,
L " foobar2000 "
} ;
const static wchar_t * appNames [ 4 ] = { L " smplayer_portable.exe " , L " smplayer.exe " , L " MPUI.exe " , L " foobar2000.exe " } ;
const static wchar_t * valueNames [ 2 ] = { L " InstallLocation " , L " InstallDir " } ;
for ( size_t i = 0 ; i < 3 ; i + + )
{
for ( size_t j = 0 ; j < 2 ; j + + )
{
QString mplayerPath ;
HKEY registryKeyHandle = NULL ;
const QString currentKey = WCHAR2QSTR ( registryPrefix [ j ] ) . append ( WCHAR2QSTR ( registryKeys [ i ] ) ) ;
if ( RegOpenKeyExW ( HKEY_LOCAL_MACHINE , QWCHAR ( currentKey ) , 0 , KEY_READ , & registryKeyHandle ) = = ERROR_SUCCESS )
{
for ( size_t k = 0 ; k < 2 ; k + + )
{
wchar_t Buffer [ 4096 ] ;
DWORD BuffSize = sizeof ( wchar_t * ) * 4096 ;
DWORD DataType = REG_NONE ;
if ( RegQueryValueExW ( registryKeyHandle , valueNames [ k ] , 0 , & DataType , reinterpret_cast < BYTE * > ( Buffer ) , & BuffSize ) = = ERROR_SUCCESS )
{
if ( ( DataType = = REG_SZ ) | | ( DataType = = REG_EXPAND_SZ ) | | ( DataType = = REG_LINK ) )
{
mplayerPath = WCHAR2QSTR ( Buffer ) ;
break ;
}
}
}
RegCloseKey ( registryKeyHandle ) ;
}
if ( ! mplayerPath . isEmpty ( ) )
{
QDir mplayerDir ( mplayerPath ) ;
if ( mplayerDir . exists ( ) )
{
for ( size_t k = 0 ; k < 4 ; k + + )
{
if ( mplayerDir . exists ( WCHAR2QSTR ( appNames [ k ] ) ) )
{
2013-10-21 15:00:03 +02:00
qDebug ( " Player found at: \n %s \n " , QUTF8 ( mplayerDir . absoluteFilePath ( WCHAR2QSTR ( appNames [ k ] ) ) ) ) ;
2013-10-07 00:01:15 +02:00
QProcess : : startDetached ( mplayerDir . absoluteFilePath ( WCHAR2QSTR ( appNames [ k ] ) ) , QStringList ( ) < < QDir : : toNativeSeparators ( mediaFilePath ) ) ;
return true ;
}
}
}
}
}
}
return false ;
}
2012-12-11 22:54:00 +01:00
/*
* Fatal application exit
*/
# pragma intrinsic(_InterlockedExchange)
void lamexp_fatal_exit ( const wchar_t * exitMessage , const wchar_t * errorBoxMessage )
{
static volatile long bFatalFlag = 0L ;
if ( _InterlockedExchange ( & bFatalFlag , 1L ) = = 0L )
{
if ( GetCurrentThreadId ( ) ! = g_main_thread_id )
{
HANDLE mainThread = OpenThread ( THREAD_TERMINATE , FALSE , g_main_thread_id ) ;
if ( mainThread ) TerminateThread ( mainThread , ULONG_MAX ) ;
}
if ( errorBoxMessage )
{
MessageBoxW ( NULL , errorBoxMessage , L " LameXP - GURU MEDITATION " , MB_ICONERROR | MB_TOPMOST | MB_TASKMODAL ) ;
}
for ( ; ; )
{
FatalAppExit ( 0 , exitMessage ) ;
TerminateProcess ( GetCurrentProcess ( ) , - 1 ) ;
}
}
2013-01-12 01:53:43 +01:00
2013-01-17 20:46:07 +01:00
TerminateThread ( GetCurrentThread ( ) , - 1 ) ;
Sleep ( INFINITE ) ;
2012-12-11 22:54:00 +01:00
}
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
2013-11-03 23:43:21 +01:00
lamexp_clean_all_tools ( ) ;
2010-12-28 21:26:16 +01:00
//Delete temporary files
2013-11-03 23:43:21 +01:00
const QString & tempFolder = lamexp_temp_folder2 ( ) ;
if ( ! tempFolder . isEmpty ( ) )
2010-12-28 21:26:16 +01:00
{
2013-11-03 23:43:21 +01:00
bool success = false ;
for ( int i = 0 ; i < 100 ; i + + )
2010-12-28 21:26:16 +01:00
{
2013-11-03 23:43:21 +01:00
if ( lamexp_clean_folder ( tempFolder ) )
2013-10-12 20:33:13 +02:00
{
2013-11-03 23:43:21 +01:00
success = true ;
break ;
2010-12-28 21:26:16 +01:00
}
2013-11-03 23:43:21 +01:00
lamexp_sleep ( 100 ) ;
}
if ( ! success )
{
MessageBoxW ( NULL , L " Sorry, LameXP was unable to clean up all temporary files. Some residual files in your TEMP directory may require manual deletion! " , L " LameXP " , MB_ICONEXCLAMATION | MB_TOPMOST ) ;
lamexp_exec_shell ( NULL , tempFolder , QString ( ) , QString ( ) , true ) ;
2010-12-28 21:26:16 +01:00
}
}
2012-08-18 16:36:39 +02:00
//Clear folder cache
2013-06-29 18:06:21 +02:00
LAMEXP_DELETE ( g_lamexp_known_folder . knownFolders ) ;
2012-08-18 16:36:39 +02:00
2010-12-28 21:26:16 +01:00
//Clear languages
2013-11-03 23:43:21 +01:00
lamexp_clean_all_translations ( ) ;
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
2013-11-03 23:43:21 +01:00
lamexp_ipc_exit ( ) ;
2012-04-06 23:15:58 +02:00
//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 ;
}
2012-06-22 15:49:56 +02:00
//Free CLI Arguments
2012-08-18 16:36:39 +02:00
LAMEXP_DELETE ( g_lamexp_argv . list ) ;
2013-11-03 23:43:21 +01:00
//Free TEMP folder
lamexp_temp_folder_clear ( ) ;
2010-12-28 21:26:16 +01:00
}
2011-04-19 16:14:05 +02:00
/*
* Initialize debug thread
*/
2013-10-26 15:49:16 +02:00
static const HANDLE g_debug_thread1 = LAMEXP_DEBUG ? NULL : lamexp_debug_thread_init ( ) ;
2011-04-19 16:14:05 +02:00
2010-11-07 16:32:54 +01:00
/*
* Get number private bytes [ debug only ]
*/
2013-10-06 19:28:12 +02:00
unsigned long lamexp_dbg_private_bytes ( void )
2010-11-07 16:32:54 +01:00
{
2011-04-19 16:14:05 +02:00
# if LAMEXP_DEBUG
2013-08-21 19:20:39 +02:00
for ( int i = 0 ; i < 8 ; i + + ) _heapmin ( ) ;
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
2013-10-18 21:37:40 +02:00
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
}
2013-11-03 23:43:21 +01:00
/*
* Output string to debugger [ debug only ]
*/
void lamexp_dbg_dbg_output_string ( const char * format , . . . )
{
# if LAMEXP_DEBUG
char buffer [ 256 ] ;
va_list args ;
va_start ( args , format ) ;
vsnprintf_s ( buffer , 256 , _TRUNCATE , format , args ) ;
OutputDebugStringA ( buffer ) ;
va_end ( args ) ;
# else
THROW ( " Cannot call this function in a non-debug build! " ) ;
# endif //LAMEXP_DEBUG
}
///////////////////////////////////////////////////////////////////////////////
// INITIALIZATION
///////////////////////////////////////////////////////////////////////////////
extern " C " void _lamexp_global_init_win32 ( void )
{
if ( ( ! LAMEXP_DEBUG ) & & lamexp_check_for_debugger ( ) )
{
lamexp_fatal_exit ( L " Not a debug build. Please unload debugger and try again! " ) ;
}
//Zero *before* constructors are called
LAMEXP_ZERO_MEMORY ( g_lamexp_argv ) ;
LAMEXP_ZERO_MEMORY ( g_lamexp_known_folder ) ;
LAMEXP_ZERO_MEMORY ( g_lamexp_os_version ) ;
LAMEXP_ZERO_MEMORY ( g_lamexp_wine ) ;
LAMEXP_ZERO_MEMORY ( g_lamexp_themes_enabled ) ;
}