/////////////////////////////////////////////////////////////////////////////// // Simple x264 Launcher // Copyright (C) 2004-2016 LoRd_MuldeR // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. // // http://www.gnu.org/licenses/gpl-2.0.txt /////////////////////////////////////////////////////////////////////////////// //x264 includes #include "global.h" #include "targetver.h" //Windows includes #define NOMINMAX #define WIN32_LEAN_AND_MEAN #include #include #include #include #include #include //C++ includes #include #include #include #include //VLD #include //Version #define ENABLE_X264_VERSION_INCLUDE #include "version.h" #undef ENABLE_X264_VERSION_INCLUDE //MUtils includes #include //Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //CRT includes #include #include #include #include #include //Debug only includes #if X264_DEBUG #include #endif //Global types 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); //Const static const char *g_x264_months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; static const char *g_x264_imageformats[] = {"png", "jpg", "gif", "ico", "svg", NULL}; //Build version static const struct { unsigned int ver_major; unsigned int ver_minor; unsigned int ver_patch; unsigned int ver_build; } g_x264_version = { (VER_X264_MAJOR), (VER_X264_MINOR), (VER_X264_PATCH), (VER_X264_BUILD), }; //Portable mode static QReadWriteLock g_portableModeLock; static bool g_portableModeData = false; static bool g_portableModeInit = false; //Data path static QString g_dataPathData; static QReadWriteLock g_dataPathLock; /////////////////////////////////////////////////////////////////////////////// // MACROS /////////////////////////////////////////////////////////////////////////////// //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) //Check for CLI flag static inline bool _CHECK_FLAG(const int argc, char **argv, const char *flag) { for(int i = 1; i < argc; i++) { if(_stricmp(argv[i], flag) == 0) return true; } return false; } #define CHECK_FLAG(FLAG) _CHECK_FLAG(argc, argv, "--" FLAG) #define X264_ZERO_MEMORY(X) SecureZeroMemory(&X, sizeof(X)) /////////////////////////////////////////////////////////////////////////////// // GLOBAL FUNCTIONS /////////////////////////////////////////////////////////////////////////////// /* * Version info */ unsigned int x264_version_major(void) { return g_x264_version.ver_major; } unsigned int x264_version_minor(void) { return (g_x264_version.ver_minor * 10) + (g_x264_version.ver_patch % 10); } unsigned int x264_version_build(void) { return g_x264_version.ver_build; } /* * Check for portable mode */ bool x264_is_portable(void) { QReadLocker readLock(&g_portableModeLock); if(g_portableModeInit) { return g_portableModeData; } readLock.unlock(); QWriteLocker writeLock(&g_portableModeLock); if(!g_portableModeInit) { if(VER_X264_PORTABLE_EDITION) { qWarning("Simple x264 Launcher portable edition!\n"); g_portableModeData = true; } else { QString baseName = QFileInfo(QApplication::applicationFilePath()).completeBaseName(); int idx1 = baseName.indexOf("x264", 0, Qt::CaseInsensitive); int idx2 = baseName.lastIndexOf("portable", -1, Qt::CaseInsensitive); g_portableModeData = (idx1 >= 0) && (idx2 >= 0) && (idx1 < idx2); } g_portableModeInit = true; } return g_portableModeData; } /* * Get data path (i.e. path to store config files) */ const QString &x264_data_path(void) { QReadLocker readLock(&g_dataPathLock); if(!g_dataPathData.isEmpty()) { return g_dataPathData; } readLock.unlock(); QWriteLocker writeLock(&g_dataPathLock); if(g_dataPathData.isEmpty()) { g_dataPathData = QDesktopServices::storageLocation(QDesktopServices::DataLocation); if(g_dataPathData.isEmpty() || x264_is_portable()) { g_dataPathData = QApplication::applicationDirPath(); } if(!QDir(g_dataPathData).mkpath(".")) { qWarning("Data directory could not be created:\n%s\n", g_dataPathData.toUtf8().constData()); g_dataPathData = QDir::currentPath(); } } return g_dataPathData; } /* * Is pre-release version? */ bool x264_is_prerelease(void) { return (VER_X264_PRE_RELEASE); } /* * Convert path to short/ANSI path */ QString x264_path2ansi(const QString &longPath, bool makeLowercase) { QString shortPath = longPath; const QString longPathNative = QDir::toNativeSeparators(longPath); DWORD buffSize = GetShortPathNameW(MUTILS_WCHR(longPathNative), NULL, NULL); if(buffSize > 0) { wchar_t *buffer = (wchar_t*) _malloca(sizeof(wchar_t) * buffSize); DWORD result = GetShortPathNameW(MUTILS_WCHR(longPathNative), buffer, buffSize); if((result > 0) && (result < buffSize)) { shortPath = QDir::fromNativeSeparators(QString::fromUtf16(reinterpret_cast(buffer), result)); if(makeLowercase) { QFileInfo info(shortPath); shortPath = QString("%1/%2").arg(info.absolutePath(), info.fileName().toLower()); } } _freea(buffer); buffer = NULL; } return shortPath; } /* * Read value from registry */ QString x264_query_reg_string(const bool bUser, const QString &path, const QString &name) { QString result; HKEY hKey = NULL; if(RegOpenKey((bUser ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE), MUTILS_WCHR(path), &hKey) == ERROR_SUCCESS) { const size_t DATA_LEN = 2048; wchar_t data[DATA_LEN]; DWORD type = REG_NONE, size = sizeof(wchar_t) * DATA_LEN; if(RegQueryValueEx(hKey, MUTILS_WCHR(name), NULL, &type, ((BYTE*)&data[0]), &size) == ERROR_SUCCESS) { if((type == REG_SZ) || (type == REG_EXPAND_SZ)) { result = MUTILS_QSTR(&data[0]); } } RegCloseKey(hKey); } return result; } /* * Inform the system that it is in use, thereby preventing the system from entering sleep */ bool x264_set_thread_execution_state(const bool systemRequired) { EXECUTION_STATE state = NULL; if(systemRequired) { state = SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED); } else { state = SetThreadExecutionState(ES_CONTINUOUS); } return (state != NULL); }