From eb88a05341bb23ec4d6030ded643b1589472ea38 Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Sat, 18 Aug 2012 16:36:39 +0200 Subject: [PATCH] Turned more global objects into pointers in order to allow late initialization. Also slightly restructured the global locks and added another global lock to guard the IPC struct. --- src/Config.h | 2 +- src/Global.cpp | 239 ++++++++++++++++++++++++++++++------------------- 2 files changed, 150 insertions(+), 91 deletions(-) diff --git a/src/Config.h b/src/Config.h index efb58ac2..55b45367 100644 --- a/src/Config.h +++ b/src/Config.h @@ -30,7 +30,7 @@ #define VER_LAMEXP_MINOR_LO 5 #define VER_LAMEXP_TYPE Beta #define VER_LAMEXP_PATCH 4 -#define VER_LAMEXP_BUILD 1087 +#define VER_LAMEXP_BUILD 1089 /////////////////////////////////////////////////////////////////////////////// // Tool versions (minimum expected versions!) diff --git a/src/Global.cpp b/src/Global.cpp index 9ad35a5e..5d5e7d77 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -86,6 +86,8 @@ Q_IMPORT_PLUGIN(QICOPlugin) #endif #endif +#define LAMEXP_ZERO_MEMORY(X) SecureZeroMemory(&X, sizeof(X)) + /////////////////////////////////////////////////////////////////////////////// // TYPES /////////////////////////////////////////////////////////////////////////////// @@ -201,8 +203,8 @@ static const unsigned int g_lamexp_toolver_coreaudio = VER_LAMEXP_TOOL_COREAUDIO //Special folders static struct { - QString temp; - QString knownFolders[3]; + QString *temp; + QMap *knownFolders; QReadWriteLock lock; } g_lamexp_folder; @@ -210,8 +212,8 @@ g_lamexp_folder; //Tools static struct { - QMap registry; - QMap versions; + QMap *registry; + QMap *versions; QReadWriteLock lock; } g_lamexp_tools; @@ -219,10 +221,10 @@ g_lamexp_tools; //Languages static struct { - QMap files; - QMap names; - QMap sysid; - QMap cntry; + QMap *files; + QMap *names; + QMap *sysid; + QMap *cntry; QReadWriteLock lock; } g_lamexp_translation; @@ -230,11 +232,19 @@ g_lamexp_translation; //Translator static struct { - QVariant instance; + QTranslator *instance; QReadWriteLock lock; } g_lamexp_currentTranslator; +//CLI Arguments +static struct +{ + QStringList *list; + QReadWriteLock lock; +} +g_lamexp_argv; + //Shared memory static const struct { @@ -259,11 +269,9 @@ static struct QSystemSemaphore *semaphore_read_mutex; QSystemSemaphore *semaphore_write; QSystemSemaphore *semaphore_write_mutex; + QReadWriteLock lock; } -g_lamexp_ipc_ptr = -{ - NULL, NULL, NULL -}; +g_lamexp_ipc_ptr; //Image formats static const char *g_lamexp_imageformats[] = {"bmp", "png", "jpg", "gif", "ico", "xpm", NULL}; //"svg" @@ -277,14 +285,6 @@ static const DWORD g_main_thread_id = GetCurrentThreadId(); //Log file static FILE *g_lamexp_log_file = NULL; -//CLI Arguments -static struct -{ - QStringList list; - QReadWriteLock lock; -} -g_lamexp_argv; - /////////////////////////////////////////////////////////////////////////////// // GLOBAL FUNCTIONS /////////////////////////////////////////////////////////////////////////////// @@ -1182,8 +1182,10 @@ bool lamexp_init_qt(int argc, char* argv[]) //Add default translations QWriteLocker writeLockTranslations(&g_lamexp_translation.lock); - g_lamexp_translation.files.insert(LAMEXP_DEFAULT_LANGID, ""); - g_lamexp_translation.names.insert(LAMEXP_DEFAULT_LANGID, "English"); + if(!g_lamexp_translation.files) g_lamexp_translation.files = new QMap(); + if(!g_lamexp_translation.names) g_lamexp_translation.names = new QMap(); + g_lamexp_translation.files->insert(LAMEXP_DEFAULT_LANGID, ""); + g_lamexp_translation.names->insert(LAMEXP_DEFAULT_LANGID, "English"); writeLockTranslations.unlock(); //Check for process elevation @@ -1223,6 +1225,8 @@ bool lamexp_init_qt(int argc, char* argv[]) */ int lamexp_init_ipc(void) { + QWriteLocker writeLock(&g_lamexp_ipc_ptr.lock); + if(g_lamexp_ipc_ptr.sharedmem && g_lamexp_ipc_ptr.semaphore_read && g_lamexp_ipc_ptr.semaphore_write && g_lamexp_ipc_ptr.semaphore_read_mutex && g_lamexp_ipc_ptr.semaphore_write_mutex) { return 0; @@ -1315,6 +1319,8 @@ int lamexp_init_ipc(void) */ void lamexp_ipc_send(unsigned int command, const char* message) { + QReadLocker readLock(&g_lamexp_ipc_ptr.lock); + if(!g_lamexp_ipc_ptr.sharedmem || !g_lamexp_ipc_ptr.semaphore_read || !g_lamexp_ipc_ptr.semaphore_write || !g_lamexp_ipc_ptr.semaphore_read_mutex || !g_lamexp_ipc_ptr.semaphore_write_mutex) { throw "Shared memory for IPC not initialized yet."; @@ -1347,6 +1353,8 @@ void lamexp_ipc_send(unsigned int command, const char* message) */ void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize) { + QReadLocker readLock(&g_lamexp_ipc_ptr.lock); + *command = 0; message[0] = '\0'; @@ -1416,17 +1424,26 @@ const QString &lamexp_temp_folder2(void) QReadLocker readLock(&g_lamexp_folder.lock); //Already initialized? - if(!g_lamexp_folder.temp.isEmpty()) + if(g_lamexp_folder.temp) { - if(QDir(g_lamexp_folder.temp).exists()) + if(!g_lamexp_folder.temp->isEmpty()) { - return g_lamexp_folder.temp; + if(QDir(*g_lamexp_folder.temp).exists()) + { + return *g_lamexp_folder.temp; + } } } readLock.unlock(); QWriteLocker writeLock(&g_lamexp_folder.lock); - g_lamexp_folder.temp.clear(); + + if(!g_lamexp_folder.temp) + { + g_lamexp_folder.temp = new QString(); + } + + g_lamexp_folder.temp->clear(); static const char *TEMP_STR = "Temp"; const QString WRITE_TEST_DATA = lamexp_rand_str(); @@ -1444,14 +1461,14 @@ const QString &lamexp_temp_folder2(void) { if(testFile.write(WRITE_TEST_DATA.toLatin1().constData()) >= strlen(WRITE_TEST_DATA.toLatin1().constData())) { - g_lamexp_folder.temp = temp.canonicalPath(); + (*g_lamexp_folder.temp) = temp.canonicalPath(); } testFile.remove(); } } - if(!g_lamexp_folder.temp.isEmpty()) + if(!g_lamexp_folder.temp->isEmpty()) { - return g_lamexp_folder.temp; + return *g_lamexp_folder.temp; } } @@ -1479,22 +1496,22 @@ const QString &lamexp_temp_folder2(void) { if(testFile.write(WRITE_TEST_DATA.toLatin1().constData()) >= strlen(WRITE_TEST_DATA.toLatin1().constData())) { - g_lamexp_folder.temp = localAppData.canonicalPath(); + (*g_lamexp_folder.temp) = localAppData.canonicalPath(); } testFile.remove(); } } } } - if(!g_lamexp_folder.temp.isEmpty()) + if(!g_lamexp_folder.temp->isEmpty()) { - return g_lamexp_folder.temp; + return *g_lamexp_folder.temp; } } //Failed to create TEMP folder! qFatal("Temporary directory could not be initialized!\n\nFirst attempt:\n%s\n\nSecond attempt:\n%s", temp.canonicalPath().toUtf8().constData(), localAppData.canonicalPath().toUtf8().constData()); - return g_lamexp_folder.temp; + return *g_lamexp_folder.temp; } /* @@ -1534,13 +1551,16 @@ void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned in { QWriteLocker writeLock(&g_lamexp_tools.lock); - if(g_lamexp_tools.registry.contains(toolName.toLower())) + if(!g_lamexp_tools.registry) g_lamexp_tools.registry = new QMap(); + if(!g_lamexp_tools.versions) g_lamexp_tools.versions = new QMap(); + + if(g_lamexp_tools.registry->contains(toolName.toLower())) { throw "lamexp_register_tool: Tool is already registered!"; } - g_lamexp_tools.registry.insert(toolName.toLower(), file); - g_lamexp_tools.versions.insert(toolName.toLower(), version); + g_lamexp_tools.registry->insert(toolName.toLower(), file); + g_lamexp_tools.versions->insert(toolName.toLower(), version); } /* @@ -1549,7 +1569,7 @@ void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned in bool lamexp_check_tool(const QString &toolName) { QReadLocker readLock(&g_lamexp_tools.lock); - return g_lamexp_tools.registry.contains(toolName.toLower()); + return (g_lamexp_tools.registry) ? g_lamexp_tools.registry->contains(toolName.toLower()) : false; } /* @@ -1559,9 +1579,16 @@ const QString lamexp_lookup_tool(const QString &toolName) { QReadLocker readLock(&g_lamexp_tools.lock); - if(g_lamexp_tools.registry.contains(toolName.toLower())) + if(g_lamexp_tools.registry) { - return g_lamexp_tools.registry.value(toolName.toLower())->filePath(); + if(g_lamexp_tools.registry->contains(toolName.toLower())) + { + return g_lamexp_tools.registry->value(toolName.toLower())->filePath(); + } + else + { + return QString(); + } } else { @@ -1576,9 +1603,16 @@ unsigned int lamexp_tool_version(const QString &toolName) { QReadLocker readLock(&g_lamexp_tools.lock); - if(g_lamexp_tools.versions.contains(toolName.toLower())) + if(g_lamexp_tools.versions) { - return g_lamexp_tools.versions.value(toolName.toLower()); + if(g_lamexp_tools.versions->contains(toolName.toLower())) + { + return g_lamexp_tools.versions->value(toolName.toLower()); + } + else + { + return UINT_MAX; + } } else { @@ -1629,10 +1663,15 @@ bool lamexp_translation_register(const QString &langId, const QString &qmFile, c return false; } - g_lamexp_translation.files.insert(langId, qmFile); - g_lamexp_translation.names.insert(langId, langName); - g_lamexp_translation.sysid.insert(langId, systemId); - g_lamexp_translation.cntry.insert(langId, country); + if(!g_lamexp_translation.files) g_lamexp_translation.files = new QMap(); + if(!g_lamexp_translation.names) g_lamexp_translation.names = new QMap(); + if(!g_lamexp_translation.sysid) g_lamexp_translation.sysid = new QMap(); + if(!g_lamexp_translation.cntry) g_lamexp_translation.cntry = new QMap(); + + g_lamexp_translation.files->insert(langId, qmFile); + g_lamexp_translation.names->insert(langId, langName); + g_lamexp_translation.sysid->insert(langId, systemId); + g_lamexp_translation.cntry->insert(langId, country); return true; } @@ -1642,8 +1681,8 @@ bool lamexp_translation_register(const QString &langId, const QString &qmFile, c */ QStringList lamexp_query_translations(void) { - QReadLocker writeLockTranslations(&g_lamexp_translation.lock); - return g_lamexp_translation.files.keys(); + QReadLocker readLockTranslations(&g_lamexp_translation.lock); + return (g_lamexp_translation.files) ? g_lamexp_translation.files->keys() : QStringList(); } /* @@ -1651,8 +1690,8 @@ QStringList lamexp_query_translations(void) */ QString lamexp_translation_name(const QString &langId) { - QReadLocker writeLockTranslations(&g_lamexp_translation.lock); - return g_lamexp_translation.names.value(langId.toLower(), QString()); + QReadLocker readLockTranslations(&g_lamexp_translation.lock); + return (g_lamexp_translation.names) ? g_lamexp_translation.names->value(langId.toLower(), QString()) : QString(); } /* @@ -1660,8 +1699,8 @@ QString lamexp_translation_name(const QString &langId) */ unsigned int lamexp_translation_sysid(const QString &langId) { - QReadLocker writeLockTranslations(&g_lamexp_translation.lock); - return g_lamexp_translation.sysid.value(langId.toLower(), 0); + QReadLocker readLockTranslations(&g_lamexp_translation.lock); + return (g_lamexp_translation.sysid) ? g_lamexp_translation.sysid->value(langId.toLower(), 0) : 0; } /* @@ -1669,8 +1708,8 @@ unsigned int lamexp_translation_sysid(const QString &langId) */ unsigned int lamexp_translation_country(const QString &langId) { - QReadLocker writeLockTranslations(&g_lamexp_translation.lock); - return g_lamexp_translation.cntry.value(langId.toLower(), 0); + QReadLocker readLockTranslations(&g_lamexp_translation.lock); + return (g_lamexp_translation.cntry) ? g_lamexp_translation.cntry->value(langId.toLower(), 0) : 0; } /* @@ -1687,7 +1726,9 @@ bool lamexp_install_translator(const QString &langId) else { QReadLocker readLock(&g_lamexp_translation.lock); - QString qmFile = g_lamexp_translation.files.value(langId.toLower(), QString()); + QString qmFile = (g_lamexp_translation.files) ? g_lamexp_translation.files->value(langId.toLower(), QString()) : QString(); + readLock.unlock(); + if(!qmFile.isEmpty()) { success = lamexp_install_translator_from_file(QString(":/localization/%1").arg(qmFile)); @@ -1709,19 +1750,18 @@ bool lamexp_install_translator_from_file(const QString &qmFile) QWriteLocker writeLock(&g_lamexp_currentTranslator.lock); bool success = false; - if(!g_lamexp_currentTranslator.instance.isValid()) + if(!g_lamexp_currentTranslator.instance) { - g_lamexp_currentTranslator.instance.setValue(new QTranslator()); + g_lamexp_currentTranslator.instance = new QTranslator(); } if(!qmFile.isEmpty()) { QString qmPath = QFileInfo(qmFile).canonicalFilePath(); - QTranslator *poTranslator = dynamic_cast(g_lamexp_currentTranslator.instance.value()); - QApplication::removeTranslator(poTranslator); - if(success = poTranslator->load(qmPath)) + QApplication::removeTranslator(g_lamexp_currentTranslator.instance); + if(success = g_lamexp_currentTranslator.instance->load(qmPath)) { - QApplication::installTranslator(poTranslator); + QApplication::installTranslator(g_lamexp_currentTranslator.instance); } else { @@ -1730,7 +1770,7 @@ bool lamexp_install_translator_from_file(const QString &qmFile) } else { - QApplication::removeTranslator(dynamic_cast(g_lamexp_currentTranslator.instance.value())); + QApplication::removeTranslator(g_lamexp_currentTranslator.instance); success = true; } @@ -1740,12 +1780,14 @@ bool lamexp_install_translator_from_file(const QString &qmFile) const QStringList &lamexp_arguments(void) { QReadLocker readLock(&g_lamexp_argv.lock); - - if(g_lamexp_argv.list.isEmpty()) + + if(!g_lamexp_argv.list) { readLock.unlock(); QWriteLocker writeLock(&g_lamexp_argv.lock); + g_lamexp_argv.list = new QStringList; + int nArgs = 0; LPWSTR *szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs); @@ -1753,7 +1795,7 @@ const QStringList &lamexp_arguments(void) { for(int i = 0; i < nArgs; i++) { - g_lamexp_argv.list << WCHAR2QSTR(szArglist[i]); + (*g_lamexp_argv.list) << WCHAR2QSTR(szArglist[i]); } LocalFree(szArglist); } @@ -1763,7 +1805,7 @@ const QStringList &lamexp_arguments(void) } } - return g_lamexp_argv.list; + return (*g_lamexp_argv.list); } /* @@ -1812,9 +1854,12 @@ QString lamexp_known_folder(lamexp_known_folder_t folder_id) } //Already in cache? - if(!g_lamexp_folder.knownFolders[folderCacheId].isEmpty()) + if(g_lamexp_folder.knownFolders) { - return g_lamexp_folder.knownFolders[folderCacheId]; + if(g_lamexp_folder.knownFolders->contains(folderCacheId)) + { + return g_lamexp_folder.knownFolders->value(folderCacheId, QString()); + } } readLock.unlock(); @@ -1875,7 +1920,8 @@ QString lamexp_known_folder(lamexp_known_folder_t folder_id) //Update cache if(!folder.isEmpty()) { - g_lamexp_folder.knownFolders[folderCacheId] = folder; + if(!g_lamexp_folder.knownFolders) g_lamexp_folder.knownFolders = new QMap(); + g_lamexp_folder.knownFolders->insert(folderCacheId, folder); } return folder; @@ -2144,6 +2190,15 @@ extern "C" FatalAppExit(0, L"Not a debug build. Please unload debugger and try again!"); TerminateProcess(GetCurrentProcess(), -1); } + + //Init global structs to NULL *before* constructors are called + LAMEXP_ZERO_MEMORY(g_lamexp_argv); + LAMEXP_ZERO_MEMORY(g_lamexp_tools); + LAMEXP_ZERO_MEMORY(g_lamexp_currentTranslator); + LAMEXP_ZERO_MEMORY(g_lamexp_translation); + LAMEXP_ZERO_MEMORY(g_lamexp_folder); + LAMEXP_ZERO_MEMORY(g_lamexp_ipc_ptr); + return WinMainCRTStartup(); } } @@ -2156,43 +2211,47 @@ void lamexp_finalization(void) qDebug("lamexp_finalization()"); //Free all tools - if(!g_lamexp_tools.registry.isEmpty()) + if(g_lamexp_tools.registry) { - QStringList keys = g_lamexp_tools.registry.keys(); + QStringList keys = g_lamexp_tools.registry->keys(); for(int i = 0; i < keys.count(); i++) { - LAMEXP_DELETE(g_lamexp_tools.registry[keys.at(i)]); + LAMEXP_DELETE((*g_lamexp_tools.registry)[keys.at(i)]); } - g_lamexp_tools.registry.clear(); - g_lamexp_tools.versions.clear(); + LAMEXP_DELETE(g_lamexp_tools.registry); + LAMEXP_DELETE(g_lamexp_tools.versions); } //Delete temporary files - if(!g_lamexp_folder.temp.isEmpty()) + if(g_lamexp_folder.temp) { - for(int i = 0; i < 100; i++) + if(!g_lamexp_folder.temp->isEmpty()) { - if(lamexp_clean_folder(g_lamexp_folder.temp)) + for(int i = 0; i < 100; i++) { - break; + if(lamexp_clean_folder(*g_lamexp_folder.temp)) + { + break; + } + Sleep(125); } - Sleep(125); } - g_lamexp_folder.temp.clear(); + LAMEXP_DELETE(g_lamexp_folder.temp); } + //Clear folder cache + LAMEXP_DELETE(g_lamexp_folder.knownFolders); + //Clear languages - if(g_lamexp_currentTranslator.instance.isValid()) + if(g_lamexp_currentTranslator.instance) { - QTranslator *poTranslator = dynamic_cast(g_lamexp_currentTranslator.instance.value()); - g_lamexp_currentTranslator.instance.clear(); - QApplication::removeTranslator(poTranslator); - LAMEXP_DELETE(poTranslator); + QApplication::removeTranslator(g_lamexp_currentTranslator.instance); + LAMEXP_DELETE(g_lamexp_currentTranslator.instance); } - g_lamexp_translation.files.clear(); - g_lamexp_translation.names.clear(); - g_lamexp_translation.cntry.clear(); - g_lamexp_translation.sysid.clear(); + LAMEXP_DELETE(g_lamexp_translation.files); + LAMEXP_DELETE(g_lamexp_translation.names); + LAMEXP_DELETE(g_lamexp_translation.cntry); + LAMEXP_DELETE(g_lamexp_translation.sysid); //Destroy Qt application object QApplication *application = dynamic_cast(QApplication::instance()); @@ -2229,7 +2288,7 @@ void lamexp_finalization(void) } //Free CLI Arguments - g_lamexp_argv.list.clear(); + LAMEXP_DELETE(g_lamexp_argv.list); } /*