Skip to content

Commit

Permalink
Windows: mention 'Controlled Folder Access' on ERROR_ACCESS_DENIED
Browse files Browse the repository at this point in the history
If WriteFile() returns ERROR_ACCESS_DENIED and registry indicates
CFA is on, tell user rpi-imager (and fat32format) should be added
to the "allowed apps" in the CFA settings.
  • Loading branch information
maxnet committed Jul 5, 2020
1 parent f90739a commit 385ee6d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 5 deletions.
24 changes: 20 additions & 4 deletions downloadthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <regex>
#include <QDebug>
#include <QProcess>
#include <QSettings>
#include <QtConcurrent/QtConcurrent>

#ifdef Q_OS_LINUX
Expand All @@ -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);
Expand Down Expand Up @@ -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 += "<br>"+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();
Expand Down Expand Up @@ -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();
Expand Down
12 changes: 11 additions & 1 deletion windows/winfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <QThread>

WinFile::WinFile(QObject *parent)
: QObject(parent), _locked(false), _h(INVALID_HANDLE_VALUE)
: QObject(parent), _locked(false), _h(INVALID_HANDLE_VALUE), _lasterrorcode(0)
{

}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -107,6 +110,7 @@ bool WinFile::seek(qint64 pos)
offset.QuadPart = pos;
if (!SetFilePointerEx(_h, offset, &current, FILE_BEGIN))
{
_lasterrorcode = GetLastError();
_lasterror = qt_error_string();
qDebug() << "Error seeking:" << _lasterror;
return false;
Expand All @@ -122,6 +126,7 @@ qint64 WinFile::pos()
offset.QuadPart = 0;
if (!SetFilePointerEx(_h, offset, &current, FILE_CURRENT))
{
_lasterrorcode = GetLastError();
_lasterror = qt_error_string();
return 0;
}
Expand All @@ -139,6 +144,11 @@ QString WinFile::errorString() const
return _lasterror;
}

int WinFile::errorCode() const
{
return _lasterrorcode;
}

bool WinFile::flush()
{
if (!FlushFileBuffers(_h))
Expand Down
2 changes: 2 additions & 0 deletions windows/winfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -34,6 +35,7 @@ class WinFile : public QObject
bool _locked;
QString _name, _lasterror;
HANDLE _h;
int _lasterrorcode;
};

#endif // WINFILE_H

0 comments on commit 385ee6d

Please sign in to comment.