Monday, December 03, 2007

NDIS Driver[1]

NDIS(Network Driver Interface Specification) driver 就是所謂的網路卡 driver,網路卡分很多種,但是常用的就是那幾種:LAN 跟 WLAN。用比較通俗的說法,就是有線跟無線網卡。

而一般所謂的 NDIS driver,通常是指 NDIS miniport driver。miniport driver 聽起來很玄,其實就是 MS 不想讓寫 Driver 的人太痛苦,所以先把架構(framework)定好,再實做整個架構,然後把介面開出來,寫 driver 的人只要實做這些介面就可以了。miniport driver 就是指這類的 driver。每個 class 都幾乎會有相對應的 miniport driver,而且它們的架構也都不一樣。

miniport driver 有好有壞,好處顯而易見,不用做太多 dirty work。而壞處呢?使用者得先懂 miniport 的架構跟 DDK,另外 debug 也不是很方便,因為雜事都讓整個 framework 包走了,出問題的話根本不知道是為甚麼,因為你沒有 framework 的 source code。

NIC 指的是 Network Interface Card,也就是網路卡。很無聊的頭字語。

要注意的是,NDIS 還有分版本喔,現在已經到 6.0 了。而 5.x 到 6.0 的差別還不小,雖然說 NDIS 6.0 可以用模擬的方式來執行 5.x 的 driver,但是 MS 並不建議這樣做。所以說,痛苦的永遠是寫 driver 的人啊。

Deserialized and Serialized NDIS Miniport Drivers

Deserialized miniport driver 會把上層交代下來的 ndis packets 儲存起來,等到適當的時機再把這些 ndis packets 送到 NIC,讓 NIC 把這些封包傳出去。Serialized miniport driver 則是上層交代一個 ndis packet,則馬上把這個 ndis packet 送到 NIC 去。想當然爾,Deserialized miniport driver 會比較有效率,所以 DDK 強烈建議用 Deserialized miniport driver。

至於要怎樣做才可以讓系統知道你的 Driver 是 Deserialized Miniport Driver?
  • 在 MiniportInitialize() 內呼叫 NdisMSetAttributesEx(),並且把 AttributeFlags 加上 NDIS_ATTRIBUTES_DESERIALIZE 這個 flag。
當然,Deserialized Miniport Driver 還有一些需求,你必須讓你的 driver 符合這些需求。請參閱 DDK。

Connection-Oriented NDIS Miniport Drivers

Connection-oriented miniport drivers 必定是 deserialized miniport drivers。目前大多數的網路卡 driver 都是 Connection-less miniport driver,所以就不用看這段了。

Driver Entry

DriverEntry() 是所有 Windows Driver 的進入點。系統只要發現到新的 Device,它就會嘗試載入對應的 Driver(如果它找的到的話),接著就會呼叫這隻 Driver 的 DriverEntry()。在 DriverEntry 內,你必須先呼叫 NdisMInitializeWrapper(),初始化 Ndis Wrapper,然後再呼叫 NdisMRegisterMiniport(),跟系統註冊你支援的函式。

不用想太多,文件怎樣寫你就怎樣做。

NDIS_STATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);

NdisMInitializeWrapper

NdisWrapperHandle 是系統給你的一個 handle,你得把它放在任何函式都可以存取它的地方,因為你會常常需要它。 程式碼如下所示:

NDIS_HANDLE                        hWrapper;
NdisMInitializeWrapper( &hWrapper, DriverObject, RegistryPath, NULL);

VOID NdisMInitializeWrapper(
    OUT PNDIS_HANDLE NdisWrapperHandle,
    IN PVOID SystemSpecific1,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3
);

NdisMRegisterMiniport

NdisWrapperHandle 就是呼叫 NdisMInitializeWrapper() 之後,系統給你的 handle。MiniportCharacteristics 則是你需要提供給系統的資訊,也就是你支援哪些函式。CharacteristicsLength 則是 MiniportCharacteristics 的大小。

NDIS_STATUS NdisMRegisterMiniport(
    IN NDIS_HANDLE NdisWrapperHandle,
    IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics,
    IN UINT CharacteristicsLength
);

MiniportCharacteristics 是個很大的資料結構,下集再講吧。

1 comment:

Unknown said...

hello, i am flug

codeblock