繁体   English   中英

Windows 上的命名管道文件存储在哪里?

[英]Where on Windows a named pipe file is stored?

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

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

引自http://en.wikipedia.org/wiki/Named_pipe

与 Unix 不同,命名管道不能安装在普通文件系统中。 也不同于它们的 Unix 对应物,命名管道是易变的(在对它们的最后一个引用关闭后被删除)。 每个管道都放置在命名管道文件系统 (NPFS) 的根目录中,挂载在特殊路径 \\.\\pipe\\ 下(即,名为“foo”的管道的完整路径名称为 \\.\\pipe\\foo )。 流水线中使用的匿名管道实际上是具有随机名称的命名管道。

当您在 ReactOS 上创建命名管道时,kernel32.dll 中的CreateNamedPipe调用 ntdll.dll 中的NtCreateNamedPipeFile ,后者执行系统调用 + SSDT 索引到 ntoskrnl.exe 中的内核模式对应项,后者调用IoCreateFile ,后者调用IopCreateFile ,后者将调用ObOpenObjectByName ,它调用ObpLookupObjectName ,该调用对象的解析例程ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure ,这将是IopParseRoutine ,它发送一个IRP与主代码IRP_MJ_CREATE_NAMED_PIPE到NPFS驱动器,其获取由它的名字\\Device\\NamedPipe (它将\\\\.\\pipe解析为\\??\\pipe ,这是到由 NPFS 驱动程序创建的\\Device\\NamedPipe DO 的符号链接)。

NPFS的DriverEntry函数赋值DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe; . NpFsdCreateNamedPipe调用NpCreateNewNamedPipe ,它将使用数据队列设置文件对象和文件对象的 CCB(上下文控制块)( FileObject->FsContext2 )。

名称为PipeName的文件对象通过\\\\.\\pipe\\PipeName访问并转换为\\Device\\NamedPipe\\PipeName 文件对象指向 Npfs 创建的NamedPipe设备对象, IoGetRelatedDeviceObject将返回该对象,这意味着所有WriteFileReadFile操作都会产生一个 IRP,该 IRP 被发送到此设备对象的设备堆栈的顶部,并传递管道名称\\PipeName 这类似于如何\\??\\C:\\Windows\\Device\\HarddiskVolume1\\Windows文件对象PDEVICE_OBJECT指向Device\\HarddiskVolume1设备对象,文件对象的文件名UNICODE_STRING\\Windows 如果查看文件对象,则可以通过获取设备对象名称并将其附加到开头来获取完整路径。 IoCallDriver最终将在设备对象的拥有驱动程序上调用。 根据传递的 IRP 中的 IRP 主要代码, IoCallDriver调用DO->DriverObject->MajorFunction[IRP_MJ_Write] ,即NpFsdWriteDO->DriverObject->MajorFunction[IRP_MJ_Read] ,即NpFsdRead 这些函数将写入和读取数据队列Ccb->DataQueue[FILE_PIPE_OUTBOUND]Ccb->DataQueue[FILE_PIPE_INBOUND] ,其中包含DataEntry标头的双向链表的头部,其中DataEntry[0]是标头和DataEntry[1]是缓冲区。 如果您将命名管道作为服务器打开,则它从入站读取并写入出站。 客户端从出站读取并写入入站。

如果使用PIPE_TYPE_MESSAGE ,那么每次写入管道时,都会将另一个DataEntry添加到链表的尾部(因为NpWriteDataQueue将在 IRP 中返回IoStatus STATUS_MORE_PROCESSING_REQUIRED ,调用函数会在调用NpAddDataQueueEntry之前检查该NpAddDataQueueEntry ),并且每个当你阅读时,一个DataEntry将从链表的头部移除( NpReadDataQueue只会在!Peek调用NpRemoveDataQueueEntry )。 如果您没有阅读所有消息,您将收到错误消息。 如果您使用PIPE_TYPE_BYTE ,则仅使用当前的DataEntry并且在您写入时不会删除任何DataEntry 简单地说, DataEntryByteOffset字段随着读取的字节数而增加,我真的不确定以字节模式写入是如何工作的。

DataEntries、CCB 和 FileObjects 分配在非分页池中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM