Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Problem with QFile writing directly to disk

    General and Desktop
    2
    5
    2885
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Lorem121
      Lorem121 last edited by Lorem121

      Hi,
      As per title said, when using QFile for directly opening a windows volume, I have successfully doing all read operations but always failed when it comes to write

      Here's snippet of the code that I'm working on

      QFile file("\\.\D:");
      if (file.open(QIODevice::ReadOnly)) {
          char buffer[0x100];
      
          if (!file.seek(someDiskOffsetValue)) {
              qDebug("Seek error: (%d) %s", file.error(),
      			file.errorString().errorString().toStdString().c_str());
          }
      	
          if (file.read(buffer, 0x100)) {
              .... // print all read data
           }
      
          file.close();
      }
      

      This code is working perfectly. However if I modify it slightly to do basic write operation

      QFile file("\\.\D:");
      if (file.open(QIODevice::ReadWrite)) {
          char buffer[0x100];
      
          if (!file.seek(someDiskOffsetValue)) {
              qDebug("Seek error: (%d) %s", file.error(),
      			file.errorString().errorString().toStdString().c_str());
          }
      	
      	// Seek error: (11) The parameter is incorrect.
      	// Note. 11 = QFileDevice::PositionError	11	The position in the file could not be changed.
      	
      	if (file.write(buffer, 0x20) > -1) {
      		qDebug("Write success");
      	}
      	else {
      		qDebug("Write error: (%d) %s", file.error(),
      			file.errorString().toStdString().c_str());
      	}
      	
      	// Write error: (11) The parameter is incorrect.
      
          file.close();
      }
      

      It always fails every time with above error message

      Anybody can point me out which part that I've done wrong?
      I'm testing it with Win7 64-bit and run the application as administrator

      Thanks

      EDIT

      Okay, apparently this is not Qt issue. Just lack of my understanding of how to deal with disk directly
      You cannot just pass random number of data to be written to the disk, it needs to follow some rules, and one of them is to write it according to its sector size

      In my case, changing the value to 512 bytes returns true

      	if (file.write(buffer, 0x100) > -1) {
      		qDebug("Write success");
      	}
      

      It still not written to the disk though, not sure what else goes wrong. But at least QFile.write returns success

      1 Reply Last reply Reply Quote 0
      • ?
        A Former User last edited by

        Hi @Lorem121,
        is the windows volume mounted? I'm not a Windows expert but I guess you have to unmount it if you want to have raw write excess.

        1 Reply Last reply Reply Quote 0
        • Lorem121
          Lorem121 last edited by

          yes, it is mounted. that's why I can access it using drive letter (\.\D:)

          but you may be right though.
          from MSDN

          A write on a volume handle will succeed if the volume does not have a mounted file system, or if one of the following conditions is true:
          
          	The sectors to be written to are boot sectors.
          	The sectors to be written to reside outside of file system space.
          	You have explicitly locked or dismounted the volume by using FSCTL_LOCK_VOLUME or FSCTL_DISMOUNT_VOLUME.
          	The volume has no actual file system. (In other words, it has a RAW file system mounted.)
          

          but to unmount using FSCTL_DISMOUNT_VOLUME, I need a variable with HANDLE type (as returned by Win32 CreateFile API)
          is there a way that I can get that from QFile?

          thanks a lot for your response

          1 Reply Last reply Reply Quote 0
          • ?
            A Former User last edited by A Former User

            Use int QFileDevice::​handle() const (QFile inherits QFileDevice). HANDLE is defined as follows: typedef void *HANDLE

            1 Reply Last reply Reply Quote 0
            • Lorem121
              Lorem121 last edited by Lorem121

              I thought QFile::handle() return int which can be used to convert to FILE *

              QFile file;
              int fd = file.handle();
              FILE *f = fdopen(fd, "rb");
              

              I don't think I can just cast it to HANDLE and expect it to works, because fd always returns small numbers (not in range for pointers)

              QFile file;
              int fd = file.handle();
              HANDLE h = (HANDLE) fd; // ???
              

              UPDATE

              apparently there is an API for converting file handle to Win32 HANDLE

              intptr_t _get_osfhandle(
              int fd
              );

              1 Reply Last reply Reply Quote 0
              • First post
                Last post