新手学VS2013+WDK8.1编写window驱动(1)

图中红框处为最近学习windows系统驱动的成果.虽然这在高手来看挺简单,但在与新手来讲确是一个很高的起步点.不仅仅要克服注册表,inf文件编写,驱动的编写.还涉及windows的原理性东西.

我的项目环境是vs2013和wdk8.1.  vs2013不需要任何的设置,编写好文件后,点击F7编译生成,就会自动生成一个inf文件和sys文件.

vs2013和WDK8.1可在微软官网下载,下载WDK8.1后安装,这时在vs2013的Vc中会出现:

我们选择WDM进行建立方案.方案名为WDMDriver.

HelloWDM项目的建立如下:

注意inf会自动生成一个,但是节不全,需要自己添加哦!

WDMDriver.inf文件代码如下:
  1. <STRONG><SPAN style="FONT-SIZE: 18px">;; The Win2K DDK documentation contains an excellent INF reference.  
  2.   
  3.   
  4. ;--------- Version Section ---------------------------------------------------  
  5.   
  6.   
  7. [Version]  
  8. Signature="$CHICAGO$"  
  9. Provider=jinzihan  
  10. DriverVer=12/12/2013,15.18.43.886  
  11. CatalogFile=WDMDriver.cat;生成的inf中没有填写,此处需要自己添加:名字.cat.此处重点  
  12. ; If device fits one of the standard classes, use the name and GUID here,  
  13. ; otherwise create your own device class and GUID as this example shows.  
  14.   
  15.   
  16. Class=QT;随便改个就行  
  17. ClassGUID={EF2962F0-0D55-4bff-B8AA-2221EE8A79AB};随便改个就行,不要与已有的冲突class和calssguid都有个对应关系.网上可查  
  18.   
  19.   
  20.   
  21.   
  22. ;--------- SourceDiskNames and SourceDiskFiles Section -----------------------  
  23.   
  24.   
  25. ; These sections identify source disks and files for installation. They are  
  26. ; shown here as an example, but commented out.  
  27.   
  28.   
  29. [SourceDisksNames]  
  30. 1 = %DiskName%,,,""  
  31.   
  32.   
  33. [SourceDisksFiles]  
  34. WDMDriver.sys = 1,,  
  35.   
  36.   
  37. ;--------- ClassInstall/ClassInstall32 Section -------------------------------  
  38.   
  39.   
  40. ; Not necessary if using a standard class  
  41.   
  42.   
  43. ; 9X Style  
  44. [ClassInstall]  
  45. Addreg=Class_AddReg  
  46.   
  47.   
  48. ; NT Style  
  49. [ClassInstall32]  
  50. Addreg=Class_AddReg  
  51.   
  52.   
  53. [Class_AddReg]  
  54. HKR,,,,%DeviceClassName%  
  55. HKR,,Icon,,"-5"  
  56.   
  57.   
  58. ;--------- DestinationDirs Section -------------------------------------------  
  59.   
  60.   
  61. [DestinationDirs]  
  62. YouMark_Files_Driver = 10,System32\Drivers  
  63.   
  64.   
  65. ;--------- Manufacturer and Models Sections ----------------------------------  
  66.   
  67.   
  68. [Manufacturer]  
  69. %MfgName%=Mfg0  
  70.   
  71.   
  72. [Mfg0]  
  73.   
  74.   
  75. ; PCI hardware Ids use the form  
  76. ; PCI\VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd  
  77. ;改成你自己的ID  
  78. %DeviceDesc%=YouMark_DDI, PCI\VEN_9999&DEV_9999  
  79.   
  80.   
  81. ;---------- DDInstall Sections -----------------------------------------------  
  82. ; --------- Windows 9X -----------------  
  83.   
  84.   
  85. ; Experimentation has shown that DDInstall root names greater than 19 characters  
  86. ; cause problems in Windows 98  
  87.   
  88.   
  89. [YouMark_DDI]  
  90. CopyFiles=YouMark_Files_Driver  
  91. AddReg=YouMark_9X_AddReg  
  92.   
  93.   
  94. [YouMark_9X_AddReg]  
  95. HKR,,DevLoader,,*ntkern  
  96. HKR,,NTMPDriver,,WDMDriver.sys  
  97. HKR, "Parameters", "BreakOnEntry", 0x00010001, 0  
  98.   
  99.   
  100. ; --------- Windows NT -----------------  
  101.   
  102.   
  103. [YouMark_DDI.NT]  
  104. CopyFiles=YouMark_Files_Driver  
  105. AddReg=YouMark_NT_AddReg  
  106.   
  107.   
  108. [YouMark_DDI.NT.Services]  
  109. Addservice = WDMDriver, 0x00000002, YouMark_AddService  
  110.   
  111.   
  112. [YouMark_AddService]  
  113. DisplayName = %SvcDesc%  
  114. ServiceType = 1 ; SERVICE_KERNEL_DRIVER  
  115. StartType = 3 ; SERVICE_DEMAND_START  
  116. ErrorControl = 1 ; SERVICE_ERROR_NORMAL  
  117. ServiceBinary = %10%\System32\Drivers\WDMDriver.sys  
  118.   
  119.   
  120. [YouMark_NT_AddReg]  
  121. HKLM, "System\CurrentControlSet\Services\WDMDriver\Parameters",\  
  122. "BreakOnEntry", 0x00010001, 0  
  123.   
  124.   
  125.   
  126.   
  127. ; --------- Files (common) -------------  
  128.   
  129.   
  130. [YouMark_Files_Driver]  
  131. WDMDriver.sys  
  132.   
  133.   
  134. ;--------- Strings Section ---------------------------------------------------  
  135.   
  136.   
  137. [Strings]  
  138. ProviderName="jinzihan"  
  139. MfgName="Zhangfan Soft"  
  140. DeviceDesc="QQ761153454";设备管理器中的显示的实例的名字.在类的下边显示  
  141. DeviceClassName="QT218967017";此为显示在设备管理器中的类的名字.在实例的上边显示.修改一次类的名字,就需要更改一次classguid的值.  
  142. SvcDesc="jinzihan"  
  143.   
  144.   
  145.   
  146.   
  147. ;inf结束inf中没有的节,可以参照我的inf自己添加.</SPAN></STRONG>  
