6#include <QtCore/qdir.h>
7#include <QtCore/qfileinfo.h>
8#include <QtCore/qmutex.h>
9#include <QtCore/qvarlengtharray.h>
12#include "private/qsystemlibrary_p.h"
28 if (
path.startsWith(
"\\\\?\\"_L1))
30 if (
path.length() < 2 ||
path.at(1) != u
':')
34 if (!(
path.at(0).unicode() >=
'A' &&
path.at(0).unicode() <=
'Z'))
36 if (!
path.endsWith(u
'\\'))
41void QStorageInfoPrivate::initRootPath()
45 const QString path = QFileSystemEntry::isDriveRootPath(rootPath)
50 valid = ready =
false;
59 valid = ready =
false;
65 const UINT
type = ::GetDriveType(
reinterpret_cast<const wchar_t *
>(
path.utf16()));
66 if (
type == DRIVE_REMOTE) {
68 DWORD bufferLength =
buffer.size();
70 UNIVERSAL_NAME_INFO *remoteNameInfo;
72 buffer.resize(bufferLength);
73 remoteNameInfo =
reinterpret_cast<UNIVERSAL_NAME_INFO *
>(
buffer.data());
74 result = ::WNetGetUniversalName(
reinterpret_cast<const wchar_t *
>(
path.utf16()),
75 UNIVERSAL_NAME_INFO_LEVEL,
78 }
while (
result == ERROR_MORE_DATA);
84 wchar_t deviceBuffer[51];
85 if (::GetVolumeNameForVolumeMountPoint(
reinterpret_cast<const wchar_t *
>(
path.utf16()),
87 sizeof(deviceBuffer) /
sizeof(
wchar_t))) {
93void QStorageInfoPrivate::doStat()
100 retrieveVolumeInfo();
101 if (!valid || !ready)
104 retrieveDiskFreeSpace();
106 if (!queryStorageProperty())
107 queryFileFsSectorSizeInformation();
110void QStorageInfoPrivate::retrieveVolumeInfo()
112 const UINT oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
117 DWORD fileSystemFlags = 0;
118 const bool result = ::GetVolumeInformation(
reinterpret_cast<const wchar_t *
>(
path.utf16()),
124 fileSystemTypeBuffer,
128 valid = ::GetLastError() == ERROR_NOT_READY;
133 readOnly = (fileSystemFlags & FILE_READ_ONLY_VOLUME) != 0;
136 ::SetErrorMode(oldmode);
139void QStorageInfoPrivate::retrieveDiskFreeSpace()
141 const UINT oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
144 ready = ::GetDiskFreeSpaceEx(
reinterpret_cast<const wchar_t *
>(
path.utf16()),
145 PULARGE_INTEGER(&bytesAvailable),
146 PULARGE_INTEGER(&bytesTotal),
147 PULARGE_INTEGER(&bytesFree));
149 ::SetErrorMode(oldmode);
157 const UINT oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
159 ::SetErrorMode(oldmode);
163 if (!drive.rootPath().isEmpty())
166 driveName[0] =
QChar(driveName[0].unicode() + 1);
167 driveBits = driveBits >> 1;
173bool QStorageInfoPrivate::queryStorageProperty()
176 if (
path.endsWith(u
'\\'))
181 FILE_SHARE_READ | FILE_SHARE_WRITE,
186 if (
handle == INVALID_HANDLE_VALUE)
189 STORAGE_PROPERTY_QUERY spq;
190 memset(&spq, 0,
sizeof(spq));
191 spq.PropertyId = StorageAccessAlignmentProperty;
192 spq.QueryType = PropertyStandardQuery;
194 STORAGE_ACCESS_ALIGNMENT_DESCRIPTOR saad;
195 memset(&saad, 0,
sizeof(saad));
199 IOCTL_STORAGE_QUERY_PROPERTY,
219 QFunctionPointer symbolFunctionPointer = ntdll->resolve(
name);
222 return symbolFunctionPointer;
225#define GENERATE_SYMBOL(symbolName, returnType, ...) \
226using Qt##symbolName = returnType (NTAPI *) (__VA_ARGS__); \
227static Qt##symbolName qt##symbolName = nullptr;
229#define RESOLVE_SYMBOL(name) \
231 qt##name = reinterpret_cast<Qt##name>(resolveSymbol(ntdll, #name)); \
236GENERATE_SYMBOL(RtlInitUnicodeString,
void, PUNICODE_STRING, PCWSTR);
237GENERATE_SYMBOL(NtCreateFile, NTSTATUS, PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
238 PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG, ULONG, ULONG, PVOID, ULONG);
239GENERATE_SYMBOL(NtQueryVolumeInformationFile, NTSTATUS,
HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
242void QStorageInfoPrivate::queryFileFsSectorSizeInformation()
244 static bool symbolsResolved = [](
auto ntdllHelper) {
246 auto ntdll = &ntdllHelper->ntdll;
247 if (!ntdll->isLoaded()) {
248 if (!ntdll->load()) {
249 qWarning(
"Unable to load ntdll.dll.");
254 RESOLVE_SYMBOL(RtlInitUnicodeString);
255 RESOLVE_SYMBOL(NtCreateFile);
256 RESOLVE_SYMBOL(NtQueryVolumeInformationFile);
260 if (!symbolsResolved)
264 memset(&ffssi, 0,
sizeof(ffssi));
268 OBJECT_ATTRIBUTES
attrs;
272 memset(&isb, 0,
sizeof(isb));
275 if (!
path.endsWith(u
'\\'))
279 qtRtlInitUnicodeString(&
name,
reinterpret_cast<const wchar_t *
>(
path.utf16()));
281 InitializeObjectAttributes(&
attrs, &
name, 0,
nullptr,
nullptr);
283 NTSTATUS status = qtNtCreateFile(&
handle,
284 FILE_READ_ATTRIBUTES,
288 FILE_ATTRIBUTE_NORMAL,
289 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
294 if (!NT_SUCCESS(status))
297 memset(&isb, 0,
sizeof(isb));
298 status = qtNtQueryVolumeInformationFile(
handle,
304 if (NT_SUCCESS(status))
305 blockSize = ffssi.PhysicalBytesPerSectorForAtomicity;
IOBluetoothDevice * device
static QString fromNativeSeparators(const QString &pathName)
static QString toNativeSeparators(const QString &pathName)
\inmodule QtCore \reentrant
void append(parameter_type t)
\macro QT_RESTRICTED_CAST_FROM_ASCII
QByteArray toLatin1() const &
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
QByteArray toUtf8() const &
Combined button and popup list for selecting options.
static struct AttrInfo attrs[]
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
QT_BEGIN_NAMESPACE struct _FILE_FS_SECTOR_SIZE_INFORMATION FILE_FS_SECTOR_SIZE_INFORMATION
enum _FSINFOCLASS FS_INFORMATION_CLASS
GLuint64 GLenum void * handle
GLsizei const GLchar *const * path
static QString canonicalPath(const QString &rootPath)
static QByteArray getDevice(const QString &rootPath)
static const int defaultBufferSize
#define QStringLiteral(str)