菜鳥之驅動開發2

來源:互聯網
上載者:User

 

在上一篇文章裡我們寫了第一個驅動程式-HelloWorld, 今天我們來完善它,主要完成兩個功能:添加一個驅動裝置與給驅動添加預設派遣(IRP)。

首先我們來完成第一個功能:添加一個驅動裝置。

代碼如下:

 

NTSTATUS CreateTheDevice(IN PDRIVER_OBJECT pDeviceObject){NTSTATUS status;PDEVICE_OBJECT pDevObj;UNICODE_STRING devName;UNICODE_STRING symLinkName;RtlInitUnicodeString(&devName, L"\\Device\\first_Device");//create devicestatus = IoCreateDevice(pDeviceObject,\0,\&devName,\FILE_DEVICE_UNKNOWN,\0,\TRUE,\&pDevObj\);if (!NT_SUCCESS(status)){if (STATUS_INSUFFICIENT_RESOURCES == status){KdPrint(("資源不足"));}if (STATUS_OBJECT_NAME_EXISTS == status){KdPrint(("指定對象名存在"));}if (STATUS_OBJECT_NAME_COLLISION == status){KdPrint(("//對象名有衝突"));}        KdPrint(("裝置建立失敗"));return status;}KdPrint(("建立裝置成功"));pDevObj->Flags |= DO_BUFFERED_IO;//建立符號連結RtlInitUnicodeString(&symLinkName,L"\\??\\firstSymDevice");status = IoCreateSymbolicLink( &symLinkName,&devName );if (!NT_SUCCESS(status)) /*status等於0*/{IoDeleteDevice( pDevObj );return status;}return STATUS_SUCCESS;}

這樣就可以給我們的驅動加入一個裝置,驅動開發是unicode的方式,所以不能直接用使用者態的API去處理字串,必須用Rtl開頭的核心功能,如上面RtlInitUnicodeString就是給第一個參數初始化。

第二個功能是關於IRP的,什麼叫IRP(I/O Request  Package).使用者模式下所有對驅動的I/O請求,全部由作業系統轉化為一個叫著IRP的資料結構,不同的IRP請求會被“派遣”到不同的派遣函數中。

有五種常用IRP類型,分別是:

#define IRP_MJ_CREATE                     0x00 //CreateFile()#define IRP_MJ_CLOSE                      0x02 //CloseHandle()  #define IRP_MJ_READ                       0x03//ReadFile#define IRP_MJ_WRITE                      0x04//WriteFile#define IRP_MJ_DEVICE_CONTROL           0x0e//DeviceIoControl 

步驟是:

1.建立IRP處理函數

2.在驅動入口外註冊IRP處理髮函數

3.實現IRP處理函數

有兩種方式註冊IRP派遣函數,第一種是只有一個派遣函數,在該派遣函數內分別對根據IRP類型做不同的處理,這種方式代碼如下:

//註冊派遺函數pDriverObject->MajorFunction[IRP_MJ_CREATE]=ddk_DispatchRoutine;//註冊派遺函數pDriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine;//註冊派遺函數pDriverObject->MajorFunction[IRP_MJ_READ]=ddk_DispatchRoutine;//註冊派遺函數pDriverObject->MajorFunction[IRP_MJ_WRITE]=ddk_DispatchRoutine;//註冊派遺函數pDriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL]=ddk_DispatchRoutine;NTSTATUS ddk_DispatchRoutine(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp){   PIO_STACK_LOCATION irpsp=IoGetCurrentIrpStackLocation(pIrp);   switch (irpsp->MajorFunction)    {   case IRP_MJ_CREATE:   break;   case IRP_MJ_CLOSE:   break;   case IRP_MJ_READ:   break;   case IRP_MJ_WRITE:   break;   case  IRP_MJ_DEVICE_CONTROL:   break;   default:     KdPrint(("其它處理"));//指示完成此IRP    } //成功返回return STATUS_SUCCESS;}

 

第二種是對每一種類型的IRP註冊一個派遣函數,代碼如下:

 

//註冊派遺函數pDriverObject->MajorFunction[IRP_MJ_CREATE]=ddk_DispatchRoutine_CREATE;//註冊派遺函數pDriverObject->MajorFunction[IRP_MJ_CLOSE]=ddk_DispatchRoutine_CLOSE;//註冊派遺函數pDriverObject->MajorFunction[IRP_MJ_READ]=ddk_DispatchRoutine_READ;//註冊派遺函數pDriverObject->MajorFunction[IRP_MJ_WRITE]=ddk_DispatchRoutine_WRITE;//註冊派遺函數pDriverObject->MajorFunction[ IRP_MJ_DEVICE_CONTROL]=ddk_DispatchRoutine_CONTROL;NTSTATUS ddk_DispatchRoutine_CONTROL(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp){    //對相應的IPR進行處理   pIrp->IoStatus.Information=0;//設定作業的位元組數為0,這裡無實際意義   pIrp->IoStatus.Status=STATUS_SUCCESS;//返回成功   IoCompleteRequest(pIrp,IO_NO_INCREMENT);//指示完成此IRP   KdPrint(("離開派遣函數\n"));//調試資訊   return STATUS_SUCCESS; //返回成功}

到此代碼介紹完畢, 記得在卸載驅動的時候,要卸載裝置,不然下次載入驅動的時候,因為裝置沒有卸載而不能成功建立裝置。請參看完整的源碼 。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.