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_MINOR_HI 0
#define VER_LAMEXP_MINOR_LO 0
#define VER_LAMEXP_BUILD 76
#define VER_LAMEXP_BUILD 78
#define VER_LAMEXP_SUFFIX TechPreview
/*

View File

@ -146,6 +146,11 @@ void ProcessingDialog::showEvent(QShowEvent *event)
button_closeDialog->setEnabled(false);
button_AbortProcess->setEnabled(false);
if(!SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS))
{
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
}
QTimer::singleShot(1000, this, SLOT(initEncoding()));
}
@ -305,7 +310,7 @@ void ProcessingDialog::logViewDoubleClicked(const QModelIndex &index)
{
const QStringList &logFile = m_progressModel->getLogFile(index);
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);
LAMEXP_DELETE(logView);
}

View File

@ -25,6 +25,7 @@
#include <QProcess>
#include <QMutex>
#include <QMutexLocker>
#include <QLibrary>
#include <Windows.h>
#define max(a,b) (((a) > (b)) ? (a) : (b))
@ -35,6 +36,12 @@ HANDLE AbstractEncoder::m_handle_jobObject = NULL;
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)
{
m_mutex_startProcess = new QMutex();
@ -42,13 +49,26 @@ AbstractEncoder::AbstractEncoder(void)
if(!m_handle_jobObject)
{
m_handle_jobObject = CreateJobObject(NULL, NULL);
if(m_handle_jobObject)
if(!CreateJobObjectPtr || !SetInformationJobObjectPtr)
{
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;
SetInformationJobObject(m_handle_jobObject, JobObjectExtendedLimitInformation, &jobExtendedLimitInfo, sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));
QLibrary Kernel32Lib("kernel32.dll");
CreateJobObjectPtr = (CreateJobObjectFun) Kernel32Lib.resolve("CreateJobObjectA");
SetInformationJobObjectPtr = (SetInformationJobObjectFun) Kernel32Lib.resolve("SetInformationJobObject");
}
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)
{
typedef BOOL (WINAPI *AssignProcessToJobObjectFun)(__in HANDLE hJob, __in HANDLE hProcess);
static AssignProcessToJobObjectFun AssignProcessToJobObjectPtr = NULL;
QMutexLocker lock(m_mutex_startProcess);
emit messageLogged(commandline2string(program, args) + "\n");
if(!AssignProcessToJobObjectPtr)
{
QLibrary Kernel32Lib("kernel32.dll");
AssignProcessToJobObjectPtr = (AssignProcessToJobObjectFun) Kernel32Lib.resolve("AssignProcessToJobObject");
}
process.setProcessChannelMode(QProcess::MergedChannels);
process.setReadChannel(QProcess::StandardOutput);
process.start(program, args);
@ -84,8 +113,14 @@ bool AbstractEncoder::startProcess(QProcess &process, const QString &program, co
if(process.waitForStarted())
{
AssignProcessToJobObject(m_handle_jobObject, process.pid()->hProcess);
SetPriorityClass(process.pid()->hProcess, BELOW_NORMAL_PRIORITY_CLASS);
if(AssignProcessToJobObjectPtr)
{
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();
emit statusUpdated(0);
return true;

View File

@ -98,7 +98,7 @@ bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputF
{
process.kill();
bAborted = true;
emit messageLogged("ABORTED BY USER !!!");
emit messageLogged("\nABORTED BY USER !!!");
break;
}
process.waitForReadyRead();
@ -133,7 +133,7 @@ bool MP3Encoder::encode(const AudioFileModel &sourceFile, const QString &outputF
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)
{

View File

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

View File

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