From 9947e9c8391bd461ef86e81ab17455c43363057d Mon Sep 17 00:00:00 2001 From: lordmulder Date: Thu, 25 Nov 2010 16:56:32 +0100 Subject: [PATCH] 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). --- src/Config.h | 2 +- src/Dialog_Processing.cpp | 7 ++++- src/Encoder_Abstract.cpp | 51 ++++++++++++++++++++++++++++------ src/Encoder_MP3.cpp | 4 +-- src/Global.cpp | 58 +++++++++++++++++++++++++++------------ src/Model_Progress.cpp | 2 +- 6 files changed, 94 insertions(+), 30 deletions(-) diff --git a/src/Config.h b/src/Config.h index d87a493f..82cbc6ef 100644 --- a/src/Config.h +++ b/src/Config.h @@ -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 /* diff --git a/src/Dialog_Processing.cpp b/src/Dialog_Processing.cpp index 4a6058a1..03ea6354 100644 --- a/src/Dialog_Processing.cpp +++ b/src/Dialog_Processing.cpp @@ -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); } diff --git a/src/Encoder_Abstract.cpp b/src/Encoder_Abstract.cpp index de965e24..103a1ba3 100644 --- a/src/Encoder_Abstract.cpp +++ b/src/Encoder_Abstract.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #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; diff --git a/src/Encoder_MP3.cpp b/src/Encoder_MP3.cpp index f56131c4..962adb43 100644 --- a/src/Encoder_MP3.cpp +++ b/src/Encoder_MP3.cpp @@ -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) { diff --git a/src/Global.cpp b/src/Global.cpp index 28d2d5b3..50e4b818 100644 --- a/src/Global.cpp +++ b/src/Global.cpp @@ -37,6 +37,7 @@ #include #include #include +#include //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); diff --git a/src/Model_Progress.cpp b/src/Model_Progress.cpp index 70166680..17996185 100644 --- a/src/Model_Progress.cpp +++ b/src/Model_Progress.cpp @@ -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')); } }