Detect the entry points for some of the Win32 API functions on Runtime, so the executable works even on antiqutated Windows versions (e.g. Windows 2000).

This commit is contained in:
LoRd_MuldeR 2010-11-25 16:56:32 +01:00
parent 4936d58092
commit 9947e9c839
6 changed files with 94 additions and 30 deletions

View File

@ -25,7 +25,7 @@
#define VER_LAMEXP_MAJOR 4 #define VER_LAMEXP_MAJOR 4
#define VER_LAMEXP_MINOR_HI 0 #define VER_LAMEXP_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 0 #define VER_LAMEXP_MINOR_LO 0
#define VER_LAMEXP_BUILD 76 #define VER_LAMEXP_BUILD 78
#define VER_LAMEXP_SUFFIX TechPreview #define VER_LAMEXP_SUFFIX TechPreview
/* /*

View File

@ -146,6 +146,11 @@ void ProcessingDialog::showEvent(QShowEvent *event)
button_closeDialog->setEnabled(false); button_closeDialog->setEnabled(false);
button_AbortProcess->setEnabled(false); button_AbortProcess->setEnabled(false);
if(!SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS))
{
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
}
QTimer::singleShot(1000, this, SLOT(initEncoding())); QTimer::singleShot(1000, this, SLOT(initEncoding()));
} }
@ -305,7 +310,7 @@ void ProcessingDialog::logViewDoubleClicked(const QModelIndex &index)
{ {
const QStringList &logFile = m_progressModel->getLogFile(index); const QStringList &logFile = m_progressModel->getLogFile(index);
LogViewDialog *logView = new LogViewDialog(this); LogViewDialog *logView = new LogViewDialog(this);
logView->setWindowTitle(QString("LameXP - %1").arg(m_progressModel->data(index, Qt::DisplayRole).toString())); logView->setWindowTitle(QString("LameXP - [%1]").arg(m_progressModel->data(index, Qt::DisplayRole).toString()));
logView->exec(logFile); logView->exec(logFile);
LAMEXP_DELETE(logView); LAMEXP_DELETE(logView);
} }

View File

@ -25,6 +25,7 @@
#include <QProcess> #include <QProcess>
#include <QMutex> #include <QMutex>
#include <QMutexLocker> #include <QMutexLocker>
#include <QLibrary>
#include <Windows.h> #include <Windows.h>
#define max(a,b) (((a) > (b)) ? (a) : (b)) #define max(a,b) (((a) > (b)) ? (a) : (b))
@ -35,6 +36,12 @@ HANDLE AbstractEncoder::m_handle_jobObject = NULL;
AbstractEncoder::AbstractEncoder(void) AbstractEncoder::AbstractEncoder(void)
{ {
typedef HANDLE (WINAPI *CreateJobObjectFun)(__in_opt LPSECURITY_ATTRIBUTES lpJobAttributes, __in_opt LPCSTR lpName);
typedef BOOL (WINAPI *SetInformationJobObjectFun)(__in HANDLE hJob, __in JOBOBJECTINFOCLASS JobObjectInformationClass, __in_bcount(cbJobObjectInformationLength) LPVOID lpJobObjectInformation, __in DWORD cbJobObjectInformationLength);
static CreateJobObjectFun CreateJobObjectPtr = NULL;
static SetInformationJobObjectFun SetInformationJobObjectPtr = NULL;
if(!m_mutex_startProcess) if(!m_mutex_startProcess)
{ {
m_mutex_startProcess = new QMutex(); m_mutex_startProcess = new QMutex();
@ -42,13 +49,26 @@ AbstractEncoder::AbstractEncoder(void)
if(!m_handle_jobObject) if(!m_handle_jobObject)
{ {
m_handle_jobObject = CreateJobObject(NULL, NULL); if(!CreateJobObjectPtr || !SetInformationJobObjectPtr)
if(m_handle_jobObject)
{ {
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobExtendedLimitInfo; QLibrary Kernel32Lib("kernel32.dll");
memset(&jobExtendedLimitInfo, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); CreateJobObjectPtr = (CreateJobObjectFun) Kernel32Lib.resolve("CreateJobObjectA");
jobExtendedLimitInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION; SetInformationJobObjectPtr = (SetInformationJobObjectFun) Kernel32Lib.resolve("SetInformationJobObject");
SetInformationJobObject(m_handle_jobObject, JobObjectExtendedLimitInformation, &jobExtendedLimitInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION)); }
if(CreateJobObjectPtr && SetInformationJobObjectPtr)
{
m_handle_jobObject = CreateJobObjectPtr(NULL, NULL);
if(m_handle_jobObject == INVALID_HANDLE_VALUE)
{
m_handle_jobObject = NULL;
}
if(m_handle_jobObject)
{
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobExtendedLimitInfo;
memset(&jobExtendedLimitInfo, 0, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
jobExtendedLimitInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION;
SetInformationJobObjectPtr(m_handle_jobObject, JobObjectExtendedLimitInformation, &jobExtendedLimitInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
}
} }
} }
@ -73,10 +93,19 @@ void AbstractEncoder::setRCMode(int mode) { m_configRCMode = max(0, mode); }
bool AbstractEncoder::startProcess(QProcess &process, const QString &program, const QStringList &args) bool AbstractEncoder::startProcess(QProcess &process, const QString &program, const QStringList &args)
{ {
typedef BOOL (WINAPI *AssignProcessToJobObjectFun)(__in HANDLE hJob, __in HANDLE hProcess);
static AssignProcessToJobObjectFun AssignProcessToJobObjectPtr = NULL;
QMutexLocker lock(m_mutex_startProcess); QMutexLocker lock(m_mutex_startProcess);
emit messageLogged(commandline2string(program, args) + "\n"); emit messageLogged(commandline2string(program, args) + "\n");
if(!AssignProcessToJobObjectPtr)
{
QLibrary Kernel32Lib("kernel32.dll");
AssignProcessToJobObjectPtr = (AssignProcessToJobObjectFun) Kernel32Lib.resolve("AssignProcessToJobObject");
}
process.setProcessChannelMode(QProcess::MergedChannels); process.setProcessChannelMode(QProcess::MergedChannels);
process.setReadChannel(QProcess::StandardOutput); process.setReadChannel(QProcess::StandardOutput);
process.start(program, args); process.start(program, args);
@ -84,8 +113,14 @@ bool AbstractEncoder::startProcess(QProcess &process, const QString &program, co
if(process.waitForStarted()) if(process.waitForStarted())
{ {
AssignProcessToJobObject(m_handle_jobObject, process.pid()->hProcess); if(AssignProcessToJobObjectPtr)
SetPriorityClass(process.pid()->hProcess, BELOW_NORMAL_PRIORITY_CLASS); {
AssignProcessToJobObjectPtr(m_handle_jobObject, process.pid()->hProcess);
}
if(!SetPriorityClass(process.pid()->hProcess, BELOW_NORMAL_PRIORITY_CLASS))
{
SetPriorityClass(process.pid()->hProcess, IDLE_PRIORITY_CLASS);
}
lock.unlock(); lock.unlock();
emit statusUpdated(0); emit statusUpdated(0);
return true; return true;

View File

@ -98,7 +98,7 @@ bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputF
{ {
process.kill(); process.kill();
bAborted = true; bAborted = true;
emit messageLogged("ABORTED BY USER !!!"); emit messageLogged("\nABORTED BY USER !!!");
break; break;
} }
process.waitForReadyRead(); process.waitForReadyRead();
@ -133,7 +133,7 @@ bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputF
process.waitForFinished(-1); process.waitForFinished(-1);
} }
emit messageLogged(QString().sprintf("\n--> Exited with code: 0x%08x", process.exitCode())); emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));
if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit) if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit)
{ {

View File

@ -37,6 +37,7 @@
#include <QSystemSemaphore> #include <QSystemSemaphore>
#include <QMutex> #include <QMutex>
#include <QTextCodec> #include <QTextCodec>
#include <QLibrary>
//LameXP includes //LameXP includes
#include "Resource.h" #include "Resource.h"
@ -284,10 +285,20 @@ void lamexp_init_console(int argc, char* argv[])
*/ */
lamexp_cpu_t lamexp_detect_cpu_features(void) lamexp_cpu_t lamexp_detect_cpu_features(void)
{ {
lamexp_cpu_t features; typedef BOOL (WINAPI *IsWow64ProcessFun)(__in HANDLE hProcess, __out PBOOL Wow64Process);
memset(&features, 0, sizeof(lamexp_cpu_t)); typedef VOID (WINAPI *GetNativeSystemInfoFun)(__out LPSYSTEM_INFO lpSystemInfo);
static IsWow64ProcessFun IsWow64ProcessPtr = NULL;
static GetNativeSystemInfoFun GetNativeSystemInfoPtr = NULL;
lamexp_cpu_t features;
SYSTEM_INFO systemInfo;
int CPUInfo[4] = {-1}; int CPUInfo[4] = {-1};
char CPUBrandString[0x40];
memset(&features, 0, sizeof(lamexp_cpu_t));
memset(&systemInfo, 0, sizeof(SYSTEM_INFO));
memset(CPUBrandString, 0, sizeof(CPUBrandString));
__cpuid(CPUInfo, 0); __cpuid(CPUInfo, 0);
if(CPUInfo[0] >= 1) if(CPUInfo[0] >= 1)
@ -304,8 +315,6 @@ lamexp_cpu_t lamexp_detect_cpu_features(void)
features.family = ((CPUInfo[0] >> 8) & 0xf) + ((CPUInfo[0] >> 20) & 0xff); features.family = ((CPUInfo[0] >> 8) & 0xf) + ((CPUInfo[0] >> 20) & 0xff);
} }
char CPUBrandString[0x40];
memset(CPUBrandString, 0, sizeof(CPUBrandString));
__cpuid(CPUInfo, 0x80000000); __cpuid(CPUInfo, 0x80000000);
int nExIds = CPUInfo[0]; int nExIds = CPUInfo[0];
@ -319,20 +328,35 @@ lamexp_cpu_t lamexp_detect_cpu_features(void)
strcpy_s(features.brand, 0x40, CPUBrandString); strcpy_s(features.brand, 0x40, CPUBrandString);
#if defined(_M_X64 ) || defined(_M_IA64) #if !defined(_M_X64 ) && !defined(_M_IA64)
features.x64 = true; if(!IsWow64ProcessPtr || !GetNativeSystemInfoPtr)
#else
BOOL x64 = FALSE;
if(IsWow64Process(GetCurrentProcess(), &x64))
{ {
features.x64 = x64; QLibrary Kernel32Lib("kernel32.dll");
IsWow64ProcessPtr = (IsWow64ProcessFun) Kernel32Lib.resolve("IsWow64Process");
GetNativeSystemInfoPtr = (GetNativeSystemInfoFun) Kernel32Lib.resolve("GetNativeSystemInfo");
} }
#endif if(IsWow64ProcessPtr)
{
SYSTEM_INFO systemInfo; BOOL x64 = FALSE;
memset(&systemInfo, 0, sizeof(SYSTEM_INFO)); if(IsWow64ProcessPtr(GetCurrentProcess(), &x64))
{
features.x64 = x64;
}
}
if(GetNativeSystemInfoPtr)
{
GetNativeSystemInfoPtr(&systemInfo);
}
else
{
GetSystemInfo(&systemInfo);
}
features.count = systemInfo.dwNumberOfProcessors;
#else
GetNativeSystemInfo(&systemInfo); GetNativeSystemInfo(&systemInfo);
features.count = systemInfo.dwNumberOfProcessors; features.count = systemInfo.dwNumberOfProcessors;
features.x64 = true;
#endif
return features; return features;
} }
@ -340,15 +364,15 @@ lamexp_cpu_t lamexp_detect_cpu_features(void)
/* /*
* Check for debugger * Check for debugger
*/ */
void WINAPI debugThreadProc(__in LPVOID lpParameter) void WINAPI debugThreadProc(__in LPVOID lpParameter)
{ {
BOOL remoteDebuggerPresent = FALSE; BOOL remoteDebuggerPresent = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess, &remoteDebuggerPresent); //CheckRemoteDebuggerPresent(GetCurrentProcess, &remoteDebuggerPresent);
while(!IsDebuggerPresent() && !remoteDebuggerPresent) while(!IsDebuggerPresent() && !remoteDebuggerPresent)
{ {
Sleep(333); Sleep(333);
CheckRemoteDebuggerPresent(GetCurrentProcess, &remoteDebuggerPresent); //CheckRemoteDebuggerPresent(GetCurrentProcess, &remoteDebuggerPresent);
} }
TerminateProcess(GetCurrentProcess(), -1); TerminateProcess(GetCurrentProcess(), -1);

View File

@ -154,7 +154,7 @@ void ProgressModel::appendToLog(const QUuid &jobId, const QString &line)
{ {
if(m_jobList.contains(jobId)) if(m_jobList.contains(jobId))
{ {
m_jobLogFile[jobId].append(line); m_jobLogFile[jobId].append(line.split('\n'));
} }
} }