diff --git a/MUtilities_VS2013.vcxproj b/MUtilities_VS2013.vcxproj index 130c12a..3ab810e 100644 --- a/MUtilities_VS2013.vcxproj +++ b/MUtilities_VS2013.vcxproj @@ -150,7 +150,7 @@ Full true true - WIN32;MUTILS_DLL_EXPORT;NDEBUG;_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;QT_NODLL;QT_NO_DEBUG;%(PreprocessorDefinitions) + WIN32;MUTILS_STATIC_LIB;NDEBUG;_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;QT_NODLL;QT_NO_DEBUG;%(PreprocessorDefinitions) MultiThreaded NoExtensions AnySuitable diff --git a/include/MUtils/Global.h b/include/MUtils/Global.h index 07a33f2..797604d 100644 --- a/include/MUtils/Global.h +++ b/include/MUtils/Global.h @@ -33,10 +33,14 @@ class QProcess; # ifdef MUTILS_DLL_EXPORT # define MUTILS_API __declspec(dllexport) # else -# define MUTILS_API __declspec(dllimport) +# ifndef MUTILS_STATIC_LIB +# define MUTILS_API __declspec(dllimport) +# else +# define MUTILS_API /*static lib*/ +# endif # endif #else -# define MUTILS_API +# define MUTILS_API #endif //Helper Macros @@ -44,6 +48,19 @@ class QProcess; #define MUTILS_MAKE_STRING(X) MUTILS_MAKE_STRING_HELPER(X) #define MUTILS_COMPILER_WARNING(TXT) __pragma(message(__FILE__ "(" MUTILS_MAKE_STRING(__LINE__) ") : warning: " TXT)) +//Check Debug Flags +#if defined(_DEBUG) || defined(DEBUG) || (!defined(NDEBUG)) +# define MUTILS_DEBUG 1 +# if defined(NDEBUG) || defined(QT_NO_DEBUG) || (!defined(QT_DEBUG)) +# error Inconsistent DEBUG flags have been detected! +# endif +#else +# define MUTILS_DEBUG 0 +# if (!defined(NDEBUG)) || (!defined(QT_NO_DEBUG)) || defined(QT_DEBUG) +# error Inconsistent DEBUG flags have been detected! +# endif +#endif + /////////////////////////////////////////////////////////////////////////////// namespace MUtils @@ -61,7 +78,14 @@ namespace MUtils MUTILS_API quint64 next_rand64(void); //Version - MUTILS_API const char* buildDate(void); + MUTILS_API const char* mutils_build_date(void); + MUTILS_API const char* mutils_build_time(void); + //Internal + namespace Internal + { + MUTILS_API int selfTest(const char *const date, const bool debug); + static const int g_selfTestRet = selfTest(__DATE__, MUTILS_DEBUG); + } } /////////////////////////////////////////////////////////////////////////////// @@ -86,6 +110,6 @@ while(0) } \ while(0) -#define MUTILS_QUTF8(STR) ((STR).toUtf8().constData()) #define MUTILS_QSTR2WCHAR(STR) (reinterpret_cast((STR).utf16())) +#define MUTILS_QSTR2QUTF8(STR) ((STR).toUtf8().constData()) #define MUTILS_WCHAR2QSTR(STR) (QString::fromUtf16(reinterpret_cast((STR)))) diff --git a/include/MUtils/OSSupport.h b/include/MUtils/OSSupport.h index 0d8ed5e..1a0f9f0 100644 --- a/include/MUtils/OSSupport.h +++ b/include/MUtils/OSSupport.h @@ -53,6 +53,11 @@ namespace MUtils } network_type_t; + //System message + MUTILS_API void system_message_nfo(const wchar_t *const title, const wchar_t *const text); + MUTILS_API void system_message_wrn(const wchar_t *const title, const wchar_t *const text); + MUTILS_API void system_message_err(const wchar_t *const title, const wchar_t *const text); + //Get known Folder MUTILS_API const QString &known_folder(known_folder_t folder_id); diff --git a/src/Global.cpp b/src/Global.cpp index 81614d2..b560432 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -102,70 +102,47 @@ QString MUtils::rand_str(const bool &bLong) // TEMP FOLDER /////////////////////////////////////////////////////////////////////////////// -static QReadWriteLock g_temp_folder_lock; -static QFile* g_temp_folder_file = NULL; -static QString* g_temp_folder_path = NULL; +static QScopedPointer g_temp_folder_file; +static QScopedPointer g_temp_folder_path; +static QReadWriteLock g_temp_folder_lock; -#define INIT_TEMP_FOLDER_RAND(OUT_PTR, FILE_PTR, BASE_DIR) do \ -{ \ - for(int _i = 0; _i < 128; _i++) \ - { \ - const QString _randDir = QString("%1/%2").arg((BASE_DIR), rand_str()); \ - if(!QDir(_randDir).exists()) \ - { \ - *(OUT_PTR) = try_init_folder(_randDir, (FILE_PTR)); \ - if(!(OUT_PTR)->isEmpty()) break; \ - } \ - } \ -} \ -while(0) +static QString try_create_subfolder(const QString &baseDir, const QString &postfix) +{ + const QString baseDirPath = QDir(baseDir).absolutePath(); + for(int i = 0; i < 32; i++) + { + QDir directory(baseDirPath); + if(directory.mkpath(postfix) && directory.cd(postfix)) + { + return directory.canonicalPath(); + } + } + return QString(); +} -static QString try_init_folder(const QString &folderPath, QFile *&lockFile) +static QString try_init_temp_folder(const QString &baseDir) { static const char *TEST_DATA = "Lorem ipsum dolor sit amet, consectetur, adipisci velit!"; - bool success = false; - - const QFileInfo folderInfo(folderPath); - const QDir folderDir(folderInfo.absoluteFilePath()); - - //Remove existing lock file - if(lockFile) - { - lockFile->remove(); - MUTILS_DELETE(lockFile); - } - - //Create folder, if it does *not* exist yet - if(!folderDir.exists()) - { - for(int i = 0; i < 16; i++) - { - if(folderDir.mkpath(".")) break; - } - } - - //Make sure folder exists now *and* is writable - if(folderDir.exists()) + QString tempPath = try_create_subfolder(baseDir, MUtils::rand_str()); + if(!tempPath.isEmpty()) { const QByteArray testData = QByteArray(TEST_DATA); for(int i = 0; i < 32; i++) { - lockFile = new QFile(folderDir.absoluteFilePath(QString("~%1.tmp").arg(MUtils::rand_str()))); - if(lockFile->open(QIODevice::ReadWrite | QIODevice::Truncate)) + g_temp_folder_file.reset(new QFile(QString("%1/~%2.lck").arg(tempPath, MUtils::rand_str()))); + if(g_temp_folder_file->open(QIODevice::ReadWrite | QIODevice::Truncate)) { - if(lockFile->write(testData) >= testData.size()) + if(g_temp_folder_file->write(testData) >= testData.size()) { - success = true; - break; + return tempPath; } - lockFile->remove(); - MUTILS_DELETE(lockFile); + g_temp_folder_file->remove(); } } } - return (success ? folderDir.canonicalPath() : QString()); + return QString(); } const QString &MUtils::temp_folder(void) @@ -173,9 +150,9 @@ const QString &MUtils::temp_folder(void) QReadLocker readLock(&g_temp_folder_lock); //Already initialized? - if(g_temp_folder_path && (!g_temp_folder_path->isEmpty())) + if((!g_temp_folder_path.isNull()) && (!g_temp_folder_path->isEmpty())) { - return (*g_temp_folder_path); + return (*g_temp_folder_path.data()); } //Obtain the write lock to initilaize @@ -183,52 +160,41 @@ const QString &MUtils::temp_folder(void) QWriteLocker writeLock(&g_temp_folder_lock); //Still uninitilaized? - if(g_temp_folder_path && (!g_temp_folder_path->isEmpty())) + if((!g_temp_folder_path.isNull()) && (!g_temp_folder_path->isEmpty())) { - return (*g_temp_folder_path); + return (*g_temp_folder_path.data()); } - //Create the string, if not done yet - if(!g_temp_folder_path) - { - g_temp_folder_path = new QString(); - } - - g_temp_folder_path->clear(); - //Try the %TMP% or %TEMP% directory first - QString tempPath = try_init_folder(QDir::temp().absolutePath(), g_temp_folder_file); + QString tempPath = try_init_temp_folder(QDir::tempPath()); if(!tempPath.isEmpty()) { - INIT_TEMP_FOLDER_RAND(g_temp_folder_path, g_temp_folder_file, tempPath); + g_temp_folder_path.reset(new QString(tempPath)); + return (*g_temp_folder_path.data()); } - //Otherwise create TEMP folder in %LOCALAPPDATA% or %SYSTEMROOT% - if(g_temp_folder_path->isEmpty()) + qWarning("%%TEMP%% directory not found -> trying fallback mode now!"); + static const OS::known_folder_t FOLDER_ID[2] = { OS::FOLDER_LOCALAPPDATA, OS::FOLDER_SYSTROOT_DIR }; + for(size_t id = 0; id < 2; id++) { - qWarning("%%TEMP%% directory not found -> trying fallback mode now!"); - static const OS::known_folder_t folderId[2] = { OS::FOLDER_LOCALAPPDATA, OS::FOLDER_SYSTROOT_DIR }; - for(size_t id = 0; (g_temp_folder_path->isEmpty() && (id < 2)); id++) + const QString &knownFolder = OS::known_folder(FOLDER_ID[id]); + if(!knownFolder.isEmpty()) { - const QString &knownFolder = OS::known_folder(folderId[id]); - if(!knownFolder.isEmpty()) + const QString tempRoot = try_create_subfolder(knownFolder, QLatin1String("TEMP")); + if(!tempRoot.isEmpty()) { - tempPath = try_init_folder(QString("%1/Temp").arg(knownFolder), g_temp_folder_file); + tempPath = try_init_temp_folder(tempRoot); if(!tempPath.isEmpty()) { - INIT_TEMP_FOLDER_RAND(g_temp_folder_path, g_temp_folder_file, tempPath); + g_temp_folder_path.reset(new QString(tempPath)); + return (*g_temp_folder_path.data()); } } } } - //Failed to create TEMP folder? - if(g_temp_folder_path->isEmpty()) - { - qFatal("Temporary directory could not be initialized !!!"); - } - - return (*g_temp_folder_path); + qFatal("Temporary directory could not be initialized !!!"); + return (*((QString*)NULL)); } /////////////////////////////////////////////////////////////////////////////// @@ -279,3 +245,33 @@ void MUtils::init_process(QProcess &process, const QString &wokringDir, const bo process.setReadChannel(QProcess::StandardOutput); process.setProcessEnvironment(env); } + +/////////////////////////////////////////////////////////////////////////////// +// LIB VERSION +/////////////////////////////////////////////////////////////////////////////// + +const char* MUtils::mutils_build_date(void) +{ + static const char *const BUILD_DATE = __DATE__; + return BUILD_DATE; +} + +const char* MUtils::mutils_build_time(void) +{ + static const char *const BUILD_TIME = __TIME__; + return BUILD_TIME; +} + +/////////////////////////////////////////////////////////////////////////////// +// SELF-TEST +/////////////////////////////////////////////////////////////////////////////// + +int MUtils::Internal::selfTest(const char *const date, const bool debug) +{ + if(strcmp(date, __DATE__) || (MUTILS_DEBUG != debug)) + { + MUtils::OS::system_message_err(L"MUtils", L"FATAL ERROR: MUtils library version mismatch detected!"); + abort(); + } + return 0; +} diff --git a/src/OSSupport_Win32.cpp b/src/OSSupport_Win32.cpp index 37b2fbd..c8145d5 100644 --- a/src/OSSupport_Win32.cpp +++ b/src/OSSupport_Win32.cpp @@ -42,14 +42,34 @@ //Main thread ID static const DWORD g_main_thread_id = GetCurrentThreadId(); +/////////////////////////////////////////////////////////////////////////////// +// SYSTEM MESSAGE +/////////////////////////////////////////////////////////////////////////////// + +void MUtils::OS::system_message_nfo(const wchar_t *const title, const wchar_t *const text) +{ + MessageBoxW(NULL, text, title, MB_TOPMOST | MB_TASKMODAL | MB_ICONINFORMATION); +} + +void MUtils::OS::system_message_wrn(const wchar_t *const title, const wchar_t *const text) +{ + MessageBoxW(NULL, text, title, MB_TOPMOST | MB_TASKMODAL | MB_ICONWARNING); +} + +void MUtils::OS::system_message_err(const wchar_t *const title, const wchar_t *const text) +{ + MessageBoxW(NULL, text, title, MB_TOPMOST | MB_TASKMODAL | MB_ICONERROR); +} + /////////////////////////////////////////////////////////////////////////////// // KNWON FOLDERS /////////////////////////////////////////////////////////////////////////////// +typedef QMap KFMap; 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); -static QMap* g_known_folders_map; +static QScopedPointer g_known_folders_map; static SHGetKnownFolderPath_t g_known_folders_fpGetKnownFolderPath; static SHGetFolderPath_t g_known_folders_fpGetFolderPath; static QReadWriteLock g_known_folders_lock; @@ -91,7 +111,7 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id) QReadLocker readLock(&g_known_folders_lock); //Already in cache? - if(g_known_folders_map) + if(!g_known_folders_map.isNull()) { if(g_known_folders_map->contains(folderId)) { @@ -104,7 +124,7 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id) QWriteLocker writeLock(&g_known_folders_lock); //Still not in cache? - if(g_known_folders_map) + if(!g_known_folders_map.isNull()) { if(g_known_folders_map->contains(folderId)) { @@ -113,7 +133,7 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id) } //Initialize on first call - if(!g_known_folders_map) + if(g_known_folders_map.isNull()) { QLibrary shell32("shell32.dll"); if(shell32.load()) @@ -121,7 +141,7 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id) g_known_folders_fpGetFolderPath = (SHGetFolderPath_t) shell32.resolve("SHGetFolderPathW"); g_known_folders_fpGetKnownFolderPath = (SHGetKnownFolderPath_t) shell32.resolve("SHGetKnownFolderPath"); } - g_known_folders_map = new QMap(); + g_known_folders_map.reset(new QMap()); } QString folderPath; @@ -244,7 +264,7 @@ static volatile bool g_fatal_exit_flag = true; static DWORD WINAPI fatal_exit_helper(LPVOID lpParameter) { - MessageBoxA(NULL, ((LPCSTR) lpParameter), "Guru Meditation", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST | MB_SETFOREGROUND); + MessageBoxA(NULL, ((LPCSTR) lpParameter), "GURU MEDITATION", MB_OK | MB_ICONERROR | MB_TASKMODAL | MB_TOPMOST | MB_SETFOREGROUND); return 0; }