diff --git a/src/solid/devices/backends/win/winstoragevolume.cpp b/src/solid/devices/backends/win/winstoragevolume.cpp index 1a1b38d..78811c8 100644 --- a/src/solid/devices/backends/win/winstoragevolume.cpp +++ b/src/solid/devices/backends/win/winstoragevolume.cpp @@ -1,99 +1,103 @@ /* Copyright 2013 Patrick von Reth This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "winstoragevolume.h" #include "windevicemanager.h" +#include "winutils_p.h" #include #include using namespace Solid::Backends::Win; WinStorageVolume::WinStorageVolume(WinDevice *device) : WinBlock(device), m_size(0) { updateCache(); } WinStorageVolume::~WinStorageVolume() { } bool WinStorageVolume::isIgnored() const { return WinBlock::driveLetterFromUdi(m_device->udi()).isNull(); } Solid::StorageVolume::UsageType WinStorageVolume::usage() const { return Solid::StorageVolume::FileSystem;//TODO:??? } void WinStorageVolume::updateCache() { wchar_t label[MAX_PATH]; wchar_t fs[MAX_PATH]; DWORD serial; DWORD flags; //TODO:get correct name wchar_t dLetter[MAX_PATH]; int dLetterSize = WinBlock::driveLetterFromUdi(m_device->udi()).toWCharArray(dLetter); dLetter[dLetterSize] = (wchar_t)'\\'; dLetter[dLetterSize + 1] = 0; + // block error dialogs from GetDiskFreeSpaceEx & other WinAPI, see bug 371012 + WinErrorBlocker block; + if (GetVolumeInformation(dLetter, label, MAX_PATH, &serial, NULL, &flags, fs, MAX_PATH)) { m_label = QString::fromWCharArray(label); m_fs = QString::fromWCharArray(fs); m_uuid = QString::number(serial, 16); } ULARGE_INTEGER size; if (GetDiskFreeSpaceEx(dLetter, NULL, &size, NULL)) { m_size = size.QuadPart; } } QString WinStorageVolume::fsType() const { return m_fs; } QString WinStorageVolume::label() const { return m_label; } QString WinStorageVolume::uuid() const { return m_uuid; } qulonglong WinStorageVolume::size() const { return m_size; } QString WinStorageVolume::encryptedContainerUdi() const { return QString(); } diff --git a/src/solid/devices/backends/win/winutils_p.h b/src/solid/devices/backends/win/winutils_p.h new file mode 100644 index 0000000..bd10c53 --- /dev/null +++ b/src/solid/devices/backends/win/winutils_p.h @@ -0,0 +1,67 @@ +/* + Copyright 2016 Kevin Funk + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef WINUTILS_P_H +#define WINUTILS_P_H + +#include "windevicemanager.h" // for qGetLastError + +#include + +/** + * @brief RAII class for blocking Windows from reporting errors + * + * Internally calls GetThreadErrorMode + SetErrorMode. This class stores the + * current error mode on construction and disables certain error reportings + * during the life time of this object + * + * @code + * { + * WinErrorBlocker blocker; // custom error mode is set + * // Your Windows API calls... + * } // end of scope: original error mode is restored + * @endcode + * + * Note that qstorageinfo_win.cpp (qtbase) does something similar to silence errors + * + * See MSDN documentation: https://msdn.microsoft.com/en-us/library/windows/desktop/dd553630(v=vs.85).aspx + */ +class WinErrorBlocker +{ +public: + WinErrorBlocker() + { + if (!::SetThreadErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX, &m_oldmode)) { + qWarning() << "Failed to call SetThreadErrorMode:" << qGetLastError(); + } + } + ~WinErrorBlocker() + { + if (!::SetThreadErrorMode(m_oldmode, NULL)) { + qWarning() << "Failed to call SetThreadErrorMode:" << qGetLastError(); + } + } + +private: + Q_DISABLE_COPY(WinErrorBlocker) + DWORD m_oldmode; +}; + +#endif