Windows 操作系統(tǒng)家族支持三種數(shù)據(jù)傳輸機(jī)制:
l 緩存IO(Buffered I/O)在內(nèi)核模式上操作對用戶數(shù)據(jù)的拷貝
l 直接IO(Direct I/O)通過內(nèi)存描述元列表(MDL, Memory Descriptor List)以及內(nèi)核模式的指針直接訪問用戶數(shù)據(jù)
l 非上述方法IO(Method neither I/O,既非緩存,也非直接IO)通過用戶模式的指針訪問用戶數(shù)據(jù)
對于標(biāo)準(zhǔn)的IO 請求,例如IRP_MJ_READ 和IRP_MJ_WRITE,由驅(qū)動在設(shè)備剛創(chuàng)建后,馬上通過修改DeviceObject->Flags 域的值來指定支持那一種傳輸機(jī)制。
緩存IO
為了以緩存IO 的方式接收讀、寫的請求,驅(qū)動會在初始化時在DeviceObject->Flags 域上設(shè)置DO_BUFFERED_IO標(biāo)志。當(dāng)驅(qū)動收到了一個緩存IO 的請求,在特定的Irp->AssociatedIrp.SystemBuffer域中會放有驅(qū)動應(yīng)該操作的內(nèi)核模式緩沖區(qū)的地址。IO管理
器在進(jìn)行讀請求時將數(shù)據(jù)由內(nèi)核模式緩沖區(qū)拷貝到用戶模式緩沖區(qū),或者在進(jìn)行寫請求時從用戶模式緩沖區(qū)向內(nèi)核模式緩沖區(qū)拷貝數(shù)據(jù)。
直接IO
為了以直接IO的方式接收讀、寫請求,驅(qū)動會在初始化時在DeviceObject->Flags 域上設(shè)置DO_DIRECT_IO標(biāo)志。當(dāng)驅(qū)動接收到一個直接IO請求,特定的Irp->MdlAddress域中會放有一個用來描述請求緩沖區(qū)的MDL 的地址。這個MDL 列出了緩沖區(qū)的虛擬地址和尺寸,連同相應(yīng)緩沖區(qū)中的物理頁表(physical pages)。IO 管理器會在將請求發(fā)送給驅(qū)動之前鎖定這些物理頁,并在(請求)完成的過程中解鎖。驅(qū)動千萬不能使用MDL 中列舉的用戶模式緩沖區(qū)地址,而必須通過調(diào)用MmGetSystemAddressForMdlSafe 宏來得到一個內(nèi)核模式的地址。
非緩存非直接IO
為了接收非緩存非直接IO 的方式的請求,驅(qū)動初始化時在DeviceObject->Flags 域上既不設(shè)置DO_BUFFERED_IO 標(biāo)志,也不設(shè)置DO_DIRECT_IO 標(biāo)志。當(dāng)驅(qū)動接收到這樣的請求,相應(yīng)的Irp->UserBuffer 域會放有附屬于這個請求的數(shù)據(jù)地址。因為這個緩沖區(qū)在用戶地址空間上,驅(qū)動程序必須在用之前使相應(yīng)的地址合法化。驅(qū)動程序在try/except 塊里調(diào)用ProbeForRead 或者ProbeForWrite 函數(shù)來合法化特定的指針。驅(qū)動還必須完全在try/except塊里處理所有對這一緩沖區(qū)的訪問。
另外,驅(qū)動還必須在應(yīng)用(manipulating)數(shù)據(jù)之前將它拷貝到池(the pool)或堆棧里一個安全的內(nèi)核模式地址。將數(shù)據(jù)拷貝到內(nèi)核模式緩沖區(qū)確保了用戶模式的調(diào)用者不會在驅(qū)動已經(jīng)合法化數(shù)據(jù)之后再修改它。
posted on 2009-09-27 13:50
水 閱讀(1562)
評論(0) 編輯 收藏 引用 所屬分類:
windows驅(qū)動