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 writeHere'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 administratorThanks
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 sizeIn 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 MSDNA 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
);