Problem with QFile writing directly to disk



  • 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



  • 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.



  • 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



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



  • 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
    );


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.