




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、標(biāo) 題: 【原創(chuàng)】【成果3.5】驅(qū)動和應(yīng)用層的三種通信方式作 者: sislcb時 間: 2008-01-04,11:57鏈 接:驅(qū)動程序和客戶應(yīng)用程序經(jīng)常需要進(jìn)行數(shù)據(jù)交換,但我們知道驅(qū)動程序和客戶應(yīng)用程序可能不在同一個地址空間,因此操作系統(tǒng)必須解決兩者之間的數(shù)據(jù)交換。驅(qū)動層和應(yīng)用層通信,主要是靠DeviceIoControl函數(shù),下面是該函數(shù)的原型:BOOLDeviceIoControl(HANDLEhDevice,/設(shè)備句柄DWORDdwIoControlCode,/IOCTL請求操作代碼LPVOIDlpInBuffer,/輸入緩沖區(qū)地址DWORDnInBufferSize,/輸入緩沖區(qū)大
2、小LPVOIDlpOutBuffer,/輸出緩沖區(qū)地址DWORDnOutBufferSize,/輸出緩沖區(qū)大小LPDWORDlpBytesReturned,/存放返回字節(jié)數(shù)的指針LPOVERLAPPEDlpOverlapped/用于異步操作的Overlapped結(jié)構(gòu)體指針1、輸入輸出緩沖I/O(METHOD_BUFFERED)2、直接輸入緩沖輸出I/O(METHOD_IN_DIRECT)3、緩沖輸入直接輸出I/O(METHOD_OUT_DIRECT)4、上面三種方法都不是(METHOD_NEITHER)為了對這些類型更詳細(xì)的描述,請看msdn上的解釋,我抄錄如下:緩沖方法(METHOD_BUF
3、FERED)備注:在下面的討論中,輸入表示數(shù)據(jù)從用戶模式的應(yīng)用程序到驅(qū)動程序,輸出表示數(shù)據(jù)從驅(qū)動程序到應(yīng)用程序。對于讀取請求,I/O管理器分配一個與用戶模式的緩沖區(qū)大小相同的系統(tǒng)緩沖區(qū)。IRP中的SystemBuffer字段包含系統(tǒng)地址。UserBuffer字段包含初始的用戶緩沖區(qū)地址。當(dāng)完成請求時,I/O管理器將驅(qū)動程序已經(jīng)提供的數(shù)據(jù)從系統(tǒng)緩沖區(qū)復(fù)制到用戶緩沖區(qū)。對于寫入請求,會分配一個系統(tǒng)緩沖區(qū)并將SystemBuffer設(shè)置為地址。用戶緩沖區(qū)的內(nèi)容會被復(fù)制到系統(tǒng)緩沖區(qū),但是不設(shè)置UserBuffer。對于IOCTL請求,會分配一個容量大小足以包含輸入緩沖區(qū)或輸出緩沖區(qū)的系統(tǒng)緩沖區(qū),并將S
4、ystemBuffer設(shè)置為分配的緩沖區(qū)地址。輸入緩沖區(qū)中的數(shù)據(jù)復(fù)制到系統(tǒng)緩沖區(qū)。UserBuffer字段設(shè)置為用戶模式輸出緩沖區(qū)地址。內(nèi)核模式驅(qū)動程序應(yīng)當(dāng)只使用系統(tǒng)緩沖區(qū),且不應(yīng)使用UserBuffer中存儲的地址。對于IOCTL,驅(qū)動程序應(yīng)當(dāng)從系統(tǒng)緩沖區(qū)獲取輸入并將輸出寫入到系統(tǒng)緩沖區(qū)。當(dāng)完成請求時,I/O系統(tǒng)將輸出數(shù)據(jù)從系統(tǒng)緩沖區(qū)復(fù)制到用戶緩沖區(qū)。直接方法(METHOD_IN/OUT_DIRECT)對于讀取和寫入請求,用戶模式緩沖區(qū)會被鎖定,并且會創(chuàng)建一個內(nèi)存描述符列表(MDL)。MDL地址會存儲在IRP的MdlAddress字段中。SystemBuffer和UserBuffer均沒有任
5、何含義。但是,驅(qū)動程序不應(yīng)當(dāng)更改這些字段的值。對于IOCTL請求,如果在METHOD_IN_DIRECT和METHOD_OUT_DIRECT中同時有一個輸出緩沖區(qū),則分配一個系統(tǒng)緩沖區(qū)(SystemBuffer又有了地址)并將輸入數(shù)據(jù)復(fù)制到其中。如果有一個輸出緩沖區(qū),且它被鎖定,則會創(chuàng)建MDL并設(shè)置MdlAddress。UserBuffer字段沒有任何含義。兩者都不方法(METHOD_NEITHER)對于讀取和寫入請求,UserBuffer字段被設(shè)置為指向初始的用戶緩沖區(qū)。不執(zhí)行任何其他操作。SystemAddress和MdlAddress沒有任何含義。對于IOCTL請求,I/O管理器將Use
6、rBuffer設(shè)置為初始的用戶輸出緩沖區(qū),而且,它將當(dāng)前I/O棧位置的設(shè)置為用戶輸入緩沖區(qū)。利用該I/O方法,由驅(qū)動程序來確定如何處理緩沖區(qū):分配系統(tǒng)緩沖區(qū)或創(chuàng)建MDL。通常,驅(qū)動程序在訪問用戶數(shù)據(jù)時不應(yīng)當(dāng)將UserBuffer字段用作地址,即使當(dāng)用戶緩沖區(qū)被鎖定時也是如此。這是由于在調(diào)用驅(qū)動程序時,在系統(tǒng)中可能看不到調(diào)用用戶的地址空間。(對于該規(guī)則的一個例外是,在最高層驅(qū)動程序?qū)RP向下傳遞到較低層的驅(qū)動程序之前,它可能需要使用UserBuffer來復(fù)制數(shù)據(jù)。)如果使用直接或兩者都不方法,在創(chuàng)建MDL之后,驅(qū)動程序可以使用MmGetSystemAddressForMdl函數(shù)來獲取有效的系統(tǒng)
7、地址以訪問用戶緩沖區(qū)。在驅(qū)動層,依傳輸類型的不同,輸入緩沖區(qū)的位置亦不同,見下表。傳輸類型位置METHOD_IN_DIRECTirp-AssociatedIrp.SystemBufferMETHOD_OUT_DIRECTirp-AssociatedIrp.SystemBufferMETHOD_BUFFEREDirp-AssociatedIrp.SystemBufferMETHOD_NEITHER位置METHOD_IN_DIRECTirp-MdlAddressMETHOD_OUT_DIRECTirp-MdlAddressMETHOD_BUFFEREDirp-AssociatedIrp.Syste
8、mBufferMETHOD_NEITHERirp-UserBuffer所以只要確定了傳輸方式后,就可以根據(jù)各自的位置來讀取和寫入數(shù)據(jù),從而實現(xiàn)應(yīng)用層和驅(qū)動的通信。下面看驅(qū)動層對ioctl控制碼的處理代碼:代碼:/METHOD_OUT_DIREC方式NTSTATUSCOMM_DirectOutIo(PIRPIrp,PIO_STACK_LOCATIONpIoStackIrp,UINT*sizeofWrite)NTSTATUSstatus=STATUS_UNSUCCESSFUL;PVOIDpInputBuffer,pOutputBuffer;ULONGoutputLength,inputLength
9、;DbgPrint(COMM_DirectOutIorn);outputLength=inputLength=pInputBuffer=Irp-AssociatedIrp.SystemBuffer;pOutputBuffer=NULL;if(Irp-MdlAddress)pOutputBuffer=MmGetSystemAddressForMdlSafe(Irp-MdlAddress,NormalPagePriority);if(pInputBuffer&pOutputBuffer)DbgPrint(COMM_DirectOutIoUserModeMessage=%s,pInputBuffer
10、);RtlCopyMemory(pOutputBuffer,pInputBuffer,outputLength);*sizeofWrite=outputLength;status=STATUS_SUCCESS;returnstatus;/METHOD_IN_DIRECTNTSTATUSCOMM_DirectInIo(PIRPIrp,PIO_STACK_LOCATIONpIoStackIrp,UINT*sizeofWrite)NTSTATUSstatus=STATUS_UNSUCCESSFUL;PVOIDpInputBuffer,pOutputBuffer;ULONGoutputLength,i
11、nputLength;DbgPrint(COMM_DirectInIorn);outputLength=inputLength=pInputBuffer=Irp-AssociatedIrp.SystemBuffer;pOutputBuffer=NULL;if(Irp-MdlAddress)pOutputBuffer=MmGetSystemAddressForMdlSafe(Irp-MdlAddress,NormalPagePriority);if(pInputBuffer&pOutputBuffer)DbgPrint(COMM_DirectInIoUserModeMessage=%s,pInp
12、utBuffer);RtlCopyMemory(pOutputBuffer,pInputBuffer,outputLength);*sizeofWrite=outputLength;status=STATUS_SUCCESS;returnstatus;/METHOD_BUFFEREDNTSTATUSCOMM_BufferedIo(PIRPIrp,PIO_STACK_LOCATIONpIoStackIrp,UINT*sizeofWrite)NTSTATUSstatus=STATUS_UNSUCCESSFUL;PVOIDpInputBuffer,pOutputBuffer;ULONGoutputL
13、ength,inputLength;DbgPrint(COMM_BufferedIorn);outputLength=inputLength=pInputBuffer=Irp-AssociatedIrp.SystemBuffer;pOutputBuffer=Irp-AssociatedIrp.SystemBuffer;if(pInputBuffer&pOutputBuffer)DbgPrint(COMM_BufferedIoUserModeMessage=%s,pInputBuffer);RtlCopyMemory(pOutputBuffer,pInputBuffer,outputLength
14、);*sizeofWrite=outputLength;status=STATUS_SUCCESS;returnstatus;/METHOD_NEITHERNTSTATUSCOMM_NeitherIo(PIRPIrp,PIO_STACK_LOCATIONpIoStackIrp,UINT*sizeofWrite)NTSTATUSstatus=STATUS_UNSUCCESSFUL;PVOIDpInputBuffer,pOutputBuffer;ULONGoutputLength,inputLength;DbgPrint(COMM_NeitherIorn);outputLength=inputLe
15、ngth=pInputBuffer=pOutputBuffer=Irp-UserBuffer;if(pInputBuffer&pOutputBuffer)DbgPrint(COMM_NeitherIoUserModeMessage=%s,pInputBuffer);RtlCopyMemory(pOutputBuffer,pInputBuffer,outputLength);*sizeofWrite=outputLength;status=STATUS_SUCCESS;returnstatus;代碼比較簡單,都是取得輸入的數(shù)據(jù),然后把數(shù)據(jù)直接拷貝到輸出,傳輸給應(yīng)用層。應(yīng)用層的代碼:procedureTfrmMain.Send_Recv_Data(AInData:String;varAOutData:String;IoctlCode:DWORD);vardwReturn:DWORD;inData:array0.1023ofchar;outData:array0.1023ofchar;beginStrPCopy(inData,AInData);ifm_hCommDevice0thenbeginDeviceIoControl(m_hCommDevice,IoctlCode,inData,Length(inData),outData,Length(outData),dwReturn,nil
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 財報背后的故事財務(wù)報告深度解讀
- 互聯(lián)網(wǎng)房地產(chǎn)案例主題ARVR技術(shù)簡介課件
- 山東2025年01月山東省棗莊市社會保險事業(yè)中心2025年公開招考1名高層次急需緊缺人才筆試歷年典型考題(歷年真題考點)解題思路附帶答案詳解
- 閱讀能力訓(xùn)練在語文教學(xué)中的重要性
- 生涯規(guī)劃與個人成長之間的深度關(guān)聯(lián)
- 質(zhì)量教育在醫(yī)藥行業(yè)中的重要性
- 脛骨骨折護(hù)理指導(dǎo)
- 湖州市2025屆三年級數(shù)學(xué)第二學(xué)期期末質(zhì)量跟蹤監(jiān)視模擬試題含解析
- 湖北孝感美珈職業(yè)學(xué)院《工程生態(tài)學(xué)》2023-2024學(xué)年第二學(xué)期期末試卷
- 黑龍江省鶴崗市綏濱縣2024-2025學(xué)年三年級數(shù)學(xué)第二學(xué)期期末經(jīng)典模擬試題含解析
- 利那洛肽治療便秘病例
- 部編版小學(xué)語文四年級下冊第二單元教材分析
- 2024年OTC焊接機器人基本操作培訓(xùn)
- 參考消息電子版在線閱讀(角度區(qū))
- 小學(xué)五年級《美術(shù)》上冊知識點匯總
- 2024年湖南高速鐵路職業(yè)技術(shù)學(xué)院高職單招(英語/數(shù)學(xué)/語文)筆試歷年參考題庫含答案解析
- 2016-2023年湖南鐵路科技職業(yè)技術(shù)學(xué)院高職單招(英語/數(shù)學(xué)/語文)筆試歷年參考題庫含答案解析
- 2023南頭古城項目簡介招商手冊
- 機修知識培訓(xùn)教材課件
- 跨云平臺的DevOps集成
- 小學(xué)綜合實踐活動《察探究活動跟著節(jié)氣去探究》課教案
評論
0/150
提交評論