一个简单的WDM驱动程序

  1 #ifdef __cplusplus
  2 extern "C"
  3 {
  4 #endif
  5 #include <wdm.h>    // 不同点之一
  6 #ifdef __cplusplus
  7 }
  8 #endif
  9 
 10 typedef struct _DEVICE_EXTENSION
 11 {
 12     PDEVICE_OBJECT fdo;
 13     PDEVICE_OBJECT NextStackDevice;
 14     UNICODE_STRING ustrDeviceName;
 15     UNICODE_STRING ustrSymbolicName;
 16 }DEVICE_EXTENSION, *PDEVICE_EXTENSION;
 17 
 18 #define PAGEDCODE    code_seg("PAGE")
 19 #define LOCKEDCODE    code_seg()
 20 #define INITCODE    code_seg("INIT")
 21 #define PAGEDDATA    data_seg("PAGE")
 22 #define LOCKEDDATA    data_seg();
 23 #define INITDATA    data_seg("INIT")
 24 
 25 #define arraysize(p) (sizeof(p) / sizeof((p)[0]))
 26 #pragma PAGEDCODE
 27 
 28 
 29 //////////////////////////////////////////////////////////////////////////
 30 // 添加设备的处理例程
 31 #pragma PAGEDCODE
 32 NTSTATUS HelloWDMAddDevice(IN PDRIVER_OBJECT pDriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
 33 {
 34     PAGED_CODE();    // PAGED_CODE()宏确保本函数运行在低于APC_LEVEL的中断优先级级别上
 35     KdPrint(("Enter HelloWDMAddDevice\n"));
 36 
 37     NTSTATUS status;
 38     PDEVICE_OBJECT fdo;
 39     UNICODE_STRING devName;
 40     
 41     RtlInitUnicodeString(&devName, L"\\Device\\MyWDMDevice");
 42     IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &devName, FILE_DEVICE_UNKNOWN, 
 43                    0, FALSE, &fdo);
 44 
 45     PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
 46     pdx->fdo = fdo;
 47     pdx->ustrDeviceName = devName;
 48     // 将fdo附加到pdo上
 49     pdx->NextStackDevice = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
 50     
 51     UNICODE_STRING symName;
 52     RtlInitUnicodeString(&symName, L"\\DosDevice\\helloWDM");
 53     status = IoCreateSymbolicLink(&symName, &devName);
 54 
 55     if (!NT_SUCCESS(status))
 56     {
 57         IoDeleteSymbolicLink(&symName);
 58         status = IoCreateSymbolicLink(&symName, &devName);
 59         if (!NT_SUCCESS(status))
 60         {
 61             return status;
 62         }
 63     }
 64 
 65     fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
 66     fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 67 
 68     KdPrint(("Leaving AddDevice!"));
 69     return STATUS_SUCCESS;
 70 }
 71 //////////////////////////////////////////////////////////////////////////
 72 // 对PNP IRP进行默认处理(叫下层驱动对此pnp进行处理)
 73 #pragma PAGEDCODE
 74 NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)
 75 {
 76     PAGED_CODE();
 77     KdPrint(("Enter DefaultPnpHandler..."));
 78     IoSkipCurrentIrpStackLocation(Irp);
 79     KdPrint(("Leaving DefaultPnpHandler"));
 80     return IoCallDriver(pdx->NextStackDevice, Irp);
 81 }
 82 
 83 
 84 //////////////////////////////////////////////////////////////////////////
 85 // IRP_MN_PNP_REMOVE_DEVICE这个irp的处理例程
 86 #pragma PAGEDCODE
 87 NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
 88 {
 89     PAGED_CODE();
 90     KdPrint(("Entering HandleRemoveDevice"));
 91 
 92     Irp->IoStatus.Status = STATUS_SUCCESS;
 93     NTSTATUS status = DefaultPnpHandler(pdx, Irp);
 94     IoDeleteSymbolicLink(&pdx->ustrSymbolicName);
 95 
 96     // 调用IoDetachDevice将fdo从设备栈中脱离
 97     if (pdx->NextStackDevice)
 98     {
 99         IoDetachDevice(pdx->NextStackDevice);
100     }
101 
102     // 删除FDO
103     IoDeleteDevice(pdx->fdo);
104     KdPrint(("Leave HandleRemoveDevice"));
105     return status;
106 }
107 
108 #pragma PAGEDCODE
109 NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo, 
110                                  IN PIRP Irp)
111 {
112     PAGED_CODE();
113     KdPrint(("Entering HelloWDMDispatchRoutine..."));
114     Irp->IoStatus.Status = STATUS_SUCCESS;
115     Irp->IoStatus.Information = 0;
116     IoCompleteRequest(Irp, IO_NO_INCREMENT);
117     KdPrint(("leaving HelloWDMDispatchRoutine..."));
118     return STATUS_SUCCESS;
119 }
120 
121 #pragma PAGEDCODE
122 void HelloWDMUnload(IN PDRIVER_OBJECT pDriverObject)
123 {
124     PAGED_CODE();
125     KdPrint(("Enter HelloWDMUnload"));
126     KdPrint(("Leaving HelloWDMUnload"));
127 }
128 
129 //////////////////////////////////////////////////////////////////////////
130 // pnp处理例程
131 #pragma PAGEDCODE
132 NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
133 {
134     PAGED_CODE();
135 
136     KdPrint(("Entering HelloWDMPnp.."));
137     NTSTATUS status = STATUS_SUCCESS;
138     PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
139     PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
140 
141     static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) = 
142     {
143         DefaultPnpHandler,    // IRP_MN_START_DEVICE
144         DefaultPnpHandler,  // IRP_MN_QUERY_REMOVE_DEVICE
145         HandleRemoveDevice,    // IRP_MN_REMOVE_DEVICE !!注意,在这里添加了相应的处理程序
146         DefaultPnpHandler,    // IRP_MN_CANCEL_REMOVE_DEVICE
147         DefaultPnpHandler,    // IRP_MN_STOP_DEVICE
148         DefaultPnpHandler,    // IRP_MN_QUERY_STOP_DEVICE
149         DefaultPnpHandler,    // IRP_MN_CANCEL_STOP_DEVICE
150         DefaultPnpHandler,    // IRP_MN_QUERY_DEVICE_RELATIONS
151         DefaultPnpHandler,    // IRP_MN_QUERY_INTERFACE
152         DefaultPnpHandler,    // IRP_MN_QUERY_CAPABILITIES
153         DefaultPnpHandler,    // IRP_MN_QUERY_RESOURCES
154         DefaultPnpHandler,    // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
155         DefaultPnpHandler,  // IRP_MN_QUERY_DEVICE_TEXT
156         DefaultPnpHandler,    // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
157         DefaultPnpHandler,
158         DefaultPnpHandler,    // IRP_MN_READ_CONFIG
159         DefaultPnpHandler,    // IRP_MN_WRITE_CONFIG
160         DefaultPnpHandler,    // IRP_MN_EJECT
161         DefaultPnpHandler,    // IRP_MN_SET_LOCK
162         DefaultPnpHandler,    // IRP_MN_QUERY_ID
163         DefaultPnpHandler,    // IRP_MN_QUERY_PNP_DEVICE_STAT
164         DefaultPnpHandler,    // IRP_MN_QUERY_BUS_INFORMATION
165         DefaultPnpHandler,    // IRP_MN_DEVICE_USAGE_NOTIFICATION
166         DefaultPnpHandler,    // IRP_MN_SURPRISE_REMOVAL
167     };
168 
169     ULONG fcn = stack->MinorFunction;
170     if (fcn >= arraysize(fcntab))
171     {        
172         // 未知的IRP类型
173         status = DefaultPnpHandler(pdx, Irp);
174         return status;
175     }
176 
177 #if DBG
178     static char * fcnname[] = 
179     {
180         "IRP_MN_START_DEVICE",
181         "IRP_MN_QUERY_REMOVE_DEVICE",
182         "IRP_MN_REMOVE_DEVICE",
183         "IRP_MN_CANCEL_REMOVE_DEVICE",
184         "IRP_MN_STOP_DEVICE",
185         "IRP_MN_QUERY_STOP_DEVICE",
186         "IRP_MN_CANCEL_STOP_DEVICE",
187         "IRP_MN_QUERY_DEVICE_RELATIONS",
188         "IRP_MN_QUERY_INTERFACE",
189         "IRP_MN_QUERY_CAPABILITIES",
190         "IRP_MN_QUERY_RESOURCES",
191         "IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
192         "IRP_MN_QUERY_DEVICE_TEXT",
193         "IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
194         "",
195         "IRP_MN_READ_CONFIG",
196         "IRP_MN_WRITE_CONFIG",
197         "IRP_MN_EJECT",
198         "IRP_MN_SET_LOCK",
199         "IRP_MN_QUERY_ID",
200         "IRP_MN_QUERY_PNP_DEVICE_STAT",
201         "IRP_MN_QUERY_BUS_INFORMATION",
202         "IRP_MN_DEVICE_USAGE_NOTIFICATION",
203         "IRP_MN_SURPRISE_REMOVAL"
204     };
205 
206     KdPrint(("PNP Request(%s)\n", fcnname[fcn]));
207 #endif //DBG
208     status = (*fcntab[fcn])(pdx, Irp);
209     KdPrint(("Leave helloWDM Pnp\n"));
210 
211     return status;
212 }
213 
214 //////////////////////////////////////////////////////////////////////////
215 // 驱动程序入口函数
216 extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
217 {
218     KdPrint(("Enter DriverEntry -- gmh"));
219 
220     DriverObject->DriverExtension->AddDevice = HelloWDMAddDevice;
221     DriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
222     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
223     DriverObject->MajorFunction[IRP_MJ_CREATE] = 
224     DriverObject->MajorFunction[IRP_MJ_READ] = 
225     DriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;
226     DriverObject->DriverUnload = HelloWDMUnload;
227 
228     KdPrint(("Leaving DriverEntry -- gmh!"));
229     return STATUS_SUCCESS;
230 }
posted @ 2012-09-19 09:33  特洛伊人  阅读(843)  评论(0编辑  收藏  举报