Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-30148

Windows: Inconsistency between QFile::isWritable() and QFileInfo::isWritable() functions.

    XMLWordPrintable

Details

    • ffc8409aa58c04c1dd140001976b55925ac959f6 (qtbase/5.9,21.12.2017, 5.9.4)

    Description

      There is some inconsistency between QFile::isWritable() and QFileInfo::isWritable() functions.

      Created manually a folder named 'FooFolder' under "C:\Program Files (x86)" folder. After that, created new text files named 'FooFile{1-3}.txt' under that 'FooFolder' folder.

      Testing against C:\Program Files (x86)\FooFolder\FooFile1.txt file. QFile::isWritable() returns false. QFileInfo::isWritable() returns true. QFile gives correct results since I cannot use Notepad to save new text into the FooFile1.txt manually.

      C:\Users\Leonard>dir /a "C:\Program Files (x86)\FooFolder"
       Volume in drive C has no label.
       Volume Serial Number is ****-****
      
       Directory of C:\Program Files (x86)\FooFolder
      
      11/03/2013  14:37    <DIR>          .
      11/03/2013  14:37    <DIR>          ..
      11/03/2013  12:02                 0 FooFile1.txt
      11/03/2013  12:02                 0 FooFile2.txt
      11/03/2013  12:02                 0 FooFile3.txt
                     3 File(s)              0 bytes
                     2 Dir(s)  ***,***,***,*** bytes free
      

      Code snippets listed below.

      qDebug() << "Using QFile class.";
      QFile fooFile(tempProgramFilesPath + QDir::separator() + "FooFile1.txt");
      qDebug() << "fooFile.fileName():" << fooFile.fileName();
      qDebug() << "fooFile.exists():" << fooFile.exists();
      qDebug() << "fooFile.isWritable():" << fooFile.isWritable();
      bool fileOpenResult;
      fileOpenResult = fooFile.open(QIODevice::ReadWrite);
      qDebug() << "Result of fooFile.open(QIODevice::ReadWrite):" << fileOpenResult;
      if(!fileOpenResult)
      {
          qDebug() << "Open file failed.";
      }
      
      qDebug() << "Using QFileInfo class.";
      QFileInfo fooFileInfo(tempProgramFilesPath + QDir::separator() + "FooFile1.txt");
      qDebug() << "fooFileInfo.fileName():" << fooFileInfo.fileName();
      qDebug() << "fooFileInfo.filePath():" << fooFileInfo.filePath();
      qDebug() << "fooFileInfo.exists():" << fooFileInfo.exists();
      qDebug() << "fooFileInfo.isWritable():" << fooFileInfo.isWritable();
      qDebug() << "fooFileInfo.permission(QFile::WriteUser):" << fooFileInfo.permission(QFile::WriteUser);
      

      Output of above code snippets.

      Using QFile class.
      fooFile.fileName(): "C:/Program Files (x86)/FooFolder/FooFile1.txt"
      fooFile.exists(): true
      fooFile.isWritable(): false
      Result of fooFile.open(QIODevice::ReadWrite): false
      Open file failed.
      
      Using QFileInfo class.
      fooFileInfo.fileName(): "FooFile1.txt"
      fooFileInfo.filePath(): "C:/Program Files (x86)/FooFolder/FooFile1.txt"
      fooFileInfo.exists(): true
      fooFileInfo.isWritable(): true
      fooFileInfo.permission(QFile::WriteUser): true
      
      Using native _taccess_s() function.
      File C:/Program Files (x86)/FooFolder/FooFile1.txt exists.
      File C:/Program Files (x86)/FooFolder/FooFile1.txt does have read permission.
      File C:/Program Files (x86)/FooFolder/FooFile1.txt does have write permission.
      File C:/Program Files (x86)/FooFolder/FooFile1.txt does have read/write permiss
      on.
      

      I have also checked native _access_s, _waccess_s Windows functions, which returns true in all cases. However, I did not dig deeper to check which native Windows API is QFileInfo::isWritable() is using.

      Additional test with AccessChk tool listed below.

      C:\Users\Leonard>"C:\Program Files\SysinternalsSuite\accesschk.exe" Leonard "C:\
      Program Files (x86)\FooFolder\FooFile1.txt"
      
      Accesschk v5.10 - Reports effective permissions for securable objects
      Copyright (C) 2006-2012 Mark Russinovich
      Sysinternals - www.sysinternals.com
      
      RW C:\Program Files (x86)\FooFolder\FooFile1.txt
      

      I understand that QFileInfo provides information about a file's name and position (path) in the file system, its access rights and whether it is a directory or symbolic link, etc. Thus, this class should be use primarily to query file permissions. I understand that QFileInfo use system API, which might gives wrong results itself on Windows. If QFileInfo is reflecting the system API correctly, then we should consider to update the documentation page explaining this discrepancy. Else, we could make both function returns same results. Please correct my understanding if I am wrong.

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-30148
          # Subject Branch Project Status CR V

          Activity

            People

              dzedsystems Dyami Caliri
              leonlee Leonard Lee
              Votes:
              2 Vote for this issue
              Watchers:
              15 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes