Added 'wma2wav' as WMA decoder and removed all support for WMA decoder by NCH Swift Sound.

This commit is contained in:
LoRd_MuldeR 2011-07-26 22:17:14 +02:00
parent c5606cf45a
commit 327ca1ae75
18 changed files with 283 additions and 269 deletions

View File

@ -19,8 +19,8 @@ a:visited { color: #0000EE; }
<a name="4.02"></a>Changes between v4.02 and v4.03:<br><ul> <a name="4.02"></a>Changes between v4.02 and v4.03:<br><ul>
<li>Updated MediaInfo to v0.7.46 (2011-07-04), compiled with MSVC 10.0 <li>Updated MediaInfo to v0.7.46 (2011-07-04), compiled with MSVC 10.0
<li>Fixed Cue Sheet import for tracks with certain characters in the title <li>Fixed Cue Sheet import for tracks with certain characters in the title
<li>Added "built-in" WMA decoder (see <a href="http://forum.doom9.org/showthread.php?t=140273">this</a> thread for details) and removed all remnants of "old" decoder
<li>Workaround for malicious "anti-virus" programs that prevent innocent applications from functioning <li>Workaround for malicious "anti-virus" programs that prevent innocent applications from functioning
<li>Detect WMA decoder (wamwav.exe) in the application directory, might be usefull for "portable" mode
<li>Enabled "Aero Glass" theme in installer and web-update program (Vista and Windows 7 only) <li>Enabled "Aero Glass" theme in installer and web-update program (Vista and Windows 7 only)
</ul><br> </ul><br>

View File

@ -127,7 +127,7 @@ Currently the following input formats are supported by LameXP:<br><ul>
<li>The True Audio (TTA) <li>The True Audio (TTA)
<li>Uncompressed PCM / Waveform Audio File (WAV/RIFF) <li>Uncompressed PCM / Waveform Audio File (WAV/RIFF)
<li>WavPack Hybrid Lossless Audio <li>WavPack Hybrid Lossless Audio
<li>Windows Media Audio (WMA), using NCH Software decoder [available as separate download]</ul> <li>Windows Media Audio (WMA), using wma2wav [built-in]</ul>
<br><br> <br><br>
@ -310,16 +310,11 @@ such streams. Still, if you want to extract the "raw" AAC stream from an MP4 fil
<a name="ebf016ab"></a><b>How do I enable WMA input (decoding) in LameXP?</b><br> <a name="ebf016ab"></a><b>How do I enable WMA input (decoding) in LameXP?</b><br>
<br> <br>
WMA input requires the WMA decoder component to be installed on your local computer. Usually LameXP will show<br> LameXP now uses its "built-in" WMA decoder, thanks to 'wma2wav'. However it has to be noted that the WMA<br>
a warning on startup, if the WMA decoder component could not be found. In that case you can simply choose<br> decoder relies on the Windows Media Format Runtime. All supported versions of Microsoft Windows should have<br>
"Download &amp; Install" in order to install the WMA decoder component on your system. Alternatively you can<br> the Windows Media Format Runtime installed as part of the Windows Media Player. But Wine does not! In case<br>
also install the WMA decoder component manually by choosing "Install WMA Decoder" from the "Tools" menu. In<br> you encounter problems with the WMA decoder, try installing the <a href="http://anonym.to/http://www.citizeninsomniac.com/WMV/wmfdist11.exe" target="_blank">Windows Media Format Runtime</a> manually. This<br>
any case you must restart LameXP after the WMA decoder component has been installed.<br> should also work under Wine. The 'N' or 'KN' editions of Windows 7 need the <a href="http://www.microsoft.com/download/en/details.aspx?id=16546" target="_blank">Windows Media Feature Pack</a>.<br><br>
<br>
It has to be noted that the WMA decoder component relies on the Windows Media Format Runtime. All supported<br>
versions of Microsoft Windows should have the Windows Media Format Runtime installed out of the box. However<br>
Wine does not! In case you encounter problems with the WMA decoder component, try downloading and installing<br>
the <a href="http://www.free-codecs.com/download/Windows_Media_Format_11.htm" target="_blank">Windows Media Format 11 Runtime</a> manually. This should also work under Linux/Wine.<br><br>
<br><br> <br><br>

View File

@ -3071,7 +3071,6 @@
</property> </property>
<addaction name="actionDisableSounds"/> <addaction name="actionDisableSounds"/>
<addaction name="actionDisableUpdateReminder"/> <addaction name="actionDisableUpdateReminder"/>
<addaction name="actionDisableWmaDecoderNotifications"/>
<addaction name="actionDisableNeroAacNotifications"/> <addaction name="actionDisableNeroAacNotifications"/>
<addaction name="actionDisableSlowStartupNotifications"/> <addaction name="actionDisableSlowStartupNotifications"/>
<addaction name="actionDisableShellIntegration"/> <addaction name="actionDisableShellIntegration"/>
@ -3079,7 +3078,6 @@
<addaction name="actionCheckForBetaUpdates"/> <addaction name="actionCheckForBetaUpdates"/>
</widget> </widget>
<addaction name="actionImportCueSheet"/> <addaction name="actionImportCueSheet"/>
<addaction name="actionInstallWMADecoder"/>
<addaction name="actionShowDropBoxWidget"/> <addaction name="actionShowDropBoxWidget"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="menuConfiguration"/> <addaction name="menuConfiguration"/>
@ -3477,6 +3475,8 @@
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/> <include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/>
<include location="../res/Icons.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>

View File

@ -27,6 +27,7 @@
<file>tools/tta.exe</file> <file>tools/tta.exe</file>
<file>tools/valdec.exe</file> <file>tools/valdec.exe</file>
<file>tools/wget.exe</file> <file>tools/wget.exe</file>
<file>tools/wma2wav.exe</file>
<file>tools/wupdate.exe</file> <file>tools/wupdate.exe</file>
<file>tools/wvunpack.exe</file> <file>tools/wvunpack.exe</file>
</qresource> </qresource>

View File

@ -30,7 +30,7 @@
#define VER_LAMEXP_MINOR_LO 3 #define VER_LAMEXP_MINOR_LO 3
#define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_TYPE Alpha
#define VER_LAMEXP_PATCH 4 #define VER_LAMEXP_PATCH 4
#define VER_LAMEXP_BUILD 603 #define VER_LAMEXP_BUILD 605
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Tools versions // Tools versions

View File

@ -31,12 +31,11 @@
WMADecoder::WMADecoder(void) WMADecoder::WMADecoder(void)
: :
m_binary(lamexp_lookup_tool("wmawav.exe")), m_binary(lamexp_lookup_tool("wma2wav.exe"))
m_semaphore(new QSystemSemaphore("{84BB780D-67D3-49DC-ADF0-97C795A55D5C}", 1))
{ {
if(m_binary.isEmpty()) if(m_binary.isEmpty())
{ {
throw "Error initializing WMA decoder. Tool 'wmawav.exe' is not registred!"; throw "Error initializing WMA decoder. Tool 'wma2wav.exe' is not registred!";
} }
} }
@ -49,26 +48,18 @@ bool WMADecoder::decode(const QString &sourceFile, const QString &outputFile, vo
QProcess process; QProcess process;
QStringList args; QStringList args;
args << pathToShort(QDir::toNativeSeparators(sourceFile)); args << "-i" << QDir::toNativeSeparators(sourceFile);
args << pathToShort(QDir::toNativeSeparators(outputFile)); args << "-o" << QDir::toNativeSeparators(outputFile) << "-f";
if(!m_semaphore->acquire())
{
emit messageLogged("Failed to acquire the semaphore!");
return false;
}
if(!startProcess(process, m_binary, args)) if(!startProcess(process, m_binary, args))
{ {
m_semaphore->release();
return false; return false;
} }
bool bTimeout = false; bool bTimeout = false;
bool bAborted = false; bool bAborted = false;
//The WMA Decoder doesn't actually send any status updates :-[ QRegExp regExp("\\[(\\d+)\\.(\\d+)%\\]");
emit statusUpdated(20 + (QUuid::createUuid().data1 % 80));
while(process.state() != QProcess::NotRunning) while(process.state() != QProcess::NotRunning)
{ {
@ -83,7 +74,7 @@ bool WMADecoder::decode(const QString &sourceFile, const QString &outputFile, vo
if(!process.bytesAvailable() && process.state() == QProcess::Running) if(!process.bytesAvailable() && process.state() == QProcess::Running)
{ {
process.kill(); process.kill();
qWarning("WmaWav process timed out <-- killing!"); qWarning("wma2wav process timed out <-- killing!");
emit messageLogged("\nPROCESS TIMEOUT !!!"); emit messageLogged("\nPROCESS TIMEOUT !!!");
bTimeout = true; bTimeout = true;
break; break;
@ -92,7 +83,13 @@ bool WMADecoder::decode(const QString &sourceFile, const QString &outputFile, vo
{ {
QByteArray line = process.readLine(); QByteArray line = process.readLine();
QString text = QString::fromUtf8(line.constData()).simplified(); QString text = QString::fromUtf8(line.constData()).simplified();
if(!text.isEmpty()) if(regExp.lastIndexIn(text) >= 0)
{
bool ok = false;
int progress = regExp.cap(1).toInt(&ok);
if(ok) emit statusUpdated(progress);
}
else if(!text.isEmpty())
{ {
emit messageLogged(text); emit messageLogged(text);
} }
@ -108,7 +105,6 @@ bool WMADecoder::decode(const QString &sourceFile, const QString &outputFile, vo
emit statusUpdated(100); emit statusUpdated(100);
emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode())); emit messageLogged(QString().sprintf("\nExited with code: 0x%04X", process.exitCode()));
m_semaphore->release();
if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit || QFileInfo(outputFile).size() == 0) if(bTimeout || bAborted || process.exitStatus() != QProcess::NormalExit || QFileInfo(outputFile).size() == 0)
{ {
@ -134,11 +130,6 @@ bool WMADecoder::isFormatSupported(const QString &containerType, const QString &
return false; return false;
} }
bool WMADecoder::isDecoderAvailable(void)
{
return lamexp_check_tool("wmawav.exe");
}
QStringList WMADecoder::supportedTypes(void) QStringList WMADecoder::supportedTypes(void)
{ {
return QStringList() << "Windows Media Audio (*.wma)"; return QStringList() << "Windows Media Audio (*.wma)";

View File

@ -33,10 +33,8 @@ public:
virtual bool decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag); virtual bool decode(const QString &sourceFile, const QString &outputFile, volatile bool *abortFlag);
static bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion); static bool isFormatSupported(const QString &containerType, const QString &containerProfile, const QString &formatType, const QString &formatProfile, const QString &formatVersion);
static bool isDecoderAvailable(void);
static QStringList supportedTypes(void); static QStringList supportedTypes(void);
private: private:
const QString m_binary; const QString m_binary;
QSystemSemaphore *m_semaphore;
}; };

View File

@ -50,14 +50,14 @@ bool WaveDecoder::decode(const QString &sourceFile, const QString &outputFile, v
size_t srcLen = wcslen(reinterpret_cast<const wchar_t*>(sourceFile.utf16())) + 3; size_t srcLen = wcslen(reinterpret_cast<const wchar_t*>(sourceFile.utf16())) + 3;
wchar_t *srcBuffer = new wchar_t[srcLen]; wchar_t *srcBuffer = new wchar_t[srcLen];
memset(srcBuffer, 0, srcLen * sizeof(wchar_t)); memset(srcBuffer, 0, srcLen * sizeof(wchar_t));
wcscpy_s(srcBuffer, srcLen, reinterpret_cast<const wchar_t*>(sourceFile.utf16())); wcsncpy_s(srcBuffer, srcLen, reinterpret_cast<const wchar_t*>(sourceFile.utf16()), _TRUNCATE);
FIX_SEPARATORS (srcBuffer); FIX_SEPARATORS (srcBuffer);
fileOperation.pFrom = srcBuffer; fileOperation.pFrom = srcBuffer;
size_t outLen = wcslen(reinterpret_cast<const wchar_t*>(outputFile.utf16())) + 3; size_t outLen = wcslen(reinterpret_cast<const wchar_t*>(outputFile.utf16())) + 3;
wchar_t *outBuffer = new wchar_t[outLen]; wchar_t *outBuffer = new wchar_t[outLen];
memset(outBuffer, 0, outLen * sizeof(wchar_t)); memset(outBuffer, 0, outLen * sizeof(wchar_t));
wcscpy_s(outBuffer, outLen, reinterpret_cast<const wchar_t*>(outputFile.utf16())); wcsncpy_s(outBuffer, outLen, reinterpret_cast<const wchar_t*>(outputFile.utf16()), _TRUNCATE);
FIX_SEPARATORS (outBuffer); FIX_SEPARATORS (outBuffer);
fileOperation.pTo = outBuffer; fileOperation.pTo = outBuffer;

View File

@ -84,13 +84,14 @@ AboutDialog::AboutDialog(SettingsModel *settings, QWidget *parent, bool firstSta
{ {
QString versionStr = QString().sprintf QString versionStr = QString().sprintf
( (
"Version %d.%02d %s, Build %d [%s], %s, Qt v%s", "Version %d.%02d %s, Build %d [%s], %s %s, Qt v%s",
lamexp_version_major(), lamexp_version_major(),
lamexp_version_minor(), lamexp_version_minor(),
lamexp_version_release(), lamexp_version_release(),
lamexp_version_build(), lamexp_version_build(),
lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(),
lamexp_version_compiler(), lamexp_version_compiler(),
lamexp_version_arch(),
qVersion() qVersion()
); );

View File

@ -339,9 +339,7 @@ MainWindow::MainWindow(FileListModel *fileListModel, AudioFileModel *metaInfo, S
actionCheckForBetaUpdates->setEnabled(!lamexp_version_demo()); actionCheckForBetaUpdates->setEnabled(!lamexp_version_demo());
connect(actionDisableUpdateReminder, SIGNAL(triggered(bool)), this, SLOT(disableUpdateReminderActionTriggered(bool))); connect(actionDisableUpdateReminder, SIGNAL(triggered(bool)), this, SLOT(disableUpdateReminderActionTriggered(bool)));
connect(actionDisableSounds, SIGNAL(triggered(bool)), this, SLOT(disableSoundsActionTriggered(bool))); connect(actionDisableSounds, SIGNAL(triggered(bool)), this, SLOT(disableSoundsActionTriggered(bool)));
connect(actionInstallWMADecoder, SIGNAL(triggered(bool)), this, SLOT(installWMADecoderActionTriggered(bool)));
connect(actionDisableNeroAacNotifications, SIGNAL(triggered(bool)), this, SLOT(disableNeroAacNotificationsActionTriggered(bool))); connect(actionDisableNeroAacNotifications, SIGNAL(triggered(bool)), this, SLOT(disableNeroAacNotificationsActionTriggered(bool)));
connect(actionDisableWmaDecoderNotifications, SIGNAL(triggered(bool)), this, SLOT(disableWmaDecoderNotificationsActionTriggered(bool)));
connect(actionDisableSlowStartupNotifications, SIGNAL(triggered(bool)), this, SLOT(disableSlowStartupNotificationsActionTriggered(bool))); connect(actionDisableSlowStartupNotifications, SIGNAL(triggered(bool)), this, SLOT(disableSlowStartupNotificationsActionTriggered(bool)));
connect(actionDisableShellIntegration, SIGNAL(triggered(bool)), this, SLOT(disableShellIntegrationActionTriggered(bool))); connect(actionDisableShellIntegration, SIGNAL(triggered(bool)), this, SLOT(disableShellIntegrationActionTriggered(bool)));
connect(actionShowDropBoxWidget, SIGNAL(triggered(bool)), this, SLOT(showDropBoxWidgetActionTriggered(bool))); connect(actionShowDropBoxWidget, SIGNAL(triggered(bool)), this, SLOT(showDropBoxWidgetActionTriggered(bool)));
@ -551,81 +549,81 @@ void MainWindow::addFolder(const QString &path, bool recursive, bool delayed)
/* /*
* Download and install WMA Decoder component * Download and install WMA Decoder component
*/ */
bool MainWindow::installWMADecoder(void) //bool MainWindow::installWMADecoder(void)
{ //{
static const char *download_url = "http://www.nch.com.au/components/wmawav.exe"; // static const char *download_url = "http://www.nch.com.au/components/wmawav.exe";
static const char *download_hash = "52a3b0e6690faf3f830c336d3c0eadfb7a4e9bc6"; // static const char *download_hash = "52a3b0e6690faf3f830c336d3c0eadfb7a4e9bc6";
//
bool bResult = false; // bool bResult = false;
//
QString binaryWGet = lamexp_lookup_tool("wget.exe"); // QString binaryWGet = lamexp_lookup_tool("wget.exe");
QString binaryElevator = lamexp_lookup_tool("elevator.exe"); // QString binaryElevator = lamexp_lookup_tool("elevator.exe");
//
if(binaryWGet.isEmpty() || binaryElevator.isEmpty()) // if(binaryWGet.isEmpty() || binaryElevator.isEmpty())
{ // {
throw "Required binary is not available!"; // throw "Required binary is not available!";
} // }
//
while(true) // while(true)
{ // {
QString setupFile = QString("%1/%2.exe").arg(lamexp_temp_folder2(), lamexp_rand_str()); // QString setupFile = QString("%1/%2.exe").arg(lamexp_temp_folder2(), lamexp_rand_str());
//
QProcess process; // QProcess process;
process.setWorkingDirectory(QFileInfo(setupFile).absolutePath()); // process.setWorkingDirectory(QFileInfo(setupFile).absolutePath());
//
QEventLoop loop; // QEventLoop loop;
connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit())); // connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()));
connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit())); // connect(&process, SIGNAL(finished(int, QProcess::ExitStatus)), &loop, SLOT(quit()));
//
process.start(binaryWGet, QStringList() << "-O" << QFileInfo(setupFile).fileName() << download_url); // process.start(binaryWGet, QStringList() << "-O" << QFileInfo(setupFile).fileName() << download_url);
m_banner->show(tr("Downloading WMA Decoder Setup, please wait..."), &loop); // m_banner->show(tr("Downloading WMA Decoder Setup, please wait..."), &loop);
//
if(process.exitCode() != 0 || QFileInfo(setupFile).size() < 10240) // if(process.exitCode() != 0 || QFileInfo(setupFile).size() < 10240)
{ // {
QFile::remove(setupFile); // QFile::remove(setupFile);
if(QMessageBox::critical(this, tr("Download Failed"), tr("Failed to download the WMA Decoder setup. Check your internet connection!"), tr("Try Again"), tr("Cancel")) == 0) // if(QMessageBox::critical(this, tr("Download Failed"), tr("Failed to download the WMA Decoder setup. Check your internet connection!"), tr("Try Again"), tr("Cancel")) == 0)
{ // {
continue; // continue;
} // }
break; // break;
} // }
//
QFile setupFileContent(setupFile); // QFile setupFileContent(setupFile);
QCryptographicHash setupFileHash(QCryptographicHash::Sha1); // QCryptographicHash setupFileHash(QCryptographicHash::Sha1);
//
setupFileContent.open(QIODevice::ReadOnly); // setupFileContent.open(QIODevice::ReadOnly);
if(setupFileContent.isOpen() && setupFileContent.isReadable()) // if(setupFileContent.isOpen() && setupFileContent.isReadable())
{ // {
setupFileHash.addData(setupFileContent.readAll()); // setupFileHash.addData(setupFileContent.readAll());
setupFileContent.close(); // setupFileContent.close();
} // }
//
if(_stricmp(setupFileHash.result().toHex().constData(), download_hash)) // if(_stricmp(setupFileHash.result().toHex().constData(), download_hash))
{ // {
qWarning("Hash miscompare:\n Expected %s\n Detected %s\n", download_hash, setupFileHash.result().toHex().constData()); // qWarning("Hash miscompare:\n Expected %s\n Detected %s\n", download_hash, setupFileHash.result().toHex().constData());
QFile::remove(setupFile); // QFile::remove(setupFile);
if(QMessageBox::critical(this, tr("Download Failed"), tr("The download seems to be corrupted. Please try again!"), tr("Try Again"), tr("Cancel")) == 0) // if(QMessageBox::critical(this, tr("Download Failed"), tr("The download seems to be corrupted. Please try again!"), tr("Try Again"), tr("Cancel")) == 0)
{ // {
continue; // continue;
} // }
break; // break;
} // }
//
QApplication::setOverrideCursor(Qt::WaitCursor); // QApplication::setOverrideCursor(Qt::WaitCursor);
process.start(binaryElevator, QStringList() << QString("/exec=%1").arg(setupFile)); // process.start(binaryElevator, QStringList() << QString("/exec=%1").arg(setupFile));
loop.exec(QEventLoop::ExcludeUserInputEvents); // loop.exec(QEventLoop::ExcludeUserInputEvents);
QFile::remove(setupFile); // QFile::remove(setupFile);
QApplication::restoreOverrideCursor(); // QApplication::restoreOverrideCursor();
//
if(QMessageBox::information(this, tr("WMA Decoder"), tr("The WMA File Decoder has been installed. Please restart LameXP now!"), tr("Quit LameXP"), tr("Postpone")) == 0) // if(QMessageBox::information(this, tr("WMA Decoder"), tr("The WMA File Decoder has been installed. Please restart LameXP now!"), tr("Quit LameXP"), tr("Postpone")) == 0)
{ // {
bResult = true; // bResult = true;
} // }
break; // break;
} // }
//
return bResult; // return bResult;
} //}
/* /*
* Check for updates * Check for updates
@ -1012,30 +1010,30 @@ void MainWindow::windowShown(void)
} }
//Check for WMA support //Check for WMA support
if(m_settings->wmaDecoderNotificationsEnabled()) //if(m_settings->wmaDecoderNotificationsEnabled())
{ //{
if(!lamexp_check_tool("wmawav.exe")) // if(!lamexp_check_tool("wmawav.exe"))
{ // {
QString messageText; // QString messageText;
messageText += QString("<nobr>%1</nobr><br>").arg(tr("LameXP has detected that the WMA File Decoder component is not currently installed on your system.").replace("-", "&minus;")); // messageText += QString("<nobr>%1</nobr><br>").arg(tr("LameXP has detected that the WMA File Decoder component is not currently installed on your system.").replace("-", "&minus;"));
messageText += QString("<nobr>%1</nobr><br><br>").arg(tr("You won't be able to process WMA files as input unless the WMA File Decoder component is installed!").replace("-", "&minus;")); // messageText += QString("<nobr>%1</nobr><br><br>").arg(tr("You won't be able to process WMA files as input unless the WMA File Decoder component is installed!").replace("-", "&minus;"));
messageText += QString("<nobr>%1</nobr>").arg(tr("Do you want to download and install the WMA File Decoder component now?").replace("-", "&minus;")); // messageText += QString("<nobr>%1</nobr>").arg(tr("Do you want to download and install the WMA File Decoder component now?").replace("-", "&minus;"));
int result = QMessageBox::information(this, tr("WMA Decoder Missing"), messageText, tr("Download && Install"), tr("Don't Show Again"), tr("Postpone")); // int result = QMessageBox::information(this, tr("WMA Decoder Missing"), messageText, tr("Download && Install"), tr("Don't Show Again"), tr("Postpone"));
if(result == 0) // if(result == 0)
{ // {
if(installWMADecoder()) // if(installWMADecoder())
{ // {
QApplication::quit(); // QApplication::quit();
return; // return;
} // }
} // }
else if(result == 1) // else if(result == 1)
{ // {
m_settings->wmaDecoderNotificationsEnabled(false); // m_settings->wmaDecoderNotificationsEnabled(false);
actionDisableWmaDecoderNotifications->setChecked(!m_settings->wmaDecoderNotificationsEnabled()); // actionDisableWmaDecoderNotifications->setChecked(!m_settings->wmaDecoderNotificationsEnabled());
} // }
} // }
} //}
//Add files from the command-line //Add files from the command-line
for(int i = 0; i < arguments.count() - 1; i++) for(int i = 0; i < arguments.count() - 1; i++)
@ -1467,28 +1465,28 @@ void MainWindow::disableNeroAacNotificationsActionTriggered(bool checked)
/* /*
* Disable WMA Decoder component action * Disable WMA Decoder component action
*/ */
void MainWindow::disableWmaDecoderNotificationsActionTriggered(bool checked) //void MainWindow::disableWmaDecoderNotificationsActionTriggered(bool checked)
{ //{
if(checked) // if(checked)
{ // {
if(0 == QMessageBox::question(this, tr("WMA Decoder Notifications"), tr("Do you really want to disable all WMA Decoder notifications?"), tr("Yes"), tr("No"), QString(), 1)) // if(0 == QMessageBox::question(this, tr("WMA Decoder Notifications"), tr("Do you really want to disable all WMA Decoder notifications?"), tr("Yes"), tr("No"), QString(), 1))
{ // {
QMessageBox::information(this, tr("WMA Decoder Notifications"), tr("All WMA Decoder notifications have been disabled.")); // QMessageBox::information(this, tr("WMA Decoder Notifications"), tr("All WMA Decoder notifications have been disabled."));
m_settings->wmaDecoderNotificationsEnabled(false); // m_settings->wmaDecoderNotificationsEnabled(false);
} // }
else // else
{ // {
m_settings->wmaDecoderNotificationsEnabled(true); // m_settings->wmaDecoderNotificationsEnabled(true);
} // }
} // }
else // else
{ // {
QMessageBox::information(this, tr("WMA Decoder Notifications"), tr("The WMA Decoder notifications have been re-enabled.")); // QMessageBox::information(this, tr("WMA Decoder Notifications"), tr("The WMA Decoder notifications have been re-enabled."));
m_settings->wmaDecoderNotificationsEnabled(true); // m_settings->wmaDecoderNotificationsEnabled(true);
} // }
//
actionDisableWmaDecoderNotifications->setChecked(!m_settings->wmaDecoderNotificationsEnabled()); // actionDisableWmaDecoderNotifications->setChecked(!m_settings->wmaDecoderNotificationsEnabled());
} //}
/* /*
* Disable slow startup action * Disable slow startup action
@ -1519,17 +1517,17 @@ void MainWindow::disableSlowStartupNotificationsActionTriggered(bool checked)
/* /*
* Download and install WMA Decoder component * Download and install WMA Decoder component
*/ */
void MainWindow::installWMADecoderActionTriggered(bool checked) //void MainWindow::installWMADecoderActionTriggered(bool checked)
{ //{
if(QMessageBox::question(this, tr("Install WMA Decoder"), tr("Do you want to download and install the WMA File Decoder component now?"), tr("Download && Install"), tr("Cancel")) == 0) // if(QMessageBox::question(this, tr("Install WMA Decoder"), tr("Do you want to download and install the WMA File Decoder component now?"), tr("Download && Install"), tr("Cancel")) == 0)
{ // {
if(installWMADecoder()) // if(installWMADecoder())
{ // {
QApplication::quit(); // QApplication::quit();
return; // return;
} // }
} // }
} //}
/* /*
* Import a Cue Sheet file * Import a Cue Sheet file

View File

@ -74,7 +74,6 @@ private slots:
void disableSlowStartupNotificationsActionTriggered(bool checked); void disableSlowStartupNotificationsActionTriggered(bool checked);
void disableSoundsActionTriggered(bool checked); void disableSoundsActionTriggered(bool checked);
void disableUpdateReminderActionTriggered(bool checked); void disableUpdateReminderActionTriggered(bool checked);
void disableWmaDecoderNotificationsActionTriggered(bool checked);
void documentActionActivated(void); void documentActionActivated(void);
void editMetaButtonClicked(void); void editMetaButtonClicked(void);
void encodeButtonClicked(void); void encodeButtonClicked(void);
@ -87,7 +86,6 @@ private slots:
void handleDelayedFiles(void); void handleDelayedFiles(void);
void importCueSheetActionTriggered(bool checked); void importCueSheetActionTriggered(bool checked);
void initOutputFolderModel(void); void initOutputFolderModel(void);
void installWMADecoderActionTriggered(bool checked);
void languageActionActivated(QAction *action); void languageActionActivated(QAction *action);
void languageFromFileActionActivated(bool checked); void languageFromFileActionActivated(bool checked);
void makeFolderButtonClicked(void); void makeFolderButtonClicked(void);

View File

@ -66,14 +66,14 @@ bool WaveEncoder::encode(const QString &sourceFile, const AudioFileModel &metaIn
size_t srcLen = wcslen(reinterpret_cast<const wchar_t*>(sourceFile.utf16())) + 3; size_t srcLen = wcslen(reinterpret_cast<const wchar_t*>(sourceFile.utf16())) + 3;
wchar_t *srcBuffer = new wchar_t[srcLen]; wchar_t *srcBuffer = new wchar_t[srcLen];
memset(srcBuffer, 0, srcLen * sizeof(wchar_t)); memset(srcBuffer, 0, srcLen * sizeof(wchar_t));
wcscpy_s(srcBuffer, srcLen, reinterpret_cast<const wchar_t*>(sourceFile.utf16())); wcsncpy_s(srcBuffer, srcLen, reinterpret_cast<const wchar_t*>(sourceFile.utf16()), _TRUNCATE);
FIX_SEPARATORS (srcBuffer); FIX_SEPARATORS (srcBuffer);
fileOperation.pFrom = srcBuffer; fileOperation.pFrom = srcBuffer;
size_t outLen = wcslen(reinterpret_cast<const wchar_t*>(outputFile.utf16())) + 3; size_t outLen = wcslen(reinterpret_cast<const wchar_t*>(outputFile.utf16())) + 3;
wchar_t *outBuffer = new wchar_t[outLen]; wchar_t *outBuffer = new wchar_t[outLen];
memset(outBuffer, 0, outLen * sizeof(wchar_t)); memset(outBuffer, 0, outLen * sizeof(wchar_t));
wcscpy_s(outBuffer, outLen, reinterpret_cast<const wchar_t*>(outputFile.utf16())); wcsncpy_s(outBuffer, outLen, reinterpret_cast<const wchar_t*>(outputFile.utf16()), _TRUNCATE);
FIX_SEPARATORS (outBuffer); FIX_SEPARATORS (outBuffer);
fileOperation.pTo = outBuffer; fileOperation.pTo = outBuffer;

View File

@ -105,6 +105,7 @@ g_lamexp_version =
static QDate g_lamexp_version_date; static QDate g_lamexp_version_date;
static const char *g_lamexp_months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; static const char *g_lamexp_months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
static const char *g_lamexp_version_raw_date = __DATE__; static const char *g_lamexp_version_raw_date = __DATE__;
static const char *g_lamexp_version_raw_time = __TIME__;
//Console attached flag //Console attached flag
static bool g_lamexp_console_attached = false; static bool g_lamexp_console_attached = false;
@ -150,6 +151,15 @@ static bool g_lamexp_console_attached = false;
#error Compiler is not supported! #error Compiler is not supported!
#endif #endif
//Architecture detection
#if defined(_M_X64)
static const char *g_lamexp_version_arch = "x64";
#elif defined(_M_IX86)
static const char *g_lamexp_version_arch = "x86";
#else
#error Architecture is not supported!
#endif
//Official web-site URL //Official web-site URL
static const char *g_lamexp_website_url = "http://lamexp.sourceforge.net/"; static const char *g_lamexp_website_url = "http://lamexp.sourceforge.net/";
static const char *g_lamexp_support_url = "http://forum.doom9.org/showthread.php?t=157726"; static const char *g_lamexp_support_url = "http://forum.doom9.org/showthread.php?t=157726";
@ -221,7 +231,9 @@ unsigned int lamexp_version_major(void) { return g_lamexp_version.ver_major; }
unsigned int lamexp_version_minor(void) { return g_lamexp_version.ver_minor; } unsigned int lamexp_version_minor(void) { return g_lamexp_version.ver_minor; }
unsigned int lamexp_version_build(void) { return g_lamexp_version.ver_build; } unsigned int lamexp_version_build(void) { return g_lamexp_version.ver_build; }
const char *lamexp_version_release(void) { return g_lamexp_version.ver_release_name; } const char *lamexp_version_release(void) { return g_lamexp_version.ver_release_name; }
const char *lamexp_version_compiler(void) {return g_lamexp_version_compiler; } const char *lamexp_version_time(void) { return g_lamexp_version_raw_time; }
const char *lamexp_version_compiler(void) { return g_lamexp_version_compiler; }
const char *lamexp_version_arch(void) { return g_lamexp_version_arch; }
unsigned int lamexp_toolver_neroaac(void) { return g_lamexp_toolver_neroaac; } unsigned int lamexp_toolver_neroaac(void) { return g_lamexp_toolver_neroaac; }
/* /*
@ -319,6 +331,19 @@ LONG WINAPI lamexp_exception_handler(__in struct _EXCEPTION_POINTERS *ExceptionI
return LONG_MAX; return LONG_MAX;
} }
void lamexp_invalid_param_handler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t)
{
if(GetCurrentThreadId() != g_main_thread_id)
{
HANDLE mainThread = OpenThread(THREAD_TERMINATE, FALSE, g_main_thread_id);
if(mainThread) TerminateThread(mainThread, ULONG_MAX);
}
FatalAppExit(0, L"Invalid parameter handler invoked, application will exit!");
TerminateProcess(GetCurrentProcess(), -1);
}
/* /*
* Qt message handler * Qt message handler
*/ */
@ -684,6 +709,7 @@ static bool lamexp_check_elevation(void)
bool lamexp_init_qt(int argc, char* argv[]) bool lamexp_init_qt(int argc, char* argv[])
{ {
static bool qt_initialized = false; static bool qt_initialized = false;
typedef BOOL (WINAPI *SetDllDirectoryProc)(WCHAR *lpPathName);
//Don't initialized again, if done already //Don't initialized again, if done already
if(qt_initialized) if(qt_initialized)
@ -691,6 +717,11 @@ bool lamexp_init_qt(int argc, char* argv[])
return true; return true;
} }
//Secure DLL loading
QLibrary kernel32("kernel32.dll");
SetDllDirectoryProc pSetDllDirectory = static_cast<SetDllDirectoryProc>(kernel32.resolve("SetDllDirectoryW"));
if(pSetDllDirectory != NULL) pSetDllDirectory(L"");
//Extract executable name from argv[] array //Extract executable name from argv[] array
char *executableName = argv[0]; char *executableName = argv[0];
while(char *temp = strpbrk(executableName, "\\/:?")) while(char *temp = strpbrk(executableName, "\\/:?"))

View File

@ -73,9 +73,11 @@ unsigned int lamexp_version_major(void);
unsigned int lamexp_version_minor(void); unsigned int lamexp_version_minor(void);
unsigned int lamexp_version_build(void); unsigned int lamexp_version_build(void);
const QDate &lamexp_version_date(void); const QDate &lamexp_version_date(void);
const char *lamexp_version_time(void);
const char *lamexp_version_release(void); const char *lamexp_version_release(void);
bool lamexp_version_demo(void); bool lamexp_version_demo(void);
const char *lamexp_version_compiler(void); const char *lamexp_version_compiler(void);
const char *lamexp_version_arch(void);
QDate lamexp_version_expires(void); QDate lamexp_version_expires(void);
unsigned int lamexp_toolver_neroaac(void); unsigned int lamexp_toolver_neroaac(void);
const char *lamexp_website_url(void); const char *lamexp_website_url(void);
@ -86,6 +88,7 @@ void lamexp_init_console(int argc, char* argv[]);
bool lamexp_init_qt(int argc, char* argv[]); bool lamexp_init_qt(int argc, char* argv[]);
int lamexp_init_ipc(void); int lamexp_init_ipc(void);
LONG WINAPI lamexp_exception_handler(__in struct _EXCEPTION_POINTERS *ExceptionInfo); LONG WINAPI lamexp_exception_handler(__in struct _EXCEPTION_POINTERS *ExceptionInfo);
void lamexp_invalid_param_handler(const wchar_t*, const wchar_t*, const wchar_t*, unsigned int, uintptr_t);
void lamexp_message_handler(QtMsgType type, const char *msg); void lamexp_message_handler(QtMsgType type, const char *msg);
void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned int version = 0); void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned int version = 0);
bool lamexp_check_tool(const QString &toolName); bool lamexp_check_tool(const QString &toolName);

View File

@ -53,14 +53,14 @@ static int lamexp_main(int argc, char* argv[])
lamexp_init_console(argc, argv); lamexp_init_console(argc, argv);
//Print version info //Print version info
qDebug("LameXP - Audio Encoder Front-End"); qDebug("LameXP - Audio Encoder Front-End v%d.%02d %s (Build #%03d)", lamexp_version_major(), lamexp_version_minor(), lamexp_version_release(), lamexp_version_build());
qDebug("Version %d.%02d %s, Build %d [%s], compiled with %s", lamexp_version_major(), lamexp_version_minor(), lamexp_version_release(), lamexp_version_build(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), lamexp_version_compiler()); qDebug("Copyright (c) 2004-%04d LoRd_MuldeR <mulder2@gmx.de>. Some rights reserved.", max(lamexp_version_date().year(),QDate::currentDate().year()));
qDebug("Copyright (C) 2004-%04d LoRd_MuldeR <MuldeR2@GMX.de>\n", max(lamexp_version_date().year(),QDate::currentDate().year())); qDebug("Built on %s at %s with %s for Win-%s.\n", lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), lamexp_version_time(), lamexp_version_compiler(), lamexp_version_arch());
//print license info //print license info
qDebug("This program is free software: you can redistribute it and/or modify"); qDebug("This program is free software: you can redistribute it and/or modify");
qDebug("it under the terms of the GNU General Public License <http://www.gnu.org/>."); qDebug("it under the terms of the GNU General Public License <http://www.gnu.org/>.");
qDebug("This program comes with ABSOLUTELY NO WARRANTY.\n"); qDebug("Note that this program is distributed with ABSOLUTELY NO WARRANTY.\n");
//Print warning, if this is a "debug" build //Print warning, if this is a "debug" build
if(LAMEXP_DEBUG) if(LAMEXP_DEBUG)
@ -240,6 +240,7 @@ int main(int argc, char* argv[])
__try __try
{ {
SetUnhandledExceptionFilter(lamexp_exception_handler); SetUnhandledExceptionFilter(lamexp_exception_handler);
_set_invalid_parameter_handler(lamexp_invalid_param_handler);
return _main(argc, argv); return _main(argc, argv);
} }
__except(1) __except(1)

View File

@ -78,6 +78,7 @@ g_lamexp_tools[] =
{"9b50cf64747d4afbad5d8d9b5a0a2d41c5a58256f47ebdbd8cc920e7e576085dfe1b14ff", CPU_TYPE_ALL, "tta.exe", 21}, {"9b50cf64747d4afbad5d8d9b5a0a2d41c5a58256f47ebdbd8cc920e7e576085dfe1b14ff", CPU_TYPE_ALL, "tta.exe", 21},
{"875871c942846f6ad163f9e4949bba2f4331bec678ca5aefe58c961b6825bd0d419a078b", CPU_TYPE_ALL, "valdec.exe", 31}, {"875871c942846f6ad163f9e4949bba2f4331bec678ca5aefe58c961b6825bd0d419a078b", CPU_TYPE_ALL, "valdec.exe", 31},
{"e657331e281840878a37eb4fb357cb79f33d528ddbd5f9b2e2f7d2194bed4720e1af8eaf", CPU_TYPE_ALL, "wget.exe", 1114}, {"e657331e281840878a37eb4fb357cb79f33d528ddbd5f9b2e2f7d2194bed4720e1af8eaf", CPU_TYPE_ALL, "wget.exe", 1114},
{"42a541d0fbcbc7ee9777f3519ffeee77f516ed26a01beb891fcc7c66d2a3e238407e6e6b", CPU_TYPE_ALL, "wma2wav.exe", 20110726},
{"a258711f7a8a0c75528f3ed4d2c17513ff8598b7e0a9d7db13ca941a3140094ffc2ffb62", CPU_TYPE_ALL, "wupdate.exe", UINT_MAX}, {"a258711f7a8a0c75528f3ed4d2c17513ff8598b7e0a9d7db13ca941a3140094ffc2ffb62", CPU_TYPE_ALL, "wupdate.exe", UINT_MAX},
{"6b053b37d47a9c8659ebf2de43ad19dcba17b9cd868b26974b9cc8c27b6167e8bf07a5a2", CPU_TYPE_ALL, "wvunpack.exe", 4601}, {"6b053b37d47a9c8659ebf2de43ad19dcba17b9cd868b26974b9cc8c27b6167e8bf07a5a2", CPU_TYPE_ALL, "wvunpack.exe", 4601},
{NULL, NULL, NULL, NULL} {NULL, NULL, NULL, NULL}
@ -224,9 +225,6 @@ void InitializationThread::run()
//Look for Nero encoder //Look for Nero encoder
initNeroAac(); initNeroAac();
//Look for WMA File decoder
initWmaDec();
delay(); delay();
m_bSuccess = true; m_bSuccess = true;
} }
@ -402,85 +400,85 @@ void InitializationThread::initNeroAac(void)
} }
void InitializationThread::initWmaDec(void) //void InitializationThread::initWmaDec(void)
{ //{
static const char* wmaDecoderComponentPath = "NCH Software/Components/wmawav/wmawav.exe"; // static const char* wmaDecoderComponentPath = "NCH Software/Components/wmawav/wmawav.exe";
//
LockedFile *wmaFileBin = NULL; // LockedFile *wmaFileBin = NULL;
QFileInfo wmaFileInfo = QFileInfo(QString("%1/%2").arg(lamexp_known_folder(lamexp_folder_programfiles), wmaDecoderComponentPath)); // QFileInfo wmaFileInfo = QFileInfo(QString("%1/%2").arg(lamexp_known_folder(lamexp_folder_programfiles), wmaDecoderComponentPath));
//
if(!(wmaFileInfo.exists() && wmaFileInfo.isFile())) // if(!(wmaFileInfo.exists() && wmaFileInfo.isFile()))
{ // {
wmaFileInfo.setFile(QString("%1/%2").arg(QDir(QCoreApplication::applicationDirPath()).canonicalPath(), "wmawav.exe")); // wmaFileInfo.setFile(QString("%1/%2").arg(QDir(QCoreApplication::applicationDirPath()).canonicalPath(), "wmawav.exe"));
} // }
if(!(wmaFileInfo.exists() && wmaFileInfo.isFile())) // if(!(wmaFileInfo.exists() && wmaFileInfo.isFile()))
{ // {
qDebug("WMA File Decoder not found -> WMA decoding support will be disabled!\n"); // qDebug("WMA File Decoder not found -> WMA decoding support will be disabled!\n");
return; // return;
} // }
//
try // try
{ // {
wmaFileBin = new LockedFile(wmaFileInfo.canonicalFilePath()); // wmaFileBin = new LockedFile(wmaFileInfo.canonicalFilePath());
} // }
catch(...) // catch(...)
{ // {
qWarning("Failed to get excluive lock to WMA File Decoder binary -> WMA decoding support will be disabled!"); // qWarning("Failed to get excluive lock to WMA File Decoder binary -> WMA decoding support will be disabled!");
return; // return;
} // }
//
QProcess process; // QProcess process;
process.setProcessChannelMode(QProcess::MergedChannels); // process.setProcessChannelMode(QProcess::MergedChannels);
process.setReadChannel(QProcess::StandardOutput); // process.setReadChannel(QProcess::StandardOutput);
process.start(wmaFileInfo.canonicalFilePath(), QStringList()); // process.start(wmaFileInfo.canonicalFilePath(), QStringList());
//
if(!process.waitForStarted()) // if(!process.waitForStarted())
{ // {
qWarning("WmaWav process failed to create!"); // qWarning("WmaWav process failed to create!");
qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData()); // qWarning("Error message: \"%s\"\n", process.errorString().toLatin1().constData());
process.kill(); // process.kill();
process.waitForFinished(-1); // process.waitForFinished(-1);
return; // return;
} // }
//
bool b_wmaWavFound = false; // bool b_wmaWavFound = false;
//
while(process.state() != QProcess::NotRunning) // while(process.state() != QProcess::NotRunning)
{ // {
if(!process.waitForReadyRead()) // if(!process.waitForReadyRead())
{ // {
if(process.state() == QProcess::Running) // if(process.state() == QProcess::Running)
{ // {
qWarning("WmaWav process time out -> killing!"); // qWarning("WmaWav process time out -> killing!");
process.kill(); // process.kill();
process.waitForFinished(-1); // process.waitForFinished(-1);
return; // return;
} // }
} // }
while(process.canReadLine()) // while(process.canReadLine())
{ // {
QString line = QString::fromUtf8(process.readLine().constData()).simplified(); // QString line = QString::fromUtf8(process.readLine().constData()).simplified();
if(line.contains("Usage: wmatowav.exe WMAFileSpec WAVFileSpec", Qt::CaseInsensitive)) // if(line.contains("Usage: wmatowav.exe WMAFileSpec WAVFileSpec", Qt::CaseInsensitive))
{ // {
b_wmaWavFound = true; // b_wmaWavFound = true;
} // }
} // }
} // }
//
if(!b_wmaWavFound) // if(!b_wmaWavFound)
{ // {
qWarning("WmaWav could not be identified -> WMA decoding support will be disabled!\n"); // qWarning("WmaWav could not be identified -> WMA decoding support will be disabled!\n");
LAMEXP_DELETE(wmaFileBin); // LAMEXP_DELETE(wmaFileBin);
return; // return;
} // }
//
qDebug("Found WMA File Decoder binary:\n%s\n", wmaFileInfo.canonicalFilePath().toUtf8().constData()); // qDebug("Found WMA File Decoder binary:\n%s\n", wmaFileInfo.canonicalFilePath().toUtf8().constData());
//
if(wmaFileBin) // if(wmaFileBin)
{ // {
lamexp_register_tool(wmaFileInfo.fileName(), wmaFileBin); // lamexp_register_tool(wmaFileInfo.fileName(), wmaFileBin);
} // }
} //}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// EVENTS // EVENTS

