Windows 是什么导致WriteFile返回错误38(错误句柄)?

Windows 是什么导致WriteFile返回错误38(错误句柄)?,windows,winapi,Windows,Winapi,什么会导致WriteFile返回错误38(错误\u HANDLE\u EOF,到达文件末尾)?本例中的“文件”是一个邮箱。我的程序的工作方式是我有一个进程(作为Windows服务运行)来创建多个子进程。每个子级打开一个同名的邮箱,以便将状态信息发送回其父级。在我的小规模测试中,这可以很好地工作,但我看到当我有几个进程时 运行(如16)我得到了这个错误。下面的代码显示了我如何在子进程中打开和写入邮件槽 是不是因为家长阅读邮件的速度不够快?是否有一种方法可以增加邮件槽的容量,从而永远不会到达文件的末

什么会导致WriteFile返回错误38(错误\u HANDLE\u EOF,到达文件末尾)?本例中的“文件”是一个邮箱。我的程序的工作方式是我有一个进程(作为Windows服务运行)来创建多个子进程。每个子级打开一个同名的邮箱,以便将状态信息发送回其父级。在我的小规模测试中,这可以很好地工作,但我看到当我有几个进程时 运行(如16)我得到了这个错误。下面的代码显示了我如何在子进程中打开和写入邮件槽

是不是因为家长阅读邮件的速度不够快?是否有一种方法可以增加邮件槽的容量,从而永远不会到达文件的末尾?我真的不知道邮箱怎么会满,只要 因为有足够的磁盘空间


WriteFile
是薄壳。如果
NtWriteFile
返回错误
NTSTATUS
,则它将转换为等效的win32错误代码(via)并
WriteFile
返回false。win32错误代码可以通过
GetLastError()
获取。但是,原始的
NTSTATUS
可以通过ntdll.dll api导出的
RtlGetLastNtStatus()
获得。win32错误代码问题-有时几个不同的
NTSTATUS
值转换为相同的win32错误

如果
错误\u句柄\u EOF
-2个不同的
NTSTATUS
转换为它: 文件的
状态\u结束\u和
状态\u文件\u强制\u关闭
。msfs.sys(处理邮件槽的驱动程序)返回的\u文件的
状态\u END\u。从另一端-
STATUS\u FILE\u FORCED\u CLOSED
(指定的文件已被另一个进程关闭)。如果邮件槽的服务器端(通过
CreateMailslot
调用创建的端)已关闭,则在将数据写入邮件槽时(通过
msfs.MsCommonWrite
)可以返回。 当最后一个服务器句柄被关闭时,所有连接的客户端都被标记为处于关闭状态(在
MsFsdCleanup
内),然后如果您为该客户端调用
WriteFile
,则返回
状态文件\u FORCED\u closed

所以-

是什么导致WriteFile返回错误38(错误句柄)


服务器进程由于某种原因关闭了self-mailslot句柄。您需要按此方向搜索-何时以及为什么关闭父进程中的mailsot句柄

我100%确定您获得了
状态\u文件\u强制\u关闭
-指定的文件已被另一个进程关闭。-allIIRC上的文件结尾不起任何作用如果服务器端正在关闭,则邮箱文件系统也会强制所有客户端处于关闭状态,并以
STATUS\u file\u FORCED\u CLOSED
的请求失败,如上所述。@eryksun-
STATUS\u file\u FORCED\u CLOSED
msfs返回!MsCommonWrite
如果结束处于关闭状态。从另一面看,msfs.sys似乎从未返回文件的状态。这两个ntstatus都转换为相同的
错误\u句柄\u EOF
。win32错误有时非常混乱。我无法理解为什么将ntstatus代码映射到win32错误不是内射的。为什么需要map@RbMm,如果关闭自己的句柄,则将是无效的句柄错误。在这种情况下,由于服务器端(FCB)被关闭和清理,客户端(CCB)被文件系统强制进入关闭状态。至于映射错误,Windows API比NT API早很多年,其错误代码集必须为Windows子系统保留和扩展。NTAPI当然不是公开的,也不打算在20世纪90年代公开,除了为驾驶员发布的有限子集。在许多情况下,我认为在决定何时重用现有错误代码以及何时使用新代码进行扩展时,考虑得还远远不够。
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);
}