1

I'm using it like this:

if(QDir("G:/").isReadable()){
    qDebug("G Is readable!"); //Do something with G:/
}

As I said, in Qt Creator it runs fine without a problem, it checks if the drive is readable, and if so it prints it to the console, if not, it does nothing.

But when I run the .exe file, it keeps giving me errors each time it does the check (every 2 seconds) if the drive isn't readable.

"There is no disk in the drive. Please insert a disk into drive G:."

I don't want this error to keep appearing, what do I do?

Edit: I think it's the isReadable function that causes the problem, is there any other way to do what I want to do? Or maybe should I write the code myself?

Metsuryu
  • 35
  • 1
  • 8
  • Is G: a mapped network drive? Those are per-session. – nobody Oct 08 '15 at 02:48
  • @AndrewMedico I'm not sure what a mapped network drive is, but I guess not. There is no G:/ normally, but it should and does appear when I plug in my android phone. Basically I'm checking if the phone is plugged in and the data from it is readable. – Metsuryu Oct 08 '15 at 09:19

1 Answers1

3

This message is generated by Windows.

There is a workaround for users that have applications that cannot be fixed. The error messages may be suppressed by setting 2 to registry key ErrorMode in:

Computer\HKEY_LOCAL\MACHINE\SYSTEM\CurrentControlSet\Control\Windows

It looks that if QDir::isReadable() is called after removing the media it triggers that error. QDir::exists() always returns true if the drive letter is present in the system, so it cannot be used here.

For now I see that it is possible to check removable media using native Windows API, see the answer to How to detect if media is inserted into a removable drive/card reader

The following code is able to detect that the media is removed without triggering the error:

#include <windows.h>

HANDLE hDevice = CreateFile (L"\\\\.\\G:",         // like "\\.\G:"
                             FILE_READ_ATTRIBUTES, // read access to the attributes
                             FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
                             NULL, OPEN_EXISTING, 0, NULL);

if (hDevice == INVALID_HANDLE_VALUE) {
    // not valid device
    return;
}

WORD cbBytesReturned;
bool bSuccess = DeviceIoControl (hDevice,                // device to be queried
                            IOCTL_STORAGE_CHECK_VERIFY2,
                            NULL, 0,                     // no input buffer
                            NULL, 0,                     // no output buffer
                            (LPDWORD)&cbBytesReturned,   // # bytes returned
                            NULL);                       // synchronous I/O

CloseHandle(hDevice); // close handle

if (bSuccess && QDir("G:/").isReadable()) {
    // G is readable
}
Community
  • 1
  • 1
Orest Hera
  • 6,706
  • 2
  • 21
  • 35
  • Thank you, I will try that. Just a minor correction, QDir::isReadable() triggers the error even if the device was never inserted in the first place. I was thinking about calling QDir::exists() and if true call QDir::isReadable(), so it would check if the drive is readable only if it exists, i'll test and see what happens. – Metsuryu Oct 08 '15 at 19:13
  • I tried, your solution works only until I insert a drive, then when I remove it the same error as before comes back. I guess that's just windows complaining about me disconnecting the drive while it is reading data? Is there a way to disable that? – Metsuryu Oct 08 '15 at 20:57
  • @Metsuryu If the application reads the drive after `DeviceIoControl()` validation it is a problem. It is possible to change app error mode by `UINT oldMode = SetErrorMode( SEM_FAILCRITICALERRORS );` Later if needed it is possible to restore error mode after that critical section `SetErrorMode(oldMode);` – Orest Hera Oct 08 '15 at 21:16
  • It appears to be working, I'm going to test it some more and let you know, thanks so much. – Metsuryu Oct 08 '15 at 21:46