Added initial file system support for winrt
While some functionality is not available for winphone (QFileSystemEngine::tempPath), some functionality can be fully supported. Other cases like checking for stale processes which is needed by QLockFile cannot be covered that easily as obtaining information about other processes is limited due to sandboxing. Change-Id: I9ea80ae2b421eea1ddfd4c5bc2f4b6f8adaee85f Done-with: Kamil Trzcinski Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com> Reviewed-by: Maurice Kalinowski <maurice.kalinowski@digia.com>
This commit is contained in:
parent
da0cb32b8e
commit
e31be2964e
@ -63,13 +63,26 @@
|
||||
# include <types.h>
|
||||
#endif
|
||||
#include <objbase.h>
|
||||
#include <shlobj.h>
|
||||
#ifndef Q_OS_WINRT
|
||||
# include <shlobj.h>
|
||||
# include <accctrl.h>
|
||||
#endif
|
||||
#include <initguid.h>
|
||||
#include <accctrl.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#define SECURITY_WIN32
|
||||
#include <security.h>
|
||||
#ifndef Q_OS_WINRT
|
||||
# define SECURITY_WIN32
|
||||
# include <security.h>
|
||||
#else // !Q_OS_WINRT
|
||||
# include <wrl.h>
|
||||
# include <windows.foundation.h>
|
||||
# include <windows.storage.h>
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
using namespace ABI::Windows::Foundation;
|
||||
using namespace ABI::Windows::Storage;
|
||||
#endif // Q_OS_WINRT
|
||||
|
||||
#ifndef SPI_GETPLATFORMTYPE
|
||||
#define SPI_GETPLATFORMTYPE 257
|
||||
@ -141,7 +154,7 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0;
|
||||
|
||||
#if defined(Q_OS_WINCE)
|
||||
#if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
|
||||
static QString qfsPrivateCurrentDir = QLatin1String("");
|
||||
// As none of the functions we try to resolve do exist on Windows CE
|
||||
// we use QT_NO_LIBRARY to shorten everything up a little bit.
|
||||
@ -289,14 +302,14 @@ static bool resolveUNCLibs()
|
||||
}
|
||||
#endif
|
||||
triedResolve = true;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
HINSTANCE hLib = QSystemLibrary::load(L"Netapi32");
|
||||
if (hLib) {
|
||||
ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum");
|
||||
if (ptrNetShareEnum)
|
||||
ptrNetApiBufferFree = (PtrNetApiBufferFree)GetProcAddress(hLib, "NetApiBufferFree");
|
||||
}
|
||||
#endif
|
||||
#endif // !Q_OS_WINCE && !Q_OS_WINRT
|
||||
}
|
||||
return ptrNetShareEnum && ptrNetApiBufferFree;
|
||||
}
|
||||
@ -304,7 +317,7 @@ static bool resolveUNCLibs()
|
||||
static QString readSymLink(const QFileSystemEntry &link)
|
||||
{
|
||||
QString result;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
HANDLE handle = CreateFile((wchar_t*)link.nativeFilePath().utf16(),
|
||||
FILE_READ_EA,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
@ -347,11 +360,11 @@ static QString readSymLink(const QFileSystemEntry &link)
|
||||
result.replace(0,matchVolName.matchedLength(), QString::fromWCharArray(buffer));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif // !Q_OS_WINCE && !Q_OS_WINRT
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(link);
|
||||
#endif // Q_OS_WINCE
|
||||
#endif // Q_OS_WINCE || Q_OS_WINRT
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -432,7 +445,11 @@ static inline bool getFindData(QString path, WIN32_FIND_DATA &findData)
|
||||
|
||||
// can't handle drives
|
||||
if (!path.endsWith(QLatin1Char(':'))) {
|
||||
#ifndef Q_OS_WINRT
|
||||
HANDLE hFind = ::FindFirstFile((wchar_t*)path.utf16(), &findData);
|
||||
#else
|
||||
HANDLE hFind = ::FindFirstFileEx((const wchar_t*)path.utf16(), FindExInfoStandard, &findData, FindExSearchNameMatch, NULL, 0);
|
||||
#endif
|
||||
if (hFind != INVALID_HANDLE_VALUE) {
|
||||
::FindClose(hFind);
|
||||
return true;
|
||||
@ -506,7 +523,7 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
|
||||
{
|
||||
// can be //server or //server/share
|
||||
QString absPath;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
QVarLengthArray<wchar_t, MAX_PATH> buf(qMax(MAX_PATH, path.size() + 1));
|
||||
wchar_t *fileName = 0;
|
||||
DWORD retLen = GetFullPathName((wchar_t*)path.utf16(), buf.size(), buf.data(), &fileName);
|
||||
@ -516,12 +533,17 @@ QString QFileSystemEngine::nativeAbsoluteFilePath(const QString &path)
|
||||
}
|
||||
if (retLen != 0)
|
||||
absPath = QString::fromWCharArray(buf.data(), retLen);
|
||||
#else
|
||||
#elif !defined(Q_OS_WINCE)
|
||||
if (QDir::isRelativePath(path))
|
||||
absPath = QDir::toNativeSeparators(QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + path));
|
||||
else
|
||||
absPath = QDir::toNativeSeparators(QDir::cleanPath(path));
|
||||
#else // Q_OS_WINRT
|
||||
if (path.startsWith(QLatin1Char('/')) || path.startsWith(QLatin1Char('\\')))
|
||||
absPath = QDir::toNativeSeparators(path);
|
||||
else
|
||||
absPath = QDir::toNativeSeparators(QDir::cleanPath(qfsPrivateCurrentDir + QLatin1Char('/') + path));
|
||||
#endif
|
||||
#endif // Q_OS_WINCE
|
||||
// This is really ugly, but GetFullPathName strips off whitespace at the end.
|
||||
// If you for instance write ". " in the lineedit of QFileDialog,
|
||||
// (which is an invalid filename) this function will strip the space off and viola,
|
||||
@ -548,9 +570,17 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
|
||||
ret = entry.filePath();
|
||||
#endif
|
||||
} else {
|
||||
#ifndef Q_OS_WINRT
|
||||
ret = QDir::cleanPath(QDir::currentPath() + QLatin1Char('/') + entry.filePath());
|
||||
#else
|
||||
// Some WinRT APIs do not support absolute paths (due to sandboxing).
|
||||
// Thus the port uses the executable's directory as its root directory
|
||||
// and treats paths relative to that as absolute paths.
|
||||
ret = QDir::cleanPath(QDir::current().relativeFilePath(entry.filePath()));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef Q_OS_WINRT
|
||||
// The path should be absolute at this point.
|
||||
// From the docs :
|
||||
// Absolute paths begin with the directory separator "/"
|
||||
@ -563,6 +593,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry)
|
||||
// Force uppercase drive letters.
|
||||
ret[0] = ret.at(0).toUpper();
|
||||
}
|
||||
#endif // !Q_OS_WINRT
|
||||
return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath());
|
||||
}
|
||||
|
||||
@ -590,18 +621,24 @@ typedef struct _FILE_ID_INFO {
|
||||
static inline QByteArray fileId(HANDLE handle)
|
||||
{
|
||||
QByteArray result;
|
||||
#ifndef Q_OS_WINRT
|
||||
BY_HANDLE_FILE_INFORMATION info;
|
||||
if (GetFileInformationByHandle(handle, &info)) {
|
||||
result = QByteArray::number(uint(info.nFileIndexLow), 16);
|
||||
result += ':';
|
||||
result += QByteArray::number(uint(info.nFileIndexHigh), 16);
|
||||
}
|
||||
#else // !Q_OS_WINRT
|
||||
Q_UNUSED(handle);
|
||||
Q_UNIMPLEMENTED();
|
||||
#endif // Q_OS_WINRT
|
||||
return result;
|
||||
}
|
||||
|
||||
// File ID for Windows starting from version 8.
|
||||
QByteArray fileIdWin8(HANDLE handle)
|
||||
{
|
||||
#ifndef Q_OS_WINRT
|
||||
typedef BOOL (WINAPI* GetFileInformationByHandleExType)(HANDLE, Q_FILE_INFO_BY_HANDLE_CLASS, void *, DWORD);
|
||||
|
||||
// Dynamically resolve GetFileInformationByHandleEx (Vista onwards).
|
||||
@ -621,6 +658,16 @@ QByteArray fileIdWin8(HANDLE handle)
|
||||
result += QByteArray((char *)&infoEx.FileId, sizeof(infoEx.FileId)).toHex();
|
||||
}
|
||||
}
|
||||
#else // !Q_OS_WINRT
|
||||
QByteArray result;
|
||||
FILE_ID_INFO infoEx;
|
||||
if (GetFileInformationByHandleEx(handle, FileIdInfo,
|
||||
&infoEx, sizeof(FILE_ID_INFO))) {
|
||||
result = QByteArray::number(infoEx.VolumeSerialNumber, 16);
|
||||
result += ':';
|
||||
result += QByteArray((char *)infoEx.FileId.Identifier, sizeof(infoEx.FileId.Identifier)).toHex();
|
||||
}
|
||||
#endif // Q_OS_WINRT
|
||||
return result;
|
||||
}
|
||||
#endif // !Q_OS_WINCE
|
||||
@ -631,8 +678,13 @@ QByteArray QFileSystemEngine::id(const QFileSystemEntry &entry)
|
||||
#ifndef Q_OS_WINCE
|
||||
QByteArray result;
|
||||
const HANDLE handle =
|
||||
#ifndef Q_OS_WINRT
|
||||
CreateFile((wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
|
||||
FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#else // !Q_OS_WINRT
|
||||
CreateFile2((const wchar_t*)entry.nativeFilePath().utf16(), GENERIC_READ,
|
||||
FILE_SHARE_READ, OPEN_EXISTING, NULL);
|
||||
#endif // Q_OS_WINRT
|
||||
if (handle) {
|
||||
result = QSysInfo::windowsVersion() >= QSysInfo::WV_WINDOWS8 ?
|
||||
fileIdWin8(handle) : fileId(handle);
|
||||
@ -810,7 +862,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa
|
||||
{
|
||||
bool entryExists = false;
|
||||
DWORD fileAttrib = 0;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
if (fname.isDriveRoot()) {
|
||||
// a valid drive ??
|
||||
DWORD drivesBitmask = ::GetLogicalDrives();
|
||||
@ -851,7 +903,7 @@ static bool tryDriveUNCFallback(const QFileSystemEntry &fname, QFileSystemMetaDa
|
||||
fileAttrib = FILE_ATTRIBUTE_DIRECTORY;
|
||||
entryExists = true;
|
||||
}
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
}
|
||||
#endif
|
||||
if (entryExists)
|
||||
@ -894,12 +946,27 @@ bool QFileSystemEngine::fillMetaData(HANDLE fHandle, QFileSystemMetaData &data,
|
||||
{
|
||||
data.entryFlags &= ~what;
|
||||
clearWinStatData(data);
|
||||
#ifndef Q_OS_WINRT
|
||||
BY_HANDLE_FILE_INFORMATION fileInfo;
|
||||
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
if (GetFileInformationByHandle(fHandle , &fileInfo)) {
|
||||
data.fillFromFindInfo(fileInfo);
|
||||
}
|
||||
SetErrorMode(oldmode);
|
||||
#else // !Q_OS_WINRT
|
||||
FILE_FULL_DIR_INFO fileInfo;
|
||||
if (GetFileInformationByHandleEx(fHandle, FileFullDirectoryInfo, &fileInfo, sizeof(fileInfo))) {
|
||||
data.fillFromFileAttribute(fileInfo.FileAttributes);
|
||||
data.creationTime_.dwHighDateTime = fileInfo.CreationTime.HighPart;
|
||||
data.creationTime_.dwLowDateTime = fileInfo.CreationTime.LowPart;
|
||||
data.lastAccessTime_.dwHighDateTime = fileInfo.LastAccessTime.HighPart;
|
||||
data.lastAccessTime_.dwLowDateTime = fileInfo.LastAccessTime.LowPart;
|
||||
data.lastWriteTime_.dwHighDateTime = fileInfo.LastWriteTime.HighPart;
|
||||
data.lastWriteTime_.dwLowDateTime = fileInfo.LastWriteTime.LowPart;
|
||||
data.fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY ? data.size_ = 0 : data.size_ = fileInfo.AllocationSize.QuadPart;
|
||||
data.knownFlagsMask |= data.Times | data.SizeAttribute;
|
||||
}
|
||||
#endif // Q_OS_WINRT
|
||||
return data.hasFlags(what);
|
||||
}
|
||||
|
||||
@ -931,7 +998,9 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
|
||||
}
|
||||
|
||||
if (what & QFileSystemMetaData::WinStatFlags) {
|
||||
#ifndef Q_OS_WINRT
|
||||
UINT oldmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
||||
#endif
|
||||
clearWinStatData(data);
|
||||
WIN32_FIND_DATA findData;
|
||||
// The memory structure for WIN32_FIND_DATA is same as WIN32_FILE_ATTRIBUTE_DATA
|
||||
@ -943,11 +1012,15 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM
|
||||
} else {
|
||||
if (!tryFindFallback(fname, data))
|
||||
if (!tryDriveUNCFallback(fname, data)) {
|
||||
#ifndef Q_OS_WINRT
|
||||
SetErrorMode(oldmode);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#ifndef Q_OS_WINRT
|
||||
SetErrorMode(oldmode);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (what & QFileSystemMetaData::Permissions)
|
||||
@ -1000,7 +1073,14 @@ static bool isDirPath(const QString &dirPath, bool *existed)
|
||||
if (path.length() == 2 && path.at(1) == QLatin1Char(':'))
|
||||
path += QLatin1Char('\\');
|
||||
|
||||
#ifndef Q_OS_WINRT
|
||||
DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16());
|
||||
#else // Q_OS_WINRT
|
||||
DWORD fileAttrib = INVALID_FILE_ATTRIBUTES;
|
||||
WIN32_FILE_ATTRIBUTE_DATA data;
|
||||
if (::GetFileAttributesEx((const wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(), GetFileExInfoStandard, &data))
|
||||
fileAttrib = data.dwFileAttributes;
|
||||
#endif // Q_OS_WINRT
|
||||
if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
|
||||
int errorCode = GetLastError();
|
||||
if (errorCode == ERROR_ACCESS_DENIED || errorCode == ERROR_SHARING_VIOLATION) {
|
||||
@ -1152,12 +1232,13 @@ QString QFileSystemEngine::homePath()
|
||||
QString QFileSystemEngine::tempPath()
|
||||
{
|
||||
QString ret;
|
||||
#ifndef Q_OS_WINRT
|
||||
wchar_t tempPath[MAX_PATH];
|
||||
const DWORD len = GetTempPath(MAX_PATH, tempPath);
|
||||
#ifdef Q_OS_WINCE
|
||||
if (len)
|
||||
ret = QString::fromWCharArray(tempPath, len);
|
||||
#else
|
||||
#else // Q_OS_WINCE
|
||||
if (len) { // GetTempPath() can return short names, expand.
|
||||
wchar_t longTempPath[MAX_PATH];
|
||||
const DWORD longLen = GetLongPathName(tempPath, longTempPath, MAX_PATH);
|
||||
@ -1165,12 +1246,33 @@ QString QFileSystemEngine::tempPath()
|
||||
QString::fromWCharArray(longTempPath, longLen) :
|
||||
QString::fromWCharArray(tempPath, len);
|
||||
}
|
||||
#endif
|
||||
#endif // !Q_OS_WINCE
|
||||
if (!ret.isEmpty()) {
|
||||
while (ret.endsWith(QLatin1Char('\\')))
|
||||
ret.chop(1);
|
||||
ret = QDir::fromNativeSeparators(ret);
|
||||
}
|
||||
#else // !Q_OS_WINRT
|
||||
// According to http://msdn.microsoft.com/en-us/library/windows/apps/windows.storage.applicationdata.temporaryfolder.aspx
|
||||
// the API is not available on winphone which should cause one of the functions
|
||||
// below to fail
|
||||
ComPtr<IApplicationDataStatics> applicationDataStatics;
|
||||
if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
|
||||
return ret;
|
||||
ComPtr<IApplicationData> applicationData;
|
||||
if (FAILED(applicationDataStatics->get_Current(&applicationData)))
|
||||
return ret;
|
||||
ComPtr<IStorageFolder> tempFolder;
|
||||
if (FAILED(applicationData->get_TemporaryFolder(&tempFolder)))
|
||||
return ret;
|
||||
ComPtr<IStorageItem> tempFolderItem;
|
||||
if (FAILED(tempFolder.As(&tempFolderItem)))
|
||||
return ret;
|
||||
HSTRING path;
|
||||
if (FAILED(tempFolderItem->get_Path(&path)))
|
||||
return ret;
|
||||
ret = QString::fromWCharArray(WindowsGetStringRawBuffer(path, nullptr));
|
||||
#endif // Q_OS_WINRT
|
||||
if (ret.isEmpty()) {
|
||||
#if !defined(Q_OS_WINCE)
|
||||
ret = QLatin1String("C:/tmp");
|
||||
@ -1189,7 +1291,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
|
||||
if(!(meta.exists() && meta.isDirectory()))
|
||||
return false;
|
||||
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
//TODO: this should really be using nativeFilePath(), but that returns a path in long format \\?\c:\foo
|
||||
//which causes many problems later on when it's returned through currentPath()
|
||||
return ::SetCurrentDirectory(reinterpret_cast<const wchar_t*>(QDir::toNativeSeparators(entry.filePath()).utf16())) != 0;
|
||||
@ -1202,7 +1304,7 @@ bool QFileSystemEngine::setCurrentPath(const QFileSystemEntry &entry)
|
||||
QFileSystemEntry QFileSystemEngine::currentPath()
|
||||
{
|
||||
QString ret;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
DWORD size = 0;
|
||||
wchar_t currentName[PATH_MAX];
|
||||
size = ::GetCurrentDirectory(PATH_MAX, currentName);
|
||||
@ -1218,13 +1320,13 @@ QFileSystemEntry QFileSystemEngine::currentPath()
|
||||
}
|
||||
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
|
||||
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
|
||||
#else
|
||||
#else // !Q_OS_WINCE && !Q_OS_WINRT
|
||||
//TODO - a race condition exists when using currentPath / setCurrentPath from multiple threads
|
||||
if (qfsPrivateCurrentDir.isEmpty())
|
||||
qfsPrivateCurrentDir = QCoreApplication::applicationDirPath();
|
||||
|
||||
ret = qfsPrivateCurrentDir;
|
||||
#endif
|
||||
#endif // Q_OS_WINCE || Q_OS_WINRT
|
||||
return QFileSystemEntry(ret, QFileSystemEntry::FromNativePath());
|
||||
}
|
||||
|
||||
@ -1242,8 +1344,16 @@ bool QFileSystemEngine::createLink(const QFileSystemEntry &source, const QFileSy
|
||||
//static
|
||||
bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
|
||||
{
|
||||
#ifndef Q_OS_WINRT
|
||||
bool ret = ::CopyFile((wchar_t*)source.nativeFilePath().utf16(),
|
||||
(wchar_t*)target.nativeFilePath().utf16(), true) != 0;
|
||||
#else // !Q_OS_WINRT
|
||||
COPYFILE2_EXTENDED_PARAMETERS copyParams = {
|
||||
sizeof(copyParams), COPY_FILE_FAIL_IF_EXISTS, NULL, NULL, NULL
|
||||
};
|
||||
bool ret = ::CopyFile2((const wchar_t*)source.nativeFilePath().utf16(),
|
||||
(const wchar_t*)target.nativeFilePath().utf16(), ©Params) != 0;
|
||||
#endif // Q_OS_WINRT
|
||||
if(!ret)
|
||||
error = QSystemError(::GetLastError(), QSystemError::NativeError);
|
||||
return ret;
|
||||
@ -1252,8 +1362,13 @@ bool QFileSystemEngine::copyFile(const QFileSystemEntry &source, const QFileSyst
|
||||
//static
|
||||
bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
|
||||
{
|
||||
#ifndef Q_OS_WINRT
|
||||
bool ret = ::MoveFile((wchar_t*)source.nativeFilePath().utf16(),
|
||||
(wchar_t*)target.nativeFilePath().utf16()) != 0;
|
||||
#else // !Q_OS_WINRT
|
||||
bool ret = ::MoveFileEx((const wchar_t*)source.nativeFilePath().utf16(),
|
||||
(const wchar_t*)target.nativeFilePath().utf16(), 0) != 0;
|
||||
#endif // Q_OS_WINRT
|
||||
if(!ret)
|
||||
error = QSystemError(::GetLastError(), QSystemError::NativeError);
|
||||
return ret;
|
||||
|
@ -39,10 +39,12 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#if _WIN32_WINNT < 0x0500
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0500
|
||||
#endif
|
||||
#if !defined(WINAPI_FAMILY)
|
||||
# if _WIN32_WINNT < 0x0500
|
||||
# undef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0500
|
||||
# endif // _WIN32_WINNT < 0x500
|
||||
#endif // !WINAPI_FAMILY
|
||||
|
||||
#include "qfilesystemiterator_p.h"
|
||||
#include "qfilesystemengine_p.h"
|
||||
@ -73,6 +75,10 @@ QFileSystemIterator::QFileSystemIterator(const QFileSystemEntry &entry, QDir::Fi
|
||||
if (!nativePath.endsWith(QLatin1Char('\\')))
|
||||
nativePath.append(QLatin1Char('\\'));
|
||||
nativePath.append(QLatin1Char('*'));
|
||||
#ifdef Q_OS_WINRT
|
||||
if (nativePath.startsWith(QLatin1Char('\\')))
|
||||
nativePath.remove(0, 1);
|
||||
#endif
|
||||
if (!dirPath.endsWith(QLatin1Char('/')))
|
||||
dirPath.append(QLatin1Char('/'));
|
||||
if ((filters & (QDir::Dirs|QDir::Drives)) && (!(filters & (QDir::Files))))
|
||||
|
@ -219,7 +219,9 @@ public:
|
||||
#if defined(Q_OS_WIN)
|
||||
inline void fillFromFileAttribute(DWORD fileAttribute, bool isDriveRoot = false);
|
||||
inline void fillFromFindData(WIN32_FIND_DATA &findData, bool setLinkType = false, bool isDriveRoot = false);
|
||||
# ifndef Q_OS_WINRT
|
||||
inline void fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo);
|
||||
# endif
|
||||
#endif
|
||||
private:
|
||||
friend class QFileSystemEngine;
|
||||
@ -340,6 +342,7 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef Q_OS_WINRT
|
||||
inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fileInfo)
|
||||
{
|
||||
fillFromFileAttribute(fileInfo.dwFileAttributes);
|
||||
@ -355,7 +358,8 @@ inline void QFileSystemMetaData::fillFromFindInfo(BY_HANDLE_FILE_INFORMATION &fi
|
||||
}
|
||||
knownFlagsMask |= Times | SizeAttribute;
|
||||
}
|
||||
#endif
|
||||
#endif // !Q_OS_WINRT
|
||||
#endif // Q_OS_WIN
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -60,14 +60,18 @@
|
||||
# include <types.h>
|
||||
#endif
|
||||
#include <objbase.h>
|
||||
#include <shlobj.h>
|
||||
#ifndef Q_OS_WINRT
|
||||
# include <shlobj.h>
|
||||
# include <accctrl.h>
|
||||
#endif
|
||||
#include <initguid.h>
|
||||
#include <accctrl.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#define SECURITY_WIN32
|
||||
#include <security.h>
|
||||
#ifndef Q_OS_WINRT
|
||||
# define SECURITY_WIN32
|
||||
# include <security.h>
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX FILENAME_MAX
|
||||
@ -93,7 +97,7 @@ QString QFSFileEnginePrivate::longFileName(const QString &path)
|
||||
return path;
|
||||
|
||||
QString absPath = QFileSystemEngine::nativeAbsoluteFilePath(path);
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
QString prefix = QLatin1String("\\\\?\\");
|
||||
if (isUncPath(absPath)) {
|
||||
prefix.append(QLatin1String("UNC\\")); // "\\\\?\\UNC\\"
|
||||
@ -121,11 +125,12 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
|
||||
if (openMode & QIODevice::WriteOnly)
|
||||
accessRights |= GENERIC_WRITE;
|
||||
|
||||
SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
|
||||
|
||||
// WriteOnly can create files, ReadOnly cannot.
|
||||
DWORD creationDisp = (openMode & QIODevice::WriteOnly) ? OPEN_ALWAYS : OPEN_EXISTING;
|
||||
// Create the file handle.
|
||||
#ifndef Q_OS_WINRT
|
||||
SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
|
||||
fileHandle = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
|
||||
accessRights,
|
||||
shareMode,
|
||||
@ -133,6 +138,13 @@ bool QFSFileEnginePrivate::nativeOpen(QIODevice::OpenMode openMode)
|
||||
creationDisp,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
#else // !Q_OS_WINRT
|
||||
fileHandle = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(),
|
||||
accessRights,
|
||||
shareMode,
|
||||
creationDisp,
|
||||
NULL);
|
||||
#endif // Q_OS_WINRT
|
||||
|
||||
// Bail out on error.
|
||||
if (fileHandle == INVALID_HANDLE_VALUE) {
|
||||
@ -473,7 +485,7 @@ int QFSFileEnginePrivate::nativeHandle() const
|
||||
*/
|
||||
bool QFSFileEnginePrivate::nativeIsSequential() const
|
||||
{
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
HANDLE handle = fileHandle;
|
||||
if (fh || fd != -1)
|
||||
handle = (HANDLE)_get_osfhandle(fh ? QT_FILENO(fh) : fd);
|
||||
@ -577,7 +589,7 @@ bool QFSFileEngine::setCurrentPath(const QString &path)
|
||||
|
||||
QString QFSFileEngine::currentPath(const QString &fileName)
|
||||
{
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
QString ret;
|
||||
//if filename is a drive: then get the pwd of that drive
|
||||
if (fileName.length() >= 2 &&
|
||||
@ -596,10 +608,10 @@ QString QFSFileEngine::currentPath(const QString &fileName)
|
||||
if (ret.length() >= 2 && ret[1] == QLatin1Char(':'))
|
||||
ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters.
|
||||
return ret;
|
||||
#else
|
||||
#else // !Q_OS_WINCE && !Q_OS_WINRT
|
||||
Q_UNUSED(fileName);
|
||||
return QFileSystemEngine::currentPath().filePath();
|
||||
#endif
|
||||
#endif // Q_OS_WINCE || Q_OS_WINRT
|
||||
}
|
||||
|
||||
QString QFSFileEngine::homePath()
|
||||
@ -620,7 +632,7 @@ QString QFSFileEngine::tempPath()
|
||||
QFileInfoList QFSFileEngine::drives()
|
||||
{
|
||||
QFileInfoList ret;
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
#if defined(Q_OS_WIN32)
|
||||
quint32 driveBits = (quint32) GetLogicalDrives() & 0x3ffffff;
|
||||
#endif
|
||||
@ -633,10 +645,10 @@ QFileInfoList QFSFileEngine::drives()
|
||||
driveBits = driveBits >> 1;
|
||||
}
|
||||
return ret;
|
||||
#else
|
||||
#else // !Q_OS_WINCE && !Q_OS_WINRT
|
||||
ret.append(QFileInfo(QLatin1String("/")));
|
||||
return ret;
|
||||
#endif
|
||||
#endif // Q_OS_WINCE || Q_OS_WINRT
|
||||
}
|
||||
|
||||
bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) const
|
||||
@ -661,7 +673,7 @@ bool QFSFileEnginePrivate::doStat(QFileSystemMetaData::MetaDataFlags flags) cons
|
||||
|
||||
bool QFSFileEngine::link(const QString &newName)
|
||||
{
|
||||
#if !defined(Q_OS_WINCE)
|
||||
#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||
#if !defined(QT_NO_LIBRARY)
|
||||
bool ret = false;
|
||||
|
||||
@ -707,7 +719,7 @@ bool QFSFileEngine::link(const QString &newName)
|
||||
Q_UNUSED(newName);
|
||||
return false;
|
||||
#endif // QT_NO_LIBRARY
|
||||
#else
|
||||
#elif defined(Q_OS_WINCE)
|
||||
QString linkName = newName;
|
||||
linkName.replace(QLatin1Char('/'), QLatin1Char('\\'));
|
||||
if (!linkName.endsWith(QLatin1String(".lnk")))
|
||||
@ -720,7 +732,11 @@ bool QFSFileEngine::link(const QString &newName)
|
||||
if (!ret)
|
||||
setError(QFile::RenameError, qt_error_string());
|
||||
return ret;
|
||||
#endif // Q_OS_WINCE
|
||||
#else // Q_OS_WINCE
|
||||
Q_UNUSED(newName);
|
||||
Q_UNIMPLEMENTED();
|
||||
return false;
|
||||
#endif // Q_OS_WINRT
|
||||
}
|
||||
|
||||
/*!
|
||||
@ -937,6 +953,7 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
|
||||
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
|
||||
QFile::MemoryMapFlags flags)
|
||||
{
|
||||
#ifndef Q_OS_WINPHONE
|
||||
Q_Q(QFSFileEngine);
|
||||
Q_UNUSED(flags);
|
||||
if (openMode == QFile::NotOpen) {
|
||||
@ -980,7 +997,11 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
|
||||
|
||||
// first create the file mapping handle
|
||||
DWORD protection = (openMode & QIODevice::WriteOnly) ? PAGE_READWRITE : PAGE_READONLY;
|
||||
#ifndef Q_OS_WINRT
|
||||
mapHandle = ::CreateFileMapping(handle, 0, protection, 0, 0, 0);
|
||||
#else
|
||||
mapHandle = ::CreateFileMappingFromApp(handle, 0, protection, 0, 0);
|
||||
#endif
|
||||
if (mapHandle == NULL) {
|
||||
q->setError(QFile::PermissionsError, qt_error_string());
|
||||
#ifdef Q_USE_DEPRECATED_MAP_API
|
||||
@ -998,15 +1019,23 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
|
||||
DWORD offsetHi = offset >> 32;
|
||||
DWORD offsetLo = offset & Q_UINT64_C(0xffffffff);
|
||||
SYSTEM_INFO sysinfo;
|
||||
#ifndef Q_OS_WINRT
|
||||
::GetSystemInfo(&sysinfo);
|
||||
#else
|
||||
::GetNativeSystemInfo(&sysinfo);
|
||||
#endif
|
||||
DWORD mask = sysinfo.dwAllocationGranularity - 1;
|
||||
DWORD extra = offset & mask;
|
||||
if (extra)
|
||||
offsetLo &= ~mask;
|
||||
|
||||
// attempt to create the map
|
||||
#ifndef Q_OS_WINRT
|
||||
LPVOID mapAddress = ::MapViewOfFile(mapHandle, access,
|
||||
offsetHi, offsetLo, size + extra);
|
||||
#else
|
||||
LPVOID mapAddress = ::MapViewOfFileFromApp(mapHandle, access, offset, size);
|
||||
#endif
|
||||
if (mapAddress) {
|
||||
uchar *address = extra + static_cast<uchar*>(mapAddress);
|
||||
maps[address] = extra;
|
||||
@ -1025,11 +1054,18 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size,
|
||||
|
||||
::CloseHandle(mapHandle);
|
||||
mapHandle = NULL;
|
||||
#else // !Q_OS_WINPHONE
|
||||
Q_UNUSED(offset);
|
||||
Q_UNUSED(size);
|
||||
Q_UNUSED(flags);
|
||||
Q_UNIMPLEMENTED();
|
||||
#endif // Q_OS_WINPHONE
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool QFSFileEnginePrivate::unmap(uchar *ptr)
|
||||
{
|
||||
#ifndef Q_OS_WINPHONE
|
||||
Q_Q(QFSFileEngine);
|
||||
if (!maps.contains(ptr)) {
|
||||
q->setError(QFile::PermissionsError, qt_error_string(ERROR_ACCESS_DENIED));
|
||||
@ -1048,6 +1084,11 @@ bool QFSFileEnginePrivate::unmap(uchar *ptr)
|
||||
}
|
||||
|
||||
return true;
|
||||
#else // !Q_OS_WINPHONE
|
||||
Q_UNUSED(ptr);
|
||||
Q_UNIMPLEMENTED();
|
||||
return false;
|
||||
#endif // Q_OS_WINPHONE
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -52,7 +52,6 @@ QT_BEGIN_NAMESPACE
|
||||
|
||||
QLockFile::LockError QLockFilePrivate::tryLock_sys()
|
||||
{
|
||||
SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
|
||||
const QFileSystemEntry fileEntry(fileName);
|
||||
// When writing, allow others to read.
|
||||
// When reading, QFile will allow others to read and write, all good.
|
||||
@ -60,6 +59,8 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
|
||||
// but Windows doesn't allow recreating it while this handle is open anyway,
|
||||
// so this would only create confusion (can't lock, but no lock file to read from).
|
||||
const DWORD dwShareMode = FILE_SHARE_READ;
|
||||
#ifndef Q_OS_WINRT
|
||||
SECURITY_ATTRIBUTES securityAtts = { sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
|
||||
HANDLE fh = CreateFile((const wchar_t*)fileEntry.nativeFilePath().utf16(),
|
||||
GENERIC_WRITE,
|
||||
dwShareMode,
|
||||
@ -67,6 +68,13 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
|
||||
CREATE_NEW, // error if already exists
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
#else // !Q_OS_WINRT
|
||||
HANDLE fh = CreateFile2((const wchar_t*)fileEntry.nativeFilePath().utf16(),
|
||||
GENERIC_WRITE,
|
||||
dwShareMode,
|
||||
CREATE_NEW, // error if already exists
|
||||
NULL);
|
||||
#endif // Q_OS_WINRT
|
||||
if (fh == INVALID_HANDLE_VALUE) {
|
||||
const DWORD lastError = GetLastError();
|
||||
switch (lastError) {
|
||||
@ -112,6 +120,9 @@ bool QLockFilePrivate::isApparentlyStale() const
|
||||
if (!getLockInfo(&pid, &hostname, &appname))
|
||||
return false;
|
||||
|
||||
// On WinRT there seems to be no way of obtaining information about other
|
||||
// processes due to sandboxing
|
||||
#ifndef Q_OS_WINRT
|
||||
HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
|
||||
if (!procHandle)
|
||||
return true;
|
||||
@ -120,6 +131,7 @@ bool QLockFilePrivate::isApparentlyStale() const
|
||||
::CloseHandle(procHandle);
|
||||
if (dwR == WAIT_TIMEOUT)
|
||||
return true;
|
||||
#endif // !Q_OS_WINRT
|
||||
const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime());
|
||||
return staleLockTime > 0 && age > staleLockTime;
|
||||
}
|
||||
|
@ -151,18 +151,27 @@ static bool createFileFromTemplate(NativeFileHandle &file,
|
||||
for (;;) {
|
||||
// Atomically create file and obtain handle
|
||||
#if defined(Q_OS_WIN)
|
||||
# ifndef Q_OS_WINRT
|
||||
file = CreateFile((const wchar_t *)path.constData(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
# else // !Q_OS_WINRT
|
||||
file = CreateFile2((const wchar_t *)path.constData(),
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, CREATE_NEW,
|
||||
NULL);
|
||||
# endif // Q_OS_WINRT
|
||||
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
return true;
|
||||
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_ACCESS_DENIED) {
|
||||
DWORD attributes = GetFileAttributes((const wchar_t *)path.constData());
|
||||
if (attributes == INVALID_FILE_ATTRIBUTES) {
|
||||
WIN32_FILE_ATTRIBUTE_DATA attributes;
|
||||
if (!GetFileAttributesEx((const wchar_t *)path.constData(),
|
||||
GetFileExInfoStandard, &attributes)
|
||||
|| attributes.dwFileAttributes == INVALID_FILE_ATTRIBUTES) {
|
||||
// Potential write error (read-only parent directory, etc.).
|
||||
error = QSystemError(err, QSystemError::NativeError);
|
||||
return false;
|
||||
@ -336,7 +345,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode)
|
||||
|
||||
d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath());
|
||||
|
||||
#if !defined(Q_OS_WIN)
|
||||
#if !defined(Q_OS_WIN) || defined(Q_OS_WINRT)
|
||||
d->closeFileHandle = true;
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user