Я считаю предложение MSalters использовать IOCTL_STORAGE_CHECK_VERIFY
очень хорошим.В использовании IOCTL_STORAGE_CHECK_VERIFY
есть небольшая хитрость.Перед использованием кода IOCTL в функции DeviceIoControl
необходимо открыть соответствующее устройство в отношении функции CreateFile
:
HANDLE hDevice = CreateFile (szDeviceName, // like "\\.\E:"
0, // no access to the drive
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, OPEN_EXISTING, 0, NULL);
Для использования DeviceIoControl
можно использовать 0 в качестве секундыпараметр CreateFile
, потому что мы не будем использовать функции ReadFile
, WriteFile
и т. д. для доступа к устройству.Реализация IOCTL_STORAGE_CHECK_VERIFY
действительно следует за некоторым чтением запросов данных .Таким образом, чтобы иметь возможность использовать IOCTL_STORAGE_CHECK_VERIFY
без ошибки ERROR_ACCESS_DENIED
(5), мы должны открыть устройство следующим образом:
HANDLE hDevice = CreateFile (szDeviceName, // like "\\.\E:"
FILE_READ_DATA, // read access to the data
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, OPEN_EXISTING, 0, NULL);
Существует еще одна версия IOCTL_STORAGE_CHECK_VERIFY
- IOCTL_STORAGE_CHECK_VERIFY2
, которая работает абсолютнотак же, как IOCTL_STORAGE_CHECK_VERIFY
, но гораздо быстрее (см. http://msdn.microsoft.com/en-us/library/ff560538.aspx).. Чтобы использовать IOCTL_STORAGE_CHECK_VERIFY2
, можно открыть устройство только с FILE_READ_ATTRIBUTES
доступом:
HANDLE hDevice = CreateFile (szDeviceName, // like "\\.\E:"
FILE_READ_ATTRIBUTES, // read access to the attributes
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, OPEN_EXISTING, 0, NULL);
Код, который проверяет существованиеноситель в приводе может выглядеть следующим образом
DWORD cbBytesReturned;
bSuccess = DeviceIoControl (hDevice, // device to be queried
IOCTL_STORAGE_CHECK_VERIFY2,
NULL, 0, // no input buffer
NULL, 0, // no output buffer
&cbBytesReturned, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
if (bSuccess)
_tprintf (TEXT("the device media are accessible\n"));
else if (GetLastError() == ERROR_NOT_READY)
_tprintf (TEXT("the device media are not accessible\n"));