具名管道與Mailslot

來源:互聯網
上載者:User

原文地址:http://book.51cto.com/art/200912/174785.htm

在做驅動與應用程式層使用具名管道通訊時,不知道如何在驅動中開啟具名管道的路徑,原來驅動中的路徑名為:"\Device\NamedPipe\MyPipe",應去層用的是"\\\\.\\Pipe\\MyPipe"

再看IoCreateFile()怎樣找到具名管道驅動模組的裝置對象。建立了一個具名管道以後,在對象目錄中就有了一個相應的節點,例如"\Device\NamedPipe\MyPipe"。注意這裡的節點"NamedPipe"是個裝置對象,而裝置對象提供解析函數。這樣,對象管理的ObOpenObjectByName()就能根據全路徑找到其具體具名管道所屬的"目錄""\Device\NamedPipe"(如果目標尚未建立)或代表著這個目標的對象。這二者都會有指標指向具名管道驅動模組的裝置對象(如果已經裝載)。下面就是驅動模組的事了。

我們看具名管道驅動模組的初始化:

 
  1. NTSTATUS STDCALL    //ReactOS-0.3.3\drivers\filesystems\npfs\npfs.c  
  2. DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)  
  3. {  
  4.    PNPFS_DEVICE_EXTENSION DeviceExtension;  
  5.    ......  
  6.  
  7.    DPRINT("Named Pipe FSD 0.0.2\n");  
  8.    ASSERT (sizeof(NPFS_CONTEXT) <= FIELD_OFFSET(IRP,Tail.Overlay.DriverContext));  
  9.    ASSERT (sizeof(NPFS_WAITER_ENTRY) <=  
  10.                                     FIELD_OFFSET(IRP, Tail.Overlay.DriverContext));  
  11.  
  12.    DriverObject->MajorFunction[IRP_MJ_CREATE]   = NpfsCreate;  
  13.    DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] =  
  14.                                                 NpfsCreateNamedPipe;  
  15.    DriverObject->MajorFunction[IRP_MJ_CLOSE]        = NpfsClose;  
  16.    DriverObject->MajorFunction[IRP_MJ_READ]         = NpfsRead;  
  17.    DriverObject->MajorFunction[IRP_MJ_WRITE]        = NpfsWrite;  
  18.    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =  
  19.                                                 NpfsQueryInformation;  
  20.    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =  
  21.                                                 NpfsSetInformation;  
  22.    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =  
  23.                                                 NpfsQueryVolumeInformation;  
  24.    DriverObject->MajorFunction[IRP_MJ_CLEANUP]  = NpfsCleanup;  
  25.    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = NpfsFlushBuffers;  
  26.    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =  
  27.                                                 NpfsFileSystemControl;  
  28.    DriverObject->DriverUnload = NULL;  
  29.    RtlInitUnicodeString(&DeviceName, L"\\Device\\NamedPipe");  
  30.    //在對象目錄中建立一個名為"\Device\NamedPipe"的裝置對象  
  31.    Status = IoCreateDevice(DriverObject, sizeof(NPFS_DEVICE_EXTENSION),  
  32.             &DeviceName, FILE_DEVICE_NAMED_PIPE, 0, FALSE, &DeviceObject);  
  33.    if (!NT_SUCCESS(Status)) return Status;    //建立裝置對象失敗  
  34.  
  35.    /* initialize the device object */  
  36.    DeviceObject->Flags = DO_DIRECT_IO;  
  37.    /* initialize the device extension */  
  38.    DeviceExtension = DeviceObject->DeviceExtension;  
  39.    InitializeListHead(&DeviceExtension->PipeListHead);  //所有具名管道FCB的隊列  
  40.    InitializeListHead(&DeviceExtension->ThreadListHead);  
  41.    KeInitializeMutex(&DeviceExtension->PipeListLock, 0);  
  42.    DeviceExtension->EmptyWaiterCount = 0;  
  43.    /* set the size quotas */  
  44.    DeviceExtension->MinQuota = PAGE_SIZE;  
  45.    DeviceExtension->DefaultQuota = 8 * PAGE_SIZE;  
  46.    DeviceExtension->MaxQuota = 64 * PAGE_SIZE;  
  47.    return STATUS_SUCCESS;  

注意這裡一方面使主功能為IRP_MJ_CREATE的函數指標指向NpfsCreate(),另一方面又使主功能為IRP_MJ_CREATE_NAMED_PIPE的函數指標指向NpfsCreateNamedPipe(),具名管道驅動是唯一提供後面這個主功能函數的驅動對象。

此外,這裡並沒有提供AddDevice函數,這說明具名管道的驅動是個"老式(Legacy)"的單塊裝置驅動,其裝置對象不會被堆疊到別的裝置對象上面。

由於路徑名為"\Device\NamedPipe",IoCreateDevice()就在對象目錄中的節點"\Device"下面建立了一個名為"NamedPipe"的裝置對象,並使其指向所建立的具名管道裝置對象。注意這裡的FILE_DEVICE_NAMED_PIPE是裝置類型,就像FILE_DEVICE_BEEP一樣,而所建立對象的類型則是IoDeviceObjectType即裝置對象。另一方面,裝置對象是提供解析函數的。

裝置對象的擴充部有個隊列PipeListHead,隊列中是所有已建立的具名管道。每個具名管道都有個"檔案控制區"即NPFS_FCB資料結構,這個資料結構就掛在PipeListHead這個隊列裡面,這個隊列就好像一個單層的目錄。此外,從本質上說具名管道無非就是資料的"中轉站",所以需要一定的緩衝區空間,這裡還為此設定了配額。

建立了裝置對象之後,核心的裝置驅動架構就可以通過IRP和IoCallDriver()調用其主功能函數了。建立或開啟具名管道時,就像對於別的裝置一樣,核心會為之建立一個代表著特定訪問內容相關的FILE_OBJECT,就是下面代碼中的FileObject,並且系統調用所返回的控制代碼就代表著這個檔案對象。

在裝置對象的解析函數IopParseDevice()中,當檔案類型為CreateFileTypeNamedPipe時所產生IRP的主功能碼是IRP_MJ_CREATE_NAMED_PIPE,而在檔案類型為CreateFileTypeNone時則是IRP_MJ_CREATE。也就是說,當IRP到達具名管道驅動模組的裝置對象時,前者表示這是服務端的建立具名管道,而後者表示這是用戶端的開啟具名管道。

再看具體的主功能函數,其中最重要的是NpfsCreateNamedPipe()和NpfsCreate()。先看前者,NpfsCreateNamedPipe()是個比較大的函數,需要分段閱讀。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.