我正在创建一个命名管道文件,如下所示:
void SavePipeFile(){
HANDLE hpipe;
BOOL bRet;
DWORD size;
hpipe =
CreateNamedPipe(
L"\\\\.\\pipe\\mypipe",
PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE,
1,
0,
0,
0,
NULL
);
if(hpipe == NULL || hpipe==INVALID_HANDLE_VALUE)
{
printf("Error opening handle\n");
}
CloseHandle(hpipe);
}
该功能存在,没有错误。但我在系统中找不到物理文件“mypipe”.Windows API是否将其保存到特定位置?在Windows 7 64bit上运行
答案 0 :(得分:8)
来自http://en.wikipedia.org/wiki/Named_pipe。
与Unix不同,命名管道无法安装在普通文件系统中。与Unix对应物不同,命名管道是易失性的(在最后一次引用它们之后被移除)。每个管道都放在命名管道文件系统(NPFS)的根目录中,安装在特殊路径\。\ pipe \下(即名为“foo”的管道的完整路径名为\。\ pipe \ foo )。在流水线操作中使用的匿名管道实际上是具有随机名称的命名管道。
答案 1 :(得分:1)
当您在ReactOS上创建一个命名管道时,kernel32.dll中的CreateNamedPipe
会调用ntdll.dll中的NtCreateNamedPipeFile
,这将对与ntoskrnl.exe中的内核模式对应的对象执行SSDT索引其中调用IoCreateFile
,调用IopCreateFile
,调用ObOpenObjectByName
,调用ObpLookupObjectName
,调用ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure
,调用对象解析例程IopParseRoutine
,将是{{ 1}},它将具有主要代码IRP_MJ_CREATE_NAMED_PIPE的IRP发送到NPFS驱动程序,并以其名称\Device\NamedPipe
获取(它将\\.\pipe
解析为\??\pipe
,即到NPFS驱动程序创建的\Device\NamedPipe
DO的符号链接)。
NPFS的DriverEntry
函数分配DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe;
。 NpFsdCreateNamedPipe
调用NpCreateNewNamedPipe
,这将设置文件对象以及带有数据队列的文件对象的CCB(上下文控制块)(FileObject->FsContext2
)。
名称为\\.\pipe\PipeName
的文件对象代表命名管道,直接指向由Npfs创建的NamedPipe
设备对象,IoGetRelatedDeviceObject
将返回该设备对象,这意味着所有{{1} }和WriteFile
操作产生一个IRP,该IRP被发送到该设备对象的设备堆栈的顶部。 ReadFile
最终将在设备对象的所属驱动程序上被调用。基于所传递的IRP中的IRP主代码,IoCallDriver
调用IoCallDriver
(即DO->DriverObject->MajorFunction[IRP_MJ_Write]
或NpFsdWrite
(即DO->DriverObject->MajorFunction[IRP_MJ_Read]
)。这些函数将写入和读取数据队列NpFsdRead
和Ccb->DataQueue[FILE_PIPE_OUTBOUND]
,它们包含Ccb->DataQueue[FILE_PIPE_INBOUND]
头的双向链接列表的头,其中DataEntry
是头,{{ 1}}是缓冲区。如果您将命名管道作为服务器打开,则它将从入站读取并写入出站。客户端从出站读取并写入到入站。
如果使用DataEntry[0]
,则每次写入管道时,都会在链接列表的末尾添加另一个DataEntry[1]
(因为PIPE_TYPE_MESSAGE
将返回{{1 }}中的DataEntry
,调用函数在调用NpWriteDataQueue
之前会对其进行检查),并且每次阅读时,IoStatus
都会从链接列表的开头({{ 1}}仅在STATUS_MORE_PROCESSING_REQUIRED
时调用NpAddDataQueueEntry
。如果您不阅读所有消息,将会收到错误消息。如果使用DataEntry
,则在写入时仅使用当前的NpReadDataQueue
,而不会删除任何NpRemoveDataQueueEntry
。简而言之,!Peek
的{{1}}字段会增加读取的字节数,而我真的不确定以字节模式进行写入的工作方式。
DataEntries,CCB和FileObject被分配在非页面缓冲池上。