Windows上存储命名管道文件的位置?

时间:2014-01-15 14:18:05

标签: c++ winapi

我正在创建一个命名管道文件,如下所示:

 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上运行

2 个答案:

答案 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])。这些函数将写入和读取数据队列NpFsdReadCcb->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被分配在非页面缓冲池上。