![](/img/trans.png)
[英]windows: is it possible to dump (direct) a text file into a named pipe
[英]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
將返回該對象,這意味着所有WriteFile
和ReadFile
操作都會產生一個 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]
,即NpFsdWrite
或DO->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
。 簡單地說, DataEntry
的ByteOffset
字段隨着讀取的字節數而增加,我真的不確定以字節模式寫入是如何工作的。
DataEntries、CCB 和 FileObjects 分配在非分頁池中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.