2014-07-08 5 views
6

Я пытаюсь вызвать функции DeviceIO асинхронно, используя структуру OVERLAPPED, как описано в MSDN. Я использую управляющий код FSCTL_ENUM_USN_DATA для перечисления MFT дисков NTFS, но я не могу запустить его асинхронно. Дескриптор файла создается с помощью FILE_FLAG_OVERLAPPED, но нет никакой разницы, использую ли я перекрываемую структуру с FILE_FLAG_OVERLAPPED или нет. Функция не возвращается сразу. Кажется, что синхронно в обоих случаях. В приведенном ниже примере показан перечисление первых 100.000 записей MFT на диске C: \. Поскольку я не очень хорошо знаком с использованием перекрывающихся структур, возможно, я сделал что-то неправильно. Мой вопрос: Как я могу выполнить DeviceIoControl (hDevice, FSCTL_ENUM_USN_DATA, ...) асинхронно? Спасибо за любую помощь.Как вызвать код DeviceIOControl асинхронно?

#include "stdafx.h" 
#include <Windows.h> 

typedef struct { 
    DWORDLONG nextusn; 
    USN_RECORD FirstUsnRecord; 
    BYTE Buffer[500]; 
}TDeviceIoControlOutputBuffer, *PTDeviceIoControlOutputBuffer; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    MFT_ENUM_DATA lInputMftData; 
    lInputMftData.StartFileReferenceNumber = 0; 
    lInputMftData.MinMajorVersion = 2; 
    lInputMftData.MaxMajorVersion = 3; 
    lInputMftData.LowUsn = 0; 
    lInputMftData.HighUsn = 0; 

    TDeviceIoControlOutputBuffer lOutputMftData; 
    DWORD lOutBytesReturned = 0; 
    HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
    OVERLAPPED lOverlapped = { 0 }; 
    lOverlapped.hEvent = hEvent; 
    LPCWSTR path = L"\\\\.\\C:"; 
    HANDLE hDevice = CreateFile(path, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 
    if (hDevice != INVALID_HANDLE_VALUE) { 
     lOutputMftData.nextusn = 0; 
     while (lOutputMftData.nextusn < 100000) { 
      lInputMftData.StartFileReferenceNumber = lOutputMftData.nextusn; 
      BOOL result = DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &lInputMftData, sizeof(lInputMftData), &lOutputMftData, sizeof(lOutputMftData), &lOutBytesReturned, &lOverlapped); 
     } 
    } 
} 
+0

Если драйвер не поддерживает асинхронный ввод/вывод в целом или по какой-то просьбой, он обрабатывает запрос ввода/вывода синхронно, игнорируя OVERLAPPED параметр. Однако я не знаю, поддерживает ли этот драйвер этот конкретный запрос в режиме асинхронного ввода-вывода. –

+0

Спасибо за ответ. В соответствии с Microsoft FSCTL_ENUM_USN_DATA можно вызвать async: http://msdn.microsoft.com/en-us/library/windows/desktop/aa364563%28v=vs.85%29.aspx – user3816574

+0

Ну, снова посмотрев на ваш код, я не видите, что вы заполняете элемент 'hEvent' переменной' lOverlapped'. Это может быть хорошей причиной для синхронного выполнения этого запроса. –

ответ

0
HEVENT hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 
OVERLAPPED lOverlapped = { 0 }; 
lOverlapped.hEvent = hEvent; 

... 

BOOL result = DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &lInputMftData, sizeof(lInputMftData), &lOutputMftData, sizeof(lOutputMftData), &lOutBytesReturned, &lOverlapped); 

// If operation is asynchronous, wait for hEvent here or somewhere else 
+0

Спасибо. Но все равно не работает. Нет асинхронизации. Наложенная структура и дескриптор устройства должны быть правильными: если я звоню, например. функция readfile с той же перекрывающейся структурой и одним и тем же дескриптором hdevice, она немедленно возвращается с GetalstError() = 997 (ERROR_IO_PENDING: выполняется операция Overlapped I/O), которая указывает, что «readfile» вызывается асинхронно. Но он не работает для устройства. – user3816574

Смежные вопросы