summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qfilesystemengine_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qfilesystemengine_win.cpp')
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp317
1 files changed, 170 insertions, 147 deletions
diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp
index 0542d9e16c..79a9936785 100644
--- a/src/corelib/io/qfilesystemengine_win.cpp
+++ b/src/corelib/io/qfilesystemengine_win.cpp
@@ -48,7 +48,6 @@
#include "qfile.h"
#include "qdir.h"
-#include "private/qmutexpool_p.h"
#include "qvarlengtharray.h"
#include "qdatetime.h"
#include "qt_windows.h"
@@ -60,6 +59,7 @@
#include <objbase.h>
#ifndef Q_OS_WINRT
# include <shlobj.h>
+# include <lm.h>
# include <accctrl.h>
#endif
#include <initguid.h>
@@ -147,48 +147,30 @@ typedef struct _REPARSE_DATA_BUFFER {
# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
#endif
-QT_BEGIN_NAMESPACE
-
-Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0;
-
-#if defined(Q_OS_WINRT)
-// As none of the functions we try to resolve do exist on WinRT we
-// avoid library loading on WinRT in general to shorten everything
-// up a little bit.
+#if defined(Q_OS_WINRT) || defined(QT_BOOTSTRAPPED)
# define QT_FEATURE_fslibs -1
#else
-# define QT_FEATURE_fslibs QT_FEATURE_library
+# define QT_FEATURE_fslibs 1
#endif // Q_OS_WINRT
#if QT_CONFIG(fslibs)
-QT_BEGIN_INCLUDE_NAMESPACE
-typedef DWORD (WINAPI *PtrGetNamedSecurityInfoW)(LPWSTR, SE_OBJECT_TYPE, SECURITY_INFORMATION, PSID*, PSID*, PACL*, PACL*, PSECURITY_DESCRIPTOR*);
-static PtrGetNamedSecurityInfoW ptrGetNamedSecurityInfoW = 0;
-typedef BOOL (WINAPI *PtrLookupAccountSidW)(LPCWSTR, PSID, LPWSTR, LPDWORD, LPWSTR, LPDWORD, PSID_NAME_USE);
-static PtrLookupAccountSidW ptrLookupAccountSidW = 0;
-typedef VOID (WINAPI *PtrBuildTrusteeWithSidW)(PTRUSTEE_W, PSID);
-static PtrBuildTrusteeWithSidW ptrBuildTrusteeWithSidW = 0;
-typedef DWORD (WINAPI *PtrGetEffectiveRightsFromAclW)(PACL, PTRUSTEE_W, OUT PACCESS_MASK);
-static PtrGetEffectiveRightsFromAclW ptrGetEffectiveRightsFromAclW = 0;
-typedef BOOL (WINAPI *PtrGetUserProfileDirectoryW)(HANDLE, LPWSTR, LPDWORD);
-static PtrGetUserProfileDirectoryW ptrGetUserProfileDirectoryW = 0;
-QT_END_INCLUDE_NAMESPACE
-
+#include <aclapi.h>
+#include <userenv.h>
static TRUSTEE_W currentUserTrusteeW;
static TRUSTEE_W worldTrusteeW;
static PSID currentUserSID = 0;
static PSID worldSID = 0;
-/*
- Deletes the allocated SIDs during global static cleanup
-*/
-class SidCleanup
+QT_BEGIN_NAMESPACE
+
+namespace {
+struct GlobalSid
{
-public:
- ~SidCleanup();
+ GlobalSid();
+ ~GlobalSid();
};
-SidCleanup::~SidCleanup()
+GlobalSid::~GlobalSid()
{
free(currentUserSID);
currentUserSID = 0;
@@ -200,39 +182,13 @@ SidCleanup::~SidCleanup()
}
}
-Q_GLOBAL_STATIC(SidCleanup, initSidCleanup)
-
-static void resolveLibs()
+GlobalSid::GlobalSid()
{
- static bool triedResolve = false;
- if (!triedResolve) {
- // need to resolve the security info functions
-
- // protect initialization
-#ifndef QT_NO_THREAD
- QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve));
- // check triedResolve again, since another thread may have already
- // done the initialization
- if (triedResolve) {
- // another thread did initialize the security function pointers,
- // so we shouldn't do it again.
- return;
- }
-#endif
-
- triedResolve = true;
- HINSTANCE advapiHnd = QSystemLibrary::load(L"advapi32");
- if (advapiHnd) {
- ptrGetNamedSecurityInfoW = (PtrGetNamedSecurityInfoW)GetProcAddress(advapiHnd, "GetNamedSecurityInfoW");
- ptrLookupAccountSidW = (PtrLookupAccountSidW)GetProcAddress(advapiHnd, "LookupAccountSidW");
- ptrBuildTrusteeWithSidW = (PtrBuildTrusteeWithSidW)GetProcAddress(advapiHnd, "BuildTrusteeWithSidW");
- ptrGetEffectiveRightsFromAclW = (PtrGetEffectiveRightsFromAclW)GetProcAddress(advapiHnd, "GetEffectiveRightsFromAclW");
- }
- if (ptrBuildTrusteeWithSidW) {
+ {
+ {
// Create TRUSTEE for current user
HANDLE hnd = ::GetCurrentProcess();
HANDLE token = 0;
- initSidCleanup();
if (::OpenProcessToken(hnd, TOKEN_QUERY, &token)) {
DWORD retsize = 0;
// GetTokenInformation requires a buffer big enough for the TOKEN_USER struct and
@@ -247,61 +203,69 @@ static void resolveLibs()
DWORD sidLen = ::GetLengthSid(tokenSid);
currentUserSID = reinterpret_cast<PSID>(malloc(sidLen));
if (::CopySid(sidLen, currentUserSID, tokenSid))
- ptrBuildTrusteeWithSidW(&currentUserTrusteeW, currentUserSID);
+ BuildTrusteeWithSid(&currentUserTrusteeW, currentUserSID);
}
free(tokenBuffer);
}
::CloseHandle(token);
}
- typedef BOOL (WINAPI *PtrAllocateAndInitializeSid)(PSID_IDENTIFIER_AUTHORITY, BYTE, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, PSID*);
- PtrAllocateAndInitializeSid ptrAllocateAndInitializeSid = (PtrAllocateAndInitializeSid)GetProcAddress(advapiHnd, "AllocateAndInitializeSid");
- if (ptrAllocateAndInitializeSid) {
+ {
// Create TRUSTEE for Everyone (World)
SID_IDENTIFIER_AUTHORITY worldAuth = { SECURITY_WORLD_SID_AUTHORITY };
- if (ptrAllocateAndInitializeSid(&worldAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &worldSID))
- ptrBuildTrusteeWithSidW(&worldTrusteeW, worldSID);
+ if (AllocateAndInitializeSid(&worldAuth, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &worldSID))
+ BuildTrusteeWithSid(&worldTrusteeW, worldSID);
}
}
- HINSTANCE userenvHnd = QSystemLibrary::load(L"userenv");
- if (userenvHnd)
- ptrGetUserProfileDirectoryW = (PtrGetUserProfileDirectoryW)GetProcAddress(userenvHnd, "GetUserProfileDirectoryW");
}
}
+
+Q_GLOBAL_STATIC(GlobalSid, initGlobalSid)
+
+QT_END_NAMESPACE
+
+} // anonymous namespace
#endif // QT_CONFIG(fslibs)
-typedef DWORD (WINAPI *PtrNetShareEnum)(LPWSTR, DWORD, LPBYTE*, DWORD, LPDWORD, LPDWORD, LPDWORD);
-static PtrNetShareEnum ptrNetShareEnum = 0;
-typedef DWORD (WINAPI *PtrNetApiBufferFree)(LPVOID);
-static PtrNetApiBufferFree ptrNetApiBufferFree = 0;
-typedef struct _SHARE_INFO_1 {
- LPWSTR shi1_netname;
- DWORD shi1_type;
- LPWSTR shi1_remark;
-} SHARE_INFO_1;
+QT_BEGIN_NAMESPACE
+Q_CORE_EXPORT int qt_ntfs_permission_lookup = 0;
-static bool resolveUNCLibs()
+static inline bool toFileTime(const QDateTime &date, FILETIME *fileTime)
{
- static bool triedResolve = false;
- if (!triedResolve) {
-#ifndef QT_NO_THREAD
- QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve));
- if (triedResolve) {
- return ptrNetShareEnum && ptrNetApiBufferFree;
- }
-#endif
- triedResolve = true;
-#if !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 // !Q_OS_WINRT
+ SYSTEMTIME sTime;
+ if (date.timeSpec() == Qt::LocalTime) {
+ SYSTEMTIME lTime;
+ const QDate d = date.date();
+ const QTime t = date.time();
+
+ lTime.wYear = d.year();
+ lTime.wMonth = d.month();
+ lTime.wDay = d.day();
+ lTime.wHour = t.hour();
+ lTime.wMinute = t.minute();
+ lTime.wSecond = t.second();
+ lTime.wMilliseconds = t.msec();
+ lTime.wDayOfWeek = d.dayOfWeek() % 7;
+
+ if (!::TzSpecificLocalTimeToSystemTime(0, &lTime, &sTime))
+ return false;
+ } else {
+ QDateTime utcDate = date.toUTC();
+ const QDate d = utcDate.date();
+ const QTime t = utcDate.time();
+
+ sTime.wYear = d.year();
+ sTime.wMonth = d.month();
+ sTime.wDay = d.day();
+ sTime.wHour = t.hour();
+ sTime.wMinute = t.minute();
+ sTime.wSecond = t.second();
+ sTime.wMilliseconds = t.msec();
+ sTime.wDayOfWeek = d.dayOfWeek() % 7;
}
- return ptrNetShareEnum && ptrNetApiBufferFree;
+
+ return ::SystemTimeToFileTime(&sTime, fileTime);
}
static QString readSymLink(const QFileSystemEntry &link)
@@ -339,7 +303,7 @@ static QString readSymLink(const QFileSystemEntry &link)
CloseHandle(handle);
#if QT_CONFIG(fslibs)
- resolveLibs();
+ initGlobalSid();
QRegExp matchVolName(QLatin1String("^Volume\\{([a-z]|[0-9]|-)+\\}\\\\"), Qt::CaseInsensitive);
if (matchVolName.indexIn(result) == 0) {
DWORD len;
@@ -436,32 +400,35 @@ static inline bool getFindData(QString path, WIN32_FIND_DATA &findData)
bool QFileSystemEngine::uncListSharesOnServer(const QString &server, QStringList *list)
{
- if (resolveUNCLibs()) {
- SHARE_INFO_1 *BufPtr, *p;
- DWORD res;
- DWORD er = 0, tr = 0, resume = 0, i;
- do {
- res = ptrNetShareEnum((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume);
- if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) {
- p = BufPtr;
- for (i = 1; i <= er; ++i) {
- if (list && p->shi1_type == 0)
- list->append(QString::fromWCharArray(p->shi1_netname));
- p++;
- }
+ DWORD res = ERROR_NOT_SUPPORTED;
+#ifndef Q_OS_WINRT
+ SHARE_INFO_1 *BufPtr, *p;
+ DWORD er = 0, tr = 0, resume = 0, i;
+ do {
+ res = NetShareEnum((wchar_t*)server.utf16(), 1, (LPBYTE *)&BufPtr, DWORD(-1), &er, &tr, &resume);
+ if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA) {
+ p = BufPtr;
+ for (i = 1; i <= er; ++i) {
+ if (list && p->shi1_type == 0)
+ list->append(QString::fromWCharArray(p->shi1_netname));
+ p++;
}
- ptrNetApiBufferFree(BufPtr);
- } while (res == ERROR_MORE_DATA);
- return res == ERROR_SUCCESS;
- }
- return false;
+ }
+ NetApiBufferFree(BufPtr);
+ } while (res == ERROR_MORE_DATA);
+#else
+ Q_UNUSED(server);
+ Q_UNUSED(list);
+#endif
+ return res == ERROR_SUCCESS;
}
void QFileSystemEngine::clearWinStatData(QFileSystemMetaData &data)
{
data.size_ = 0;
data.fileAttribute_ = 0;
- data.creationTime_ = FILETIME();
+ data.birthTime_ = FILETIME();
+ data.changeTime_ = FILETIME();
data.lastAccessTime_ = FILETIME();
data.lastWriteTime_ = FILETIME();
}
@@ -642,36 +609,72 @@ QByteArray QFileSystemEngine::id(HANDLE fHandle)
}
//static
+bool QFileSystemEngine::setFileTime(HANDLE fHandle, const QDateTime &newDate,
+ QAbstractFileEngine::FileTime time, QSystemError &error)
+{
+ FILETIME fTime;
+ FILETIME *pLastWrite = NULL;
+ FILETIME *pLastAccess = NULL;
+ FILETIME *pCreationTime = NULL;
+
+ switch (time) {
+ case QAbstractFileEngine::ModificationTime:
+ pLastWrite = &fTime;
+ break;
+
+ case QAbstractFileEngine::AccessTime:
+ pLastAccess = &fTime;
+ break;
+
+ case QAbstractFileEngine::BirthTime:
+ pCreationTime = &fTime;
+ break;
+
+ default:
+ error = QSystemError(ERROR_INVALID_PARAMETER, QSystemError::NativeError);
+ return false;
+ }
+
+ if (!toFileTime(newDate, &fTime))
+ return false;
+
+ if (!::SetFileTime(fHandle, pCreationTime, pLastAccess, pLastWrite)) {
+ error = QSystemError(::GetLastError(), QSystemError::NativeError);
+ return false;
+ }
+ return true;
+}
+
QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEngine::FileOwner own)
{
QString name;
#if QT_CONFIG(fslibs)
extern int qt_ntfs_permission_lookup;
- if((qt_ntfs_permission_lookup > 0) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) {
- resolveLibs();
- if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) {
+ if (qt_ntfs_permission_lookup > 0) {
+ initGlobalSid();
+ {
PSID pOwner = 0;
PSECURITY_DESCRIPTOR pSD;
- if (ptrGetNamedSecurityInfoW((wchar_t*)entry.nativeFilePath().utf16(), SE_FILE_OBJECT,
- own == QAbstractFileEngine::OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION,
- own == QAbstractFileEngine::OwnerUser ? &pOwner : 0, own == QAbstractFileEngine::OwnerGroup ? &pOwner : 0,
- 0, 0, &pSD) == ERROR_SUCCESS) {
+ if (GetNamedSecurityInfo(reinterpret_cast<const wchar_t*>(entry.nativeFilePath().utf16()), SE_FILE_OBJECT,
+ own == QAbstractFileEngine::OwnerGroup ? GROUP_SECURITY_INFORMATION : OWNER_SECURITY_INFORMATION,
+ own == QAbstractFileEngine::OwnerUser ? &pOwner : 0, own == QAbstractFileEngine::OwnerGroup ? &pOwner : 0,
+ 0, 0, &pSD) == ERROR_SUCCESS) {
DWORD lowner = 64;
DWORD ldomain = 64;
QVarLengthArray<wchar_t, 64> owner(lowner);
QVarLengthArray<wchar_t, 64> domain(ldomain);
SID_NAME_USE use = SidTypeUnknown;
// First call, to determine size of the strings (with '\0').
- if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner,
- (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) {
+ if (!LookupAccountSid(NULL, pOwner, (LPWSTR)owner.data(), &lowner,
+ domain.data(), &ldomain, &use)) {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
if (lowner > (DWORD)owner.size())
owner.resize(lowner);
if (ldomain > (DWORD)domain.size())
domain.resize(ldomain);
// Second call, try on resized buf-s
- if (!ptrLookupAccountSidW(NULL, pOwner, (LPWSTR)owner.data(), &lowner,
- (LPWSTR)domain.data(), &ldomain, (SID_NAME_USE*)&use)) {
+ if (!LookupAccountSid(NULL, pOwner, owner.data(), &lowner,
+ domain.data(), &ldomain, &use)) {
lowner = 0;
}
} else {
@@ -696,9 +699,9 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst
QFileSystemMetaData::MetaDataFlags what)
{
#if QT_CONFIG(fslibs)
- if((qt_ntfs_permission_lookup > 0) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) {
- resolveLibs();
- if(ptrGetNamedSecurityInfoW && ptrBuildTrusteeWithSidW && ptrGetEffectiveRightsFromAclW) {
+ if (qt_ntfs_permission_lookup > 0) {
+ initGlobalSid();
+ {
enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 };
QString fname = entry.nativeFilePath();
@@ -706,15 +709,15 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst
PSID pGroup = 0;
PACL pDacl;
PSECURITY_DESCRIPTOR pSD;
- DWORD res = ptrGetNamedSecurityInfoW((wchar_t*)fname.utf16(), SE_FILE_OBJECT,
- OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
- &pOwner, &pGroup, &pDacl, 0, &pSD);
+ DWORD res = GetNamedSecurityInfo(reinterpret_cast<const wchar_t*>(fname.utf16()), SE_FILE_OBJECT,
+ OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ &pOwner, &pGroup, &pDacl, 0, &pSD);
if(res == ERROR_SUCCESS) {
ACCESS_MASK access_mask;
TRUSTEE_W trustee;
if (what & QFileSystemMetaData::UserPermissions) { // user
data.knownFlagsMask |= QFileSystemMetaData::UserPermissions;
- if(ptrGetEffectiveRightsFromAclW(pDacl, &currentUserTrusteeW, &access_mask) != ERROR_SUCCESS)
+ if (GetEffectiveRightsFromAcl(pDacl, &currentUserTrusteeW, &access_mask) != ERROR_SUCCESS)
access_mask = (ACCESS_MASK)-1;
if(access_mask & ReadMask)
data.entryFlags |= QFileSystemMetaData::UserReadPermission;
@@ -725,8 +728,8 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst
}
if (what & QFileSystemMetaData::OwnerPermissions) { // owner
data.knownFlagsMask |= QFileSystemMetaData::OwnerPermissions;
- ptrBuildTrusteeWithSidW(&trustee, pOwner);
- if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS)
+ BuildTrusteeWithSid(&trustee, pOwner);
+ if (GetEffectiveRightsFromAcl(pDacl, &trustee, &access_mask) != ERROR_SUCCESS)
access_mask = (ACCESS_MASK)-1;
if(access_mask & ReadMask)
data.entryFlags |= QFileSystemMetaData::OwnerReadPermission;
@@ -737,8 +740,8 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst
}
if (what & QFileSystemMetaData::GroupPermissions) { // group
data.knownFlagsMask |= QFileSystemMetaData::GroupPermissions;
- ptrBuildTrusteeWithSidW(&trustee, pGroup);
- if(ptrGetEffectiveRightsFromAclW(pDacl, &trustee, &access_mask) != ERROR_SUCCESS)
+ BuildTrusteeWithSid(&trustee, pGroup);
+ if (GetEffectiveRightsFromAcl(pDacl, &trustee, &access_mask) != ERROR_SUCCESS)
access_mask = (ACCESS_MASK)-1;
if(access_mask & ReadMask)
data.entryFlags |= QFileSystemMetaData::GroupReadPermission;
@@ -749,7 +752,7 @@ bool QFileSystemEngine::fillPermissions(const QFileSystemEntry &entry, QFileSyst
}
if (what & QFileSystemMetaData::OtherPermissions) { // other (world)
data.knownFlagsMask |= QFileSystemMetaData::OtherPermissions;
- if(ptrGetEffectiveRightsFromAclW(pDacl, &worldTrusteeW, &access_mask) != ERROR_SUCCESS)
+ if (GetEffectiveRightsFromAcl(pDacl, &worldTrusteeW, &access_mask) != ERROR_SUCCESS)
access_mask = (ACCESS_MASK)-1; // ###
if(access_mask & ReadMask)
data.entryFlags |= QFileSystemMetaData::OtherReadPermission;
@@ -902,8 +905,10 @@ bool QFileSystemEngine::fillMetaData(HANDLE fHandle, QFileSystemMetaData &data,
FILE_BASIC_INFO fileBasicInfo;
if (GetFileInformationByHandleEx(fHandle, FileBasicInfo, &fileBasicInfo, sizeof(fileBasicInfo))) {
data.fillFromFileAttribute(fileBasicInfo.FileAttributes);
- data.creationTime_.dwHighDateTime = fileBasicInfo.CreationTime.HighPart;
- data.creationTime_.dwLowDateTime = fileBasicInfo.CreationTime.LowPart;
+ data.birthTime_.dwHighDateTime = fileBasicInfo.CreationTime.HighPart;
+ data.birthTime_.dwLowDateTime = fileBasicInfo.CreationTime.LowPart;
+ data.changeTime_.dwHighDateTime = fileBasicInfo.ChangeTime.HighPart;
+ data.changeTime_.dwLowDateTime = fileBasicInfo.ChangeTime.LowPart;
data.lastAccessTime_.dwHighDateTime = fileBasicInfo.LastAccessTime.HighPart;
data.lastAccessTime_.dwLowDateTime = fileBasicInfo.LastAccessTime.LowPart;
data.lastWriteTime_.dwHighDateTime = fileBasicInfo.LastWriteTime.HighPart;
@@ -1160,19 +1165,19 @@ QString QFileSystemEngine::homePath()
{
QString ret;
#if QT_CONFIG(fslibs)
- resolveLibs();
- if (ptrGetUserProfileDirectoryW) {
+ initGlobalSid();
+ {
HANDLE hnd = ::GetCurrentProcess();
HANDLE token = 0;
BOOL ok = ::OpenProcessToken(hnd, TOKEN_QUERY, &token);
if (ok) {
DWORD dwBufferSize = 0;
// First call, to determine size of the strings (with '\0').
- ok = ptrGetUserProfileDirectoryW(token, NULL, &dwBufferSize);
+ ok = GetUserProfileDirectory(token, NULL, &dwBufferSize);
if (!ok && dwBufferSize != 0) { // We got the required buffer size
wchar_t *userDirectory = new wchar_t[dwBufferSize];
// Second call, now we can fill the allocated buffer.
- ok = ptrGetUserProfileDirectoryW(token, userDirectory, &dwBufferSize);
+ ok = GetUserProfileDirectory(token, userDirectory, &dwBufferSize);
if (ok)
ret = QString::fromWCharArray(userDirectory);
delete [] userDirectory;
@@ -1318,6 +1323,17 @@ bool QFileSystemEngine::renameFile(const QFileSystemEntry &source, const QFileSy
}
//static
+bool QFileSystemEngine::renameOverwriteFile(const QFileSystemEntry &source, const QFileSystemEntry &target, QSystemError &error)
+{
+ bool ret = ::MoveFileEx(reinterpret_cast<const wchar_t *>(source.nativeFilePath().utf16()),
+ reinterpret_cast<const wchar_t *>(target.nativeFilePath().utf16()),
+ MOVEFILE_REPLACE_EXISTING) != 0;
+ if (!ret)
+ error = QSystemError(::GetLastError(), QSystemError::NativeError);
+ return ret;
+}
+
+//static
bool QFileSystemEngine::removeFile(const QFileSystemEntry &entry, QSystemError &error)
{
bool ret = ::DeleteFile((wchar_t*)entry.nativeFilePath().utf16()) != 0;
@@ -1349,6 +1365,9 @@ bool QFileSystemEngine::setPermissions(const QFileSystemEntry &entry, QFile::Per
static inline QDateTime fileTimeToQDateTime(const FILETIME *time)
{
+ if (time->dwHighDateTime == 0 && time->dwLowDateTime == 0)
+ return QDateTime();
+
SYSTEMTIME sTime;
FileTimeToSystemTime(time, &sTime);
return QDateTime(QDate(sTime.wYear, sTime.wMonth, sTime.wDay),
@@ -1356,9 +1375,13 @@ static inline QDateTime fileTimeToQDateTime(const FILETIME *time)
Qt::UTC);
}
-QDateTime QFileSystemMetaData::creationTime() const
+QDateTime QFileSystemMetaData::birthTime() const
+{
+ return fileTimeToQDateTime(&birthTime_);
+}
+QDateTime QFileSystemMetaData::metadataChangeTime() const
{
- return fileTimeToQDateTime(&creationTime_);
+ return fileTimeToQDateTime(&changeTime_);
}
QDateTime QFileSystemMetaData::modificationTime() const
{