應用程式與驅動程式6種通訊方式
---**於網際網路,交流學習---
應用程式與驅動程式通訊方式據我所知,細分可以分6種,readfile,wirtefile方式的緩衝區裝置讀寫,直接方式讀寫,和其他方式讀寫。io裝置控制操作(即 devicecontrol)的緩衝記憶體模式ioctl,直接記憶體方式的ioctl,其他記憶體方式的ioctl!當然還有一種就是建立檔案,然後檔案讀寫也應該算是一種通訊吧,這裡不討論這個!
下面是方式都是用
readfile,wirtefile
裝置控制操作的方法基本上與上面3中相對應!
1、緩衝區方式裝置讀寫:
在建立device後,須要指定方式為device的flags有 do_buffered_io!通過應用層api函式readfile,writefile,等函式,ntoskrnl.exe建立irp 後,readfile和writefile引數的緩衝區就在irp->associatedirp.systembuffer,同時要求讀寫的偏移量,和長度都在pio_stack_location stack = iogetcurrentirpstacklocation(pirp) 資料型別中的 stack->parameters.read.length,stack->parameters.read.byteoffset(該型別為large_interge型別),
2、直接方式讀寫
在建立device後,須要指定方式為device的flags有 do_direct_io!通過應用層api函式readfile,writefile等函式,ntoskrnl.exe建立的irp 後,readfile和writefile引數的緩衝區將被鎖住,然後作業系統將這段緩衝區在核心模式位址再次對映一遍,這樣應用層的緩衝區和記憶體層的就指向同乙個物理記憶體!而核心模式用mdl資料結構記錄這段記憶體,這個虛擬記憶體大小在 mmgetbytecount(pirp->mdladdress),首位址在 mmge***lvirtualaddress(pirp->mdladdress);偏移量為 mmge***lbyteoffset(pirp->mdladdress)(這裡的偏移量不是檔案讀寫的偏移量,而是在mdl中的偏移量)然後檔案的長度還是stack->parameters.read.length,這個值和 mmgetbytecount(pirp->mdladdress)是一樣的,要不然就出錯了,而真正的讀寫偏移量還是在 stack->parameters.read.byteoffset!這裡無論是讀還是寫,都要得到mdl在核心模式下的對映,因此還要用 mmgetsystemaddressformdlsafe(pirp->mdladdress,normalpagepriority)將其轉化為核心模式,然後可以讀寫該位址,就會轉化到應用層相應的記憶體!!
3、其他方式讀寫
這種方式很少用到,在建立device後,flags既不標誌 do_buffered_io也不標誌do_direct_io,readfile和writefile提供的緩衝區記憶體位址,可以再irp的 pirp->userbuffer欄位得到,而長度和偏移量還是在stack->paameters.read中,但是用這種方法須要注意的是readfile可能把空指標位址或者非法位址傳遞給驅動程式,因此驅動程式使用使用者模式位址錢須要檢查是否可讀或者可寫,可以用 probeforwrite或者probeforwrite函式和try模組。
這裡有個問題困擾著我,就是應用層用getfilesize函式時用第一種方法處理該irp時結果是正確的,就是衝pirp->associatedirp.systembuffer;得到 pfile_standard_information結構指標,然後講該結構的endoffile設定為你自己檔案的長度,然後結束該 irp,getfilesize就能得到正確的檔案長度,但是用方法三就是的時候用getfilesize,我同樣用 pirp->userbufer得到pfile_standard_information結構指標,然後設定後,在getfilesize裡面去得不到正確的長度!!這個是為什麼?還有就是該irp的currentstacklocation-stack,該欄位裡面的 stack->parameters.queryfile.length指的是什麼,顯示的都是24,無**長度為多少,還是用哪種方法都市24,很鬱悶!!!
下面是方式都是用io裝置控制操作的方法基本上與上面3中相對應!
對於io裝置控制操作,不知道為什麼可以用設定do_direct_io後就能對三種方式都適用,而且stack->parameters.read.length/write.length 都是對應應用層的deviceiocontrol函式中的第6個引數也就是輸出緩衝區!deviceiocontrol函式的輸入輸出緩衝區長度都再 stack->parameters.deviceiocontrol.inputbufferlength/outputbufferlength 中
4、緩衝記憶體ioctl,在deviceiocontrol函式第二個引數的時候,使用ctl_code來產生該常數,其中method欄位設定為method_buffered,在核心模式中輸入緩衝區很輸出緩衝區都為 pirp->associatedirp.systembuffer,
5、直接方式ioctl,在deviceiocontrol函式第二個引數的時候,使用ctl_code來產生該常數,其中method欄位設定為method_in_direct/method_out_direct(最好使用第乙個,因為第乙個對所有的開啟裝置方式都通用)!對於第4中的區別是輸入緩衝區還在pirp->assocatedirp.systembuffer 中,但是輸出緩衝區卻是pirp->mdladdress,因此在核心對輸出的寫應該寫在 mmgetsystemaddressformdlsafe(pirp->mdladdress)中,
6、其他方式ioctl,在deviceiocontrol函式第二個引數的時候,使用ctl_code來產生該常數,其中method欄位設定為mehtod_neither,輸入緩衝區為 stack->parameters.deviceiocontrol.tyep3inputbuffer;輸出緩衝區為 pirp->userbuffer
驅動程式與應用程式之間的通訊
驅動程式與應用程式之間的通訊 驅動程式必須與應用程式進行通訊,才能最終達到應用程式控制裝置的目的,不然驅動有qiu用。要通訊就涉及到3個方面 1.應用程式與驅動程式通訊 2.驅動程式與應用程式通訊 3.資料傳輸 下面分別討論 1。應用程式與驅動程式通訊 2。驅動程式與應用程式通訊 2 1 驅動程式在...
驅動程式和應用程式通訊方法
驅動程式必須與應用程式進行通訊,才能最終達到應用程式控制裝置的目的,不然驅動有qiu用。要通訊就涉及到3個方面 1.應用程式與驅動程式通訊 2.驅動程式與應用程式通訊 3.資料傳輸 下面分別討論 1。應用程式與驅動程式通訊 1 1 應用程式實現與驅動通訊的過程 用createfile開啟裝置,用de...
驅動程式和應用程式之間通訊
正文 q 請問有什麼方法實現驅動程式主動和應用程式進行實時通訊,而不用應用程式採用定時查詢的方法?比如驅動有一事件發生需要立即通知應用程式,或驅動程式需要向應用程式讀取一些內容.a 有乙個很容易的方式,在驅動程式和應用程式之間用乙個事件。在應用程式createfile的時候,驅動程式iocreate...