Драйвер устройства: время ожидания функции Windows ReadFile - PullRequest
2 голосов
/ 31 октября 2011

Я использую драйвер устройства, который иногда пропускает прерывание от оборудования.

Для чтения данных с устройства я использую функцию

  BOOL WINAPI ReadFile(
   __in         HANDLE hFile,
   __out        LPVOID lpBuffer,
   __in         DWORD nNumberOfBytesToRead,
   __out_opt    LPDWORD lpNumberOfBytesRead,
   __inout_opt  LPOVERLAPPED lpOverlapped
  ); 

Эта функция навсегда блокируется, когда драйвер устройства пропускает прерывание.Это приводит к остановке программы, и для ее решения необходимо перезапустить окна.

Чтобы это исправить, я хочу использовать ограничение времени ожидания при вызове Readfile ().Но когда я использую

  BOOL WINAPI SetCommTimeouts(
   __in  HANDLE hFile,
   __in  LPCOMMTIMEOUTS lpCommTimeouts
  );

, происходит сбой с кодом ошибки 87 (недопустимые параметры).Видимо, я не могу использовать этот тайм-аут на дескрипторе драйвера устройства.Как я могу это исправить?Есть ли другой способ установить ограничение времени ожидания для драйвера устройства?

спасибо

1 Ответ

4 голосов
/ 31 октября 2011

Вам необходимо переключиться на асинхронный ввод / вывод.Откройте драйвер устройства, предоставив флаг FILE_FLAG_OVERLAPPED для CreateFile , а затем передайте перекрывающуюся структуру при вызове ReadFile .Дескриптор будет сигнализироваться после завершения ввода-вывода, поэтому вы можете использовать WaitForSingleObject , где вы указываете дескриптор, переданный в ReadFile, и время ожидания.

Не все драйверы устройств поддерживают асинхронный ввод-вывод, поэтомуэто может на самом деле не работать для вас.В этом случае ReadFile по-прежнему будет блокироваться и не будет возвращать «ERROR_PENDING_IO».

Если время ожидания истекло, вам также следует вызвать CancelIO , чтобы убить ReadFile до того, какперекрывающаяся структура выходит за рамки видимости.В противном случае, если это произойдет позже, он попытается записать память, в которой использовалась перекрывающаяся структура.

Асинхронный ввод-вывод немного сложен для правильного выполнения, поэтому внимательно прочитайте документы.

Обновление: Мне пришла в голову альтернатива, что вы можете позвонить CancelIEx из потока наблюдения.Будучи более новым API, он может отсутствовать на платформах, которые вы должны поддерживать.

...