;; The Win2K DDK documentation contains an excellent INF reference.


;--------- Version Section ---------------------------------------------------


[Version]
Signature="$CHICAGO$"
Provider=jinzihan
DriverVer=12/12/2013,15.18.43.886
CatalogFile=WDMDriver.cat;生成的inf中没有填写,此处需要自己添加:名字.cat.此处重点
; If device fits one of the standard classes, use the name and GUID here,
; otherwise create your own device class and GUID as this example shows.


Class=QT;随便改个就行
ClassGUID={EF2962F0-0D55-4bff-B8AA-2221EE8A79AB};随便改个就行,不要与已有的冲突class和calssguid都有个对应关系.网上可查




;--------- SourceDiskNames and SourceDiskFiles Section -----------------------


; These sections identify source disks and files for installation. They are
; shown here as an example, but commented out.


[SourceDisksNames]
1 = %DiskName%,,,""


[SourceDisksFiles]
WDMDriver.sys = 1,,


;--------- ClassInstall/ClassInstall32 Section -------------------------------


; Not necessary if using a standard class


; 9X Style
[ClassInstall]
Addreg=Class_AddReg


; NT Style
[ClassInstall32]
Addreg=Class_AddReg


[Class_AddReg]
HKR,,,,%DeviceClassName%
HKR,,Icon,,"-5"


;--------- DestinationDirs Section -------------------------------------------


[DestinationDirs]
YouMark_Files_Driver = 10,System32\Drivers


;--------- Manufacturer and Models Sections ----------------------------------


[Manufacturer]
%MfgName%=Mfg0


[Mfg0]


; PCI hardware Ids use the form
; PCI\VEN_aaaa&DEV_bbbb&SUBSYS_cccccccc&REV_dd
;改成你自己的ID
%DeviceDesc%=YouMark_DDI, PCI\VEN_9999&DEV_9999


;---------- DDInstall Sections -----------------------------------------------
; --------- Windows 9X -----------------


; Experimentation has shown that DDInstall root names greater than 19 characters
; cause problems in Windows 98


[YouMark_DDI]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_9X_AddReg


