生活随笔
收集整理的這篇文章主要介紹了
《Windows驱动开发技术详解》读书笔记(一)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
??首先需要安裝DDK,這里我選擇Microsoft Windows Server 2003 SP1 DDK
Windows驅(qū)動分成兩類,一類是不支持即插即用的NT式驅(qū)動,一類是支持即插即用的WDM驅(qū)動.
首先來看一個最簡單的NT式驅(qū)動。
?
#pragma?once ??#ifdef?__cplusplus ?extern?"C"?{ ?#endif ?#include?<NTDDK.h> ?#ifdef?__cplusplus ?} ?#endif? ??#define?PAGEDCODE?code_seg("PAGE") ?#define?LOCKEDCODE?code_seg() ?#define?INITCODE?code_seg("INIT") ??#define?PAGEDDATA?data_seg("PAGE") ?#define?LOCKEDDATA?data_seg() ?#define?INITDATA?data_seg("INIT") ??#define?arraysize(p)?(sizeof(p)/sizeof((p)[0])) ??typedef?struct?_DEVICE_EXTENSION?{ ?????PDEVICE_OBJECT?pDevice; ?????UNICODE_STRING?ustrDeviceName;?????????UNICODE_STRING?ustrSymLinkName;?????}?DEVICE_EXTENSION,?*PDEVICE_EXTENSION; ???NTSTATUS?CreateDevice?(IN?PDRIVER_OBJECT?pDriverObject); ?VOID?HelloDDKUnload?(IN?PDRIVER_OBJECT?pDriverObject); ?NTSTATUS?HelloDDKDispatchRoutine(IN?PDEVICE_OBJECT?pDevObj, ??????????????????????????????????IN?PIRP?pIrp);? ? Driver.h頭文件中包含了開發(fā)NT式驅(qū)動所需要的NTDDK.h,此外還定義了幾個標志來指明函數(shù)和變量分配在分頁內(nèi)存還是非分頁內(nèi)存中。Windows驅(qū)動程序的入口函數(shù)是DriverEntry函數(shù),
?
#include?"Driver.h" ??????????#pragma?INITCODE ?extern?"C"?NTSTATUS?DriverEntry?( ?????????????IN?PDRIVER_OBJECT?pDriverObject, ?????????????IN?PUNICODE_STRING?pRegistryPath????)? ?{ ?????NTSTATUS?status; ?????KdPrint(("Enter?DriverEntry\n")); ???????????pDriverObject->DriverUnload?=?HelloDDKUnload; ?????pDriverObject->MajorFunction[IRP_MJ_CREATE]?=?HelloDDKDispatchRoutine; ?????pDriverObject->MajorFunction[IRP_MJ_CLOSE]?=?HelloDDKDispatchRoutine; ?????pDriverObject->MajorFunction[IRP_MJ_WRITE]?=?HelloDDKDispatchRoutine; ?????pDriverObject->MajorFunction[IRP_MJ_READ]?=?HelloDDKDispatchRoutine; ????? ??????????status?=?CreateDevice(pDriverObject); ??????KdPrint(("DriverEntry?end\n")); ?????return?status; ?} ?????????#pragma?INITCODE???//指明此函數(shù)加載到INIT內(nèi)存區(qū)域(即只在加載的時候需要載入內(nèi)存,加載成功后可以從內(nèi)存中卸載掉) ?NTSTATUS?CreateDevice?( ?????????IN?PDRIVER_OBJECT????pDriverObject)? ?{ ?????NTSTATUS?status; ?????PDEVICE_OBJECT?pDevObj; ?????PDEVICE_EXTENSION?pDevExt; ????? ??????????UNICODE_STRING?devName; ?????RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice"); ????? ??????????status?=?IoCreateDevice(?pDriverObject, ?????????????????????????sizeof(DEVICE_EXTENSION), ?????????????????????????&(UNICODE_STRING)devName, ?????????????????????????FILE_DEVICE_UNKNOWN,?????????????????????????0,?TRUE, ?????????????????????????&pDevObj?); ?????if?(!NT_SUCCESS(status)) ?????????return?status; ??????pDevObj->Flags?|=?DO_BUFFERED_IO; ?????pDevExt?=?(PDEVICE_EXTENSION)pDevObj->DeviceExtension; ?????pDevExt->pDevice?=?pDevObj; ?????pDevExt->ustrDeviceName?=?devName; ??????????UNICODE_STRING?symLinkName; ?????RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK"); ?????pDevExt->ustrSymLinkName?=?symLinkName; ?????status?=?IoCreateSymbolicLink(?&symLinkName,&devName?); ?????if?(!NT_SUCCESS(status))? ?????{ ?????????IoDeleteDevice(?pDevObj?); ?????????return?status; ?????} ?????return?STATUS_SUCCESS; ?} ?????????#pragma?PAGEDCODE ?VOID?HelloDDKUnload?(IN?PDRIVER_OBJECT?pDriverObject)? ?{?????PDEVICE_OBJECT????pNextObj; ?????KdPrint(("Enter?DriverUnload\n")); ?????pNextObj?=?pDriverObject->DeviceObject; ?????while?(pNextObj?!=?NULL)? ?????{ ?????????PDEVICE_EXTENSION?pDevExt?=?(PDEVICE_EXTENSION) ?????????????pNextObj->DeviceExtension; ???????????????????UNICODE_STRING?pLinkName?=?pDevExt->ustrSymLinkName; ?????????IoDeleteSymbolicLink(&pLinkName); ?????????pNextObj?=?pNextObj->NextDevice; ?????????IoDeleteDevice(?pDevExt->pDevice?); ?????} ?} ??????????#pragma?PAGEDCODE ?NTSTATUS?HelloDDKDispatchRoutine(IN?PDEVICE_OBJECT?pDevObj, ??????????????????????????????????IN?PIRP?pIrp)? ?{ ?????KdPrint(("Enter?HelloDDKDispatchRoutine\n")); ?????NTSTATUS?status?=?STATUS_SUCCESS; ??????????pIrp->IoStatus.Status?=?status; ?????pIrp->IoStatus.Information?=?0;?????????IoCompleteRequest(?pIrp,?IO_NO_INCREMENT?); ?????KdPrint(("Leave?HelloDDKDispatchRoutine\n")); ?????return?status; ?}? 有兩種編譯驅(qū)動的辦法,一種是用DDK環(huán)境來編譯,需要在源代碼所在目錄下創(chuàng)建兩個文件makefile和Sources,
makefile內(nèi)容如下,功能是引入DDK的bin目錄下的makefile.def文件:
!INCLUDE?$(NTMAKEENV)\makefile.def? ?Sources內(nèi)容如下:
TARGETNAME=HelloDDK ?TARGETTYPE=DRIVER ?TARGETPATH=OBJ ?INCLUDES=$(BASEDIR)\inc;\ ??????????$(BASEDIR)\inc\ddk;\ ?SOURCES=Driver.cpp\ ? ?然后在開始菜單中選擇“Windows XP Checked Build Environment”編譯環(huán)境,進入需要編譯的目錄,輸入”build“命令就可以,
編譯后的驅(qū)動位于objchk_wxp_x86"i386目錄下,名為HelloDDK.sys
第二種編譯方式是使用VC++進行編譯
1,用vc新建工程。在"project"選項卡中,選擇win32 Application,選擇一個空的工程。
2,將兩個源文件Driver.h和Driver.cpp拷貝到工程目錄中,并添加到工程中。
3,增加新的編譯版本,去掉Debug 和Release 版本,增加一個Win32 Driver Check Edition
4,修改工程屬性。選擇"Project|Setting",或者直接按下Alt+F7鍵,彈出"Project Settings"。在對話框中,選擇“General”選項卡。將Intermediate files和Output files都改為MyDriver_Check.
5,選擇C/C++選項卡,將原有的Project Options 內(nèi)容全部刪除替換成如下內(nèi)容:
/nologo?/Gz?/MLd?/W3?/WX?/Z7?/Od?/D?WIN32=100?/D?_X86_=1?/D?WINVER=0x500?/D?DBG=1?/Fo"MyDriver_Check/"?/Fd"MyDriver_Check/"?/FD?/c? 6,選擇Link選項卡,將原有的Project Options 內(nèi)容全部刪除,替換成如下內(nèi)容:
ntoskrnl.lib?/nologo?/base:"0x10000"?/stack:0x400000,0x1000?/entry:"DriverEntry"?/subsystem:console?/incremental:no?/pdb:"MyDriver_Check/HelloDDK.pdb"?/map:"MyDriver_Check/HelloDDK.map"?/debug?/machine:I386?/nodefaultlib?/out:"MyDriver_Check/HelloDDK.sys"?/pdbtype:sept?/subsystem:native?/driver?/SECTION:INIT,D?/RELEASE?/IGNORE:4078 ? 7。修改VC的lib目錄和include目錄。
在vc中選擇"Tools"|"Options",在彈出的對話框中選擇“Directories”選項卡。在“Show directories for”下拉菜單中選擇“Include files”菜單,添加
D:\WINDDK\3790.1830\INC\W2K? 和
D:\WINDDK\3790.1830\INC\DDK\W2K? 并將這兩個目錄置于最上。
在"Show directories for "下拉菜單中選擇“Library files”菜單,添加目錄
D:\WINDDK\3790.1830\LIB\W2K\I386? 并置于最上端。
8,按照書上所述的步驟做完后編譯,會報錯如下:
fatal?error?C1083:?Cannot?open?include?file:?'specstrings.h':?No?such?file?or?directory? 原因是include目錄設(shè)置沒完整,加入如下目錄既可以正確編譯
?
D:\WINDDK\3790.1830\INC\CRT? 最后來安裝此驅(qū)動,這里使用Driver Studio3.2.1中的Driver Monitor來完成
?
?
轉(zhuǎn)載于:https://blog.51cto.com/phinecos/368163
總結(jié)
以上是生活随笔為你收集整理的《Windows驱动开发技术详解》读书笔记(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。