diff --git a/downloadthread.cpp b/downloadthread.cpp index 0498f1850..c0d1c3a4e 100644 --- a/downloadthread.cpp +++ b/downloadthread.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #ifdef Q_OS_LINUX @@ -34,7 +35,7 @@ int DownloadThread::_curlCount = 0; DownloadThread::DownloadThread(const QByteArray &url, const QByteArray &localfilename, const QByteArray &expectedHash, QObject *parent) : QThread(parent), _startOffset(0), _lastDlTotal(0), _lastDlNow(0), _verifyTotal(0), _lastVerifyNow(0), _bytesWritten(0), _sectorsStart(-1), _url(url), _filename(localfilename), _expectedHash(expectedHash), _firstBlock(nullptr), _cancelled(false), _successful(false), _verifyEnabled(false), _cacheEnabled(false), _lastModified(0), _serverTime(0), _lastFailureTime(0), - _file(NULL), _writehash(OSLIST_HASH_ALGORITHM), _verifyhash(OSLIST_HASH_ALGORITHM), _inputBufferSize(0) + _inputBufferSize(0), _file(NULL), _writehash(OSLIST_HASH_ALGORITHM), _verifyhash(OSLIST_HASH_ALGORITHM) { if (!_curlCount) curl_global_init(CURL_GLOBAL_DEFAULT); @@ -333,7 +334,22 @@ void DownloadThread::run() break; case CURLE_WRITE_ERROR: deleteDownloadedFile(); - _onDownloadError("Error writing file to disk"); + +#ifdef Q_OS_WIN + if (_file.errorCode() == ERROR_ACCESS_DENIED) + { + QString msg = tr("Access denied error while writing file to disk."); + QSettings registry("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Defender\\Windows Defender Exploit Guard\\Controlled Folder Access", + QSettings::Registry64Format); + if (registry.value("EnableControlledFolderAccess").toInt() == 1) + { + msg += "
"+tr("Controlled Folder Access seems to be enabled. Please add both rpi-imager.exe and fat32format.exe to the list of allowed apps and try again."); + } + _onDownloadError(msg); + } + else +#endif + _onDownloadError(tr("Error writing file to disk")); break; case CURLE_ABORTED_BY_CALLBACK: deleteDownloadedFile(); @@ -619,10 +635,10 @@ void DownloadThread::_writeComplete() eject_disk(_filename.constData()); #ifdef Q_OS_WIN - QStringList args = {"start", "StorSvc"}; + QStringList args2 = {"start", "StorSvc"}; QProcess *p2 = new QProcess(this); qDebug() << "Restarting storage services"; - p2->startDetached("net", args); + p2->startDetached("net", args2); #endif emit success(); diff --git a/windows/winfile.cpp b/windows/winfile.cpp index 105e2ad3a..580b772cc 100644 --- a/windows/winfile.cpp +++ b/windows/winfile.cpp @@ -8,7 +8,7 @@ #include WinFile::WinFile(QObject *parent) - : QObject(parent), _locked(false), _h(INVALID_HANDLE_VALUE) + : QObject(parent), _locked(false), _h(INVALID_HANDLE_VALUE), _lasterrorcode(0) { } @@ -44,6 +44,7 @@ bool WinFile::open(QIODevice::OpenMode) if (_h == INVALID_HANDLE_VALUE) { + _lasterrorcode = GetLastError(); _lasterror = qt_error_string(); qDebug() << "Error opening:" << _lasterror; return false; @@ -80,6 +81,7 @@ qint64 WinFile::write(const char *data, qint64 maxSize) if (!WriteFile(_h, data, maxSize, &bytesWritten, NULL)) { + _lasterrorcode = GetLastError(); _lasterror = qt_error_string(); return -1; } @@ -93,6 +95,7 @@ qint64 WinFile::read(char *data, qint64 maxSize) if (!ReadFile(_h, data, maxSize, &bytesRead, NULL)) { + _lasterrorcode = GetLastError(); _lasterror = qt_error_string(); return -1; } @@ -107,6 +110,7 @@ bool WinFile::seek(qint64 pos) offset.QuadPart = pos; if (!SetFilePointerEx(_h, offset, ¤t, FILE_BEGIN)) { + _lasterrorcode = GetLastError(); _lasterror = qt_error_string(); qDebug() << "Error seeking:" << _lasterror; return false; @@ -122,6 +126,7 @@ qint64 WinFile::pos() offset.QuadPart = 0; if (!SetFilePointerEx(_h, offset, ¤t, FILE_CURRENT)) { + _lasterrorcode = GetLastError(); _lasterror = qt_error_string(); return 0; } @@ -139,6 +144,11 @@ QString WinFile::errorString() const return _lasterror; } +int WinFile::errorCode() const +{ + return _lasterrorcode; +} + bool WinFile::flush() { if (!FlushFileBuffers(_h)) diff --git a/windows/winfile.h b/windows/winfile.h index f70983551..b72f7cbd1 100644 --- a/windows/winfile.h +++ b/windows/winfile.h @@ -24,6 +24,7 @@ class WinFile : public QObject qint64 read(char *data, qint64 maxSize); HANDLE handle(); QString errorString() const; + int errorCode() const; bool flush(); bool seek(qint64 pos); qint64 pos(); @@ -34,6 +35,7 @@ class WinFile : public QObject bool _locked; QString _name, _lasterror; HANDLE _h; + int _lasterrorcode; }; #endif // WINFILE_H