如果你確定要使用Visual Studio 2015 編寫驅動,那么在你安裝Visual Studio 2015 和WDK之前,一定一定要注意一件事情,那就是確保SDK和WDK版本保持一致,切記切記!!!否則會出現什么問題,Visual Studio 2015里面宏定義的SDK和系統當前能夠正常使用的不一致,無法正常編譯驅動程序!!!
我今晚先前解決的問題就是這個原因造成的,當時我使用的SDK比WDK版本高,導致Visual Studio 2015宏定義的值全部是高版本的SDK,在編譯驅動時候,無法找到對應的lib和頭文件!!
先前問題和解決方法:http://www.cnblogs.com/sunylat/p/6286289.html
如果你已經出現我這樣的問題了,不要緊,把當前和WDK不匹配的SDK刪除,隨后安裝和當前WDK匹配的SDK就可以了!!
剛剛編譯先前可以正常編譯的UMDF驅動,結果出錯了,查找了一下資料,發現是驅動時間戳驗證問題,解決方法:對工程屬性里面的inf2cat工具的屬性設置為“是”就可以了!如下圖:
參考文章:http://www.yiiyee.cn/Blog/vs2012/
另外我告訴大家,張帆的《windows驅動開發技術詳解》,第一個DDK的例子,我已經順利編譯通過了!需要設置這一步就能夠順利編譯了:工程屬性->C/C++->常規->將警告視為錯誤,把這項修改為“否”!
下面是我編譯的張帆的第一個DDK例子的代碼:
driver.h
/************************************************************************ * 文件名稱:Driver.h * 作 者:張帆 * 完成日期:2007-11-1 *************************************************************************/ #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.cpp
/************************************************************************ * 文件名稱:Driver.cpp * 作 者:張帆 * 完成日期:2007-11-1 *************************************************************************/ #include "Driver.h" /************************************************************************ * 函數名稱:DriverEntry * 功能描述:初始化驅動程序,定位和申請硬件資源,創建內核對象 * 參數列表: pDriverObject:從I/O管理器中傳進來的驅動對象 pRegistryPath:驅動程序在注冊表的中的路徑 * 返回 值:返回初始化驅動狀態 *************************************************************************/ #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; } /************************************************************************ * 函數名稱:CreateDevice * 功能描述:初始化設備對象 * 參數列表: pDriverObject:從I/O管理器中傳進來的驅動對象 * 返回 值:返回初始化狀態 *************************************************************************/ #pragma INITCODE 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; } /************************************************************************ * 函數名稱:HelloDDKUnload * 功能描述:負責驅動程序的卸載操作 * 參數列表: pDriverObject:驅動對象 * 返回 值:返回狀態 *************************************************************************/ #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); } } /************************************************************************ * 函數名稱:HelloDDKDispatchRoutine * 功能描述:對讀IRP進行處理 * 參數列表: pDevObj:功能設備對象 pIrp:從IO請求包 * 返回 值:返回狀態 *************************************************************************/ #pragma PAGEDCODE NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) { KdPrint(("Enter HelloDDKDispatchRoutine\n")); NTSTATUS status = STATUS_SUCCESS; // 完成IRP pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; // bytes xfered IoCompleteRequest(pIrp, IO_NO_INCREMENT); KdPrint(("Leave HelloDDKDispatchRoutine\n")); return status; }