Что заставляет WriteFile возвращать ошибку 38 (ERROR_HANDLE_EOF)? - PullRequest
1 голос
/ 09 июня 2019

Что заставит WriteFile вернуть ошибку 38 (ERROR_HANDLE_EOF, Достигнут конец файла)? «Файл» в этом случае является почтовым ящиком. Моя программа работает так, что у меня есть процесс (работающий как служба Windows), который создает несколько дочерних процессов. Каждый ребенок открывает почтовый ящик с тем же именем, чтобы отправить информацию о статусе его родителю. В моем небольшом тестировании это работает нормально, но я вижу случаи, когда у меня есть несколько процессов работает (как 16) я получаю эту ошибку. Приведенный ниже код показывает, как я открываю и пишу в почтовый ящик в дочернем процессе.

Возможно, потому что родитель недостаточно быстро читает почтовый ящик? Есть ли способ увеличить емкость почтового ящика, чтобы конец файла не был достигнут? Я действительно не вижу, как почтовый ящик может заполниться в любом случае, пока так как есть место на диске (которого там много).

char gLocalSlotName[256]="\\\\.\\mailslot\\TMAgentSlot-ComputerName";

gAgentSlot = CreateFile(gLocalSlotName, GENERIC_WRITE, FILE_SHARE_READ, (LPSECURITY_ATTRIBUTES) NULL,
                               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL);


fResult = WriteFile(gAgentSlot, (char *)&ProcStat, sizeof(PROCSTAT), &cbWritten, (LPOVERLAPPED) NULL);
if (!fResult) {
  derr = GetLastError();
  printf("WriteFile error=%d", derr);
}

1 Ответ

2 голосов
/ 09 июня 2019

WriteFile - тонкая оболочка над NtWriteFile. если NtWriteFile возвращает ошибку NTSTATUS - она ​​будет преобразована в эквивалентный ей код ошибки win32 (через RtlNtStatusToDosError) и WriteFile вернет false. Код ошибки win32, который вы можете получить через GetLastError(). однако оригинальный NTSTATUS вы можете получить через RtlGetLastNtStatus(), экспортированный ntdll.dll api. проблема с кодами ошибок win32 - иногда несколько разных значений NTSTATUS конвертируются в одну и ту же ошибку win32.

в случае ERROR_HANDLE_EOF - 2 различных NTSTATUS преобразованных в него: STATUS_END_OF_FILE и STATUS_FILE_FORCED_CLOSED. STATUS_END_OF_FILE никогда (похоже) не возвращается msfs.sys (драйвер, который обрабатывает почтовые ящики). с другой стороны - STATUS_FILE_FORCED_CLOSED ( указанный файл был закрыт другим процессом. ) может быть возвращен при записи данных в почтовый ящик (msfs.MsCommonWrite), если серверный конец почтового ящика (конец, который вы создать через CreateMailslot вызов) уже закрыт. формально, когда последний дескриптор сервера был закрыт - все подключающиеся клиенты отмечены как находящиеся в закрытом состоянии (внутри MsFsdCleanup), а затем, если вы вызываете WriteFile для такого клиента - STATUS_FILE_FORCED_CLOSED возвращается.

так -

Что заставляет WriteFile возвращать ошибку 38 (ERROR_HANDLE_EOF)?

серверный процесс по какой-то причине закрывает сам дескриптор почтового ящика. вам нужен поиск в этом направлении - когда и почему вы закрываете дескриптор mailsot в родительском процессе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...