梦织未来Windows驱动编程 第03课 驱动的编程规范
驅(qū)動部分包括基本的驅(qū)動卸載函數(shù)、驅(qū)動打開關(guān)閉讀取寫入操作最簡單的分發(fā)例程。代碼如下:
1 //CreateDevice.c 2 //2016.07.14 3 4 #include "ntddk.h" 5 6 //驅(qū)動卸載函數(shù)Self 7 VOID MyDriverUnload(PDRIVER_OBJECT pDriverObject) 8 { 9 UNICODE_STRING usSymName; 10 RtlInitUnicodeString(&usSymName, L"\\??\\FirstDevice"); 11 12 //先刪除符號鏈接,后刪除設(shè)備對象 13 if (pDriverObject->DeviceObject != NULL) 14 { 15 IoDeleteSymbolicLink(&usSymName); //刪除符號鏈接 16 IoDeleteDevice(pDriverObject->DeviceObject); //刪除設(shè)備對象 17 KdPrint(("Delete Device Sucess.")); 18 } 19 } 20 21 //創(chuàng)建設(shè)備函數(shù)Self 22 NTSTATUS CreateDevice(PDRIVER_OBJECT pDriverObject) 23 { 24 NTSTATUS Status; 25 UNICODE_STRING usDevName; 26 UNICODE_STRING usSymName; 27 PDEVICE_OBJECT pDevObj; //設(shè)備對象,用于指向創(chuàng)建的設(shè)備 28 29 //DDK API 為UNICODE_STRING賦值的函數(shù) 30 RtlInitUnicodeString(&usDevName, L"\\Device\\FirstDevice"); 31 32 //創(chuàng)建設(shè)備函數(shù)API 創(chuàng)建設(shè)備"\\Device\\FirstDevice" 33 //設(shè)備創(chuàng)建后,會返回給pDevObj,同時給pDriverObject->DeviceObject賦值 34 //The IoCreateDevice routine creates a device object for use by a driver. 35 /* 36 NTSTATUS IoCreateDevice( 37 _In_ PDRIVER_OBJECT DriverObject, 38 _In_ ULONG DeviceExtensionSize, 39 _In_opt_ PUNICODE_STRING DeviceName, 40 _In_ DEVICE_TYPE DeviceType, 41 _In_ ULONG DeviceCharacteristics, 42 _In_ BOOLEAN Exclusive, 43 _Out_ PDEVICE_OBJECT *DeviceObject 44 ); 45 */ 46 Status = IoCreateDevice(pDriverObject, 47 0, 48 &usDevName, 49 FILE_DEVICE_UNKNOWN, 50 FILE_DEVICE_SECURE_OPEN, 51 TRUE, 52 &pDevObj); 53 if (!NT_SUCCESS(Status)) //檢查返回值 54 { 55 return Status; 56 } 57 58 //DO_BUFFERED_IO or DO_DIRECT_IO 59 //Specifies the type of buffering that is used by the I/O manager for I/O requests that are sent to the device stack. 60 //Higher-level drivers OR this member with the same value as the next-lower driver in the stack, except possibly for highest-level drivers. 61 pDevObj->Flags |= DO_BUFFERED_IO; 62 63 RtlInitUnicodeString(&usSymName, L"\\??\\FirstDevice"); 64 65 //The IoCreateSymbolicLink routine sets up a symbolic link between a device object name and a user-visible name for the device. 66 /* 67 NTSTATUS IoCreateSymbolicLink( 68 _In_ PUNICODE_STRING SymbolicLinkName, 69 _In_ PUNICODE_STRING DeviceName 70 ); 71 */ 72 Status = IoCreateSymbolicLink(&usSymName, &usDevName); //DDK API 創(chuàng)建符號鏈接 73 if (!NT_SUCCESS(Status)) 74 { 75 IoDeleteDevice(pDevObj); //刪除設(shè)備對象 76 return Status; 77 } 78 79 return STATUS_SUCCESS; 80 } 81 82 //打開設(shè)備的函數(shù) 83 NTSTATUS CreateCompleteRoutine(PDRIVER_OBJECT pDriverObject, PIRP pIrp) 84 { 85 NTSTATUS Status; 86 87 Status = STATUS_SUCCESS; 88 89 KdPrint(("Create")); 90 91 //A driver sets an IRP's I/O status block to indicate the final status of an I/O request, before calling IoCompleteRequest for the IRP. 92 93 //This is the completion status, either STATUS_SUCCESS if the requested operation was completed successfully or an informational, warning, or error STATUS_ XXX value. 94 //For more information, see Using NTSTATUS values. 95 pIrp->IoStatus.Status = Status; 96 //This is the completion status, either STATUS_SUCCESS if the requested operation was completed successfully or an informational, warning, or error STATUS_ XXX value. 97 //For more information, see Using NTSTATUS values. 98 pIrp->IoStatus.Information = 0; 99 100 //The IoCompleteRequest routine indicates that the caller has completed all processing for a given I/O request and is returning the given IRP to the I/O manager. 101 //IO_NO_INCREMENT 不再往下層傳遞 102 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 103 return Status; 104 } 105 106 //關(guān)閉設(shè)備的函數(shù) 107 NTSTATUS CloseCompleteRoutine(PDRIVER_OBJECT pDriverObject, PIRP pIrp) 108 { 109 NTSTATUS Status; 110 111 Status = STATUS_SUCCESS; 112 113 KdPrint(("Close")); 114 115 pIrp->IoStatus.Status = Status; 116 pIrp->IoStatus.Information = 0; 117 118 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 119 return Status; 120 } 121 122 //讀取設(shè)備的函數(shù) 123 NTSTATUS ReadCompleteRoutine(PDRIVER_OBJECT pDriverObject, PIRP pIrp) 124 { 125 NTSTATUS Status; 126 127 Status = STATUS_SUCCESS; 128 129 KdPrint(("Read")); 130 131 pIrp->IoStatus.Status = Status; 132 pIrp->IoStatus.Information = 0; 133 134 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 135 return Status; 136 } 137 138 //寫入設(shè)備的函數(shù) 139 NTSTATUS WriteCompleteRoutine(PDRIVER_OBJECT pDriverObject, PIRP pIrp) 140 { 141 NTSTATUS Status; 142 143 Status = STATUS_SUCCESS; 144 145 KdPrint(("Write")); 146 147 pIrp->IoStatus.Status = Status; 148 pIrp->IoStatus.Information = 0; 149 150 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 151 return Status; 152 } 153 154 //驅(qū)動程序入口函數(shù) 155 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) 156 { 157 //輸出信息 158 //DbgPrint("1111"); 159 160 161 NTSTATUS Status; 162 Status = CreateDevice(pDriverObject); //創(chuàng)建設(shè)備對象和符號鏈接 163 if (!NT_SUCCESS(Status)) 164 { 165 KdPrint(("Create Device Failed.")); 166 } else { 167 KdPrint(("Create Device Sucess.")); 168 KdPrint(("%wZ", pRegistryPath)); 169 } 170 171 //打開關(guān)閉讀取寫入的分發(fā)例程賦值 172 pDriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)CreateCompleteRoutine; //打開設(shè)備 173 pDriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)CloseCompleteRoutine; //關(guān)閉設(shè)備 174 pDriverObject->MajorFunction[IRP_MJ_READ] = (PDRIVER_DISPATCH)ReadCompleteRoutine; //讀取設(shè)備 175 pDriverObject->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH)WriteCompleteRoutine; //寫入設(shè)備 176 177 //驅(qū)動卸載函數(shù)賦值 178 pDriverObject->DriverUnload = MyDriverUnload; 179 180 return STATUS_SUCCESS; 181 } CreateDevice.c
?
應(yīng)用層采用了MFC創(chuàng)建了一個窗口,窗口有三個按鈕:Create、Read、Write。界面如下:
?
其中Create按鈕的處理函數(shù)如下:
1 void CCheckMyDriverDlg::OnCreateButton() 2 { 3 // TODO: 在此添加控件通知處理程序代碼 4 HANDLE hFile = CreateFileW(L"\\\\.\\FirstDevice", 5 FILE_ALL_ACCESS, 6 0, 7 NULL, 8 OPEN_EXISTING, 9 FILE_ATTRIBUTE_NORMAL, 10 NULL); 11 if (hFile == INVALID_HANDLE_VALUE) 12 { 13 AfxMessageBox (L"Open Device Failed."); 14 return; 15 } 16 17 CloseHandle (hFile); 18 }?
Read按鈕的處理函數(shù)如下:
1 void CCheckMyDriverDlg::OnReadButton() 2 { 3 // TODO: 在此添加控件通知處理程序代碼 4 HANDLE hFile = CreateFileW(L"\\\\.\\FirstDevice", 5 FILE_ALL_ACCESS, 6 0, 7 NULL, 8 OPEN_EXISTING, 9 FILE_ATTRIBUTE_NORMAL, 10 NULL); 11 if (hFile == INVALID_HANDLE_VALUE) 12 { 13 AfxMessageBox (L"Open Device Failed."); 14 return; 15 } 16 17 wchar_t Buffer[MAX_PATH] = {0}; 18 DWORD len = 0; 19 if (!ReadFile (hFile, Buffer, MAX_PATH-1, &len, NULL)) 20 { 21 AfxMessageBox (L"Read Device Failed."); 22 return; 23 } 24 25 CloseHandle (hFile); 26 27 }?
Write按鈕的處理函數(shù)如下:
1 void CCheckMyDriverDlg::OnWriteButton() 2 { 3 // TODO: 在此添加控件通知處理程序代碼 4 HANDLE hFile = CreateFileW(L"\\\\.\\FirstDevice", 5 FILE_ALL_ACCESS, 6 0, 7 NULL, 8 OPEN_EXISTING, 9 FILE_ATTRIBUTE_NORMAL, 10 NULL); 11 if (hFile == INVALID_HANDLE_VALUE) 12 { 13 AfxMessageBox (L"Open Device Failed."); 14 return; 15 } 16 17 wchar_t Buffer[MAX_PATH] = L"What The Fuck, Man ?"; 18 DWORD len; 19 if (!WriteFile (hFile, Buffer, MAX_PATH, &len, NULL)) 20 { 21 AfxMessageBox (L"Write Device Failed."); 22 return; 23 } 24 25 CloseHandle (hFile); 26 27 }?
?
?以下為操作部分:
將生成的FirstDevice.sys文件復(fù)制到XP虛擬機(jī)下,使用驅(qū)動加載工具InstDrv安裝并啟動驅(qū)動后,在Dbgview工具內(nèi)有如下輸出信息:
并能夠找到相應(yīng)注冊表,使用WinObj工具查看設(shè)備對象\\Device\\FirstDevice:
然后查看符號鏈接\\??\\FirstDevice:
?
使用InstDrv停止此驅(qū)動時輸出:
?
?期間并未出現(xiàn)藍(lán)屏問題
?
安裝驅(qū)動程序后,使用上面寫的MFC程序CheckMyDriver.exe,點擊Create按鈕后,輸出
?
點擊Read按鈕后,輸出:
?
點擊Write按鈕后,輸出:
?
?
?以上操作均為出現(xiàn)藍(lán)屏。本課結(jié)束。
?
由于本人剛開始學(xué)習(xí)驅(qū)動程序,實力有限,可能對于某些地方的理解并不正確,希望大家能提出意見建議,共同學(xué)習(xí),共同進(jìn)步。
最后謝謝大家的支持。
2016-07-14?14:58:13
轉(zhuǎn)載于:https://www.cnblogs.com/linuxxiaoyu/p/5668153.html
總結(jié)
以上是生活随笔為你收集整理的梦织未来Windows驱动编程 第03课 驱动的编程规范的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 陌生人社会_陌生人之旅
- 下一篇: 第五十期:详解语音识别技术的发展