前言:
本文討論w2k&xp適用的ndis5.x 網路架構。
ndis4.0原始碼太老,ros又yy了太多,所以這次的參考**基本都是自己f5的…具體結構都有了,我f5的毫無壓力=。=
除錯的時候利用imd(中間層驅動)下斷點,更無壓力了...
ndis5.x網路的堆疊結構大概是:
winsock api → afd → 協議驅動tcpip(其上層是tdi介面 ) →可能存在的中間層驅動→ndiswan 系統提供中間層驅動(用於簡化規程對於miniport的繫結) →miniport介面卡網絡卡驅動
ndis管理的部分,就是抽象成 "規程端(protocol edge) → 小埠端(miniport edge) → 規程端→ 小埠端" 這一流程的管理,tcpip是最靠前的規程驅動,只有規程端,真實網絡卡驅動只有小埠端,中間層驅動都同時具備小埠和規程的特徵屬性
winsock**用程式呼叫協議驅動主要處理網路連線的邏輯,afd將這些請求轉化為協議層明白的引數(tdi規範)發給tcpip
如上圖所示,實際上要更複雜一點,ndiswan是系統提供的乙個中間層驅動,提供了許多服務
一、驅動程式初始化 —— 向ndis註冊
ndis內部維護了若干全域性鍊錶 用來儲存協議驅動,小埠驅動,介面卡驅動的相關結構
這裡主要看看passthru,同時包含了協議驅動和微埠驅動的部分特性
a.在driverentry中 初始化包裝控制代碼
這個api不過是填充了如下結構
+0x000 driverobject : 0x81447030 _driver_object
+0x004 serviceregpath : _unicode_string "\registry\machine\system\controlset001\services\passthrump"
b.回到driverentry,緊接著,要填充乙個ndis_miniport_characteristics
然後呼叫ndisimregisterlayeredminiport註冊我們的微埠驅動,但這個是中間層驅動呼叫的,真正的微埠驅動呼叫的是ndismregisterminiport,但這兩個都是呼叫內部函式ndisregisterminiportdriver,中間層只是多加了乙個標誌位
&mchars,
sizeof(mchars),
&driverhandle);
ndisregisterminiportdriver的邏輯:
1.一大堆判斷版本、判斷引數有效性,如果一些引數是空的,將返回ndis_status_bad_characteristics
2.填充driverobject的派遣函式
3. 呼叫ioallocatedriverobjectextension分配乙個_ndis_m_driver_block作為驅動擴充套件,並返回在driverhandle中
4.初始化結構 除錯資訊如下
kd> dt _ndis_m_driver_block 814880b0
ndis!_ndis_m_driver_block,在driverext中,driverhanle
+0x000 nextdriver : 0x817cf010 _ndis_m_driver_block ;全域性鍊錶ndisminidriverlist
+0x004 miniportqueue : 0x81342ad0 _ndis_miniport_block ;所有的miniport block鍊錶
+0x00c associatedprotocol : 0x817be4c8 _ndis_protocol_block ;關聯的protblock
+0x010 devicelist : _list_entry [ 0x81484898 - 0x81484898 ]
+0x018 pendingdevicelist : (null)
+0x01c unloadhandler : 0xf763e540 void passthru!ptunload+0
+0x020 miniportcharacteristics : _ndis51_miniport_characteristics
+0x09c miniportsremovedevent : _kevent
+0x0ac ref : _reference
+0x0b4 flags : 1
+0x0b8 imstartremovemutex : _kmutant
+0x0d8 driverversion : 0
c. 回到driverentry,接下來該初始化協議驅動了,呼叫
ndisregisterprotocol(&status,
&prothandle,
&pchars,
sizeof(ndis_protocol_characteristics));
ndisregisterprotocol的邏輯比較簡單:
1、引數判斷 竟然還有dbgprint
2、初始化結構_ndis_protocol_block 存放在prothandle中返回
ndis!_ndis_protocol_block
+0x000 openqueue : 0x81593008 _ndis_open_block ;openblock佇列
+0x004 ref : _reference
+0x00c deregevent : (null)
+0x010 nextprotocol : 0x8145c588 _ndis_protocol_block ;下乙個prot繫結
+0x014 protocolcharacteristics : _ndis50_protocol_characteristics
+0x080 workitem : _work_queue_item
+0x090 mutex : _kmutant
+0x0b0 mutexowner : 0x10b46
+0x0b4 binddevicename : (null)
+0x0b8 rootdevicename : 0x816d53ec _unicode_string "\device\ndiswanip"
+0x0bc associatedminidriver : 0x81484888 _ndis_m_driver_block 關聯的miniblock
+0x0c0 bindingadapter : 0x816e1130 _ndis_miniport_block 繫結的adapter
d.初始化的最後一步,將小埠驅動和協議驅動聯絡起來,這個就更簡單了
ndisimassociateminiport(driverhandle, prothandle);
_ndis_protocol_block *__stdcall ndisimassociateminiport(_ndis_m_driver_block *minidriverhandle, _ndis_protocol_block *prothandle)
小結:
至此初始化部分就完成了,ndis_handle是乙個討厭的東西,ndis隱藏了真實結構的真相,這裡總結一下各個handle都是什麼
prothandle 協議控制代碼,是_ndis_protocol_block,儲存了_ndis_open_block(這個很重要),協議全域性鍊錶節點,協議特徵表,連線的微埠驅動
探索設計模式之三 抽象工廠模式
前面介紹的 簡單工廠模式 和 工廠方法模式 立足點都是避免顯式的建立具體物件,封裝建立物件時可能出現的變化點,這已經能比較好的解決單個物件建立的問題,但實際業務中,還經常出現需要一系列物件互相關聯使用來完成任務的情況。對於存在關聯 以來的產品來說,使用簡單工廠或者工廠方法乙個乙個的建立其中的具體產品...
網路協議系列之三 IP
前言 這篇部落格主要對ip協議中一些基礎知識點加以總結,並將書中一些晦澀難懂的部分去除了。ip位址協議是網路層中最重要的協議,ip位址協議可以對網際網路上的所有裝置進行唯一標識,也正因為有了ip協議,我們的計算機才能實現與全球任意一台裝置進行通訊。同時這也是網路層存在的意義,我將對部分的內容分為兩個...
iphone開發記憶體管理之三 深拷貝和淺拷貝
在iphone程式中,屬性合成中的retain copy assign有什麼區別?1 assign就不用說了,因為基本上是為簡單資料型別準備的,原子類型別,例如cgpoint cgfloat等,而不是ns物件們 2 retain vs copy copy其實是建立了乙個相同的物件,而retain不是...