[YouMark_9X_AddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,WDMDriver.sys
HKR, "Parameters", "BreakOnEntry", 0x00010001, 0


; --------- Windows NT -----------------


[YouMark_DDI.NT]
CopyFiles=YouMark_Files_Driver
AddReg=YouMark_NT_AddReg


[YouMark_DDI.NT.Services]
Addservice = WDMDriver, 0x00000002, YouMark_AddService


[YouMark_AddService]
DisplayName = %SvcDesc%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\System32\Drivers\WDMDriver.sys


[YouMark_NT_AddReg]
HKLM, "System\CurrentControlSet\Services\WDMDriver\Parameters",\
"BreakOnEntry", 0x00010001, 0




; --------- Files (common) -------------


[YouMark_Files_Driver]
WDMDriver.sys


;--------- Strings Section ---------------------------------------------------


[Strings]
ProviderName="jinzihan"
MfgName="Zhangfan Soft"
DeviceDesc="QQ761153454";设备管理器中的显示的实例的名字.在类的下边显示
DeviceClassName="QT218967017";此为显示在设备管理器中的类的名字.在实例的上边显示.修改一次类的名字,就需要更改一次classguid的值.
SvcDesc="jinzihan"




;inf结束inf中没有的节,可以参照我的inf自己添加.



驱动主体HelloWDM.cpp文件:

  1. <STRONG><SPAN style="FONT-SIZE: 18px">/************************************************************************ 
  2. * 文件名称:HelloWDM.cpp 
  3. * 作    者:张帆 
  4. * 完成日期:2007-11-1 
  5. *************************************************************************/  
  6. #include "HelloWDM.h"   
  7.   
  8. /************************************************************************ 
  9. * 函数名称:DriverEntry 
  10. * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象 
  11. * 参数列表: 
  12. pDriverObject:从I/O管理器中传进来的驱动对象 
  13. pRegistryPath:驱动程序在注册表的中的路径 
  14. * 返回 值:返回初始化驱动状态 
  15. *************************************************************************/  
  16. #pragma INITCODE    
  17. extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,  
  18.     IN PUNICODE_STRING pRegistryPath)  
  19. {  
  20.     KdPrint(("jinzihan Enter DriverEntry\n"));  
  21.   
  22.     pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;  
  23.     pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;  
  24.     pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =  
  25.         pDriverObject->MajorFunction[IRP_MJ_CREATE] =  
  26.         pDriverObject->MajorFunction[IRP_MJ_READ] =  
  27.         pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;  
  28.     pDriverObject->DriverUnload = HelloWDMUnload;  
  29.   
  30.     KdPrint(("Leave DriverEntry\n"));  
  31.     return STATUS_SUCCESS;  
  32. }  
  33.   
  34. /************************************************************************ 
  35. * 函数名称:HelloWDMAddDevice 
  36. * 功能描述:添加新设备 
  37. * 参数列表: 
  38. DriverObject:从I/O管理器中传进来的驱动对象 
  39. PhysicalDeviceObject:从I/O管理器中传进来的物理设备对象 
  40. * 返回 值:返回添加新设备状态 
  41. *************************************************************************/  
  42. #pragma PAGEDCODE   
  43. NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,  
  44.     IN PDEVICE_OBJECT PhysicalDeviceObject)  
  45. {  
  46.     PAGED_CODE();  
  47.     KdPrint(("Enter HelloWDMAddDevice123\n"));  
  48.   
  49.     NTSTATUS status;  
  50.     PDEVICE_OBJECT fdo;  
  51.     UNICODE_STRING devName;  
  52.     RtlInitUnicodeString(&devName, L"\\Device\\MyWDMDevice");  
  53.     status = IoCreateDevice(  
  54.         DriverObject,  
  55.         sizeof(DEVICE_EXTENSION),  
  56.         &(UNICODE_STRING)devName,  
  57.         FILE_DEVICE_UNKNOWN,  
  58.         0,  
  59.         FALSE,  
  60.         &fdo);  
  61.     if (!NT_SUCCESS(status))  
  62.         return status;  
  63.     PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;  
  64.     pdx->fdo = fdo;  
  65.     pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);  
  66.     UNICODE_STRING symLinkName;  
  67.     RtlInitUnicodeString(&symLinkName, L"\\DosDevices\\HelloWDM");  
  68.   
  69.     pdx->ustrDeviceName = devName;  
  70.     pdx->ustrSymLinkName = symLinkName;  
  71.     status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName, &(UNICODE_STRING)devName);  
  72.   
  73.     if (!NT_SUCCESS(status))  
  74.     {  
  75.         IoDeleteSymbolicLink(&pdx->ustrSymLinkName);  
  76.         status = IoCreateSymbolicLink(&symLinkName, &devName);  
  77.         if (!NT_SUCCESS(status))  
  78.         {  
  79.             return status;  
  80.         }  
  81.     }  
  82.   
  83.     fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;  
  84.     fdo->Flags &= ~DO_DEVICE_INITIALIZING;  
  85.   
  86.     KdPrint(("Leave HelloWDMAddDevice\n"));  
  87.     return STATUS_SUCCESS;  
  88. }  
  89.   
  90. /************************************************************************ 
  91. * 函数名称:DefaultPnpHandler 
  92. * 功能描述:对PNP IRP进行缺省处理 
  93. * 参数列表: 
  94. pdx:设备对象的扩展 
  95. Irp:从IO请求包 
  96. * 返回 值:返回状态 
  97. *************************************************************************/  
  98. #pragma PAGEDCODE   
  99. NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)  
  100. {  
  101.     PAGED_CODE();  
  102.     KdPrint(("Enter DefaultPnpHandler\n"));  
  103.     IoSkipCurrentIrpStackLocation(Irp);  
  104.     KdPrint(("Leave DefaultPnpHandler\n"));  
  105.     return IoCallDriver(pdx->NextStackDevice, Irp);  
  106. }  
  107.   
  108. /************************************************************************ 
  109. * 函数名称:HandleRemoveDevice 
  110. * 功能描述:对IRP_MN_REMOVE_DEVICE IRP进行处理 
  111. * 参数列表: 
  112. fdo:功能设备对象 
  113. Irp:从IO请求包 
  114. * 返回 值:返回状态 
  115. *************************************************************************/  
  116. #pragma PAGEDCODE   
  117. NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)  
  118. {  
  119.     PAGED_CODE();  
  120.     KdPrint(("Enter HandleRemoveDevice\n"));  
  121.   
  122.     Irp->IoStatus.Status = STATUS_SUCCESS;  
  123.     NTSTATUS status = DefaultPnpHandler(pdx, Irp);  
  124.     IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName);  
  125.   
  126.     //调用IoDetachDevice()把fdo从设备栈中脱开:   
  127.     if (pdx->NextStackDevice)  
  128.         IoDetachDevice(pdx->NextStackDevice);  
  129.   
  130.     //删除fdo:   
  131.     IoDeleteDevice(pdx->fdo);  
  132.     KdPrint(("Leave HandleRemoveDevice\n"));  
  133.     return status;  
  134. }  
  135.   
  136. /************************************************************************ 
  137. * 函数名称:HelloWDMPnp 
  138. * 功能描述:对即插即用IRP进行处理 
  139. * 参数列表: 
  140. fdo:功能设备对象 
  141. Irp:从IO请求包 
  142. * 返回 值:返回状态 
  143. *************************************************************************/  
  144. #pragma PAGEDCODE   
  145. NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,  
  146.     IN PIRP Irp)  
  147. {  
  148.     PAGED_CODE();  
  149.   
  150.     KdPrint(("Enter HelloWDMPnp\n"));  
  151.     NTSTATUS status = STATUS_SUCCESS;  
  152.     PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;  
  153.     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);  
  154.     static NTSTATUS(*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =  
  155.     {  
  156.         DefaultPnpHandler,      // IRP_MN_START_DEVICE   
  157.         DefaultPnpHandler,      // IRP_MN_QUERY_REMOVE_DEVICE   
  158.         HandleRemoveDevice,     // IRP_MN_REMOVE_DEVICE   
  159.         DefaultPnpHandler,      // IRP_MN_CANCEL_REMOVE_DEVICE   
  160.         DefaultPnpHandler,      // IRP_MN_STOP_DEVICE   
  161.         DefaultPnpHandler,      // IRP_MN_QUERY_STOP_DEVICE   
  162.         DefaultPnpHandler,      // IRP_MN_CANCEL_STOP_DEVICE   
  163.         DefaultPnpHandler,      // IRP_MN_QUERY_DEVICE_RELATIONS   
  164.         DefaultPnpHandler,      // IRP_MN_QUERY_INTERFACE   
  165.         DefaultPnpHandler,      // IRP_MN_QUERY_CAPABILITIES   
  166.         DefaultPnpHandler,      // IRP_MN_QUERY_RESOURCES   
  167.         DefaultPnpHandler,      // IRP_MN_QUERY_RESOURCE_REQUIREMENTS   
  168.         DefaultPnpHandler,      // IRP_MN_QUERY_DEVICE_TEXT   
  169.         DefaultPnpHandler,      // IRP_MN_FILTER_RESOURCE_REQUIREMENTS   
  170.         DefaultPnpHandler,      //    
  171.         DefaultPnpHandler,      // IRP_MN_READ_CONFIG   
  172.         DefaultPnpHandler,      // IRP_MN_WRITE_CONFIG   
  173.         DefaultPnpHandler,      // IRP_MN_EJECT   
  174.         DefaultPnpHandler,      // IRP_MN_SET_LOCK   
  175.         DefaultPnpHandler,      // IRP_MN_QUERY_ID   
  176.         DefaultPnpHandler,      // IRP_MN_QUERY_PNP_DEVICE_STATE   
  177.         DefaultPnpHandler,      // IRP_MN_QUERY_BUS_INFORMATION   
  178.         DefaultPnpHandler,      // IRP_MN_DEVICE_USAGE_NOTIFICATION   
  179.         DefaultPnpHandler,      // IRP_MN_SURPRISE_REMOVAL   
  180.     };  
  181.   
  182.     ULONG fcn = stack->MinorFunction;  
  183.     if (fcn >= arraysize(fcntab))  
  184.     {                       // unknown function   
  185.         status = DefaultPnpHandler(pdx, Irp); // some function we don't know about   
  186.         return status;  
  187.     }                       // unknown function   
  188.   
  189. #if DBG   
  190.     static char* fcnname[] =  
  191.     {  
  192.         "IRP_MN_START_DEVICE",  
  193.         "IRP_MN_QUERY_REMOVE_DEVICE",  
  194.         "IRP_MN_REMOVE_DEVICE",  
  195.         "IRP_MN_CANCEL_REMOVE_DEVICE",  
  196.         "IRP_MN_STOP_DEVICE",  
  197.         "IRP_MN_QUERY_STOP_DEVICE",  
  198.         "IRP_MN_CANCEL_STOP_DEVICE",  
  199.         "IRP_MN_QUERY_DEVICE_RELATIONS",  
  200.         "IRP_MN_QUERY_INTERFACE",  
  201.         "IRP_MN_QUERY_CAPABILITIES",  
  202.         "IRP_MN_QUERY_RESOURCES",  
  203.         "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",  
  204.         "IRP_MN_QUERY_DEVICE_TEXT",  
  205.         "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",  
  206.         "",  
  207.         "IRP_MN_READ_CONFIG",  
  208.         "IRP_MN_WRITE_CONFIG",  
  209.         "IRP_MN_EJECT",  
  210.         "IRP_MN_SET_LOCK",  
  211.         "IRP_MN_QUERY_ID",  
  212.         "IRP_MN_QUERY_PNP_DEVICE_STATE",  
  213.         "IRP_MN_QUERY_BUS_INFORMATION",  
  214.         "IRP_MN_DEVICE_USAGE_NOTIFICATION",  
  215.         "IRP_MN_SURPRISE_REMOVAL",  
  216.     };  
  217.   
  218.     KdPrint(("PNP Request (%s)\n", fcnname[fcn]));  
  219. #endif // DBG   
  220.   
  221.     status = (*fcntab[fcn])(pdx, Irp);  
  222.     KdPrint(("Leave HelloWDMPnp\n"));  
  223.     return status;  
  224. }  
  225.   
  226. /************************************************************************ 
  227. * 函数名称:HelloWDMDispatchRoutine 
  228. * 功能描述:对缺省IRP进行处理 
  229. * 参数列表: 
  230. fdo:功能设备对象 
  231. Irp:从IO请求包 
  232. * 返回 值:返回状态 
  233. *************************************************************************/  
  234. #pragma PAGEDCODE   
  235. NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,  
  236.     IN PIRP Irp)  
  237. {  
  238.     PAGED_CODE();  
  239.     KdPrint(("Enter HelloWDMDispatchRoutine\n"));  
  240.     Irp->IoStatus.Status = STATUS_SUCCESS;  
  241.     Irp->IoStatus.Information = 0;   // no bytes xfered   
  242.     IoCompleteRequest(Irp, IO_NO_INCREMENT);  
  243.     KdPrint(("Leave HelloWDMDispatchRoutine\n"));  
  244.     return STATUS_SUCCESS;  
  245. }  
  246.   
  247. /************************************************************************ 
  248. * 函数名称:HelloWDMUnload 
  249. * 功能描述:负责驱动程序的卸载操作 
  250. * 参数列表: 
  251. DriverObject:驱动对象 
  252. * 返回 值:返回状态 
  253. *************************************************************************/  
  254. #pragma PAGEDCODE   
  255. void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject)  
  256. {  
  257.     PAGED_CODE();  
  258.     KdPrint(("Enter HelloWDMUnload\n"));  
  259.     KdPrint(("Leave HelloWDMUnload\n"));  
  260. }</SPAN></STRONG>  
