From 7994e068224a34e4edb53bc30a8043dcd5c87ccf Mon Sep 17 00:00:00 2001 From: lordmulder Date: Sun, 26 Jun 2011 19:21:00 +0200 Subject: [PATCH] LockedFile class: Initialize QFile object with existing file descriptor instead of re-opening the file. This is done in order to avoid one CreateFile() call, which potentially speeds up the initialization procedure and/or avoids potential problems with bogus "anti-virus" programs. WARNING: Passing file descriptors into Qt functions/class works with "fully static" builds only! Otherwise the "main" application and the Qt DLL's use their own CRT each, which results in crash when passing file descriptors between the different CRT's. --- src/Config.h | 2 +- src/LockedFile.cpp | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/Config.h b/src/Config.h index 85a48adc..a8606c60 100644 --- a/src/Config.h +++ b/src/Config.h @@ -30,7 +30,7 @@ #define VER_LAMEXP_MINOR_LO 3 #define VER_LAMEXP_TYPE Alpha #define VER_LAMEXP_PATCH 1 -#define VER_LAMEXP_BUILD 586 +#define VER_LAMEXP_BUILD 589 /////////////////////////////////////////////////////////////////////////////// // Tools versions diff --git a/src/LockedFile.cpp b/src/LockedFile.cpp index 8aa521fa..e3d1ea6f 100644 --- a/src/LockedFile.cpp +++ b/src/LockedFile.cpp @@ -28,6 +28,12 @@ #include #include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// + #define THROW(STR) \ { \ char error_msg[512]; \ @@ -35,7 +41,16 @@ throw error_msg; \ } -LockedFile::LockedFile(const QString &resourcePath, const QString &outPath, const QByteArray &expectedHash) +// WARNING: Passing file descriptors into Qt does NOT work with dynamically linked CRT! +#ifdef QT_NODLL + static const bool g_useFileDescr = 1; +#else + static const bool g_useFileDescr = 0; +#endif + +/////////////////////////////////////////////////////////////////////////////// + + LockedFile::LockedFile(const QString &resourcePath, const QString &outPath, const QByteArray &expectedHash) { m_fileHandle = NULL; QResource resource(resourcePath); @@ -90,17 +105,32 @@ LockedFile::LockedFile(const QString &resourcePath, const QString &outPath, cons throw error_msg; } + //Open file for reading + if(g_useFileDescr) + { + int fd = _open_osfhandle(reinterpret_cast(m_fileHandle), _O_RDONLY | _O_BINARY); + if(fd >= 0) outFile.open(fd, QIODevice::ReadOnly); + } + else + { + for(int i = 0; i < 64; i++) + { + if(outFile.open(QIODevice::ReadOnly)) break; + if(!i) qWarning("Failed to re-open file on first attemp, retrying..."); + Sleep(100); + } + } + //Verify file contents - outFile.open(QIODevice::ReadOnly); QCryptographicHash fileHash(QCryptographicHash::Sha1); - if(outFile.isOpen() && outFile.isReadable()) + if(outFile.isOpen() /*&& outFile.isReadable()*/) { fileHash.addData(outFile.readAll()); outFile.close(); } else { - QFile::remove(QFileInfo(outFile).canonicalFilePath()); + QFile::remove(m_filePath); THROW(QString("File '%1' could not be read!").arg(QFileInfo(outFile).fileName()).toLatin1().constData()); } @@ -109,7 +139,7 @@ LockedFile::LockedFile(const QString &resourcePath, const QString &outPath, cons { qWarning("\nFile checksum error:\n Expected = %040s\n Detected = %040s\n", expectedHash.constData(), fileHash.result().toHex().constData()); LAMEXP_CLOSE(m_fileHandle); - QFile::remove(QFileInfo(outFile).canonicalFilePath()); + QFile::remove(m_filePath); THROW(QString("File '%1' is corruputed, take care!").arg(QFileInfo(resourcePath).absoluteFilePath().replace(QRegExp("^:/"), QString())).toLatin1().constData()); } }