驅(qū)動(dòng)和應(yīng)用層的三種通信方式_第1頁(yè)
驅(qū)動(dòng)和應(yīng)用層的三種通信方式_第2頁(yè)
驅(qū)動(dòng)和應(yīng)用層的三種通信方式_第3頁(yè)
驅(qū)動(dòng)和應(yīng)用層的三種通信方式_第4頁(yè)
驅(qū)動(dòng)和應(yīng)用層的三種通信方式_第5頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

標(biāo)題:【原創(chuàng)】【成果3.5】驅(qū)動(dòng)和應(yīng)用層的三種通信方式作者:sislcb時(shí)間:2008-01-04,11:57鏈接:/showthread.php?t=57666驅(qū)動(dòng)程序和客戶應(yīng)用程序經(jīng)常需要進(jìn)行數(shù)據(jù)交換,但我們知道驅(qū)動(dòng)程序和客戶應(yīng)用程序可能不在同一個(gè)地址空間,因此操作系統(tǒng)必須解決兩者之間的數(shù)據(jù)交換。驅(qū)動(dòng)層和應(yīng)用層通信,主要是靠DeviceIoControl函數(shù),下面是該函數(shù)的原型:BOOLDeviceIoControl(HANDLEhDevice,//設(shè)備句柄DWORDdwIoControlCode,//IOCTL請(qǐng)求操作代碼LPVOIDlpInBuffer,//輸入緩沖區(qū)地址DWORDnInBufferSize,//輸入緩沖區(qū)大小LPVOIDlpOutBuffer,//輸出緩沖區(qū)地址DWORDnOutBufferSize,//輸出緩沖區(qū)大小LPDWORDlpBytesReturned,//存放返回字節(jié)數(shù)的指針LPOVERLAPPEDlpOverlapped//用于同步操作的Overlapped結(jié)構(gòu)體指針);dwIoControlCode要進(jìn)行操作的控制碼。驅(qū)動(dòng)程序可以通過(guò)CTL_CODE宏來(lái)組合定義一個(gè)控制碼,并在IRP_MJ_DEVICE_CONTROL的實(shí)現(xiàn)中進(jìn)行控制碼的操作。在驅(qū)動(dòng)層,irpStack->Parameters.DeviceIoControl.IoControlCode表示了這個(gè)控制碼。IOCTL請(qǐng)求有四種緩沖策略,下面一一介紹。1、輸入輸出緩沖I/O(METHOD_BUFFERED)2、直接輸入緩沖輸出I/O(METHOD_IN_DIRECT)3、緩沖輸入直接輸出I/O(METHOD_OUT_DIRECT)4、上面三種方法都不是(METHOD_NEITHER)為了對(duì)這些類型更詳細(xì)的描述,請(qǐng)看msdn上的解釋,我抄錄如下:"緩沖”方法(METHOD_BUFFERED)備注:在下面的討論中,〃輸入〃表示數(shù)據(jù)從用戶模式的應(yīng)用程序到驅(qū)動(dòng)程序,〃輸出〃表示數(shù)據(jù)從驅(qū)動(dòng)程序到應(yīng)用程序。對(duì)于讀取請(qǐng)求,I/O管理器分配一個(gè)與用戶模式的緩沖區(qū)大小相同的系統(tǒng)緩沖區(qū)。IRP中的SystemBuffer字段包含系統(tǒng)地址。UserBuffer字段包含初始的用戶緩沖區(qū)地址。當(dāng)完成請(qǐng)求時(shí),I/O管理器將驅(qū)動(dòng)程序已經(jīng)提供的數(shù)據(jù)從系統(tǒng)緩沖區(qū)復(fù)制到用戶緩沖區(qū)。對(duì)于寫(xiě)入請(qǐng)求,會(huì)分配一個(gè)系統(tǒng)緩沖區(qū)并將SystemBuffer設(shè)置為地址。用戶緩沖區(qū)的內(nèi)容會(huì)被復(fù)制到系統(tǒng)緩沖區(qū),但是不設(shè)置UserBuffer。對(duì)于IOCTL請(qǐng)求,會(huì)分配一個(gè)容量大小足以包含輸入緩沖區(qū)或輸出緩沖區(qū)的系統(tǒng)緩沖區(qū),并將SystemBuffer設(shè)置為分配的緩沖區(qū)地址。輸入緩沖區(qū)中的數(shù)據(jù)復(fù)制到系統(tǒng)緩沖區(qū)。UserBuffer字段設(shè)置為用戶模式輸出緩沖區(qū)地址。內(nèi)核模式驅(qū)動(dòng)程序應(yīng)當(dāng)只使用系統(tǒng)緩沖區(qū),且不應(yīng)使用UserBuffer中存儲(chǔ)的地址。對(duì)于IOCTL,驅(qū)動(dòng)程序應(yīng)當(dāng)從系統(tǒng)緩沖區(qū)獲取輸入并將輸出寫(xiě)入到系統(tǒng)緩沖區(qū)。當(dāng)完成請(qǐng)求時(shí),I/O系統(tǒng)將輸出數(shù)據(jù)從系統(tǒng)緩沖區(qū)復(fù)制到用戶緩沖區(qū)?!敝苯?方法(METHOD_IN/OUT_DIRECT)對(duì)于讀取和寫(xiě)入請(qǐng)求,用戶模式緩沖區(qū)會(huì)被鎖定,并且會(huì)創(chuàng)建一個(gè)內(nèi)存描述符列表(MDL)。MDL地址會(huì)存儲(chǔ)在IRP的MdlAddress字段中。SystemBuffer和UserBuffer均沒(méi)有任何含義。但是,驅(qū)動(dòng)程序不應(yīng)當(dāng)更改這些字段的值。對(duì)于IOCTL請(qǐng)求,如果在METHOD_IN_DIRECT和METHOD_OUT_DIRECT中同時(shí)有一個(gè)輸出緩沖區(qū),則分配一個(gè)系統(tǒng)緩沖區(qū)(SystemBuffer又有了地址)并將輸入數(shù)據(jù)復(fù)制到其中。如果有一個(gè)輸出緩沖區(qū),且它被鎖定,則會(huì)創(chuàng)建MDL并設(shè)置MdlAddress。UserBuffer字段沒(méi)有任何含義。”兩者都不”方法(METHOD_NEITHER)對(duì)于讀取和寫(xiě)入請(qǐng)求,UserBuffer字段被設(shè)置為指向初始的用戶緩沖區(qū)。不執(zhí)行任何其他操作。SystemAddress和MdlAddress沒(méi)有任何含義。對(duì)于IOCTL請(qǐng)求,I/O管理器將UserBuffer設(shè)置為初始的用戶輸出緩沖區(qū),而且,它將當(dāng)前I/O棧位置的Parameters.DeviceIoControl.Type3InputBuffer設(shè)置為用戶輸入緩沖區(qū)。利用該I/O方法,由驅(qū)動(dòng)程序來(lái)確定如何處理緩沖區(qū):分配系統(tǒng)緩沖區(qū)或創(chuàng)建MDL。通常,驅(qū)動(dòng)程序在訪問(wèn)用戶數(shù)據(jù)時(shí)不應(yīng)當(dāng)將UserBuffer字段用作地址,即使當(dāng)用戶緩沖區(qū)被鎖定時(shí)也是如此。這是由于在調(diào)用驅(qū)動(dòng)程序時(shí),在系統(tǒng)中可能看不到調(diào)用用戶的地址空間。(對(duì)于該規(guī)則的一個(gè)例外是,在最高層驅(qū)動(dòng)程序?qū)RP向下傳遞到較低層的驅(qū)動(dòng)程序之前,它可能需要使用UserBuffer來(lái)復(fù)制數(shù)據(jù)。)如果使用〃直接〃或〃兩者都不〃方法,在創(chuàng)建MDL之后,驅(qū)動(dòng)程序可以使用MmGetSystemAddressForMdl函數(shù)來(lái)獲取有效的系統(tǒng)地址以訪問(wèn)用戶緩沖區(qū)。在驅(qū)動(dòng)層,依傳輸類型的不同,輸入緩沖區(qū)的位置亦不同,見(jiàn)下表。傳輸類型位置

METHOD_IN_DIRECTirp->AssociatedIrp.SystemBufferMETHOD_OUT_DIRECTirp->AssociatedIrp.SystemBufferMETHOD_BUFFEREDirp->AssociatedIrp.SystemBufferMETHOD_NEITHERirpStack->Parameters.DeviceIoControl.Type3InputBuffer傳輸類型傳輸類型METHOD_IN_DIRECTMETHOD_OUT_DIRECTMETHOD_BUFFEREDystemBufferMETHOD_NEITHER位置irp->MdlAddressirp->MdlAddressirp->AssociatedIrp.Sirp->UserBuffer所以只要確定了傳輸方式后,就可以根據(jù)各自的位置來(lái)讀取和寫(xiě)入數(shù)據(jù),從而實(shí)現(xiàn)應(yīng)用層和驅(qū)動(dòng)的通信。下面看驅(qū)動(dòng)層對(duì)ioctl控制碼的處理代碼:代碼://METHOD_OUT_DIREC方式NTSTATUSCOMM_DirectOutIo(PIRPIrp,PIO_STACK_LOCATIONpIoStackIrp,UINT*sizeofWrite)NTSTATUSstatusSTATUS_UNSUCCESSFUL;PVOIDpInputBuffer,NTSTATUSstatusSTATUS_UNSUCCESSFUL;ULONGoutputLength,inputLength;DbgPrint(〃COMM_DirectOutIo\r\n〃);ULONGoutputLength=pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;inputLength=pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;pInputBuffer=Irp->AssociatedIrp.SystemBuffer;pOutputBuffer=NULL;if(Irp->MdlAddress)pOutputBuffer=MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);if(pInputBuffer&&pOutputBuffer)(DbgPrint("COMM_DirectOutIoUserModeMessage='%s'",pInputBuffer);RtlCopyMemory(pOutputBuffer,pInputBuffer,outputLength);*sizeofWrite=outputLength;status=STATUS_SUCCESS;}}//METHOD_IN_DIRECTNTSTATUSCOMM_DirectInIo(PIRPIrp,PIO_STACK_LOCATIONploStackIrp,UINT*sizeofWrite)(NTSTATUSstatus=STATUS_UNSUCCESSFUL;PVOIDpInputBuffer,pOutputBuffer;ULONGoutputLength,inputLength;DbgPrint(〃COMM_DirectInIo\r\n〃);outputLength=pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;inputLength=pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;pInputBuffer=Irp->AssociatedIrp.SystemBuffer;pOutputBuffer=NULL;if(Irp->MdlAddress)pOutputBuffer=MmGetSystemAddressForMdlSafe(Irp->MdlAddress,NormalPagePriority);if(pInputBuffer&&pOutputBuffer)(DbgPrint(〃COMM_DirectInIoUserModeMessage='%s'",pInputBuffer);RtlCopyMemory(pOutputBuffer,pInputBuffer,outputLength);*sizeofWrite=outputLength;status=STATUS_SUCCESS;}returnstatus;}//METHOD_BUFFEREDNTSTATUSCOMM_BufferedIo(PIRPIrp,PIO_STACK_LOCATIONpIoStackIrp,UINT*sizeofWrite)(NTSTATUSstatus=STATUS_UNSUCCESSFUL;PVOIDpInputBuffer,pOutputBuffer;ULONGoutputLength,inputLength;DbgPrint("COMM_BufferedIo\r\n");outputLength=pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;inputLength=pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;pInputBuffer=Irp->AssociatedIrp.SystemBuffer;pOutputBuffer=Irp->AssociatedIrp.SystemBuffer;if(pInputBuffer&&pOutputBuffer)(DbgPrint("COMM_BufferedIoUserModeMessage='%s'〃,pInputBuffer);RtlCopyMemory(pOutputBuffer,pInputBuffer,outputLength);*sizeofWrite=outputLength;status=STATUS_SUCCESS;}returnstatus;}//METHOD_NEITHERNTSTATUSCOMM_NeitherIo(PIRPIrp,PIO_STACK_LOCATIONpIoStackIrp,UINT*sizeofWrite)(NTSTATUSstatus=STATUS_UNSUCCESSFUL;PVOIDpInputBuffer,pOutputBuffer;ULONGoutputLength,inputLength;DbgPrint(〃COMM_NeitherIo\r\n〃);outputLength=pIoStackIrp->Parameters.DeviceIoControl.OutputBufferLength;inputLength=pIoStackIrp->Parameters.DeviceIoControl.InputBufferLength;pInputBuffer=pIoStackIrp->Parameters.DeviceIoControl.Type3InputBuffer;pOutputBuffer=Irp->UserBuffer;if(pInputBuffer&&pOutputBuffer)(DbgPrint("COMM_NeitherIoUserModeMessage='%s'〃,pInputBuffer);RtlCopyMemory(pOutputBuffer,pInputBuffer,outputLength);*sizeofWrite=outputLength;status=STATUS_SUCCESS;}returnstatus;}代碼比較簡(jiǎn)單,都是取

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論