/************************************************************************
* 文件名称:HelloWDM.cpp
* 作    者:张帆
* 完成日期:2007-11-1
*************************************************************************/
#include "HelloWDM.h"

/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
pDriverObject:从I/O管理器中传进来的驱动对象
pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE 
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
	IN PUNICODE_STRING pRegistryPath)
{
	KdPrint(("jinzihan Enter DriverEntry\n"));

	pDriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
	pDriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
		pDriverObject->MajorFunction[IRP_MJ_CREATE] =
		pDriverObject->MajorFunction[IRP_MJ_READ] =
		pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;
	pDriverObject->DriverUnload = HelloWDMUnload;

	KdPrint(("Leave DriverEntry\n"));
	return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:HelloWDMAddDevice
* 功能描述:添加新设备
* 参数列表:
DriverObject:从I/O管理器中传进来的驱动对象
PhysicalDeviceObject:从I/O管理器中传进来的物理设备对象
* 返回 值:返回添加新设备状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
	IN PDEVICE_OBJECT PhysicalDeviceObject)
{
	PAGED_CODE();
	KdPrint(("Enter HelloWDMAddDevice123\n"));

	NTSTATUS status;
	PDEVICE_OBJECT fdo;
	UNICODE_STRING devName;
	RtlInitUnicodeString(&devName, L"\\Device\\MyWDMDevice");
	status = IoCreateDevice(
		DriverObject,
		sizeof(DEVICE_EXTENSION),
		&(UNICODE_STRING)devName,
		FILE_DEVICE_UNKNOWN,
		0,
		FALSE,
		&fdo);
	if (!NT_SUCCESS(status))
		return status;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	pdx->fdo = fdo;
	pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
	UNICODE_STRING symLinkName;
	RtlInitUnicodeString(&symLinkName, L"\\DosDevices\\HelloWDM");

	pdx->ustrDeviceName = devName;
	pdx->ustrSymLinkName = symLinkName;
	status = IoCreateSymbolicLink(&(UNICODE_STRING)symLinkName, &(UNICODE_STRING)devName);

	if (!NT_SUCCESS(status))
	{
		IoDeleteSymbolicLink(&pdx->ustrSymLinkName);
		status = IoCreateSymbolicLink(&symLinkName, &devName);
		if (!NT_SUCCESS(status))
		{
			return status;
		}
	}

	fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
	fdo->Flags &= ~DO_DEVICE_INITIALIZING;

	KdPrint(("Leave HelloWDMAddDevice\n"));
	return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:DefaultPnpHandler
* 功能描述:对PNP IRP进行缺省处理
* 参数列表:
pdx:设备对象的扩展
Irp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)
{
	PAGED_CODE();
	KdPrint(("Enter DefaultPnpHandler\n"));
	IoSkipCurrentIrpStackLocation(Irp);
	KdPrint(("Leave DefaultPnpHandler\n"));
	return IoCallDriver(pdx->NextStackDevice, Irp);
}

