4

I had to change the program on Qt that I did not write. I located the place in the code and know what I want it to, but I do not know what to change, so seek help. Code is as follows:

QFile file(path);
qint64 size = filesize(path);
qint64 blockSize = 10240;
bool ok = file.open(QIODevice::ReadWrite);

if (ok)
{
    QTime t;
    t.start();
    file.seek(0);
    for (int i = 0; i < ceil(double(size) / double(blockSize)); i++)
    {
        qint64 block = size - i * blockSize;
        if (block > blockSize)
        {
            block = blockSize;
        }

        QByteArray data;
        data.resize(block);
        data.fill('0');
        file.write(data, block);
    }
    file.close();
    file.remove();
}

Here are replaced by the contents of the file with zeros for the inability to recover after its deletion. Googling I came to two conclusions, either there is no real writing in the file, or it writes new data to other disk sectors, and the old remain in place. How to make so that the contents of the file really replaced with zeros for the inability to recover it? Any help will be really appreciated!

Oliver
  • 9,239
  • 9
  • 69
  • 100
user3497819
  • 41
  • 1
  • 2
  • there is absolutely no guarantee that the old block isn't still there on the disk/in some backup. – ratchet freak Apr 04 '14 at 11:37
  • This is a frequently asked question- search for securely erasing files. [Example 1](http://stackoverflow.com/a/11835491/2167797) [Example 2](http://stackoverflow.com/q/7757495/2167797) It's a hard problem and better left up to a tool that already does it rather than trying to develop your own (Qt offers no functionality to do this, it will be very OS dependent). – Linville Apr 04 '14 at 11:40
  • 3
    if you don't want anybody to read the content of your file when you don't need the file, then, probably, you want the same when you still need the file. So the simplest way to prevent anybody from reading an existing and deleted file - to encrypt it. I understand that this is not what you ask, and it's hard to encrypt file safely, but this can help. Generally you just can't be sure that the file can't be recovered until you physically melt you disk. – JustAnotherCurious Apr 04 '14 at 11:57

3 Answers3

2

I would personally just use shred or a similar tool via QProcess. That is probably the best effect / effort ratio in this case.

I do not think you should invent this yourself as this is not a Qt specific thing, nor is it something common.

László Papp
  • 51,870
  • 39
  • 111
  • 135
  • `shred` does pretty much what the code above means to do... On Windows, a port of `shred` is insufficient. `SDelete` is the only reasonable solution (or an exact reimplementation). – Kuba hasn't forgotten Monica Apr 04 '14 at 20:02
  • No, as others pointed out it is platform dependent. You cannot just implement this in Qt. Moreover, shred does far more and different than the code above. Here is the [source code](http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/shred.c). Also, I do not recall mentioning a "port of shred". – László Papp Apr 04 '14 at 22:17
  • Apart from doing direct I/O, shred doesn't do anything that's interesting anymore. The multiple-overwrites cargo cult is rather old and boring these days. If you overwrite things on a modern hard drive once, the data is gone, and nobody can recover it. – Kuba hasn't forgotten Monica Apr 04 '14 at 23:51
  • I do not know what you mean. Let us imagine for a second what you are trying to say is true, still there are many "old" hard drives around, but I am not sure what you are saying is true. Perhaps, you skipped reading through the other linked thread in the OP's question. You seem to have a very simplistic view of this thing even though companies have specialized for this task for decades. – László Papp Apr 05 '14 at 04:31
  • An "old" hard drive for the purpose of this discussion is something that can store <1GB. There is no specialist company, and I'm 100% sure of that, that can recover data from an IDE/ATA/SCSI hard drive with >1GB capacity that was overwritten with zeroes *once*. It'd be super cool if it was possible, but it isn't. – Kuba hasn't forgotten Monica Apr 05 '14 at 15:05
  • Actually, there is. In fact, I was even interviewed for such a role in the past, but oh well, I do not mind if you write this ignore. I really have no any idea how this is related to 1 GB, either. – László Papp Apr 05 '14 at 15:10
  • The [Gutmann technique](http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html) is the only published method for recovering overwritten data. It applied to MFM/RLL drives, which are **long** obsolete. Gutmann himself acknowledges that it does not apply to modern PRML/EPRML drives (standard since the late 90s), and no one has demonstrated ability to recover overwritten data from those types. Further, overwriting is less useful with SSDs - the writes go to some other free block and the original data can remain intact until the controller gets around to cleaning it up. – nobody May 31 '14 at 22:13
1

The code is rather convoluted. It's not worth "fixing".

Below is a reasonably sane implementation that should work, as long as such an approach can work at all on your system. If you say that it "doesn't work" - how do you check that? On what platform? What Qt version?

Note that on Windows, this tool is useless with compressed, encrypted and sparse files. Internally, writing to such files first copies the clusters and then does modifications in copied clusters, leaving the original data behind. The SDelete tool copes with those appropriately.

bool shred(const QString & fileName) {
  QFile file(fileName); 
  QFileInfo fi(file);
  qint64 fileSize = fi.size();
  if (! file.open(QIODevice::ReadWrite | QIODevice::Unbuffered)) return false;

  QByteArray block(65536, '\0');
  while (fileSize > 0) {
    if (fileSize < block.size()) block.truncate(fileSize);
    qint64 written = file.write(block);
    if (written != block.size()) return false;
    fileSize -= written;
  }
  Q_ASSERT(fileSize == 0);
  fsync(file.handle());
  return file.remove();
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • 1
    Why open the file ReadWrite instead of WriteOnly? Also, I think you should close() before remove(), for Windows. – Frank Osterfeld Apr 04 '14 at 18:47
  • A `WriteOnly` open could conceiveably truncate the file, and we don't want that. The `ReadWrite` open shouldn't hurt, I don't think. The `close()` is done automatically by `remove()`, it's a behavior of `QFile` and not platform-dependent. – Kuba hasn't forgotten Monica Apr 04 '14 at 19:58
  • I use Qt Creator 2.6.0, based on Qt 4.8.3 (32-bit) at Windows 7. Tried to take your advice, but the compiler generates an error "error: 'fsync' was not declared in this scope", how to solve it? – user3497819 Apr 08 '14 at 11:33
1
QDir destination;
destination.remove("path to file");
Marko Stojkovic
  • 3,255
  • 4
  • 19
  • 20