Simple-x264-Launcher/src/global.cpp

334 lines
8.0 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Simple x264 Launcher
// Copyright (C) 2004-2015 LoRd_MuldeR <MuldeR2@GMX.de>
//
// 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 <Windows.h>
#include <MMSystem.h>
#include <ShellAPI.h>
#include <Objbase.h>
#include <Psapi.h>
#include <SensAPI.h>
//C++ includes
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <time.h>
//VLD
#include <vld.h>
//Version
#define ENABLE_X264_VERSION_INCLUDE
#include "version.h"
#undef ENABLE_X264_VERSION_INCLUDE
//MUtils includes
#include <MUtils/Global.h>
//Qt includes
#include <QApplication>
#include <QMessageBox>
#include <QDir>
#include <QUuid>
#include <QMap>
#include <QDate>
#include <QIcon>
#include <QPlastiqueStyle>
#include <QImageReader>
#include <QSharedMemory>
#include <QSysInfo>
#include <QStringList>
#include <QSystemSemaphore>
#include <QDesktopServices>
#include <QMutex>
#include <QTextCodec>
#include <QLibrary>
#include <QRegExp>
#include <QResource>
#include <QTranslator>
#include <QEventLoop>
#include <QTimer>
#include <QLibraryInfo>
#include <QEvent>
#include <QReadLocker>
#include <QWriteLocker>
#include <QProcess>
//CRT includes
#include <fstream>
#include <io.h>
#include <fcntl.h>
#include <intrin.h>
#include <process.h>
//Debug only includes
#if X264_DEBUG
#include <Psapi.h>
#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<const unsigned short*>(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);
}