/************************************************************************
* 函数名称:HandleRemoveDevice
* 功能描述:对IRP_MN_REMOVE_DEVICE IRP进行处理
* 参数列表:
fdo:功能设备对象
Irp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
	PAGED_CODE();
	KdPrint(("Enter HandleRemoveDevice\n"));

	Irp->IoStatus.Status = STATUS_SUCCESS;
	NTSTATUS status = DefaultPnpHandler(pdx, Irp);
	IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName);

	//调用IoDetachDevice()把fdo从设备栈中脱开:
	if (pdx->NextStackDevice)
		IoDetachDevice(pdx->NextStackDevice);

	//删除fdo:
	IoDeleteDevice(pdx->fdo);
	KdPrint(("Leave HandleRemoveDevice\n"));
	return status;
}

/************************************************************************
* 函数名称:HelloWDMPnp
* 功能描述:对即插即用IRP进行处理
* 参数列表:
fdo:功能设备对象
Irp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
	IN PIRP Irp)
{
	PAGED_CODE();

	KdPrint(("Enter HelloWDMPnp\n"));
	NTSTATUS status = STATUS_SUCCESS;
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	static NTSTATUS(*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =
	{
		DefaultPnpHandler,		// IRP_MN_START_DEVICE
		DefaultPnpHandler,		// IRP_MN_QUERY_REMOVE_DEVICE
		HandleRemoveDevice,		// IRP_MN_REMOVE_DEVICE
		DefaultPnpHandler,		// IRP_MN_CANCEL_REMOVE_DEVICE
		DefaultPnpHandler,		// IRP_MN_STOP_DEVICE
		DefaultPnpHandler,		// IRP_MN_QUERY_STOP_DEVICE
		DefaultPnpHandler,		// IRP_MN_CANCEL_STOP_DEVICE
		DefaultPnpHandler,		// IRP_MN_QUERY_DEVICE_RELATIONS
		DefaultPnpHandler,		// IRP_MN_QUERY_INTERFACE
		DefaultPnpHandler,		// IRP_MN_QUERY_CAPABILITIES
		DefaultPnpHandler,		// IRP_MN_QUERY_RESOURCES
		DefaultPnpHandler,		// IRP_MN_QUERY_RESOURCE_REQUIREMENTS
		DefaultPnpHandler,		// IRP_MN_QUERY_DEVICE_TEXT
		DefaultPnpHandler,		// IRP_MN_FILTER_RESOURCE_REQUIREMENTS
		DefaultPnpHandler,		// 
		DefaultPnpHandler,		// IRP_MN_READ_CONFIG
		DefaultPnpHandler,		// IRP_MN_WRITE_CONFIG
		DefaultPnpHandler,		// IRP_MN_EJECT
		DefaultPnpHandler,		// IRP_MN_SET_LOCK
		DefaultPnpHandler,		// IRP_MN_QUERY_ID
		DefaultPnpHandler,		// IRP_MN_QUERY_PNP_DEVICE_STATE
		DefaultPnpHandler,		// IRP_MN_QUERY_BUS_INFORMATION
		DefaultPnpHandler,		// IRP_MN_DEVICE_USAGE_NOTIFICATION
		DefaultPnpHandler,		// IRP_MN_SURPRISE_REMOVAL
	};

	ULONG fcn = stack->MinorFunction;
	if (fcn >= arraysize(fcntab))
	{						// unknown function
		status = DefaultPnpHandler(pdx, Irp); // some function we don't know about
		return status;
	}						// unknown function

#if DBG
	static char* fcnname[] =
	{
		"IRP_MN_START_DEVICE",
		"IRP_MN_QUERY_REMOVE_DEVICE",
		"IRP_MN_REMOVE_DEVICE",
		"IRP_MN_CANCEL_REMOVE_DEVICE",
		"IRP_MN_STOP_DEVICE",
		"IRP_MN_QUERY_STOP_DEVICE",
		"IRP_MN_CANCEL_STOP_DEVICE",
		"IRP_MN_QUERY_DEVICE_RELATIONS",
		"IRP_MN_QUERY_INTERFACE",
		"IRP_MN_QUERY_CAPABILITIES",
		"IRP_MN_QUERY_RESOURCES",
		"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
		"IRP_MN_QUERY_DEVICE_TEXT",
		"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
		"",
		"IRP_MN_READ_CONFIG",
		"IRP_MN_WRITE_CONFIG",
		"IRP_MN_EJECT",
		"IRP_MN_SET_LOCK",
		"IRP_MN_QUERY_ID",
		"IRP_MN_QUERY_PNP_DEVICE_STATE",
		"IRP_MN_QUERY_BUS_INFORMATION",
		"IRP_MN_DEVICE_USAGE_NOTIFICATION",
		"IRP_MN_SURPRISE_REMOVAL",
	};

	KdPrint(("PNP Request (%s)\n", fcnname[fcn]));
#endif // DBG

	status = (*fcntab[fcn])(pdx, Irp);
	KdPrint(("Leave HelloWDMPnp\n"));
	return status;
}

/************************************************************************
* 函数名称:HelloWDMDispatchRoutine
* 功能描述:对缺省IRP进行处理
* 参数列表:
fdo:功能设备对象
Irp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,
	IN PIRP Irp)
{
	PAGED_CODE();
	KdPrint(("Enter HelloWDMDispatchRoutine\n"));
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;	// no bytes xfered
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	KdPrint(("Leave HelloWDMDispatchRoutine\n"));
	return STATUS_SUCCESS;
}

/************************************************************************
* 函数名称:HelloWDMUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
DriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject)
{
	PAGED_CODE();
	KdPrint(("Enter HelloWDMUnload\n"));
	KdPrint(("Leave HelloWDMUnload\n"));
}

头文件HelloWDM.h如下:
  1. <STRONG><SPAN style="FONT-SIZE: 18px">/************************************************************************  
  2. * 文件名称:HelloWDM.h                                                   
  3. * 作    者:张帆  
  4. * 完成日期:2007-11-1  
  5. *************************************************************************/  
  6.   
  7. #ifdef __cplusplus  
  8. extern "C"  
  9. {  
  10. #endif  
  11. #include <wdm.h>  
  12. #ifdef __cplusplus  
  13. }  
  14. #endif   
  15.   
  16. typedef struct _DEVICE_EXTENSION  
  17. {  
  18.     PDEVICE_OBJECT fdo;  
  19.     PDEVICE_OBJECT NextStackDevice;  
  20.     UNICODE_STRING ustrDeviceName;  // 设备名  
  21.     UNICODE_STRING ustrSymLinkName; // 符号链接名  
  22. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;  
  23.   
  24. #define PAGEDCODE code_seg("PAGE")  
  25. #define LOCKEDCODE code_seg()  
  26. #define INITCODE code_seg("INIT")  
  27.   
  28. #define PAGEDDATA data_seg("PAGE")  
  29. #define LOCKEDDATA data_seg()  
  30. #define INITDATA data_seg("INIT")  
  31.   
  32. #define arraysize(p) (sizeof(p)/sizeof((p)[0]))  
  33.   
  34. NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,  
  35.                            IN PDEVICE_OBJECT PhysicalDeviceObject);  
  36. NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,  
  37.                         IN PIRP Irp);  
  38. NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,  
  39.                                  IN PIRP Irp);  
  40. void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject);  
  41.   
  42. extern "C"  
  43. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,  
  44.                      IN PUNICODE_STRING RegistryPath);</SPAN></STRONG>  
