summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/winrt/qwinrtfileengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/winrt/qwinrtfileengine.cpp')
-rw-r--r--src/plugins/platforms/winrt/qwinrtfileengine.cpp554
1 files changed, 0 insertions, 554 deletions
diff --git a/src/plugins/platforms/winrt/qwinrtfileengine.cpp b/src/plugins/platforms/winrt/qwinrtfileengine.cpp
deleted file mode 100644
index 962e4ab938..0000000000
--- a/src/plugins/platforms/winrt/qwinrtfileengine.cpp
+++ /dev/null
@@ -1,554 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwinrtfileengine.h"
-
-#include <QtCore/QDateTime>
-#include <QtCore/QCoreApplication>
-#include <QtCore/QHash>
-#include <QtCore/qfunctions_winrt.h>
-#include <QtCore/private/qfsfileengine_p.h>
-
-#include <wrl.h>
-#include <windows.storage.h>
-#include <robuffer.h>
-
-using namespace Microsoft::WRL;
-using namespace Microsoft::WRL::Wrappers;
-using namespace ABI::Windows::Foundation;
-using namespace ABI::Windows::Storage;
-using namespace ABI::Windows::Storage::Streams;
-
-typedef IAsyncOperationCompletedHandler<IRandomAccessStream *> StreamCompletedHandler;
-typedef IAsyncOperationWithProgressCompletedHandler<IBuffer *, UINT32> StreamReadCompletedHandler;
-
-QT_BEGIN_NAMESPACE
-
-#define RETURN_AND_SET_ERROR_IF_FAILED(error, ret) \
- setError(error, qt_error_string(hr)); \
- if (FAILED(hr)) \
- return ret;
-
-Q_GLOBAL_STATIC(QWinRTFileEngineHandler, handlerInstance)
-
-class QWinRTFileEngineHandlerPrivate
-{
-public:
- QHash<QString, ComPtr<IStorageItem>> files;
-};
-
-class QWinRTFileEnginePrivate
-{
-public:
- QWinRTFileEnginePrivate(const QString &fileName, IStorageItem *file)
- : fileName(fileName), file(file), openMode(QIODevice::NotOpen)
- {
- HRESULT hr;
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(),
- IID_PPV_ARGS(&bufferFactory));
- Q_ASSERT_SUCCEEDED(hr);
-
- lastSeparator = fileName.size() - 1;
- for (int i = lastSeparator; i >= 0; --i) {
- if (fileName.at(i).unicode() == '/' || fileName.at(i).unicode() == '\\') {
- lastSeparator = i;
- break;
- }
- }
-
- firstDot = fileName.size();
- for (int i = lastSeparator; i < fileName.size(); ++i) {
- if (fileName.at(i).unicode() == '.') {
- firstDot = i;
- break;
- }
- }
- }
-
- ComPtr<IBufferFactory> bufferFactory;
-
- QString fileName;
- int lastSeparator;
- int firstDot;
- ComPtr<IStorageItem> file;
- ComPtr<IRandomAccessStream> stream;
- QIODevice::OpenMode openMode;
-
- qint64 pos;
-
-private:
- QWinRTFileEngineHandler *q_ptr;
- Q_DECLARE_PUBLIC(QWinRTFileEngineHandler)
-};
-
-
-QWinRTFileEngineHandler::QWinRTFileEngineHandler()
- : d_ptr(new QWinRTFileEngineHandlerPrivate)
-{
-}
-
-void QWinRTFileEngineHandler::registerFile(const QString &fileName, IStorageItem *file)
-{
- handlerInstance->d_func()->files.insert(QDir::cleanPath(fileName), file);
-}
-
-IStorageItem *QWinRTFileEngineHandler::registeredFile(const QString &fileName)
-{
- return handlerInstance->d_func()->files.value(fileName).Get();
-}
-
-QAbstractFileEngine *QWinRTFileEngineHandler::create(const QString &fileName) const
-{
- Q_D(const QWinRTFileEngineHandler);
-
- QHash<QString, ComPtr<IStorageItem>>::const_iterator file = d->files.find(fileName);
- if (file != d->files.end())
- return new QWinRTFileEngine(fileName, file.value().Get());
-
- return nullptr;
-}
-
-static HRESULT getDestinationFolder(const QString &fileName, const QString &newFileName,
- IStorageItem *file, IStorageFolder **folder)
-{
- HRESULT hr;
- ComPtr<IAsyncOperation<StorageFolder *>> op;
- QFileInfo newFileInfo(newFileName);
- QFileInfo fileInfo(fileName);
- if (fileInfo.dir() == newFileInfo.dir()) {
- ComPtr<IStorageItem2> item;
- hr = file->QueryInterface(IID_PPV_ARGS(&item));
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = item->GetParentAsync(&op);
- } else {
- ComPtr<IStorageFolderStatics> folderFactory;
- hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_StorageFolder).Get(),
- IID_PPV_ARGS(&folderFactory));
- Q_ASSERT_SUCCEEDED(hr);
-
- const QString newFilePath = QDir::toNativeSeparators(newFileInfo.absolutePath());
- HStringReference nativeNewFilePath(reinterpret_cast<LPCWSTR>(newFilePath.utf16()),
- uint(newFilePath.length()));
- hr = folderFactory->GetFolderFromPathAsync(nativeNewFilePath.Get(), &op);
- }
- if (FAILED(hr))
- return hr;
- return QWinRTFunctions::await(op, folder);
-}
-
-QWinRTFileEngine::QWinRTFileEngine(const QString &fileName, IStorageItem *file)
- : d_ptr(new QWinRTFileEnginePrivate(fileName, file))
-{
-}
-
-bool QWinRTFileEngine::open(QIODevice::OpenMode openMode)
-{
- Q_D(QWinRTFileEngine);
-
- FileAccessMode fileAccessMode = (openMode & QIODevice::WriteOnly)
- ? FileAccessMode_ReadWrite : FileAccessMode_Read;
-
- HRESULT hr;
- ComPtr<IStorageFile> file;
- hr = d->file.As(&file);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false);
-
- ComPtr<IAsyncOperation<IRandomAccessStream *>> op;
- hr = file->OpenAsync(fileAccessMode, &op);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false);
-
- hr = QWinRTFunctions::await(op, d->stream.GetAddressOf());
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::OpenError, false);
-
- const ProcessOpenModeResult res = processOpenModeFlags(openMode);
- if (!res.ok) {
- setError(QFileDevice::OpenError, res.error);
- return false;
- }
- d->openMode = res.openMode;
- if (d->openMode & QIODevice::Truncate) {
- if (!setSize(0)) {
- close();
- setError(QFileDevice::OpenError, QLatin1String("Could not truncate file"));
- return false;
- }
- }
-
- return SUCCEEDED(hr);
-}
-
-bool QWinRTFileEngine::close()
-{
- Q_D(QWinRTFileEngine);
-
- if (!d->stream)
- return false;
-
- ComPtr<IClosable> closable;
- HRESULT hr = d->stream.As(&closable);
- Q_ASSERT_SUCCEEDED(hr);
-
- hr = closable->Close();
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::UnspecifiedError, false);
- d->stream.Reset();
- d->openMode = QIODevice::NotOpen;
- return SUCCEEDED(hr);
-}
-
-bool QWinRTFileEngine::flush()
-{
- Q_D(QWinRTFileEngine);
-
- if (!d->stream)
- return false;
-
- if (!(d->openMode & QIODevice::WriteOnly))
- return true;
-
- ComPtr<IOutputStream> stream;
- HRESULT hr = d->stream.As(&stream);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, false);
- ComPtr<IAsyncOperation<bool>> flushOp;
- hr = stream->FlushAsync(&flushOp);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, false);
- boolean flushed;
- hr = QWinRTFunctions::await(flushOp, &flushed);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, false);
-
- return true;
-}
-
-qint64 QWinRTFileEngine::size() const
-{
- Q_D(const QWinRTFileEngine);
-
- if (!d->stream)
- return 0;
-
- UINT64 size;
- HRESULT hr;
- hr = d->stream->get_Size(&size);
- RETURN_IF_FAILED("Failed to get file size", return 0);
-
- return qint64(size);
-}
-
-bool QWinRTFileEngine::setSize(qint64 size)
-{
- Q_D(QWinRTFileEngine);
- if (!d->stream) {
- setError(QFileDevice::ResizeError, QLatin1String("File must be open to be resized"));
- return false;
- }
-
- if (size < 0) {
- setError(QFileDevice::ResizeError, QLatin1String("File size cannot be negative"));
- return false;
- }
-
- HRESULT hr = d->stream->put_Size(static_cast<quint64>(size));
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ResizeError, false);
- if (!flush()) {
- setError(QFileDevice::ResizeError, QLatin1String("Could not flush file"));
- return false;
- }
-
- return true;
-}
-
-qint64 QWinRTFileEngine::pos() const
-{
- Q_D(const QWinRTFileEngine);
- return d->pos;
-}
-
-bool QWinRTFileEngine::seek(qint64 pos)
-{
- Q_D(QWinRTFileEngine);
-
- if (!d->stream)
- return false;
-
- HRESULT hr = d->stream->Seek(UINT64(pos));
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::PositionError, false);
- d->pos = pos;
- return SUCCEEDED(hr);
-}
-
-bool QWinRTFileEngine::remove()
-{
- Q_D(QWinRTFileEngine);
-
- ComPtr<IAsyncAction> op;
- HRESULT hr = d->file->DeleteAsync(StorageDeleteOption_Default, &op);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RemoveError, false);
-
- hr = QWinRTFunctions::await(op);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RemoveError, false);
- return SUCCEEDED(hr);
-}
-
-bool QWinRTFileEngine::copy(const QString &newName)
-{
- Q_D(QWinRTFileEngine);
-
- HRESULT hr;
- ComPtr<IStorageFolder> destinationFolder;
- hr = getDestinationFolder(d->fileName, newName, d->file.Get(), destinationFolder.GetAddressOf());
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
-
- ComPtr<IStorageFile> file;
- hr = d->file.As(&file);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
-
- const QString destinationName = QFileInfo(newName).fileName();
- HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()),
- uint(destinationName.length()));
- ComPtr<IAsyncOperation<StorageFile *>> op;
- hr = file->CopyOverloadDefaultOptions(destinationFolder.Get(), nativeDestinationName.Get(), &op);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
-
- ComPtr<IStorageFile> newFile;
- hr = QWinRTFunctions::await(op, newFile.GetAddressOf());
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::CopyError, false);
- return SUCCEEDED(hr);
-}
-
-bool QWinRTFileEngine::rename(const QString &newName)
-{
- Q_D(QWinRTFileEngine);
-
- HRESULT hr;
- ComPtr<IStorageFolder> destinationFolder;
- hr = getDestinationFolder(d->fileName, newName, d->file.Get(), destinationFolder.GetAddressOf());
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
-
- const QString destinationName = QFileInfo(newName).fileName();
- HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()),
- uint(destinationName.length()));
- ComPtr<IAsyncAction> op;
- hr = d->file->RenameAsyncOverloadDefaultOptions(nativeDestinationName.Get(), &op);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
- return SUCCEEDED(hr);
-}
-
-bool QWinRTFileEngine::renameOverwrite(const QString &newName)
-{
- Q_D(QWinRTFileEngine);
-
- HRESULT hr;
- ComPtr<IStorageFolder> destinationFolder;
- hr = getDestinationFolder(d->fileName, newName, d->file.Get(), destinationFolder.GetAddressOf());
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
-
- const QString destinationName = QFileInfo(newName).fileName();
- HStringReference nativeDestinationName(reinterpret_cast<LPCWSTR>(destinationName.utf16()),
- uint(destinationName.length()));
- ComPtr<IAsyncAction> op;
- hr = d->file->RenameAsync(nativeDestinationName.Get(), NameCollisionOption_ReplaceExisting, &op);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::RenameError, false);
- return SUCCEEDED(hr);
-}
-
-QAbstractFileEngine::FileFlags QWinRTFileEngine::fileFlags(FileFlags type) const
-{
- Q_D(const QWinRTFileEngine);
-
- FileFlags flags = ExistsFlag|ReadOwnerPerm|ReadUserPerm|WriteOwnerPerm|WriteUserPerm;
-
- HRESULT hr;
- FileAttributes attributes;
- hr = d->file->get_Attributes(&attributes);
- RETURN_IF_FAILED("Failed to get file attributes", return flags);
- if (attributes & FileAttributes_ReadOnly)
- flags ^= WriteUserPerm;
- if (attributes & FileAttributes_Directory)
- flags |= DirectoryType;
- else
- flags |= FileType;
-
- return type & flags;
-}
-
-bool QWinRTFileEngine::setPermissions(uint perms)
-{
- Q_UNUSED(perms);
- Q_UNIMPLEMENTED();
- return false;
-}
-
-QString QWinRTFileEngine::fileName(FileName type) const
-{
- Q_D(const QWinRTFileEngine);
-
- switch (type) {
- default:
- case DefaultName:
- case AbsoluteName:
- case CanonicalName:
- break;
- case BaseName:
- return d->lastSeparator < 0
- ? d->fileName : d->fileName.mid(d->lastSeparator, d->firstDot - d->lastSeparator);
- case PathName:
- case AbsolutePathName:
- case CanonicalPathName:
- return d->fileName.mid(0, d->lastSeparator);
- case LinkName:
- case BundleName:
- return QString();
- }
- return d->fileName;
-}
-
-QDateTime QWinRTFileEngine::fileTime(FileTime type) const
-{
- Q_D(const QWinRTFileEngine);
-
- HRESULT hr;
- DateTime dateTime = { 0 };
- switch (type) {
- case BirthTime:
- hr = d->file->get_DateCreated(&dateTime);
- RETURN_IF_FAILED("Failed to get file creation time", return QDateTime());
- break;
- case MetadataChangeTime:
- case ModificationTime:
- case AccessTime: {
- ComPtr<IAsyncOperation<FileProperties::BasicProperties *>> op;
- hr = d->file->GetBasicPropertiesAsync(&op);
- RETURN_IF_FAILED("Failed to initiate file properties", return QDateTime());
- ComPtr<FileProperties::IBasicProperties> properties;
- hr = QWinRTFunctions::await(op, properties.GetAddressOf());
- RETURN_IF_FAILED("Failed to get file properties", return QDateTime());
- hr = properties->get_DateModified(&dateTime);
- RETURN_IF_FAILED("Failed to get file date", return QDateTime());
- }
- break;
- }
-
- SYSTEMTIME systemTime;
- FileTimeToSystemTime((const FILETIME *)&dateTime, &systemTime);
- QDate date(systemTime.wYear, systemTime.wMonth, systemTime.wDay);
- QTime time(systemTime.wHour, systemTime.wMinute, systemTime.wSecond, systemTime.wMilliseconds);
- return QDateTime(date, time);
-}
-
-qint64 QWinRTFileEngine::read(char *data, qint64 maxlen)
-{
- Q_D(QWinRTFileEngine);
-
- if (!d->stream)
- return -1;
-
- ComPtr<IInputStream> stream;
- HRESULT hr = d->stream.As(&stream);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
-
- UINT32 length = UINT32(qBound(quint64(0), quint64(maxlen), quint64(UINT32_MAX)));
- ComPtr<IBuffer> buffer;
- hr = d->bufferFactory->Create(length, &buffer);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
-
- ComPtr<IAsyncOperationWithProgress<IBuffer *, UINT32>> op;
- hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &op);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
-
- // Quoting MSDN IInputStream::ReadAsync() documentation:
- // "Depending on the implementation, the data that's read might be placed
- // into the input buffer, or it might be returned in a different buffer."
- // Using GetAddressOf can cause ref counting errors leaking the original
- // buffer.
- ComPtr<IBuffer> effectiveBuffer;
- hr = QWinRTFunctions::await(op, effectiveBuffer.GetAddressOf());
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
-
- hr = effectiveBuffer->get_Length(&length);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
-
- ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
- hr = effectiveBuffer.As(&byteArrayAccess);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
-
- byte *bytes;
- hr = byteArrayAccess->Buffer(&bytes);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::ReadError, -1);
- memcpy(data, bytes, length);
- return qint64(length);
-}
-
-qint64 QWinRTFileEngine::write(const char *data, qint64 maxlen)
-{
- Q_D(QWinRTFileEngine);
-
- if (!d->stream)
- return -1;
-
- ComPtr<IOutputStream> stream;
- HRESULT hr = d->stream.As(&stream);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
-
- UINT32 length = UINT32(qBound(quint64(0), quint64(maxlen), quint64(UINT_MAX)));
- ComPtr<IBuffer> buffer;
- hr = d->bufferFactory->Create(length, &buffer);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
- hr = buffer->put_Length(length);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
-
- ComPtr<Windows::Storage::Streams::IBufferByteAccess> byteArrayAccess;
- hr = buffer.As(&byteArrayAccess);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
-
- byte *bytes;
- hr = byteArrayAccess->Buffer(&bytes);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
- memcpy(bytes, data, length);
-
- ComPtr<IAsyncOperationWithProgress<UINT32, UINT32>> op;
- hr = stream->WriteAsync(buffer.Get(), &op);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
-
- hr = QWinRTFunctions::await(op, &length);
- RETURN_AND_SET_ERROR_IF_FAILED(QFileDevice::WriteError, -1);
-
- return qint64(length);
-}
-
-QT_END_NAMESPACE