summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRitt Konstantin <ritt.ks@gmail.com>2009-07-20 17:47:32 (GMT)
committerJoerg Bornemann <joerg.bornemann@trolltech.com>2009-07-20 17:48:10 (GMT)
commit6ca14dce65634e202b36499c76c268c87f78ceb6 (patch)
tree9eefeb9ebd0cd203e95b671f94eeaa4315fb3f69
parentee4a76e2a1afade93ec89e9a7875837b195706e9 (diff)
downloadQt-6ca14dce65634e202b36499c76c268c87f78ceb6.zip
Qt-6ca14dce65634e202b36499c76c268c87f78ceb6.tar.gz
Qt-6ca14dce65634e202b36499c76c268c87f78ceb6.tar.bz2
Workaround for transacted, locked and inaccesible files
wich can not be stat'ed in a natural way. FindFirstFile solves this problem. Task-number: 167099 Task-number: 189202 Merge-request: 880 Reviewed-by: Joerg Bornemann <joerg.bornemann@trolltech.com>
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp88
-rw-r--r--tests/auto/qfileinfo/tst_qfileinfo.cpp18
2 files changed, 104 insertions, 2 deletions
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index d4e2e93..53f0144 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -527,6 +527,29 @@ qint64 QFSFileEnginePrivate::nativeSize() const
WIN32_FILE_ATTRIBUTE_DATA attribData;
bool ok = ::GetFileAttributesEx((const wchar_t*)nativeFilePath.constData(),
GetFileExInfoStandard, &attribData);
+ if (!ok) {
+ int errorCode = GetLastError();
+ if (errorCode != ERROR_INVALID_NAME
+ && errorCode != ERROR_FILE_NOT_FOUND && errorCode != ERROR_PATH_NOT_FOUND) {
+ QByteArray path = nativeFilePath;
+ // path for the FindFirstFile should not end with a trailing slash
+ while (path.endsWith('\\'))
+ path.chop(1);
+
+ // FindFirstFile can not handle drives
+ if (!path.endsWith(':')) {
+ WIN32_FIND_DATA findData;
+ HANDLE hFind = ::FindFirstFile((const wchar_t*)path.constData(),
+ &findData);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ ::FindClose(hFind);
+ ok = true;
+ attribData.nFileSizeHigh = findData.nFileSizeHigh;
+ attribData.nFileSizeLow = findData.nFileSizeLow;
+ }
+ }
+ }
+ }
if (ok) {
qint64 size = attribData.nFileSizeHigh;
size <<= 32;
@@ -878,6 +901,26 @@ static inline bool isDirPath(const QString &dirPath, bool *existed)
path += QLatin1Char('\\');
DWORD fileAttrib = ::GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16());
+ if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
+ int errorCode = GetLastError();
+ if (errorCode != ERROR_INVALID_NAME
+ && errorCode != ERROR_FILE_NOT_FOUND && errorCode != ERROR_PATH_NOT_FOUND) {
+ // path for the FindFirstFile should not end with a trailing slash
+ while (path.endsWith(QLatin1Char('\\')))
+ path.chop(1);
+
+ // FindFirstFile can not handle drives
+ if (!path.endsWith(QLatin1Char(':'))) {
+ WIN32_FIND_DATA findData;
+ HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(),
+ &findData);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ ::FindClose(hFind);
+ fileAttrib = findData.dwFileAttributes;
+ }
+ }
+ }
+ }
if (existed)
*existed = fileAttrib != INVALID_FILE_ATTRIBUTES;
@@ -1149,6 +1192,27 @@ bool QFSFileEnginePrivate::doStat() const
#endif
} else {
fileAttrib = GetFileAttributes((wchar_t*)QFSFileEnginePrivate::longFileName(fname).utf16());
+ if (fileAttrib == INVALID_FILE_ATTRIBUTES) {
+ int errorCode = GetLastError();
+ if (errorCode != ERROR_INVALID_NAME
+ && errorCode != ERROR_FILE_NOT_FOUND && errorCode != ERROR_PATH_NOT_FOUND) {
+ QString path = QDir::toNativeSeparators(fname);
+ // path for the FindFirstFile should not end with a trailing slash
+ while (path.endsWith(QLatin1Char('\\')))
+ path.chop(1);
+
+ // FindFirstFile can not handle drives
+ if (!path.endsWith(QLatin1Char(':'))) {
+ WIN32_FIND_DATA findData;
+ HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(),
+ &findData);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ ::FindClose(hFind);
+ fileAttrib = findData.dwFileAttributes;
+ }
+ }
+ }
+ }
could_stat = fileAttrib != INVALID_FILE_ATTRIBUTES;
if (!could_stat) {
#if !defined(Q_OS_WINCE)
@@ -1744,6 +1808,30 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const
} else {
WIN32_FILE_ATTRIBUTE_DATA attribData;
bool ok = ::GetFileAttributesEx((wchar_t*)QFSFileEnginePrivate::longFileName(d->filePath).utf16(), GetFileExInfoStandard, &attribData);
+ if (!ok) {
+ int errorCode = GetLastError();
+ if (errorCode != ERROR_INVALID_NAME
+ && errorCode != ERROR_FILE_NOT_FOUND && errorCode != ERROR_PATH_NOT_FOUND) {
+ QString path = QDir::toNativeSeparators(d->filePath);
+ // path for the FindFirstFile should not end with a trailing slash
+ while (path.endsWith(QLatin1Char('\\')))
+ path.chop(1);
+
+ // FindFirstFile can not handle drives
+ if (!path.endsWith(QLatin1Char(':'))) {
+ WIN32_FIND_DATA findData;
+ HANDLE hFind = ::FindFirstFile((wchar_t*)QFSFileEnginePrivate::longFileName(path).utf16(),
+ &findData);
+ if (hFind != INVALID_HANDLE_VALUE) {
+ ::FindClose(hFind);
+ ok = true;
+ attribData.ftCreationTime = findData.ftCreationTime;
+ attribData.ftLastWriteTime = findData.ftLastWriteTime;
+ attribData.ftLastAccessTime = findData.ftLastAccessTime;
+ }
+ }
+ }
+ }
if (ok) {
if(time == CreationTime)
ret = fileTimeToQDateTime(&attribData.ftCreationTime);
diff --git a/tests/auto/qfileinfo/tst_qfileinfo.cpp b/tests/auto/qfileinfo/tst_qfileinfo.cpp
index 48dc357..e5831fd 100644
--- a/tests/auto/qfileinfo/tst_qfileinfo.cpp
+++ b/tests/auto/qfileinfo/tst_qfileinfo.cpp
@@ -127,6 +127,8 @@ private slots:
void size_data();
void size();
+ void systemFiles();
+
void compare_data();
void compare();
@@ -354,8 +356,9 @@ void tst_QFileInfo::exists_data()
QTest::newRow("data6") << "resources/*" << false;
QTest::newRow("data7") << "resources/*.foo" << false;
QTest::newRow("data8") << "resources/*.ext1" << false;
- QTest::newRow("data9") << "." << true;
- QTest::newRow("data10") << ". " << false;
+ QTest::newRow("data9") << "resources/file?.ext1" << false;
+ QTest::newRow("data10") << "." << true;
+ QTest::newRow("data11") << ". " << false;
QTest::newRow("simple dir") << "resources" << true;
QTest::newRow("simple dir with slash") << "resources/" << true;
@@ -741,6 +744,17 @@ void tst_QFileInfo::size()
QTEST(int(fi.size()), "size");
}
+void tst_QFileInfo::systemFiles()
+{
+#ifndef Q_OS_WIN
+ QSKIP("This is a Windows only test", SkipAll);
+#endif
+ QFileInfo fi("c:\\pagefile.sys");
+ QVERIFY(fi.exists()); // task 167099
+ QVERIFY(fi.size() > 0); // task 189202
+ QVERIFY(fi.lastModified().isValid());
+}
+
void tst_QFileInfo::compare_data()
{
QTest::addColumn<QString>("file1");