View File

@ -42,7 +42,6 @@ private:
void delay(void); void delay(void);
void initTranslations(void); void initTranslations(void);
void initNeroAac(void); void initNeroAac(void);
void initWmaDec(void);
bool m_bSuccess; bool m_bSuccess;
lamexp_cpu_t m_cpuFeatures; lamexp_cpu_t m_cpuFeatures;

View File

@ -114,7 +114,7 @@ void ProcessThread::processFile()
qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData()); qDebug("Process thread %s has started.", m_jobId.toString().toLatin1().constData());
emit processStateInitialized(m_jobId, QFileInfo(m_audioFile.filePath()).fileName(), tr("Starting..."), ProgressModel::JobRunning); emit processStateInitialized(m_jobId, QFileInfo(m_audioFile.filePath()).fileName(), tr("Starting..."), ProgressModel::JobRunning);
handleMessage(QString().sprintf("LameXP v%u.%02u (Build #%u), compiled at %s", lamexp_version_major(), lamexp_version_minor(), lamexp_version_build(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData())); handleMessage(QString().sprintf("LameXP v%u.%02u (Build #%u), compiled on %s at %s", lamexp_version_major(), lamexp_version_minor(), lamexp_version_build(), lamexp_version_date().toString(Qt::ISODate).toLatin1().constData(), lamexp_version_time()));
handleMessage("\n-------------------------------\n"); handleMessage("\n-------------------------------\n");
//Generate output file name //Generate output file name