2016年8月29日 星期一

TDI Operations - I

Opening a Transport Address

下圖展示了核心模式客戶端何開它底層傳輸驅動的一個傳輸位址:


在開了一個傳輸基於綁定所建立的裝置物件以後,TDI客戶端通常會透過開一個表示為傳輸位址(transport address)的檔案物件來與本地端節點溝通。要做到這個,客戶端EA(extended attributes)緩衝區內設定指定的位址,並將其指定為參數後調用ZwCreateFile。在EA緩衝區內,客戶將EaName設定為系統所定義的TdiTransportAddress,緊接EaName之後的EATDI定義的TRANSPORT_ADDRESS型態。


當客戶端調用ZwCreateFile的時候它可以指定一個傳輸位址是要自己獨享或是與其他客乎端共享。客戶端在成功地開一個獨享的傳輸位址,可以保證在客戶端關閉這個位址前,其他客戶不能使用。

要在網路上做無連線通信(UDP),假設底層傳輸端支援廣播數據報,則客戶端可以在EA緩衝內指定底層的傳輸廣播(broadcast)位址。這樣的位址是公享的不能被任一客戶端所獨佔。

在客戶端調用ZwCreateFile 後,系統的I/O管理員會建立一個客戶端程序特定的檔案物件來表示一個位址,以及調用TDI傳輸驅動的TdiDispatchCreate例程,TDI傳輸驅動會收到一個包含客戶端提供給ZwCreateFile參數的IRPTdiDispatchCreate會分析其中的EA訊息,並且在調用成後以後設定開位址的內部狀態。

在調用ZwCreateFile 成功以後,此函式會回傳客戶端一個檔案handle,而客戶端可以使用ObReferenceObjectByHandle來獲得一個檔案物件的指標,此時,客戶端已經準備好可以建立一個 TDI_XXX IO請求來與底層傳輸做溝通。舉例,客戶端可以在一個開的位址上收發數據報。

一般來說,客戶端首先必須決定是否註冊一個或多個 ClientEventXxx 處理程序以及是否要使用開的位址來與遠端節點進行溝通,在這個例子客戶端必須開一個連接節點(connection endpoint)

如果客戶端想要接收一些網路事件,它可以透過TdiBuildSetEventHandler來安裝請求餅切提交一個或多個TDI_SET_EVENT_HANDLER請求來註冊自己的ClientEventXxx 處例程序。更多有關安裝以及提交IOCTL請求的資訊,Packaging and Submitting IOCTL Requests.

在客戶端註冊完自己的 ClientEventXxx 處理程序以後,它已經準備好在開起的連接節點上溝通,在 Opening a Connection Endpoint中有描述這段過程。而在Sending and Receiving Connectionless Data裡則有描述一個無連線通信。

當一個開的傳輸位址結束網路上的通信,客戶端必須透過調用 ZwClose 來關閉一個表示傳輸位址的檔案物件。詳細的過程在Closing a Transport Address or Control Channel內有描述。

沒有留言:

張貼留言