diff --git a/.gitignore b/.gitignore index dc2aafa2..653454a2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,28 @@ -/LameXP_*.user -/LameXP_*.opensdf -/LameXP_*.sdf -/LameXP_*.suo -/LameXP_*.ncb -/LameXP_*.sln.docstates +*.user +*.opensdf +*.sdf +*.suo +*.ncb +*.docstates +*.db +*.old +*.bak +*.rar +*.zip /bin -etc/Deployment/*.exe -etc/Deployment/_postproc.bat -etc/Deployment/buildenv.txt -etc/Prerequisites/qt4_static/lib -etc/Prerequisites/qt4_static/plugins -etc/Prerequisites/qt4_static/bin -etc/Prerequisites/*.old -etc/Translation/*.ts.bak +/etc/Addins +/etc/Deployment/_postproc.bat +/etc/Deployment/buildenv.txt +/etc/Prerequisites/qt4_static/lib +/etc/Prerequisites/qt4_static/plugins +/etc/Prerequisites/qt4_static/bin +/etc/Prerequisites/qt4_dll +/etc/Prerequisites/keccak/ipch +/etc/Prerequisites/keccak/obj +/etc/Prerequisites/z_old /ipch /obj -/src/Config.h.bak -/tmp/MOC_*.cpp -/tmp/QRC_*.cpp -/tmp/UIC_*.h -/gui/*.ui.bak* -*.db +/out +/res/tools/old +/tmp/*.cpp +/tmp/*.h diff --git a/src/Config.h b/src/Config.h index 812267d2..4da575d9 100644 --- a/src/Config.h +++ b/src/Config.h @@ -35,7 +35,7 @@ #define VER_LAMEXP_MINOR_LO 1 #define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_PATCH 1 -#define VER_LAMEXP_BUILD 1560 +#define VER_LAMEXP_BUILD 1562 #define VER_LAMEXP_CONFG 1558 /////////////////////////////////////////////////////////////////////////////// diff --git a/src/Global.h b/src/Global.h index da262127..3e1d113b 100644 --- a/src/Global.h +++ b/src/Global.h @@ -171,7 +171,7 @@ bool lamexp_detect_wine(void); bool lamexp_enable_close_button(const QWidget *win, const bool bEnable = true); bool lamexp_exec_shell(const QWidget *win, const QString &url, const bool explore = false); bool lamexp_exec_shell(const QWidget *win, const QString &url, const QString ¶meters, const QString &directory, const bool explore = false); -void lamexp_fatal_exit(const wchar_t* exitMessage, const wchar_t* errorBoxMessage = NULL); +void lamexp_fatal_exit(const char* const errorMessage); void lamexp_finalization(void); unsigned __int64 lamexp_free_diskspace(const QString &path, bool *ok = NULL); void lamexp_free_window_icon(lamexp_icon_t *icon); @@ -292,6 +292,13 @@ while(0) throw std::runtime_error(_error_msg); \ } \ while(0) +#define PRINT_ERROR(X, ...) do \ +{ \ + fflush(stdout); \ + fprintf(stderr, (X), __VA_ARGS__); \ + fflush(stderr); \ +} \ +while(0) //Memory check #if LAMEXP_DEBUG diff --git a/src/Global_Tools.cpp b/src/Global_Tools.cpp index dceb662f..cdbe0fac 100644 --- a/src/Global_Tools.cpp +++ b/src/Global_Tools.cpp @@ -167,26 +167,28 @@ const QString lamexp_version2string(const QString &pattern, unsigned int version } QString result = pattern; - int digits = result.count("?", Qt::CaseInsensitive); + const int digits = result.count(QChar(L'?'), 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); + int pos = 0, index = -1; + const QString versionStr = QString().sprintf("%0*u", digits, version); + Q_ASSERT(versionStr.length() == digits); - while(index >= 0 && pos < versionStr.length()) + while((index = result.indexOf(QChar(L'?'), Qt::CaseInsensitive)) >= 0) { result[index] = versionStr[pos++]; - index = result.indexOf("?", Qt::CaseInsensitive); } if(tag) { - result.replace(QChar('#'), *tag, Qt::CaseInsensitive); + if((index = result.indexOf(QChar(L'#'), Qt::CaseInsensitive)) >= 0) + { + result.remove(index, 1).insert(index, (*tag)); + } } return result; diff --git a/src/Global_Win32.cpp b/src/Global_Win32.cpp index f476a7bc..09a95d51 100644 --- a/src/Global_Win32.cpp +++ b/src/Global_Win32.cpp @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -127,6 +126,78 @@ while(0) typedef HRESULT (WINAPI *SHGetKnownFolderPath_t)(const GUID &rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath); typedef HRESULT (WINAPI *SHGetFolderPath_t)(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath); +/////////////////////////////////////////////////////////////////////////////// +// CRITICAL SECTION +/////////////////////////////////////////////////////////////////////////////// + +/* + * wrapper for native Win32 critical sections + */ +class CriticalSection +{ +public: + inline CriticalSection(void) + { + InitializeCriticalSection(&m_win32criticalSection); + } + + inline ~CriticalSection(void) + { + DeleteCriticalSection(&m_win32criticalSection); + } + + inline void enter(void) + { + EnterCriticalSection(&m_win32criticalSection); + } + + inline bool tryEnter(void) + { + return TryEnterCriticalSection(&m_win32criticalSection); + } + + inline void leave(void) + { + LeaveCriticalSection(&m_win32criticalSection); + } + +protected: + CRITICAL_SECTION m_win32criticalSection; +}; + +/* + * RAII-style critical section locker + */ +class CSLocker +{ +public: + inline CSLocker(CriticalSection &criticalSection) + : + m_locked(false), + m_criticalSection(criticalSection) + { + m_criticalSection.enter(); + m_locked = true; + } + + inline ~CSLocker(void) + { + forceUnlock(); + } + + inline void forceUnlock(void) + { + if(m_locked) + { + m_criticalSection.leave(); + m_locked = false; + } + } +protected: + volatile bool m_locked; + CriticalSection &m_criticalSection; +}; + /////////////////////////////////////////////////////////////////////////////// // GLOBAL VARS /////////////////////////////////////////////////////////////////////////////// @@ -134,6 +205,13 @@ typedef HRESULT (WINAPI *SHGetFolderPath_t)(HWND hwndOwner, int nFolder, HANDLE //Console attached flag static bool g_lamexp_console_attached = false; +//Fatal exit flags +static volatile bool g_lamexp_fatal_flag = true; +static CriticalSection g_lamexp_fatal_lock; + +//Global locks +static CriticalSection g_lamexp_message_lock; + //Special folders static struct { @@ -202,9 +280,6 @@ g_lamexp_sounds; //Image formats static const char *g_lamexp_imageformats[] = {"bmp", "png", "jpg", "gif", "ico", "xpm", NULL}; //"svg" -//Global locks -static QMutex g_lamexp_message_mutex; - //Main thread ID static const DWORD g_main_thread_id = GetCurrentThreadId(); @@ -541,7 +616,7 @@ void lamexp_message_handler(QtMsgType type, const char *msg) return; } - QMutexLocker lock(&g_lamexp_message_mutex); + CSLocker lock(g_lamexp_message_lock); if(g_lamexp_log_file) { @@ -559,8 +634,8 @@ void lamexp_message_handler(QtMsgType type, const char *msg) if((type == QtCriticalMsg) || (type == QtFatalMsg)) { - lock.unlock(); - lamexp_fatal_exit(L"The application has encountered a critical error and will exit now!", QWCHAR(QString::fromUtf8(msg))); + lock.forceUnlock(); + lamexp_fatal_exit(msg); } } @@ -569,7 +644,7 @@ void lamexp_message_handler(QtMsgType type, const char *msg) */ 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!"); + lamexp_fatal_exit("Invalid parameter handler invoked, application will exit!"); } /* @@ -578,7 +653,7 @@ static void lamexp_invalid_param_handler(const wchar_t* exp, const wchar_t* fun, static void lamexp_signal_handler(int signal_num) { signal(signal_num, lamexp_signal_handler); - lamexp_fatal_exit(L"Signal handler invoked, application will exit!"); + lamexp_fatal_exit("Signal handler invoked, application will exit!"); } /* @@ -586,7 +661,7 @@ static void lamexp_signal_handler(int signal_num) */ static LONG WINAPI lamexp_exception_handler(struct _EXCEPTION_POINTERS *ExceptionInfo) { - lamexp_fatal_exit(L"Unhandeled exception handler invoked, application will exit!"); + lamexp_fatal_exit("Unhandeled exception handler invoked, application will exit!"); return LONG_MAX; } @@ -831,7 +906,7 @@ static unsigned int __stdcall lamexp_debug_thread_proc(LPVOID lpParameter) { if(lamexp_check_for_debugger()) { - lamexp_fatal_exit(L"Not a debug build. Please unload debugger and try again!"); + lamexp_fatal_exit("Not a debug build. Please unload debugger and try again!"); return 666; } lamexp_sleep(100); @@ -845,7 +920,7 @@ static HANDLE lamexp_debug_thread_init() { if(lamexp_check_for_debugger()) { - lamexp_fatal_exit(L"Not a debug build. Please unload debugger and try again!"); + lamexp_fatal_exit("Not a debug build. Please unload debugger and try again!"); } const uintptr_t h = _beginthreadex(NULL, 0, lamexp_debug_thread_proc, NULL, 0, NULL); return (HANDLE)(h^0xdeadbeef); @@ -858,7 +933,7 @@ static bool lamexp_event_filter(void *message, long *result) { if((!(LAMEXP_DEBUG)) && lamexp_check_for_debugger()) { - lamexp_fatal_exit(L"Not a debug build. Please unload debugger and try again!"); + lamexp_fatal_exit("Not a debug build. Please unload debugger and try again!"); } switch(reinterpret_cast(message)->message) @@ -2280,36 +2355,46 @@ bool lamexp_is_executable(const QString &path) return bIsExecutable; } +/* + * Fatal application exit - helper + */ +static DWORD WINAPI lamexp_fatal_exit_helper(LPVOID lpParameter) +{ + MessageBoxA(NULL, ((LPCSTR) lpParameter), "LameXP - Guru Meditation", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST | MB_SETFOREGROUND); + return 0; +} + /* * Fatal application exit */ -#pragma intrinsic(_InterlockedExchange) -void lamexp_fatal_exit(const wchar_t* exitMessage, const wchar_t* errorBoxMessage) +void lamexp_fatal_exit(const char* const errorMessage) { - 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); - } + g_lamexp_fatal_lock.enter(); - if(errorBoxMessage) - { - MessageBoxW(NULL, errorBoxMessage, L"LameXP - GURU MEDITATION", MB_ICONERROR | MB_TOPMOST | MB_TASKMODAL); - } + if(!g_lamexp_fatal_flag) + { + return; /*prevent recursive invocation*/ + } - for(;;) + g_lamexp_fatal_flag = false; + + if(g_main_thread_id != GetCurrentThreadId()) + { + if(HANDLE hThreadMain = OpenThread(THREAD_SUSPEND_RESUME, FALSE, g_main_thread_id)) { - FatalAppExit(0, exitMessage); - TerminateProcess(GetCurrentProcess(), -1); + SuspendThread(hThreadMain); /*stop main thread*/ } } - TerminateThread(GetCurrentThread(), -1); - Sleep(INFINITE); + if(HANDLE hThread = CreateThread(NULL, 0, lamexp_fatal_exit_helper, (LPVOID) errorMessage, 0, NULL)) + { + WaitForSingleObject(hThread, INFINITE); + } + + for(;;) + { + TerminateProcess(GetCurrentProcess(), 666); + } } /* @@ -2358,7 +2443,7 @@ 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!"); + lamexp_fatal_exit("Not a debug build. Please unload debugger and try again!"); } //Zero *before* constructors are called diff --git a/src/Global_Zero.cpp b/src/Global_Zero.cpp index 9302fe1b..d75c6e7f 100644 --- a/src/Global_Zero.cpp +++ b/src/Global_Zero.cpp @@ -40,7 +40,7 @@ static size_t lamexp_entry_check(void) volatile size_t retVal = 0xA199B5AF; if(g_lamexp_entry_check_flag != 0x8761F64D) { - lamexp_fatal_exit(L"Application initialization has failed, take care!"); + lamexp_fatal_exit("Application initialization has failed, take care!"); } return retVal; } @@ -73,7 +73,7 @@ extern "C" int lamexp_entry_point(void) { if(g_lamexp_entry_check_flag != 0x789E09B2) { - lamexp_fatal_exit(L"Application initialization has failed, take care!"); + lamexp_fatal_exit("Application initialization has failed, take care!"); } //Call global initialization functions diff --git a/src/Main.cpp b/src/Main.cpp index 7b1a687d..3305b570 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -235,15 +235,13 @@ static int _main(int argc, char* argv[]) } catch(const std::exception &error) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } catch(...) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } return iResult; } @@ -266,10 +264,8 @@ int main(int argc, char* argv[]) } __except(1) { - fflush(stdout); - fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnhandeled structured exception error!\n"); - lamexp_fatal_exit(L"Unhandeled structured exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnhandeled structured exception error!\n"); + lamexp_fatal_exit("Unhandeled structured exception error, application will exit!"); } } } diff --git a/src/Thread_CPUObserver.cpp b/src/Thread_CPUObserver.cpp index 02005485..724817a0 100644 --- a/src/Thread_CPUObserver.cpp +++ b/src/Thread_CPUObserver.cpp @@ -56,15 +56,13 @@ void CPUObserverThread::run(void) } catch(const std::exception &error) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } catch(...) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } while(m_semaphore.available()) m_semaphore.tryAcquire(); diff --git a/src/Thread_CheckUpdate.cpp b/src/Thread_CheckUpdate.cpp index 95e4d001..7e69b347 100644 --- a/src/Thread_CheckUpdate.cpp +++ b/src/Thread_CheckUpdate.cpp @@ -229,15 +229,13 @@ void UpdateCheckThread::run(void) } catch(const std::exception &error) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } catch(...) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } qDebug("Update checker thread completed."); diff --git a/src/Thread_DiskObserver.cpp b/src/Thread_DiskObserver.cpp index 6276aefa..b5efa813 100644 --- a/src/Thread_DiskObserver.cpp +++ b/src/Thread_DiskObserver.cpp @@ -57,15 +57,13 @@ void DiskObserverThread::run(void) } catch(const std::exception &error) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } catch(...) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } while(m_semaphore.available()) m_semaphore.tryAcquire(); diff --git a/src/Thread_FileAnalyzer_Task.cpp b/src/Thread_FileAnalyzer_Task.cpp index 465284f0..a4563490 100644 --- a/src/Thread_FileAnalyzer_Task.cpp +++ b/src/Thread_FileAnalyzer_Task.cpp @@ -81,15 +81,13 @@ void AnalyzeTask::run() } catch(const std::exception &error) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } catch(...) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } } diff --git a/src/Thread_Initialization.cpp b/src/Thread_Initialization.cpp index 23fa8343..19e5f2f8 100644 --- a/src/Thread_Initialization.cpp +++ b/src/Thread_Initialization.cpp @@ -232,15 +232,13 @@ void InitializationThread::run(void) } catch(const std::exception &error) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } catch(...) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } } diff --git a/src/Thread_Process.cpp b/src/Thread_Process.cpp index b15a18fa..78f75be3 100644 --- a/src/Thread_Process.cpp +++ b/src/Thread_Process.cpp @@ -179,15 +179,13 @@ void ProcessThread::run() } catch(const std::exception &error) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } catch(...) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } } diff --git a/src/Thread_RAMObserver.cpp b/src/Thread_RAMObserver.cpp index 12553542..4b0385aa 100644 --- a/src/Thread_RAMObserver.cpp +++ b/src/Thread_RAMObserver.cpp @@ -56,15 +56,13 @@ void RAMObserverThread::run(void) } catch(const std::exception &error) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nException error:\n%s\n", error.what()); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } catch(...) { - fflush(stdout); fflush(stderr); - fprintf(stderr, "\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); - lamexp_fatal_exit(L"Unhandeled C++ exception error, application will exit!"); + PRINT_ERROR("\nGURU MEDITATION !!!\n\nUnknown exception error!\n"); + lamexp_fatal_exit("Unhandeled C++ exception error, application will exit!"); } while(m_semaphore.available()) m_semaphore.tryAcquire();