/************************************************************************
* 文件名称:HelloWDM.h                                                 
* 作    者:张帆
* 完成日期:2007-11-1
*************************************************************************/

#ifdef __cplusplus
extern "C"
{
#endif
#include <wdm.h>
#ifdef __cplusplus
}
#endif 

typedef struct _DEVICE_EXTENSION
{
    PDEVICE_OBJECT fdo;
    PDEVICE_OBJECT NextStackDevice;
	UNICODE_STRING ustrDeviceName;	// 设备名
	UNICODE_STRING ustrSymLinkName;	// 符号链接名
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

#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]))

NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT DriverObject,
                           IN PDEVICE_OBJECT PhysicalDeviceObject);
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
                        IN PIRP Irp);
NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,
								 IN PIRP Irp);
void HelloWDMUnload(IN PDRIVER_OBJECT DriverObject);

extern "C"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
                     IN PUNICODE_STRING RegistryPath);




有兴趣的朋友
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
VS2015+WDK10是指在Windows 10系统下搭建驱动开发环境的组合。首先需要安装Visual Studio 2015 Enterprise,然后再安装WDK 10。注意,WDK10必须在安装VS2015之后进行安装。安装完成后,可以在VS2015的界面菜单上看到driver菜单,从而可以进行驱动开发。\[1\] 在搭建环境时,可以选择下载Community版本的VS2015,因为这个版本是免费且功能齐全的。安装包的大小大约为7G左右。安装完成后,需要选择安装Visual C++和Windows 10 SDK。\[3\] 通过搭建VS2015+WDK10的环境,可以在Windows 10系统上直接新建驱动项目并编译通过,然后在Win7及以上的系统上运行。这样可以避免自己制作模板等繁琐的步骤。\[2\] #### 引用[.reference_title] - *1* [Win10下VS2015(WDK10)驱动开发环境配置](https://blog.csdn.net/liuyez123/article/details/50857621)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [VS2015+WDK10+Win10 Win7以上系统驱动发开环境搭建](https://blog.csdn.net/wlanye/article/details/94962999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [VS2015 + WDK10](https://blog.csdn.net/qq_25867649/article/details/54598506)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值