diff --git a/downloadthread.cpp b/downloadthread.cpp index c0d1c3a..cabf308 100644 --- a/downloadthread.cpp +++ b/downloadthread.cpp @@ -171,8 +171,17 @@ bool DownloadThread::_openAndPrepareDevice() #ifdef Q_OS_DARWIN _filename.replace("/dev/disk", "/dev/rdisk"); - if (!_file.authOpen(_filename)) { - emit error(tr("Error running authopen to gain access to disk device '%1'").arg(QString(_filename))); + auto authopenresult = _file.authOpen(_filename); + + if (authopenresult == _file.authOpenCancelled) { + /* User cancelled authentication */ + emit error(tr("Authentication cancelled")); + return false; + } else if (authopenresult == _file.authOpenError) { + QString msg = tr("Error running authopen to gain access to disk device '%1'").arg(QString(_filename)); + msg += "
"+tr("Please verify if 'Raspberry Pi Imager' is allowed access to 'removable volumes' in privacy settings (under 'files and folders' or alternatively give it 'full disk access')."); + QProcess::execute("open x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"); + emit error(msg); return false; } #else diff --git a/mac/macfile.cpp b/mac/macfile.cpp index 7f890b9..91529db 100644 --- a/mac/macfile.cpp +++ b/mac/macfile.cpp @@ -22,7 +22,7 @@ bool MacFile::isSequential() const return false; } -bool MacFile::authOpen(const QByteArray &filename) +MacFile::authOpenResult MacFile::authOpen(const QByteArray &filename) { int fd = -1; @@ -34,13 +34,13 @@ bool MacFile::authOpen(const QByteArray &filename) kAuthorizationFlagPreAuthorize; AuthorizationRef authRef; if (AuthorizationCreate(&rights, nullptr, flags, &authRef) != 0) - return false; + return authOpenCancelled; AuthorizationExternalForm externalForm; if (AuthorizationMakeExternalForm(authRef, &externalForm) != 0) { AuthorizationFree(authRef, 0); - return false; + return authOpenError; } const char *cmd = "/usr/libexec/authopen"; @@ -110,17 +110,17 @@ bool MacFile::authOpen(const QByteArray &filename) if (wpid == -1) { qDebug() << "waitpid() failed executing authopen"; - return false; + return authOpenError; } if (WEXITSTATUS(status)) { qDebug() << "authopen returned failure code" << WEXITSTATUS(status); - return false; + return authOpenError; } qDebug() << "fd received:" << fd; } AuthorizationFree(authRef, 0); - return open(fd, QIODevice::ReadWrite | QIODevice::ExistingOnly | QIODevice::Unbuffered, QFileDevice::AutoCloseHandle); + return open(fd, QIODevice::ReadWrite | QIODevice::ExistingOnly | QIODevice::Unbuffered, QFileDevice::AutoCloseHandle) ? authOpenSuccess : authOpenError; } diff --git a/mac/macfile.h b/mac/macfile.h index 6bc842a..b24dd3d 100644 --- a/mac/macfile.h +++ b/mac/macfile.h @@ -12,9 +12,11 @@ class MacFile : public QFile { Q_OBJECT public: + enum authOpenResult {authOpenCancelled, authOpenSuccess, authOpenError }; + MacFile(QObject *parent = nullptr); virtual bool isSequential() const; - bool authOpen(const QByteArray &filename); + authOpenResult authOpen(const QByteArray &filename); }; #endif // MACFILE_H