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.
This commit is contained in:
parent
bde198ee10
commit
7994e06822
@ -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
|
||||
|
@ -28,6 +28,12 @@
|
||||
#include <QDir>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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<intptr_t>(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());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user