简体   繁体   English

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

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

I am creating a named pipe file as follows:我正在创建一个命名管道文件,如下所示:

 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);


}

The function exists ok,no errors.But I can't find the physical file "mypipe" in the system.Does Windows API saves it to a specific location?Running on Windows 7 64bit函数存在正常,没有错误。但是我在系统中找不到物理文件“mypipe”。Windows API 是否将其保存到特定位置?在 Windows 7 64 位上运行

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

Named pipes cannot be mounted within a normal filesystem, unlike in Unix.与 Unix 不同,命名管道不能安装在普通文件系统中。 Also unlike their Unix counterparts, named pipes are volatile (removed after the last reference to them is closed).也不同于它们的 Unix 对应物,命名管道是易变的(在对它们的最后一个引用关闭后被删除)。 Every pipe is placed in the root directory of the named pipe filesystem (NPFS), mounted under the special path \\.\\pipe\\ (that is, a pipe named "foo" would have a full path name of \\.\\pipe\\foo).每个管道都放置在命名管道文件系统 (NPFS) 的根目录中,挂载在特殊路径 \\.\\pipe\\ 下(即,名为“foo”的管道的完整路径名称为 \\.\\pipe\\foo )。 Anonymous pipes used in pipelining are actually named pipes with a random name.流水线中使用的匿名管道实际上是具有随机名称的命名管道。

When you create a named pipe on ReactOS, CreateNamedPipe in kernel32.dll calls NtCreateNamedPipeFile in ntdll.dll, which performs a syscall + index into SSDT to its kernel mode counterpart in ntoskrnl.exe, which calls IoCreateFile , which calls IopCreateFile , which will call ObOpenObjectByName , which calls ObpLookupObjectName , which calls the object parse routine ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure , which will be IopParseRoutine , which sends an IRP with major code IRP_MJ_CREATE_NAMED_PIPE to the NPFS driver, which it acquires by its name \\Device\\NamedPipe (it will parse \\\\.\\pipe as \\??\\pipe , which is a symbolic link to the \\Device\\NamedPipe DO created by the NPFS driver).当您在 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 的符号链接)。

The DriverEntry function of the NPFS assigns DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe; NPFS的DriverEntry函数赋值DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = NpFsdCreateNamedPipe; . . NpFsdCreateNamedPipe calls NpCreateNewNamedPipe , which will set up the file object and the CCB (Context Control Block) ( FileObject->FsContext2 ) of the file object with the data queues. NpFsdCreateNamedPipe调用NpCreateNewNamedPipe ,它将使用数据队列设置文件对象和文件对象的 CCB(上下文控制块)( FileObject->FsContext2 )。

The file object of name PipeName is accessed via \\\\.\\pipe\\PipeName and translates to \\Device\\NamedPipe\\PipeName .名称为PipeName的文件对象通过\\\\.\\pipe\\PipeName访问并转换为\\Device\\NamedPipe\\PipeName The file object points to the NamedPipe device object created by the Npfs, which IoGetRelatedDeviceObject will return, meaning that all WriteFile and ReadFile operations result in an IRP, which gets sent to the top of the device stack of this Device Object, passing the pipe name \\PipeName .文件对象指向 Npfs 创建的NamedPipe设备对象, IoGetRelatedDeviceObject将返回该对象,这意味着所有WriteFileReadFile操作都会产生一个 IRP,该 IRP 被发送到此设备对象的设备堆栈的顶部,并传递管道名称\\PipeName This is similar to how \\??\\C:\\Windows ie \\Device\\HarddiskVolume1\\Windows file object PDEVICE_OBJECT points to the Device\\HarddiskVolume1 device object, the file name UNICODE_STRING of the file object being \\Windows .这类似于如何\\??\\C:\\Windows\\Device\\HarddiskVolume1\\Windows文件对象PDEVICE_OBJECT指向Device\\HarddiskVolume1设备对象,文件对象的文件名UNICODE_STRING\\Windows If you look at the file object, you can get the full path by getting the device object name and appending it to the start.如果查看文件对象,则可以通过获取设备对象名称并将其附加到开头来获取完整路径。 IoCallDriver will be eventually called on the owning driver of the device object. IoCallDriver最终将在设备对象的拥有驱动程序上调用。 Based on the IRP major code in the IRP passed, IoCallDriver calls either DO->DriverObject->MajorFunction[IRP_MJ_Write] , which is NpFsdWrite or DO->DriverObject->MajorFunction[IRP_MJ_Read] , which is NpFsdRead .根据传递的 IRP 中的 IRP 主要代码, IoCallDriver调用DO->DriverObject->MajorFunction[IRP_MJ_Write] ,即NpFsdWriteDO->DriverObject->MajorFunction[IRP_MJ_Read] ,即NpFsdRead Those functions will write and read to the data queues Ccb->DataQueue[FILE_PIPE_OUTBOUND] and Ccb->DataQueue[FILE_PIPE_INBOUND] , which contain the head of a doubly linked list of DataEntry headers where DataEntry[0] is the header and DataEntry[1] is the buffer.这些函数将写入和读取数据队列Ccb->DataQueue[FILE_PIPE_OUTBOUND]Ccb->DataQueue[FILE_PIPE_INBOUND] ,其中包含DataEntry标头的双向链表的头部,其中DataEntry[0]是标头和DataEntry[1]是缓冲区。 If you open the named pipe as a server then it reads from the inbound and writes to the outbound.如果您将命名管道作为服务器打开,则它从入站读取并写入出站。 The client reads from the outbound and writes to the inbound.客户端从出站读取并写入入站。

If you use PIPE_TYPE_MESSAGE , then every time you write to the pipe, another DataEntry will be added to the tail of the linked list (because NpWriteDataQueue will return with IoStatus STATUS_MORE_PROCESSING_REQUIRED in the IRP, which the calling function checks before calling NpAddDataQueueEntry ), and each time you read, a DataEntry will be removed from the head of the linked list ( NpReadDataQueue will only call NpRemoveDataQueueEntry if !Peek ).如果使用PIPE_TYPE_MESSAGE ,那么每次写入管道时,都会将另一个DataEntry添加到链表的尾部(因为NpWriteDataQueue将在 IRP 中返回IoStatus STATUS_MORE_PROCESSING_REQUIRED ,调用函数会在调用NpAddDataQueueEntry之前检查该NpAddDataQueueEntry ),并且每个当你阅读时,一个DataEntry将从链表的头部移除( NpReadDataQueue只会在!Peek调用NpRemoveDataQueueEntry )。 You will get an error if you do not read all of the message.如果您没有阅读所有消息,您将收到错误消息。 If you use PIPE_TYPE_BYTE , then only the current DataEntry is used and no DataEntry s are removed when you write.如果您使用PIPE_TYPE_BYTE ,则仅使用当前的DataEntry并且在您写入时不会删除任何DataEntry Simply, the ByteOffset field of the DataEntry is increased by the number of bytes read, and I'm really not sure how writing in byte mode works.简单地说, DataEntryByteOffset字段随着读取的字节数而增加,我真的不确定以字节模式写入是如何工作的。

DataEntries, CCBs and FileObjects are allocated on the non-paged pool. DataEntries、CCB 和 FileObjects 分配在非分页池中。

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

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